diff --git a/.codex/skills/mendcode-release-flow/SKILL.md b/.codex/skills/mendcode-release-flow/SKILL.md new file mode 100644 index 00000000..bb59cbdb --- /dev/null +++ b/.codex/skills/mendcode-release-flow/SKILL.md @@ -0,0 +1,66 @@ +--- +name: mendcode-release-flow +description: Use for MendCode project changes, release prep, PR promotion, version bump decisions, changelog updates, installer validation, and dev-to-main synchronization. Trigger whenever work may ship to users, touches package metadata/versioning, installer/update/health/changelog behavior, or the user mentions bumping a version, release, changelog, PR to dev/main, or letting the user test before shipping. +--- + +# MendCode Release Flow + +Follow this workflow for MendCode changes that may ship. + +## Non-negotiables + +- For maintainer/agent work inside the main MendCode repository, use the local `dev` branch by default. Do not create a separate branch unless the user explicitly asks for one, the current worktree has unrelated changes in the same files, or a GitHub contribution flow requires it. +- Preserve unrelated local changes. If the active checkout is dirty, inspect the touched files first. Work in-place on `dev` only when the requested files are clean or the existing edits are clearly part of the same user-approved task. +- If unrelated dirty files conflict with the task, stop and explain the blocker before creating a worktree or branch. +- Before editing release/version/package files, ask or verify whether another agent already bumped the version locally or remotely. +- Do not publish a release, merge to `main`, or overwrite a user worktree without explicit user intent. +- Never leave open public PRs/issues as noise. Close, merge, or explain exactly why they must remain open. +- Never hide security/release failures. If a supply-chain, secret, CodeQL, release, or installer check fails, keep the issue open until fixed or document the exact reason it is accepted. + +## Branch Policy + +- Internal MendCode maintainers and local agents work on `dev` by default. +- External contributors should use a fork or feature branch and open a PR targeting `dev`, not `main`. +- `main` is the public release branch. Only promote `dev` to `main` after CI passes, the user-visible change has been tested, version/changelog state is correct, and the user intends to ship. +- For internal promotion, prefer a direct `dev` -> `main` PR. Do not create `codex/*` promotion branches unless GitHub cannot represent the intended merge directly or a conflict must be resolved outside the user's local checkout. +- If an emergency promotion branch/worktree is unavoidable, delete the remote branch, local branch, and temporary worktree immediately after merge or close. +- Local release or promotion workspaces under `$TMPDIR/mendcode` must be run through `src/mendcode/script/release` or its sourced cleanup helper so the current workspace's `src/mendcode/node_modules` is removed on success or failure. Do not run broad age-based temp cleaners or delete unowned/active temp workspaces. +- Do not merge random branches directly into `main`. Bring useful branches back through PRs to `dev`, then delete stale branches after merge. +- Before starting, check whether another PR/agent already contains the same work. Prefer continuing the existing local `dev` work over creating a duplicate branch. + +## Standard Flow + +1. Inspect `git status`, `git worktree list`, open PRs/issues, latest GitHub release, `origin/dev`, and `origin/main`. +2. If a version bump may be needed, determine whether the bump already exists: + - Check `CHANGELOG.md`. + - Check `src/mendcode/packages/opencode/package.json`. + - Check extension/package metadata such as `src/mendcode/packages/extensions/zed/extension.toml`. + - Check recent merged PRs and tags. +3. Ask the user before choosing a new version unless the version is already clearly bumped by another agent. +4. Implement the change on local `dev` unless the Branch Policy says a separate branch/worktree is required. +5. Run focused tests/scripts for the touched area. Use existing repo scripts and generated-client/build checks when relevant. +6. Stop and let the user test locally when the change is user-visible. Do not bump/changelog/merge until the user says it works, unless they explicitly ask for fully autonomous shipping. +7. After the user confirms it works: + - Bump version if needed. + - Add or update `CHANGELOG.md`. + - Open a PR to `dev`, wait for CI, and merge. + - Promote `dev` to `main` with a direct PR whenever possible, resolving conflicts deliberately. + - Sync `main` back to `dev` if needed so both branches have the same tree. +8. If releasing: + - Use the Release workflow from `main`. + - Verify SHA256SUMS. + - Publish with real release notes/changelog, not only a SHA. + - Smoke-test the public installer in a temporary `HOME`. + +## Required Checks + +- For code: run the narrow test file or command covering the changed path. +- For release: verify `mendcode --version` prints the release version. +- For installer: test `curl -fsSL https://raw.githubusercontent.com/MendCode/MendCode/main/src/mendcode/install | bash -s -- --no-modify-path` in a temporary `HOME`. +- For supply chain: verify secret scan, dependency review/vulnerability checks, CodeQL/Semgrep, and release artifact checksums before publishing. +- For branch hygiene: verify open PRs/issues, latest release, branches, and `git diff origin/main..origin/dev`. +- For local safety: before committing, review `git diff --name-only` and stage only files intentionally changed for this task. + +## Reporting + +Report only facts that were verified: PR numbers, release URL, version, test commands, and installer result. If the user asked not to report process, keep the final short. diff --git a/.codex/skills/mendcode-session-guardrails/SKILL.md b/.codex/skills/mendcode-session-guardrails/SKILL.md new file mode 100644 index 00000000..d4973144 --- /dev/null +++ b/.codex/skills/mendcode-session-guardrails/SKILL.md @@ -0,0 +1,46 @@ +--- +name: mendcode-session-guardrails +description: Use at the start of every task in the MendCode repository. Enforces local-only work, risk-based validation, minimal changes, and protection of disk, memory, CPU, and TUI rendering. Load this skill before inspecting or editing code, docs, config, tests, or runtime files. +--- + +# MendCode Session Guardrails + +Apply these rules to every task in this repository unless the user explicitly overrides a specific rule. + +## GitHub and external writes + +- Work locally by default. Never run `git push`, create, update, merge, or close GitHub PRs/issues, publish releases/packages, upload artifacts, or post GitHub comments. +- A direct user request authorizes only that specific external write. Otherwise stop before it and ask. +- Read-only commands such as `git status`, `git diff`, branch inspection, or remote inspection are allowed when relevant. +- Do not create a commit unless the user explicitly asks for one. + +## Scope and non-regression + +- Inspect the worktree before editing. Preserve unrelated changes; never reset, clean, revert, or overwrite them. +- Read the relevant callers, tests, configuration, and nearby patterns before changing behavior. +- Make the smallest patch that solves the requested problem. Avoid broad refactors, dependency changes, generated output, migrations, or public API changes unless they are required. +- Do not claim that MendCode is safe merely because a change is small: check imports, data flow, error paths, and affected callers. +- For TUI/runtime work, preserve state ownership and event flow. Do not introduce render loops, duplicate subscriptions, unstable keys, unbounded concurrency, or unnecessary rerenders. + +## Tests and validation + +- For executable behavior, run the narrowest relevant test, typecheck, lint, or runtime smoke check after editing. +- For a genuinely tiny non-executable change (for example, a skill, documentation, or formatting-only edit), skip the full test suite and validate the file format, frontmatter, and focused diff instead. +- Treat configuration changes as executable when they can alter runtime behavior; validate them accordingly. +- Do not run a full build or full test suite by habit. Expand validation only when the risk or repository workflow requires it, or the user asks. +- Report every check that actually ran and clearly state checks that were intentionally skipped. + +## Disk, memory, CPU, and rendering budget + +- Prefer targeted reads/searches and bounded commands over full-repository scans, large logs, or repeated whole-file rewrites. +- Do not create unnecessary generated files, caches, dumps, screenshots, or temporary artifacts; clean up anything required for validation. +- Avoid unbounded loops, polling, watchers, retries, uncontrolled parallelism, and duplicate work. +- Keep memory and CPU usage bounded with pagination, lazy work, bounded concurrency, and existing caches/abstractions where appropriate. +- For UI/TUI changes, avoid rendering entire histories or large collections when only a visible/changed slice is needed. +- If a change could affect performance or resource usage, inspect and validate that path specifically instead of assuming it is harmless. + +## Stop conditions and reporting + +- Ask before destructive actions, production/billing changes, security-impacting changes, or material scope expansion. +- Before finishing, inspect only the relevant diff and confirm no accidental artifacts or unrelated files were changed. +- Report concisely: changed files, real validation results, skipped checks, blockers, and non-goals. diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 00000000..65a57bb5 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,66 @@ +name: Bug report +description: Report a reproducible MendCode bug +title: "[Bug]: " +labels: + - bug +body: + - type: textarea + id: summary + attributes: + label: Summary + description: What happened? + validations: + required: true + - type: textarea + id: reproduce + attributes: + label: Steps to reproduce + description: Give the smallest reproduction you can. + placeholder: | + 1. Run ... + 2. Open ... + 3. See ... + validations: + required: true + - type: textarea + id: expected + attributes: + label: Expected behavior + validations: + required: true + - type: textarea + id: actual + attributes: + label: Actual behavior + validations: + required: true + - type: input + id: version + attributes: + label: MendCode version + placeholder: mend --version + - type: input + id: os + attributes: + label: OS + placeholder: macOS, Linux, Windows, WSL + - type: input + id: terminal + attributes: + label: Terminal + placeholder: Ghostty, iTerm2, Terminal.app, Windows Terminal + - type: textarea + id: config + attributes: + label: Relevant config + description: Redact secrets. Do not paste API keys or private prompts. + render: text + - type: checkboxes + id: checks + attributes: + label: Checks + options: + - label: I searched existing issues and discussions. + required: true + - label: I removed secrets and private config from this report. + required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..260120b9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: false +contact_links: + - name: Discussions + url: https://github.com/MendCode/MendCode/discussions + about: Ask setup, package, mflow, TUI customization, and plugin/widget questions. + - name: Private vulnerability report + url: https://github.com/MendCode/MendCode/security/advisories/new + about: Report security issues privately. Do not open public issues for vulnerabilities. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 00000000..084e2925 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,45 @@ +name: Feature request +description: Suggest a MendCode feature or improvement +title: "[Feature]: " +labels: + - enhancement +body: + - type: textarea + id: problem + attributes: + label: Problem + description: What user problem should this solve? + validations: + required: true + - type: textarea + id: solution + attributes: + label: Desired behavior + description: What should MendCode do? + validations: + required: true + - type: textarea + id: alternatives + attributes: + label: Alternatives considered + - type: dropdown + id: area + attributes: + label: Area + options: + - CLI/setup + - TUI customization + - Plugins/widgets + - Packages/team sharing + - mflow + - TSM/worktrees + - Models/providers + - Docs + - Other + - type: checkboxes + id: checks + attributes: + label: Checks + options: + - label: I searched existing issues and discussions. + required: true diff --git a/.github/ISSUE_TEMPLATE/question.yml b/.github/ISSUE_TEMPLATE/question.yml new file mode 100644 index 00000000..c20bdffd --- /dev/null +++ b/.github/ISSUE_TEMPLATE/question.yml @@ -0,0 +1,21 @@ +name: Question +description: Ask a usage question +title: "[Question]: " +labels: + - question +body: + - type: markdown + attributes: + value: For general usage help, GitHub Discussions may be a better place than Issues. + - type: textarea + id: question + attributes: + label: Question + description: What are you trying to do? + validations: + required: true + - type: textarea + id: context + attributes: + label: Context + description: Include commands, docs links, or config snippets. Redact secrets. diff --git a/.github/codeql/codeql-config.yml b/.github/codeql/codeql-config.yml new file mode 100644 index 00000000..ef2e55b6 --- /dev/null +++ b/.github/codeql/codeql-config.yml @@ -0,0 +1,4 @@ +name: MendCode CodeQL + +paths-ignore: + - src/mendcode/packages/opencode/script/run-workspace-server diff --git a/.github/dependabot.yml b/.github/dependabot.yml index dc429ced..c09f3e0e 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -9,6 +9,8 @@ updates: time: "09:00" timezone: "America/New_York" open-pull-requests-limit: 0 + cooldown: + default-days: 7 groups: bun-dependencies: patterns: @@ -27,6 +29,8 @@ updates: time: "09:05" timezone: "America/New_York" open-pull-requests-limit: 0 + cooldown: + default-days: 7 groups: bun-github-action: patterns: @@ -45,6 +49,8 @@ updates: time: "09:10" timezone: "America/New_York" open-pull-requests-limit: 0 + cooldown: + default-days: 7 groups: bun-console-resource: patterns: @@ -63,6 +69,8 @@ updates: time: "09:15" timezone: "America/New_York" open-pull-requests-limit: 0 + cooldown: + default-days: 7 groups: bun-vscode-sdk: patterns: @@ -81,6 +89,8 @@ updates: time: "09:30" timezone: "America/New_York" open-pull-requests-limit: 0 + cooldown: + default-days: 7 groups: github-actions: patterns: diff --git a/.github/osv-release.toml b/.github/osv-release.toml new file mode 100644 index 00000000..0e900e17 --- /dev/null +++ b/.github/osv-release.toml @@ -0,0 +1,3 @@ +[[IgnoredVulns]] +id = "GHSA-j965-2qgj-vjmq" +reason = "aws-sdk v2 has no fixed version reported by OSV. It is retained only as a transitive package while release artifacts are built with scripts disabled, SBOM, and provenance attestations." diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..0371a57d --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,32 @@ +## Summary + +Describe what changed and why. + +## Type + +- [ ] Bug fix +- [ ] Feature +- [ ] Documentation +- [ ] Refactor +- [ ] Release/package maintenance +- [ ] Security hardening + +## Verification + +List the commands or manual checks you ran. + +```bash + +``` + +## Screenshots or Recordings + +Required for TUI/UI-facing changes when practical. + +## Checklist + +- [ ] I kept this PR focused. +- [ ] I tested the affected behavior. +- [ ] I updated docs when behavior changed. +- [ ] I did not include secrets, private config, or unrelated local files. +- [ ] I checked whether release assets, installer behavior, or package docs need updates. diff --git a/.github/release.yml b/.github/release.yml new file mode 100644 index 00000000..2c6efac1 --- /dev/null +++ b/.github/release.yml @@ -0,0 +1,25 @@ +changelog: + exclude: + labels: + - ignore-for-release + authors: + - dependabot + categories: + - title: Features + labels: + - enhancement + - feature + - title: Fixes + labels: + - bug + - fix + - title: Documentation + labels: + - documentation + - docs + - title: Security + labels: + - security + - title: Other + labels: + - "*" diff --git a/.github/scripts/supply-chain-preflight.sh b/.github/scripts/supply-chain-preflight.sh new file mode 100755 index 00000000..5b4bf49a --- /dev/null +++ b/.github/scripts/supply-chain-preflight.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +set -euo pipefail + +root=$(git rev-parse --show-toplevel) +cd "$root" + +failures=() + +add_failure() { + failures+=("$1") +} + +while IFS= read -r -d '' file; do + case "$file" in + .git/*|*/node_modules/*|*/dist/*) continue ;; + esac + if LC_ALL=C grep -nP '[\x{200B}\x{200C}\x{200D}\x{200E}\x{200F}\x{202A}-\x{202E}\x{2066}-\x{2069}\x{FEFF}]' "$file" >/tmp/mendcode-invisible.$$ 2>/dev/null; then + add_failure "Invisible Unicode control found in $file" + cat /tmp/mendcode-invisible.$$ >&2 || true + fi +done < <(git ls-files -z) +rm -f /tmp/mendcode-invisible.$$ + +if git ls-files -z | grep -zE '(^|/)\.env($|\.)|(^|/).*\.(pem|key|p12|pfx)$' | grep -zvE '\.env\.example$' >/tmp/mendcode-risky-files.$$; then + add_failure "Risky secret-like tracked file path found" + tr '\0' '\n' &2 +fi +rm -f /tmp/mendcode-risky-files.$$ + +while IFS= read -r -d '' file; do + while IFS= read -r line; do + ref=$(printf '%s\n' "$line" | sed -E 's/^.*uses:[[:space:]]*[^@]+@([^[:space:]#'\''"]+).*$/\1/') + case "$ref" in + [0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]) + ;; + *) + add_failure "Workflow action is not pinned to a full commit SHA: $file :: $line" + ;; + esac + done < <(grep -nE 'uses: [^[:space:]#]+@' "$file" | grep -vE 'uses: docker://' || true) +done < <(find .github/workflows -type f \( -name '*.yml' -o -name '*.yaml' \) -print0) + +if grep -RInP 'curl .*\| *(bash|sh)|wget .*\| *(bash|sh)' .github src/mendcode/script src/mendcode/packages/opencode/script 2>/dev/null \ + | grep -v '^\.github/scripts/supply-chain-preflight\.sh:'; then + add_failure "Pipe-to-shell command found in automation path" +fi + +if git ls-files | grep -E '(^|/)opencode-.*\.(zip|tar\.gz)$' | grep -v '^src/mendcode/packages/opencode/dist/' >/dev/null; then + add_failure "Found opencode-named release archive outside ignored dist output" +fi + +if [ "${#failures[@]}" -gt 0 ]; then + printf 'Supply-chain preflight failed:\n' >&2 + printf ' - %s\n' "${failures[@]}" >&2 + exit 1 +fi + +echo "Supply-chain preflight OK" diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 00000000..120fe2ff --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,74 @@ +name: CodeQL + +on: + pull_request: + paths-ignore: + - "**/*.md" + - "docs/**" + - "src/mendcode/packages/web/src/content/docs/**" + - "src/mendcode/packages/web/public/**" + - "src/mendcode/packages/web/README.md" + - "CHANGELOG.md" + - "ACKNOWLEDGEMENTS.md" + - "CODE_OF_CONDUCT.md" + - "CONTRIBUTING.md" + - "LICENSE" + - "SECURITY.md" + - "SUPPORT.md" + push: + branches: + - main + paths-ignore: + - "**/*.md" + - "docs/**" + - "src/mendcode/packages/web/src/content/docs/**" + - "src/mendcode/packages/web/public/**" + - "src/mendcode/packages/web/README.md" + - "CHANGELOG.md" + - "ACKNOWLEDGEMENTS.md" + - "CODE_OF_CONDUCT.md" + - "CONTRIBUTING.md" + - "LICENSE" + - "SECURITY.md" + - "SUPPORT.md" + schedule: + - cron: "31 13 * * 1" + workflow_dispatch: + +permissions: + contents: read + security-events: write + +concurrency: + group: codeql-${{ github.ref }} + cancel-in-progress: true + +jobs: + analyze: + name: Analyze JavaScript and TypeScript + runs-on: blacksmith-4vcpu-ubuntu-2404 + timeout-minutes: 20 + # Reuse main's CodeQL database for pull requests and analyze the diff with + # the existing code as context. CodeQL falls back to a full scan when the + # base database, diff ranges, or runner requirements are unavailable. + env: + CODEQL_ACTION_OVERLAY_ANALYSIS: "true" + CODEQL_ACTION_OVERLAY_ANALYSIS_CODE_SCANNING_JAVASCRIPT: "true" + CODEQL_ACTION_DIFF_INFORMED_QUERIES: "true" + steps: + - name: Checkout repository + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 + with: + persist-credentials: false + + - name: Initialize CodeQL + uses: github/codeql-action/init@411bbbe57033eedfc1a82d68c01345aa96c737d7 + with: + languages: javascript-typescript + build-mode: none + config-file: ./.github/codeql/codeql-config.yml + + - name: Perform CodeQL analysis + uses: github/codeql-action/analyze@411bbbe57033eedfc1a82d68c01345aa96c737d7 + with: + category: "/language:javascript-typescript" diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml new file mode 100644 index 00000000..317da9b3 --- /dev/null +++ b/.github/workflows/dependency-review.yml @@ -0,0 +1,35 @@ +name: Dependency Review + +on: + pull_request: + branches: + - main + - dev + +permissions: + contents: read + pull-requests: read + +concurrency: + group: dependency-review-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + dependency-review: + name: Dependency review + runs-on: blacksmith-4vcpu-ubuntu-2404 + timeout-minutes: 10 + steps: + - name: Checkout repository + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 + with: + persist-credentials: false + + - name: Review dependency changes + uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 + with: + fail-on-severity: high + deny-licenses: GPL-2.0, GPL-3.0, AGPL-1.0, AGPL-3.0 + # These existing packages publish missing/non-canonical SPDX metadata; keep the license gate enabled for all other dependencies. + allow-dependencies-licenses: "pkg:npm/@pierre/diffs, pkg:npm/@openauthjs/openauth, pkg:npm/opencontrol" + comment-summary-in-pr: always diff --git a/.github/workflows/prerelease.yml b/.github/workflows/prerelease.yml new file mode 100644 index 00000000..25714f55 --- /dev/null +++ b/.github/workflows/prerelease.yml @@ -0,0 +1,91 @@ +name: Prerelease candidate + +on: + schedule: + - cron: "23 6 * * *" + workflow_dispatch: + inputs: + channel: + description: "Candidate channel" + type: choice + options: [beta, nightly] + default: beta + required: true + beta_number: + description: "Positive beta sequence, required for beta" + type: string + required: false + dry_run: + description: "Keep artifacts in Actions without creating a release draft" + type: boolean + default: true + required: true + +permissions: + contents: read + +concurrency: + group: prerelease-candidate + cancel-in-progress: false + +jobs: + select: + runs-on: blacksmith-4vcpu-ubuntu-2404 + outputs: + changed: ${{ steps.candidate.outputs.changed }} + version: ${{ steps.candidate.outputs.version }} + sha: ${{ steps.candidate.outputs.sha }} + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 + with: + ref: dev + fetch-depth: 0 + persist-credentials: false + - name: Select immutable candidate + id: candidate + shell: bash + env: + CHANNEL: ${{ inputs.channel || 'nightly' }} + BETA_NUMBER: ${{ inputs.beta_number }} + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} + run: | + set -euo pipefail + sha="$(git rev-parse HEAD)" + base="$(node -p 'JSON.parse(require("fs").readFileSync("src/mendcode/packages/opencode/package.json", "utf8")).version')" + [[ "$base" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || { echo "Package version must be stable semver" >&2; exit 1; } + if [ "$CHANNEL" = nightly ]; then + # Tags are never moved. Any successful draft on this source already + # represents the daily candidate, including reruns and manual runs. + previous="$(gh api "repos/${GH_REPO}/releases?per_page=100" --jq '.[] | select(.tag_name | test("^v[0-9]+\\.[0-9]+\\.[0-9]+-nightly\\.")) | .target_commitish')" + if git tag --points-at "$sha" | grep -Eq '^v[0-9]+\.[0-9]+\.[0-9]+-nightly\.' || printf '%s\n' "$previous" | grep -Fxq "$sha"; then + echo "changed=false" >> "$GITHUB_OUTPUT" + exit 0 + fi + version="${base}-nightly.$(date -u +%Y%m%d).${GITHUB_RUN_ID}" + elif [ "$CHANNEL" = beta ]; then + [[ "$BETA_NUMBER" =~ ^[1-9][0-9]*$ ]] || { echo "beta_number must be positive" >&2; exit 1; } + version="${base}-beta.${BETA_NUMBER}" + else + echo "Unsupported prerelease channel" >&2 + exit 1 + fi + echo "changed=true" >> "$GITHUB_OUTPUT" + echo "sha=$sha" >> "$GITHUB_OUTPUT" + echo "version=$version" >> "$GITHUB_OUTPUT" + + build: + needs: select + if: needs.select.outputs.changed == 'true' + permissions: + contents: write + attestations: write + id-token: write + uses: ./.github/workflows/release.yml + with: + version: ${{ needs.select.outputs.version }} + source_sha: ${{ needs.select.outputs.sha }} + prerelease: true + # Scheduled runs create reviewable drafts. Publication still requires the + # platform acceptance gates and an explicit promotion; never age-based. + dry_run: ${{ github.event_name == 'workflow_dispatch' && inputs.dry_run }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..c2b785c2 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,539 @@ +name: Release + +on: + workflow_dispatch: + inputs: + version: + description: "Release version without leading v, for example 1.14.39" + required: true + type: string + dry_run: + description: "Build and attest assets without publishing a GitHub Release" + required: true + default: true + type: boolean + prerelease: + description: "Mark the GitHub Release as prerelease" + required: true + default: false + type: boolean + source_sha: + description: "Exact candidate commit already tested; required when publishing" + required: true + type: string + workflow_call: + inputs: + version: + required: true + type: string + dry_run: + required: true + type: boolean + prerelease: + required: true + type: boolean + source_sha: + required: true + type: string + +permissions: + contents: read + +concurrency: + group: release-${{ inputs.version }} + cancel-in-progress: false + +jobs: + build-release: + name: Build Linux and Windows baseline release assets + runs-on: blacksmith-4vcpu-ubuntu-2404 + timeout-minutes: 60 + permissions: + attestations: write + contents: read + id-token: write + env: + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} + VERSION: ${{ inputs.version }} + MENDCODE_VERSION: ${{ inputs.version }} + OPENCODE_VERSION: ${{ inputs.version }} + BUN_INSTALL_CACHE_DIR: /tmp/mendcode-bun-cache + steps: + - name: Validate release input + shell: bash + run: | + set -euo pipefail + if [[ ! "${VERSION}" =~ ^[0-9]+\.[0-9]+\.[0-9]+([-+][0-9A-Za-z.-]+)?$ ]]; then + echo "version must be semver without leading v: ${VERSION}" >&2 + exit 1 + fi + if [[ ! "${SOURCE_SHA}" =~ ^[a-f0-9]{40}$ ]]; then + echo "source_sha must be the exact candidate commit" >&2 + exit 1 + fi + env: + SOURCE_SHA: ${{ inputs.source_sha }} + + - name: Checkout repository + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 + with: + fetch-depth: 0 + persist-credentials: false + ref: ${{ inputs.source_sha }} + + - name: Ensure release runs from main + if: ${{ inputs.dry_run == false }} + shell: bash + run: | + set -euo pipefail + branch="${GITHUB_REF_NAME:-}" + if [ "$PRERELEASE" = "false" ] && [ "$branch" != "main" ]; then + echo "publishing releases is only allowed from main; current ref is ${branch}" >&2 + exit 1 + fi + if [ "$PRERELEASE" = "false" ]; then + git merge-base --is-ancestor HEAD origin/main + else + git merge-base --is-ancestor HEAD origin/dev + fi + env: + PRERELEASE: ${{ inputs.prerelease }} + + - name: Validate channel and immutable version + shell: bash + env: + PRERELEASE: ${{ inputs.prerelease }} + run: | + set -euo pipefail + node --input-type=module -e 'import {releaseChannel} from "./src/mendcode/script/release-index.mjs"; if ((releaseChannel(process.env.VERSION) !== "stable") !== (process.env.PRERELEASE === "true")) throw Error("Version and prerelease flag disagree")' + if git rev-parse --verify "refs/tags/v${VERSION}" >/dev/null 2>&1; then + echo "Release tag already exists; releases are immutable" >&2 + exit 1 + fi + + - name: Supply-chain preflight + shell: bash + run: bash .github/scripts/supply-chain-preflight.sh + + - name: Block vulnerable release dependencies + shell: bash + run: | + set -euo pipefail + docker run --rm \ + -v "$PWD:/src" \ + ghcr.io/google/osv-scanner:v2.3.8@sha256:64e86bec6df2466feea5137fc7c78fb3b7c21ec077f014d7130f64810e50676b \ + scan --config /src/.github/osv-release.toml --lockfile /src/src/mendcode/pnpm-lock.yaml + + - name: Setup Node + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 + with: + node-version: "24" + + - name: Setup pnpm + uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 + with: + version: 11.0.9 + + - name: Setup Bun + uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 + with: + bun-version-file: src/mendcode/package.json + + - name: Install dependencies with frozen lockfile + working-directory: src/mendcode + shell: bash + run: | + set -euo pipefail + pnpm --pm-on-fail=ignore install --frozen-lockfile --ignore-scripts + bun run --cwd packages/opencode fix-node-pty + + - name: Build release assets + working-directory: src/mendcode + shell: bash + run: | + set -euo pipefail + bun run --cwd packages/opencode script/build.ts --release-assets --skip-embed-web-ui --skip-install --exclude-os=darwin + + - name: Verify release contracts and types + working-directory: src/mendcode + shell: bash + run: | + set -euo pipefail + node --test script/release-index.test.mjs + bun run --cwd packages/opencode typecheck + cd packages/opencode + for test_file in test/installation/*.test.ts test/cli/upgrade-channel.test.ts test/cli/tui/shared-server.test.ts test/cli/tui/thread.test.ts; do + bash -c 'export MENDCODE_DB="${TMPDIR:-/tmp}/opencode-test-data-$$/share/release.db"; exec bun test --timeout 30000 "$@"' bash "$test_file" + done + + - name: Upload release artifacts to workflow + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a + with: + name: mendcode-release-${{ inputs.version }}-linux-windows-baseline + path: | + src/mendcode/packages/opencode/dist/mendcode-linux-*.tar.gz + src/mendcode/packages/opencode/dist/mendcode-windows-x64-baseline.zip + if-no-files-found: error + retention-days: 7 + + build-windows: + name: Build Windows ${{ matrix.arch }} release assets + runs-on: ${{ matrix.runner }} + timeout-minutes: 60 + strategy: + fail-fast: false + matrix: + include: + - runner: blacksmith-4vcpu-windows-2025 + arch: x64 + build_args: --single + expected_executables: 1 + - runner: windows-11-arm + arch: arm64 + build_args: --single + expected_executables: 1 + permissions: + contents: read + env: + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} + VERSION: ${{ inputs.version }} + MENDCODE_VERSION: ${{ inputs.version }} + OPENCODE_VERSION: ${{ inputs.version }} + steps: + - name: Checkout repository + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 + with: + fetch-depth: 0 + persist-credentials: false + ref: ${{ inputs.source_sha }} + + - name: Setup Node + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 + with: + node-version: "24" + + - name: Setup pnpm + uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 + with: + version: 11.0.9 + + - name: Setup Bun + uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 + with: + bun-version-file: src/mendcode/package.json + + - name: Install dependencies with frozen lockfile + working-directory: src/mendcode + shell: pwsh + run: | + pnpm --pm-on-fail=ignore install --frozen-lockfile --ignore-scripts + bun run --cwd packages/opencode fix-node-pty + + - name: Build native Windows release assets + working-directory: src/mendcode + shell: pwsh + run: bun run --cwd packages/opencode script/build.ts --skip-embed-web-ui --skip-install ${{ matrix.build_args }} + + - name: Verify Windows executable metadata + working-directory: src/mendcode + shell: pwsh + run: | + $executables = @(Get-ChildItem packages/opencode/dist/mendcode-windows-${{ matrix.arch }}*/bin/mendcode.exe) + if ($executables.Count -ne ${{ matrix.expected_executables }}) { + throw "expected ${{ matrix.expected_executables }} Windows ${{ matrix.arch }} executable(s), found $($executables.Count)" + } + foreach ($executable in $executables) { + if ($executable.VersionInfo.ProductName -ne "MendCode") { + throw "$($executable.FullName) retained the Bun product metadata" + } + if ($executable.VersionInfo.FileDescription -ne "MendCode AI coding terminal") { + throw "$($executable.FullName) has unexpected file description: $($executable.VersionInfo.FileDescription)" + } + } + + - name: Package Windows release assets + working-directory: src/mendcode + shell: pwsh + run: | + Get-ChildItem packages/opencode/dist/mendcode-windows-* -Directory | ForEach-Object { + Compress-Archive -Path "$($_.FullName)/bin/*" -DestinationPath "packages/opencode/dist/$($_.Name).zip" -Force + } + + - name: Verify native Windows installer recovery and failure preservation + working-directory: src/mendcode + shell: pwsh + run: | + $ErrorActionPreference = "Stop" + $candidate = Get-ChildItem packages/opencode/dist/mendcode-windows-${{ matrix.arch }}*/bin/mendcode.exe | Select-Object -First 1 + if (-not $candidate) { throw "Native installer test executable is missing" } + $env:MENDCODE_INSTALLER_TEST_BINARY = $candidate.FullName + bun run script/windows-installer-smoke.ts + if ($LASTEXITCODE -ne 0) { throw "Native installer acceptance failed" } + + - name: Upload Windows release artifacts to workflow + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a + with: + name: mendcode-release-${{ inputs.version }}-windows-${{ matrix.arch }} + path: src/mendcode/packages/opencode/dist/*.zip + if-no-files-found: error + retention-days: 7 + + build-darwin: + name: Build Darwin ${{ matrix.arch }} release asset + runs-on: ${{ matrix.runner }} + strategy: + fail-fast: false + matrix: + include: + - runner: blacksmith-6vcpu-macos-15 + arch: arm64 + - runner: macos-15-intel + arch: x64 + permissions: + contents: read + env: + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} + VERSION: ${{ inputs.version }} + MENDCODE_VERSION: ${{ inputs.version }} + OPENCODE_VERSION: ${{ inputs.version }} + BUN_INSTALL_CACHE_DIR: /tmp/mendcode-bun-cache + steps: + - name: Checkout repository + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 + with: + fetch-depth: 0 + persist-credentials: false + ref: ${{ inputs.source_sha }} + + - name: Setup Node + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 + with: + node-version: "24" + + - name: Setup pnpm + uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 + with: + version: 11.0.9 + + - name: Setup Bun + uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 + with: + bun-version-file: src/mendcode/package.json + + - name: Install dependencies with frozen lockfile + working-directory: src/mendcode + shell: bash + run: | + set -euo pipefail + pnpm --pm-on-fail=ignore install --frozen-lockfile --ignore-scripts + bun run --cwd packages/opencode fix-node-pty + + - name: Build native Darwin release asset + working-directory: src/mendcode + shell: bash + run: | + set -euo pipefail + actual_arch="$(uname -m)" + case "${{ matrix.arch }}:${actual_arch}" in + arm64:arm64|x64:x86_64) ;; + *) echo "unexpected Darwin runner architecture: expected ${{ matrix.arch }}, got ${actual_arch}" >&2; exit 1 ;; + esac + if [ "${{ matrix.arch }}" = "x64" ]; then + # The release contract includes both AVX2 and baseline Intel archives. + bun run --cwd packages/opencode script/build.ts --single --release-assets --skip-embed-web-ui --skip-install + mv packages/opencode/dist/mendcode-darwin-x64.zip /tmp/mendcode-darwin-x64.zip + bun run --cwd packages/opencode script/build.ts --single --baseline --release-assets --skip-embed-web-ui --skip-install + mv /tmp/mendcode-darwin-x64.zip packages/opencode/dist/mendcode-darwin-x64.zip + else + bun run --cwd packages/opencode script/build.ts --single --release-assets --skip-embed-web-ui --skip-install + fi + + + - name: Upload Darwin release asset to workflow + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a + with: + name: mendcode-release-${{ inputs.version }}-darwin-${{ matrix.arch }} + path: src/mendcode/packages/opencode/dist/*.zip + if-no-files-found: error + retention-days: 7 + + assemble-release: + name: Assemble and attest release assets + if: ${{ always() && needs.build-release.result == 'success' && needs.build-windows.result == 'success' && needs.build-darwin.result == 'success' }} + needs: [build-release, build-windows, build-darwin] + runs-on: blacksmith-4vcpu-ubuntu-2404 + permissions: + attestations: write + contents: read + id-token: write + env: + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} + VERSION: ${{ inputs.version }} + steps: + - name: Checkout repository + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 + with: + fetch-depth: 0 + persist-credentials: false + ref: ${{ inputs.source_sha }} + + - name: Download platform release assets + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c + with: + pattern: mendcode-release-${{ inputs.version }}-* + path: dist + merge-multiple: true + + - name: Rebuild release checksums + working-directory: dist + shell: bash + run: | + set -euo pipefail + find . -maxdepth 1 \( -name '*.zip' -o -name '*.tar.gz' \) -print | sort | xargs shasum -a 256 > SHA256SUMS + + - name: Check release assets + shell: bash + run: bash src/mendcode/script/check-release-assets.sh dist + + - name: Write release manifest + working-directory: dist + shell: bash + run: | + set -euo pipefail + { + echo "version=${VERSION}" + echo "repo=${GITHUB_REPOSITORY}" + echo "sha=${RELEASE_COMMIT}" + echo "run=${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" + echo "created=$(date -u +%Y-%m-%dT%H:%M:%SZ)" + echo + cat SHA256SUMS + } > RELEASE-MANIFEST.txt + env: + RELEASE_COMMIT: ${{ inputs.source_sha }} + + - name: Write versioned release index + env: + RELEASE_COMMIT: ${{ inputs.source_sha }} + run: | + set -euo pipefail + test "$(git rev-parse HEAD)" = "$RELEASE_COMMIT" + node src/mendcode/script/release-index.mjs dist + + - name: Generate SBOM + uses: anchore/sbom-action@e22c389904149dbc22b58101806040fa8d37a610 + with: + path: src/mendcode + format: spdx-json + output-file: dist/mendcode.spdx.json + upload-artifact: false + + - name: Attest release artifacts + uses: actions/attest-build-provenance@43d14bc2b83dec42d39ecae14e916627a18bb661 + with: + subject-path: | + dist/*.zip + dist/*.tar.gz + dist/SHA256SUMS + dist/RELEASE-MANIFEST.txt + dist/release-index.json + dist/mendcode.spdx.json + + - name: Upload assembled release artifacts to workflow + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a + with: + name: mendcode-release-${{ inputs.version }} + path: dist/* + if-no-files-found: error + retention-days: 7 + + publish-release: + name: Create draft GitHub Release + if: ${{ inputs.dry_run == false }} + needs: assemble-release + runs-on: blacksmith-4vcpu-ubuntu-2404 + timeout-minutes: 10 + environment: release + permissions: + contents: write + env: + GH_TOKEN: ${{ github.token }} + VERSION: ${{ inputs.version }} + steps: + - name: Checkout release source + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 + with: + persist-credentials: false + ref: ${{ inputs.source_sha }} + + - name: Download release artifacts + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c + with: + name: mendcode-release-${{ inputs.version }} + path: dist + + - name: Create draft GitHub Release + working-directory: dist + shell: bash + run: | + set -euo pipefail + tag="v${VERSION}" + notes="${RUNNER_TEMP}/mendcode-release-notes.md" + section_found=false + { + printf '# %s\n' "$tag" + while IFS= read -r line; do + if [[ "$line" == "## ${VERSION} - "* ]]; then + section_found=true + continue + fi + if [[ "$section_found" == true && "$line" == "## "* ]]; then + break + fi + if [[ "$section_found" == true ]]; then + printf '%s\n' "$line" + fi + done < "${GITHUB_WORKSPACE}/CHANGELOG.md" + } > "$notes" + if [[ "$section_found" != true && "$PRERELEASE" != "true" ]]; then + echo "Missing CHANGELOG.md section for ${VERSION}" >&2 + exit 1 + fi + if [[ "$PRERELEASE" == "true" ]]; then + printf '\nExperimental prerelease from %s. Concurrency remains opt-in.\n' "$RELEASE_COMMIT" >> "$notes" + fi + cat >> "$notes" <&2 + exit 1 + fi diff --git a/.github/workflows/stable-startup.yml b/.github/workflows/stable-startup.yml new file mode 100644 index 00000000..08fa1356 --- /dev/null +++ b/.github/workflows/stable-startup.yml @@ -0,0 +1,38 @@ +name: Stable startup regression +on: + pull_request: + paths: ["src/mendcode/**", ".github/workflows/stable-startup.yml"] + workflow_dispatch: +permissions: + contents: read +jobs: + startup: + runs-on: blacksmith-4vcpu-ubuntu-2404 + timeout-minutes: 15 + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 + with: + persist-credentials: false + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 + with: + node-version: "24" + - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 + with: + version: 11.0.9 + - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 + with: + bun-version-file: src/mendcode/package.json + - name: Prepare frozen dependencies and test catalog + working-directory: src/mendcode + run: | + pnpm --pm-on-fail=ignore install --frozen-lockfile --ignore-scripts + cd packages/opencode + bun run script/fix-node-pty.ts + MODELS_DEV_API_JSON="$PWD/test/tool/fixtures/models-api.json" bun run script/generate.ts + - name: Typecheck and isolated startup regressions + working-directory: src/mendcode/packages/opencode + run: | + bun run typecheck + for test_file in test/installation/backend-startup.test.ts test/storage/compatibility.test.ts test/cli/tui/thread.test.ts test/plugin/auth-override.test.ts; do + bash -c 'export MENDCODE_DB="${TMPDIR:-/tmp}/opencode-test-data-$$/share/contracts.db"; exec bun test --timeout 30000 "$@"' bash "$test_file" + done diff --git a/.github/workflows/windows-installer.yml b/.github/workflows/windows-installer.yml new file mode 100644 index 00000000..91ad341b --- /dev/null +++ b/.github/workflows/windows-installer.yml @@ -0,0 +1,49 @@ +name: Windows installer contracts + +on: + pull_request: + paths: + - "src/mendcode/install.ps1" + - "src/mendcode/script/windows-installer-smoke.ts" + - ".github/workflows/windows-installer.yml" + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: windows-installer-${{ github.ref }} + cancel-in-progress: true + +jobs: + installer: + runs-on: windows-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 + with: + persist-credentials: false + - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 + with: + bun-version-file: src/mendcode/package.json + - name: Verify published executable fixture + shell: pwsh + env: + GH_TOKEN: ${{ github.token }} + run: | + $ErrorActionPreference = "Stop" + $fixture = Join-Path $env:RUNNER_TEMP "mendcode-fixture" + gh release download v0.1.43 --repo MendCode/MendCode --pattern mendcode-windows-x64.zip --pattern SHA256SUMS --dir $fixture + if ($LASTEXITCODE -ne 0) { throw "Fixture download failed" } + $archive = Join-Path $fixture "mendcode-windows-x64.zip" + gh attestation verify $archive --repo MendCode/MendCode --signer-workflow MendCode/MendCode/.github/workflows/release.yml --deny-self-hosted-runners + if ($LASTEXITCODE -ne 0) { throw "Fixture provenance failed" } + Expand-Archive -LiteralPath $archive -DestinationPath (Join-Path $fixture "bin") + "MENDCODE_INSTALLER_TEST_BINARY=$(Join-Path $fixture 'bin/mendcode.exe')" >> $env:GITHUB_ENV + "MENDCODE_VERSION=0.1.43" >> $env:GITHUB_ENV + - name: Exercise current installer with verified fixture + working-directory: src/mendcode + shell: pwsh + run: | + bun run script/windows-installer-smoke.ts + if ($LASTEXITCODE -ne 0) { throw "Windows installer contract failed" } diff --git a/.gitignore b/.gitignore index 09c3717e..2f894bd3 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,11 @@ coverage/ # MendCode generated/runtime state. The release repo must not carry local # project state; users get a fresh .mendcode from `mend init`. .mendcode/ +!.mendcode/ +!.mendcode/.gitignore +.mendcode/* +!.mendcode/skills/ +!.mendcode/skills/** # MendCode package artifacts. Some package snapshots are still tracked for now, # but new local files under those app/docs surfaces must stay off git until @@ -56,3 +61,4 @@ src/mendcode/packages/opencode/src/provider/models-snapshot.js # mflow local state .mflow/ +.mflowignore diff --git a/.mendcode/skills/mendcode-release-flow/SKILL.md b/.mendcode/skills/mendcode-release-flow/SKILL.md new file mode 100644 index 00000000..247fe540 --- /dev/null +++ b/.mendcode/skills/mendcode-release-flow/SKILL.md @@ -0,0 +1,74 @@ +--- +name: mendcode-release-flow +description: Use for MendCode project changes, release prep, PR promotion, version bump decisions, changelog updates, installer validation, and dev-to-main synchronization. Trigger whenever work may ship to users, touches package metadata/versioning, installer/update/health/changelog behavior, or the user mentions bumping a version, release, changelog, PR to dev/main, or letting the user test before shipping. +export: false +--- + +# MendCode Release Flow + +Follow this workflow for MendCode changes that may ship. + +## Non-negotiables + +- For maintainer/agent work inside the main MendCode repository, use the local `dev` branch by default. Do not create a separate branch unless the user explicitly asks for one, the current worktree has unrelated changes in the same files, or a GitHub contribution flow requires it. +- Preserve unrelated local changes. If the active checkout is dirty, inspect the touched files first. Work in-place on `dev` only when the requested files are clean or the existing edits are clearly part of the same user-approved task. +- If unrelated dirty files conflict with the task, stop and explain the blocker before creating a worktree or branch. +- Before editing release/version/package files, ask or verify whether another agent already bumped the version locally or remotely. +- Do not publish a release, merge to `main`, or overwrite a user worktree without explicit user intent. +- Never leave open public PRs/issues as noise. Close, merge, or explain exactly why they must remain open. +- Never hide security/release failures. If a supply-chain, secret, CodeQL, release, or installer check fails, keep the issue open until fixed or document the exact reason it is accepted. +- For user-visible TUI/session changes, stop after focused validation and the manual smoke gate. Do not dispatch or publish a release until the user explicitly confirms the smoke scenario works. + +## Branch Policy + +- Internal MendCode maintainers and local agents work on `dev` by default. +- External contributors should use a fork or feature branch and open a PR targeting `dev`, not `main`. +- `main` is the public release branch. Only promote `dev` to `main` after CI passes, the user-visible change has been tested, version/changelog state is correct, and the user intends to ship. +- For internal promotion, prefer a direct `dev` -> `main` PR. Do not create `codex/*` promotion branches unless GitHub cannot represent the intended merge directly or a conflict must be resolved outside the user's local checkout. +- If an emergency promotion branch/worktree is unavoidable, delete the remote branch, local branch, and temporary worktree immediately after merge or close. +- Local release or promotion workspaces under `$TMPDIR/mendcode` must be run through `src/mendcode/script/release` or its sourced cleanup helper so the current workspace's `src/mendcode/node_modules` is removed on success or failure. Do not run broad age-based temp cleaners or delete unowned/active temp workspaces. +- Do not merge random branches directly into `main`. Bring useful branches back through PRs to `dev`, then delete stale branches after merge. +- Before starting, check whether another PR/agent already contains the same work. Prefer continuing the existing local `dev` work over creating a duplicate branch. + +## Standard Flow + +1. Inspect `git status`, `git worktree list`, open PRs/issues, latest GitHub release, `origin/dev`, and `origin/main`. +2. If a version bump may be needed, determine whether the bump already exists: + - Check `CHANGELOG.md`. + - Check `src/mendcode/packages/opencode/package.json`. + - Check extension/package metadata such as `src/mendcode/packages/extensions/zed/extension.toml`. + - Check recent merged PRs and tags. +3. Ask the user before choosing a new version unless the version is already clearly bumped by another agent. +4. Implement the change on local `dev` unless the Branch Policy says a separate branch/worktree is required. +5. Run focused tests/scripts for the touched area. Use existing repo scripts and generated-client/build checks when relevant. +6. For user-visible queue, transcript, or compaction changes, run the local no-token smoke gate in `src/mendcode/packages/opencode`: + ```bash + bun run test:queue-compaction:manual + ``` + It uses an isolated temporary project, a local mock OpenAI-compatible server, a 50,000-token model context, and a 40,000-token compaction trigger. It must not read or modify the user's global config, database, credentials, or token budget. +7. Stop and let the user test locally when the change is user-visible. Do not bump/changelog/merge until the user says it works, unless they explicitly ask for fully autonomous shipping. +8. After the user confirms it works: + - Bump version if needed. + - Add or update `CHANGELOG.md`. + - Open a PR to `dev`, wait for CI, and merge. + - Promote `dev` to `main` with a direct PR whenever possible, resolving conflicts deliberately. + - Sync `main` back to `dev` if needed so both branches have the same tree. +9. If releasing: + - Use the Release workflow from `main`. + - Verify SHA256SUMS. + - Publish with real release notes/changelog, not only a SHA. + - Smoke-test the public installer in a temporary `HOME`. + +## Required Checks + +- For code: run the narrow test file or command covering the changed path. +- For user-visible TUI/session changes: run `bun run test:queue-compaction:manual` and record the user's confirmation before release promotion. +- For release: verify `mendcode --version` prints the release version. +- For installer: test `curl -fsSL https://raw.githubusercontent.com/MendCode/MendCode/main/src/mendcode/install | bash -s -- --no-modify-path` in a temporary `HOME`. +- For supply chain: verify secret scan, dependency review/vulnerability checks, CodeQL/Semgrep, and release artifact checksums before publishing. +- For branch hygiene: verify open PRs/issues, latest release, branches, and `git diff origin/main..origin/dev`. +- For local safety: before committing, review `git diff --name-only` and stage only files intentionally changed for this task. + +## Reporting + +Report only facts that were verified: PR numbers, release URL, version, test commands, and installer result. If the user asked not to report process, keep the final short. diff --git a/.mendcode/skills/mendcode-session-guardrails/SKILL.md b/.mendcode/skills/mendcode-session-guardrails/SKILL.md new file mode 100644 index 00000000..f4d887a9 --- /dev/null +++ b/.mendcode/skills/mendcode-session-guardrails/SKILL.md @@ -0,0 +1,47 @@ +--- +name: mendcode-session-guardrails +description: Use at the start of every task in the MendCode repository. Enforces local-only work, risk-based validation, minimal changes, and protection of disk, memory, CPU, and TUI rendering. Load this skill before inspecting or editing code, docs, config, tests, or runtime files. +export: false +--- + +# MendCode Session Guardrails + +Apply these rules to every task in this repository unless the user explicitly overrides a specific rule. + +## GitHub and external writes + +- Work locally by default. Never run `git push`, create, update, merge, or close GitHub PRs/issues, publish releases/packages, upload artifacts, or post GitHub comments. +- A direct user request authorizes only that specific external write. Otherwise stop before it and ask. +- Read-only commands such as `git status`, `git diff`, branch inspection, or remote inspection are allowed when relevant. +- Do not create a commit unless the user explicitly asks for one. + +## Scope and non-regression + +- Inspect the worktree before editing. Preserve unrelated changes; never reset, clean, revert, or overwrite them. +- Read the relevant callers, tests, configuration, and nearby patterns before changing behavior. +- Make the smallest patch that solves the requested problem. Avoid broad refactors, dependency changes, generated output, migrations, or public API changes unless they are required. +- Do not claim that MendCode is safe merely because a change is small: check imports, data flow, error paths, and affected callers. +- For TUI/runtime work, preserve state ownership and event flow. Do not introduce render loops, duplicate subscriptions, unstable keys, unbounded concurrency, or unnecessary rerenders. + +## Tests and validation + +- For executable behavior, run the narrowest relevant test, typecheck, lint, or runtime smoke check after editing. +- For a genuinely tiny non-executable change (for example, a skill, documentation, or formatting-only edit), skip the full test suite and validate the file format, frontmatter, and focused diff instead. +- Treat configuration changes as executable when they can alter runtime behavior; validate them accordingly. +- Do not run a full build or full test suite by habit. Expand validation only when the risk or repository workflow requires it, or the user asks. +- Report every check that actually ran and clearly state checks that were intentionally skipped. + +## Disk, memory, CPU, and rendering budget + +- Prefer targeted reads/searches and bounded commands over full-repository scans, large logs, or repeated whole-file rewrites. +- Do not create unnecessary generated files, caches, dumps, screenshots, or temporary artifacts; clean up anything required for validation. +- Avoid unbounded loops, polling, watchers, retries, uncontrolled parallelism, and duplicate work. +- Keep memory and CPU usage bounded with pagination, lazy work, bounded concurrency, and existing caches/abstractions where appropriate. +- For UI/TUI changes, avoid rendering entire histories or large collections when only a visible/changed slice is needed. +- If a change could affect performance or resource usage, inspect and validate that path specifically instead of assuming it is harmless. + +## Stop conditions and reporting + +- Ask before destructive actions, production/billing changes, security-impacting changes, or material scope expansion. +- Before finishing, inspect only the relevant diff and confirm no accidental artifacts or unrelated files were changed. +- Report concisely: changed files, real validation results, skipped checks, blockers, and non-goals. diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..6965d403 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,1109 @@ +# Changelog + +## 0.1.44-beta.16 - 2026-09-23 + +### Added + +- Add opt-in Memory & Evolution setup controls with bounded evidence, policy + gating, candidate review, and reversible project-scoped promotion. +- Add adaptive reasoning policy/runtime support with explicit user controls and + focused validation coverage. + +### Changed + +- Accept provider-native and local model identifiers without a rigid catalog + allowlist while preserving provider and path safety validation. +- Aggregate prompt-cache usage across the active user turn for more accurate TUI + status reporting. + +### Fixed + +- Harden queued peer delivery, compaction recovery, and session state checks so + accepted messages are not persisted into a target session while its runner is + still busy. + +### Tests + +- Add focused regressions for Memory & Evolution, adaptive reasoning, provider + compatibility, model validation, prompt cache reporting, and peer delivery. + +## 0.1.44-beta.15 - 2026-09-14 + +### Fixed + +- Restore compatibility with databases created by beta.11 and later by bundling + the previously released TODO target-lock migration with its original identity. + +### Tests + +- Verify the beta.11 migration hash and confirm compatible databases are inspected + without changing their bytes. + +## 0.1.44-beta.14 - 2026-09-14 + +### Added + +- Run automatic memory learning through a persisted, bounded background worker so + completed chat turns no longer wait for the memory provider; expose extraction + outcomes, Dream maintenance, write policy, and Markdown sharing controls. +- Add recoverable memory maintenance and revision-aware Markdown import/export + with explicit opt-in scopes, validation, and visible conflicts. + +### Changed + +- Keep GPT-6 Astra compatible with the current Codex Responses Lite protocol and + surface normalized multi-provider cache-hit usage to prompt status integrations. +- Make the Minimal prompt preset truly compact and retain the final Arcade/Snake + board after compaction without leaving timers or input focus active. + +### Fixed + +- Preserve queued prompt delivery and terminal cancellation while compaction, + background extraction, reconnect recovery, or long-running shell work settles. +- Keep provider startup usable when metadata loading fails or a valid catalog is + empty, and report configuration errors without trapping Home in startup state. +- Carry forward database compatibility checks and Blacksmith-backed security and + startup regression workflows from the latest public branch. + +### Tests + +- Add focused regressions for memory workers, Dream and Markdown sharing, provider + startup, Astra OAuth compatibility, cache reporting, compact prompt layout, + final compaction rendering, queue delivery, and repeated cancellation. + +## 0.1.44-beta.7 - 2026-09-10 + +### Added + +- Add passive prompt-cache controls by project, session, provider, and exact + model through `mendcode cache status|enable|disable` and the `cache` config + block, without enabling keepalive or remote-cache deletion. +- Add conservative smart-mode adapters, cache lineage fingerprints, and + provider cache observations that keep unsupported bindings unknown. + +### Fixed + +- Keep ChatGPT OAuth Responses Lite transport affinity separate from managed + cache keys, rotate affinity when instructions change or disappear, and honor + explicit cache disablement without forwarding MendCode's internal marker. +- Remove generated cache keys and provider annotations when the effective + policy is `off`. + +### Tests + +- Add configuration, adapter, lineage, provider-transform, and ChatGPT OAuth + regressions for cache scope resolution, safe fallback, and disablement. + +## 0.1.44-beta.6 - 2026-09-09 + +### Fixed + +- Complete terminal loop runs without waiting on the owner session that is + executing `run_once`, preventing a circular wait and duplicate notification. +- Deliver background loop notifications asynchronously while returning direct + `run_once` results to the calling session. +- Keep `Send now` attached to the first visible queued prompt when synthetic + runtime notifications are present. +- Preserve transcript follow mode when a viewport resize or tall Shell output + reflow moves an already-bottom scroll position. +- Add native PTY coverage for queued notifications, transcript paging and + double-`Esc` cancellation. +- Retry bounded Windows executable activation when a transient security scan + briefly holds the freshly verified candidate, while preserving atomic rollback. + +## 0.1.44-beta.5 - 2026-09-09 + +### Fixed + +- Pin the release dependency tree to fixed `@ai-sdk/provider-utils 4.0.33`, + `hono 4.13.5` and `js-yaml 4.3.2` versions, with matching provider types. +- Make repeated `Esc` cancellation settle active, queued, peer, and owner-wake + work without replaying a cancelled prompt; a fresh explicit submission is + required to resume the session. + +## 0.1.44-beta.4 - 2026-09-07 + +### Added + +- Native/portable compaction checkpoints and explicitly configured compound-model + workflow plans, snapshots and execution accounting. +- AI configuration inspection, planning, validation and permission-gated apply + through the shared backend, CLI and native tool. + +### Fixed + +- Update the transitive query-string parser to `qs 6.16.0`, fixing + GHSA-4mjr-xmp4-gh2g and GHSA-x5fp-wj9c-mxmx without extending expired exceptions. +- Normalize replayed tool arguments and bound connection retry behavior. +- Fence targeted turn and shell cancellation without escalating a stale target + into an unrelated global abort. +- Serialize release-channel changes and verify the installed version before + committing a channel transition. +- Use the shell parser for action facts and bind the frozen execution environment + without exposing environment values in fingerprints. + +### Experimental limits + +- This development beta does not complete the readiness specifications. Shell + commands with unverified execution identities require manual approval; automatic + Git/read-command semantic adapters remain unfinished. +- Cold-restart cancellation, Windows deferred channel transitions, real shared-CLI + multi-client coverage, live-provider compaction canaries and human/native + acceptance remain incomplete. See `docs/beta-integration-readiness.md`. +- No database schema migration or automatic feature activation is introduced. + Existing beta databases must not be forced back to an older stable runtime. +- Release publication remains subject to security, build and artifact checks. + +## 0.1.44-beta.3 - 2026-09-05 + +### Fixed + +- Update Drizzle ORM and Kit to the fixed `1.0.0-beta.20` versions, including + correct SQL identifier escaping (GHSA-gpj5-g38j-94v9). No schema migration is generated. + +### Added + +- Backend-owned Smart Approval review, exact action grants, history and revocation, + with causal user authority and matching TUI, SDK and ACP controls. +- `mendcode context` for estimated context composition, provider-reported cache + usage and request timing. Missing provider metrics remain unavailable. +- Stable per-turn memory snapshots and bounded secondary-tool discovery, with a + configuration fallback to the complete permitted catalog. +- Opt-in Code Mode adapted from the pinned OpenCode v2 interpreter. Nested tools + retain host permissions and audit records while only the final result enters + model context. Code Mode remains disabled by default. +- Native macOS screenshot capture with crop/window targeting, image attachments, + bounded previews and limited navigation keys tied to a recent capture. + +### Compatibility and validation limits + +- This is an experimental beta. Native provider compaction is not enabled; + the portable summarizer remains active. No measured cache-saving claim is made. +- Native computer tools currently support macOS only. Pointer control, arbitrary + typing and browser DOM automation are not included. Interactive keyboard and + Smart Approval TUI acceptance remain pending; OS permissions are not bypassed. +- Code Mode is a confined language in a worker, not an OS sandbox or hard heap + quota. Broader resource and permission lifecycle validation remains pending. +- No database migration or automatic continuity activation is introduced. + Existing beta databases must not be forced back to the stable runtime. + +## 0.1.44 stable - 2026-09-05 + +The stable hotfix is published separately from the beta runtime. It carries the +phase-aware startup deadline, rejects incompatible recorded prerelease schemas +before writing, repairs PowerShell 5.1 installer parsing, and loads bundled +GitLab/Poe authentication modules through the existing plugin boundary. + +The beta line already includes these startup and authentication fixes and uses +its broader schema compatibility checks. Release channels and experimental +continuity remain in beta; beta databases must not be forced back to stable. +See [release and recovery guidance](docs/releases-and-startup-recovery.md). + +## 0.1.44-beta.2 - 2026-09-05 + +### Fixed + +- Let a newly spawned backend finish a large pre-migration database snapshot + instead of stopping it after eight seconds. Verified backup/migration phases + have a bounded 15-minute preparation window and visible progress messages. +- Keep the 30-second client readiness deadline separate from database preparation. + Failed children stop the wait, and startup errors identify the recorded phase. +- Document published beta channels, large-history recovery and stable promotion. + +Experimental continuity remains opt-in. This does not enable native OpenAI async +transport, async shell or Windows rollback. + +## 0.1.44-beta.1 - 2026-09-05 + +This beta introduces release channels and updater recovery. It is an opt-in +prerelease; stable installations remain on the stable channel. + +### Fixed + +- Bound installer downloads, verify checksums, stage replacement atomically, + retain the previous executable, and record update and startup failures. +- Preserve explicit database paths when starting the shared backend and report + incompatible or unavailable backends instead of silently opening another writer. +- Route `run` and `stats` through the shared backend. Failed runs return a failure + exit status, and rejected requests no longer wait indefinitely for session events. +- Preserve quotes and backslashes in run arguments and load bundled GitLab/Poe + authentication plugins through the existing compatibility boundary. + +### Added + +- `mendcode upgrade channel`, `channel set stable|beta|nightly`, `--check`, and + compatibility-checked `--rollback`; channel selection never installs by itself. +- Immutable release indexes with workflow provenance verification and pinned + installers, plus separate beta/nightly publication workflows. +- Experimental async read tools, questions, session recall and versioned working + notes under the existing executor. All experimental flags default off. +- Ctrl+T widgets for questions and jobs, model-family prompt profiles, and optional + balanced reasoning Auto that preserves manual choices. + +### Limitations + +- Native OpenAI async/steering and async shell are not enabled. Windows rollback + is unavailable. Some local database commands still require closing the backend. +- An incompatible downgrade is blocked by this version; database backups are never + restored automatically. Keep beta opt-in when sharing sessions with stable. +- The original v0.1.43 existing-installation incident was not reproduced; these + changes address independently demonstrated updater and startup defects. + +### Validation + +- Linux CI: 153 Bun tests, release-index contracts, typecheck and security checks. +- Isolated macOS installation/upgrade and two-client TUI checks; no live-provider + parity or token-savings claim is made. + +## 0.1.43 - 2026-09-04 + +MendCode v0.1.43 adds the current OpenAI GPT-5.6 family and GPT-6 Astra to +the model and Codex OAuth surfaces while keeping the terminal session view +compact during concurrent work. + +### Changed + +- Add GPT-6 Astra plus GPT-5.6 Sol, Terra, and Luna API and ChatGPT OAuth + presets with documented limits, pricing, reasoning levels, and fast/pro + variants where the provider exposes them. +- Keep the OpenAI model picker populated from an in-process fallback when a + cached or bundled `models.dev` catalog predates the current model family; + live provider metadata still takes precedence. +- Keep Commands history in the Ctrl+T horizontal widget tray with a direct + action to open the originating session. +- Record the Codex CLI `0.153.3` comparison and the compatibility decisions in + the release audit. + +### Fixed + +- Allow GPT-6 Astra through the ChatGPT OAuth model filter with its documented + context and input limits while retaining the existing Responses Lite scope + for GPT-5.6 tiers. + +### Tests + +- Add model-catalog fallback, model-preset, Astra OAuth filtering, mode + normalization, and context-limit regressions. + +## 0.1.42 - 2026-09-03 + +MendCode v0.1.42 makes queued prompts, cancellation, reconnection, and communication between sessions reliable under concurrent work. + +### Changed + +- Present agent-to-agent discovery as `sessions` and deliver same-workspace session messages automatically without an acceptance click. +- Keep queued prompts serialized per session and automatically dispatch them after the active response reaches a terminal state. +- Retry transient backend and prompt-delivery failures at a short bounded interval while preserving accepted message identity. + +### Fixed + +- Keep double-`Esc` cancellation targeted to the active message and replay an interrupt requested while an earlier abort is still settling. +- Prevent queued prompts from being reordered, duplicated, stranded after compaction, or dropped during cancellation and reconnect races. +- Avoid stale `Generating...` and network-retry states after a terminal response while preserving real active tool work. +- Prevent removal of unregistered worktree directories. +- Harden session routing, workspace ownership, filesystem boundaries, authentication, share identifiers, RPC framing, migrations, and webhook verification. +- Ship a real MendCode VS Code icon and keep launcher/package installation paths MendCode-owned. + +### Tests + +- Add regressions for immediate send-then-`Esc`, double-`Esc`, FIFO prompt delivery, compaction recovery, session messaging, reconnect retries, worktree removal, and security boundaries. +- Run focused prompt, runner, TUI, worktree, filesystem, function, SDK, memory, auth, share, workflow, and migration checks plus package typecheck. + +## 0.1.41 - 2026-08-28 + +MendCode v0.1.41 keeps terminal connection and session state truthful while completing MendCode-owned application branding. + +### Changed + +- Use the MendCode icon for native Windows executables and align browser, touch, and installable web-app assets with the same identity. + +### Fixed + +- Stop presenting snapshot reconciliation on an already-connected local transport as a MendCode reconnection or connection loss. +- Populate the home Agent View from normal root sessions when the aggregate or background feed is empty or temporarily unavailable. +- Regenerate favicon and maskable web-app images so every published size contains the visible MendCode symbol. +- Upgrade the transitive `pacote` release dependency to 21.5.1 to remediate GHSA-w4pp-8pjf-rmxw. + +### Tests + +- Add regressions for connected recovery presentation, real reconnect preservation, Agent View session fallback, and child-session filtering. +- Run the complete 4,352-test suite plus focused TUI, Agent View, connection recovery, typecheck, lint, native binary, and isolated fake-provider PTY validation. + +## 0.1.40 - 2026-08-26 + +MendCode v0.1.40 makes session completion, cancellation, reconnection, and installation state consistent across providers and platforms. + +### Changed + +- Store new MendCode state in MendCode-owned data directories while preserving and safely migrating compatible legacy OpenCode state. +- Route provider cancellation through the active turn and keep recovery tied to the owning session after reconnects or workspace changes. +- Expose the existing Mflow instance routes through the experimental Effect HTTP API contracts. + +### Fixed + +- Clear stale `Generating...` activity after the latest assistant turn has already reached an explicit terminal finish or error state. +- Prevent stale tool activity from overriding a completed latest turn while preserving real activity from later user turns or incomplete tools. +- Avoid replaying cancellation and wake signals into a different session owner during provider, backend, and reconnect races. +- Make global data migration transactional, idempotent, and non-destructive when source and destination layouts overlap or already contain data. +- Write server plugin registrations to `mendcode.json[c]` so installed plugins are loaded by the MendCode runtime. +- Keep release builds working when the removed web application package is absent. +- Align SDK, schema snapshot, truncation, model-cache, memory, and profile regressions with their current runtime contracts. + +### Tests + +- Add isolated installer and global-layout migration coverage across Unix, macOS, Windows, XDG, legacy, and already-migrated states. +- Add fake-provider and compiled PTY regressions for normal completion, reconnect recovery, provider cancellation, double-`Esc`, and stale activity cleanup. +- Run focused HTTP API, SDK, memory, model, truncation, schema, session, provider, installer, and TUI checks plus the complete typecheck and test suite. + +## 0.1.39 - 2026-08-26 + +MendCode v0.1.39 makes interruption reliable across folders and recovers legacy installs without disrupting active sessions. + +### Changed + +- Route session controls through the owning workspace or directory instead of the currently selected project. +- Keep the global `Esc` interrupt available when the editor, transcript, or another TUI widget owns focus. +- Preserve explicit backend and provider retry state while their live heartbeat is still fresh. + +### Fixed + +- Fall back from a stale targeted cancellation to a bounded `session.abort` without leaving large or old sessions running indefinitely. +- Prevent cancellation outbox entries captured under an old route from replaying into another backend. +- Update Windows installations through the native PowerShell path instead of assuming WSL `/bin/bash` exists. +- Reconcile legacy SQLite migration journals transactionally when the existing schema is already present. + +### Tests + +- Run focused session-control, prompt, runner, installation, database-migration, workspace-routing, build, and startup smoke checks. + +## 0.1.38 - 2026-08-25 + +MendCode v0.1.38 hardens Smart Approval and keeps long-running sessions truthful during retries, reconnects, and large TUI turns. + +### Changed + +- Bind Smart Approval to the exact tool call and originating user turn instead of the latest prompt in the session. +- Keep bounded workspace inspections for explicit sync, audit, and inspect tasks moving without broadening writes or external-directory access. +- Show distinct retry states for the MendCode backend and the AI/provider backend while live heartbeats are fresh. + +### Fixed + +- Fail closed for writes, directory creation, absolute or traversal paths, scripts, validators, unknown executables, and misleading `--dry-run` or `--check` flags. +- Prevent duplicate or stale Smart Approval replies when multiple TUI routes observe the same pending request. +- Keep busy/retry activity visible through fresh heartbeats without persisting heartbeat churn to SQLite. +- Reconcile terminal assistant turns so stale Generating, retrying, and agent-state labels do not survive a completed or interrupted response. + +### Tests + +- Run 275 focused TUI, session, permission, Smart Approval, and schema regressions with 0 failures. + +## 0.1.37 - 2026-08-23 + +MendCode v0.1.37 prevents orphaned macOS Loop services and makes Workflow completion recovery bounded and executable. + +### Changed + +- Run macOS Loop LaunchAgents as one-shot scheduler ticks instead of leaving a persistent Bun coordinator alive between wakeups. +- Accept bounded package-manager validation commands from relative project subdirectories, including `pnpm --dir app build`. + +### Fixed + +- Self-uninstall project Loop services after their final scheduled Loop disappears, including services already waking with an empty project scope. +- Remove macOS LaunchAgents by their loaded label so a service can safely uninstall itself while it is running. +- Reject unsupported Workflow completion commands before task execution instead of blocking after every task has finished. +- Time out a stalled structured completion auditor after 3 minutes, cancel its child session, and route it through the existing bounded retry or blocked state instead of auditing forever or overlapping the retry. +- Route completion audits through the explicit read-only Explore profile instead of silently inheriting the primary Build agent. +- Resume a Workflow whose work already finished but whose completion audit was blocked by creating a fresh audit generation without rerunning completed tasks. +- Keep explicit `workflows start|resume|retry-* --wait` CLI runs attached until a durable stop instead of disposing their runner immediately. + +### Tests + +- Add focused regressions for macOS one-shot scheduling and self-uninstall routing, package-manager validation safety, early Workflow plan validation, and stalled completion auditors. +- Run 96 focused public-launcher, Loop, Workflow, scheduler, persistence, and completion tests with isolated test state, plus a real isolated macOS LaunchAgent self-removal smoke. + +## 0.1.36 - 2026-08-23 + +MendCode v0.1.36 makes Loop and Workflow supervision durable, observable, and consistent with the workspace users actually inspect. + +### Changed + +- Show the interruption confirmation only after the first `Esc` press, on the left side of the activity row; a second `Esc` still targets the same active turn. +- Display completion-audit lifecycle, attempt, lease countdown or expiry age, last update, and the active auditor chat directly in the Workflow monitor. +- Open the current completion-auditor transcript before completed task transcripts while a Workflow audit is active. + +### Fixed + +- Reclaim expired completion-audit leases after restart even when every Workflow task is already complete, without falling back to a permanently queued run. +- Renew active completion-audit leases without increasing the attempt count, so long auditor turns cannot reject their own final evidence as stale. +- Avoid duplicate workspace-update events when a recovered Workflow reuses the same workspace lease. +- Execute Loop workers inside their authoritative leased worktree, preserve that path and branch through terminal state, and notify the parent chat with the exact workspace location. +- Keep Loop draft behavior aligned across legacy and Effect HTTP routes, including full contracts that omit optional cost or token caps. +- Prevent large transcripts from visibly unmounting when a submitted message moves into the optimistic render window. +- Preserve keyboard permission selection when OpenTUI reports synthetic or parked pointer movement. + +### Tests + +- Add focused regressions for audit restart recovery, duplicate lease events, auditor transcript routing, audit-state presentation, two-step interruption placement, Loop route parity, worktree ownership, large-session submission, and permission selection. +- Run 335 release-focused Loop, Workflow, TUI, session, permission, and route tests with isolated state, plus the native Darwin build and startup smoke checks. + +## 0.1.35 - 2026-08-22 + +MendCode v0.1.35 makes long-running sessions, Loop execution, Usage Insights, and local agent collaboration more immediate and reliable. + +### Added + +- Add a customizable Usage Insights widget layout with persisted visibility controls and a subscription-usage widget backed by local Codex rate-limit telemetry. +- Add same-project peer discovery and bounded, approval-gated peer messages that preserve visible source provenance without granting tool permissions. + +### Changed + +- Require a second `Esc` press for the same active turn before interruption, with a visible confirmation window that remains responsive during clipboard inspection and compaction. +- Keep Loop workers fail-closed after an unfinished tool attempt instead of automatically replaying work with unknown side effects. +- Refresh large session transcripts, Git status, selected-day statistics, and Loop chat activity without blocking the visible interface on expensive auxiliary data. +- Display accurate background follow-up wording instead of reporting that an agent resumed when detached work merely completed. + +### Fixed + +- Prevent prompt submission from briefly unmounting or blanking a large transcript before the optimistic user turn is rendered. +- Prevent overlapping Loop daemon ticks, restore project-scoped Loop discovery for isolated worktrees, and accept canonical macOS temporary-directory aliases in permission checks. +- Keep selected Usage Insights days current until manually pinned, then update arrow-key navigation synchronously without remounting the dashboard. +- Preserve keyboard permission selection during synthetic pointer movement and keep compact reasoning, transcript spacing, and grouped tool continuation presentation stable. + +### Tests + +- Add focused regressions for two-step interruption, prompt mounting, transcript sync and virtualization, Loop scheduling and recovery, permission path aliases, Usage Insights widgets, subscription telemetry, and peer messaging. +- Run the release-focused agent, session, Loop, TUI, stats, collaboration, and tool suites with isolated test state. + +## 0.1.34 - 2026-08-20 + +MendCode v0.1.34 fixes remaining session presentation regressions from v0.1.33. + +### Fixed + +- Size short Full reasoning blocks to their content instead of reserving the entire bounded reasoning viewport and leaving a large blank gap in the session transcript. +- Keep the same bounded, scrollable reasoning behavior in the normal session route and the experimental Session v2 renderer. +- Keep keyboard navigation on the selected permission option when OpenTUI rechecks hover state during layout changes. +- Remove the fixed transcript clearance that left unused space above the session prompt while preserving the virtualizer's real bottom spacer. + +### Tests + +- Add regressions for short Full reasoning layout, keyboard permission navigation, and transcript spacing. +- Run the focused TUI presentation, permission prompt, session layout, and session initialization suites. + +## 0.1.33 - 2026-08-20 + +MendCode v0.1.33 is a reliability hotfix for updates, long-running activity, and context-pack presentation. + +### Fixed + +- Prevent in-app updates from failing when GUI-launched processes do not expose Bash through `PATH`; surface actionable updater errors and verify the installed version. +- Keep Arcade games visible after context compaction completes so the game is not removed with the compacted transcript. +- Clear stale Generating/activity state after an aborted shell command leaves a completed assistant timestamp without finish metadata. + +### Tests + +- Add updater failure and installed-version verification regressions. +- Add Arcade-after-compaction and aborted-activity regressions. + +## 0.1.32 - 2026-08-20 + +MendCode v0.1.32 hardens long-running sessions so activity, cancellation, scrolling, and approval state remain truthful while large tools and commands are still running. + +### Added + +- Add bounded multi-pass bottom-follow reflow for large tool output, transcript relayouts, and the Session v2 route. +- Add persisted cancellation retry state with bounded backoff and explicit unknown/failed status instead of silently losing `Esc` requests. +- Add local tool activity detection for Agent View and a bounded Full reasoning viewport that follows only its own content. + +### Changed + +- Keep `Esc` available as a global active-session interrupt while preserving approval, question, and plan-review dismissal semantics. +- Keep the shell default timeout configurable and raise its fallback to 10 minutes so long edits, builds, and device commands have time to finish. +- Route every Smart Approval shell request through prompt-scoped review; safe reads and directory access are no longer auto-approved without the current user prompt. +- Render memory actions with explicit add/update/search labels and success/active tones instead of treating completed actions as errors. + +### Fixed + +- Prevent large tool-height changes and delayed OpenTUI reflows from detaching a session that is still following the bottom. +- Detach bottom-follow immediately when a manual upward scroll overlaps a delayed tool reflow, so follow mode cannot pull the viewport back down. +- Prevent the Activity footer and Agents view from becoming idle while a tool remains pending or running after a long edit or command. +- Prevent `Esc` from being consumed by an inner transcript/widget before it reaches the active session interrupt command. +- Prevent Full reasoning content from expanding the entire chat and forcing the outer session scroll to move. + +### Tests + +- Run focused session-control, scroll/activity, Agent View, shell, permission, Smart Approval, presentation, and renderer suites (315 cases in the release-focused run). +- Verify persisted runtime recovery and source/installed parity with `test:session-runtime:smoke` without provider requests. +- Verify Linux, Darwin, and Windows package builds with the release builder using the existing no-embed-web-UI release path. + +## 0.1.31 - 2026-08-19 + +MendCode v0.1.31 adds completion-verified Loop and Workflow execution and keeps long-running agent work visibly active until it actually finishes. + +### Added + +- Add completion contracts, auditing, and validation so Loop and Workflow runs only report success after a complete iteration satisfies its required checks. +- Add durable workflow planning, execution, scheduling, receipts, and recovery state across the runtime, server, tools, and TUI monitors. +- Add focused regression coverage for completion validation, Loop/Workflow orchestration, scheduler recovery, and long-running session activity. + +### Changed + +- Expand the Loop and Workflow views with phase-aware status, receipts, task progress, and terminal outcome details. +- Keep workflow task and phase state synchronized across adapters, background execution, persistence, and recovery. +- Refresh live session status with bounded in-memory heartbeats while provider and tool work is still running. + +### Fixed + +- Prevent long-running sessions from becoming idle after the stale status snapshot timeout while work is still active. +- Prevent incomplete Loop or Workflow runs from being presented as completed before their validation contract passes. +- Preserve authoritative activity state through the TUI activity footer and Agents view during long-running execution. + +### Tests + +- Run focused completion, Loop/Workflow, scheduler, TUI activity, edit, and patch-tool regression suites. +- Verify the local source CLI manually with `mend --isolated` and a long-running `sleep 90` activity check. + +## 0.1.30 - 2026-08-18 + +MendCode v0.1.30 expands Full Prompt Context product awareness, completes Mermaid ASCII presentation, and hardens session history, test isolation, memory extraction, Usage Insights, reconnecting TUI activity, release presentation, and Windows builds. + +### Added + +- Add a Full Prompt Context capability catalog backed by the real CLI command families, covering TUI and slash-command discovery, native tools, custom tools, MCP, packages, workflows, memory, browser automation, and collaboration surfaces without leaking it into Minimal or Focus modes. +- Add public agent-facing product, image-generation, custom-tool, screenshot, automation, and extension contracts to the README. + +### Changed + +- Apply provider presets to every built-in model role, show connected providers first, expose OpenAI-specific presets only when OpenAI is connected, and prioritize free DeepSeek, GLM, and Qwen options in the OpenCode catalog. +- Disable the memory side-chat role by default and remove it from Setup while preserving the bounded memory extractor and Dream proposal roles. +- Switch Setup mouse actions to activate on release and use the scrollable Usage Insights layout before low-height terminals clip panels. +- Build optimized Windows x64 and ARM64 release assets on native Windows runners, cross-build the baseline x64 asset on Linux, verify executable metadata, and assemble them with the Linux and Darwin artifacts. +- Use version tags as GitHub release display names and populate draft release notes from the matching changelog section. + +### Fixed + +- Keep transcript scrolling responsive while the pointer is over a Mermaid card, while preserving Shift-wheel horizontal panning and working zoom, fit, and centering controls. +- Fail closed before a test fixture can open or reset a SQLite database outside its isolated temporary roots, and block accidental root-level test discovery. +- Bound automatic memory extraction to 45 seconds by default so a stalled extractor cannot keep a completed session busy indefinitely. +- Make the manual queue/compaction smoke single-instance, recover stale locks, terminate child processes on interruption, and clean its isolated fixture and lock on exit. +- Keep live long-running session activity authoritative beyond the stale snapshot timeout and stop tool animations immediately when `Esc` interrupts a run. +- Keep managed local-server reconnection alive with bounded backoff, resume accepted prompts when the stream recovers, and restart a stopped connection when the user submits again. +- Keep `Editing...` and `Patching...` authoritative during transient reconnects and while a large completed edit remains the latest assistant event, then transition when newer output begins. + +### Tests + +- Add nested transcript/Card interaction coverage for Mermaid zoom and wheel routing, plus regression coverage that rejects production-like SQLite paths during tests. +- Add focused coverage for Full Prompt Context isolation, real CLI-family projection, provider-wide presets, free OpenCode model ordering, compact Usage Insights layouts, memory-extraction timeout recovery, queue-smoke lock cleanup, reconnect recovery, and ordered TUI activity phases. +- Confirm the local-only queue/compaction smoke manually with three mock requests and no external provider contact. + +## 0.1.29 - 2026-08-04 + +MendCode v0.1.29 fixes Windows installation, packaging, and release presentation so the corrected assets are available through the standard download paths. + +### Added + +- Add a Windows CMD installer that uses the built-in `curl.exe` and `tar.exe` tools without requiring PowerShell. +- Document direct Windows ZIP downloads and the no-PowerShell installation path. + +### Changed + +- Make Windows release bundles deterministic and include MendCode icon and metadata. + +### Fixed + +- Detect x64 and ARM64 correctly from PowerShell, including 32-bit PowerShell on 64-bit Windows. +- Avoid Bun Windows linker failures caused by split bundles. + +### Tests + +- Run the focused installation test suite. +- Build Windows x64, ARM64, and baseline release assets and smoke-test `--version` and `--help`. + +## 0.1.28 - 2026-08-04 + +MendCode v0.1.28 adds durable Loop Workflows and provider-aware image generation, strengthens detached background-task delivery, and improves workflow and session recovery across the TUI and server transports. + +### Added + +- Add durable Loop Workflows with validated plans, policy gates, background execution, scheduling, persistence, recovery, CLI/API routes, and a dedicated TUI monitor. +- Add the `image_gen` tool with Codex OAuth, OpenRouter, and OpenAI-compatible adapters, persisted artifacts, optional captions, and safe edit inputs. +- Add workflow-run deletion and richer workflow progress, receipt, artifact, and recovery metadata to the server API and generated JavaScript SDK. +- Add focused workflow, image-generation, background-task, queue/compaction, server-route, scheduler, and TUI regression coverage. + +### Changed + +- Keep first-class workflows in the dedicated Workflows view instead of mixing workflow coordinators into Agent View. +- Expose workflow receipts, progress, queued work, terminal outcomes, and recovery state consistently across the TUI and server transports. +- Keep image generation independently configured from the active chat model and expose it only when the provider contract and permissions support it. +- Improve compaction, reconnect, long-session, error, and workflow-monitor presentation while keeping the prompt focused during active work. + +### Fixed + +- Persist, replay, acknowledge, and instance-scope detached background-task completion notifications so idle owners resume reliably without duplicate or cross-project terminal deliveries. +- Keep the shared server alive while detached work is active and classify missing terminal outcomes as interrupted instead of leaving tasks indefinitely active. +- Preserve queued prompt state through compaction and reconnects, restore prompt focus after compaction, and clear stale working or disconnected indicators when execution settles. +- Require workflow artifact consumers to depend on their producers, reject direct starts with unresolved gates, and improve recovery and cleanup of interrupted workflow runs. +- Keep long-running non-shell tools alive across stream-idle periods and handle unknown image-generation results without crashing the session. +- Update release dependency overrides to patched versions of `brace-expansion`, `fast-uri`, `hono`, `ip-address`, `postcss`, `socket.io-parser`, and `undici`. +- Skip the optional post-install setup prompt when `curl | bash` has no controlling terminal instead of failing after a successful installation. + +### Tests + +- Confirm the local queue/compaction smoke with a local-only provider; no external provider was contacted. +- Add targeted regressions for workflow plan validation, scheduler recovery, detached task wakeups, server lifetime, transcript state, prompt initialization, and dedicated workflow rendering. + +## 0.1.27 - 2026-08-02 + +MendCode v0.1.27 improves TUI reliability and narrow-terminal rendering while making prompt behavior, customization, and release metadata more explicit. + +### Added + +- Add compact, width-bounded Mermaid flowchart layouts for long vertical and horizontal diagrams, including automatic rotation when a horizontal diagram cannot fit. +- Add explicit MendCode prompt guidance for task lifecycle discipline, cost-aware model routing, loop activation consent, background-subagent consent, custom tools/pages/widgets, and the supported TUI rendering surface. +- Add regression coverage for interrupted prompt state, reconnecting permission synchronization, Agent View ordering, compact flowcharts, and the expanded prompt contract. + +### Changed + +- Expand the full prompt mode description with TODO, Loop Workflow, cost, TUI, and extension context while preserving the provider-focused harness contract. +- Make loop activation and background delegation require explicit user intent when the request does not already provide it. +- Bound normal and advanced Usage Insights fetch sizes separately and adapt heatmap cell widths and labels for narrow terminals. +- Retry and reconcile session permission-mode synchronization across transient local-server reconnects instead of surfacing avoidable errors. + +### Fixed + +- Clear the TUI working indicator immediately after a user interrupts a running command, even when a stale unfinished assistant message remains in the frontend cache. +- Order active Agent View rows by turn start time instead of later tool-update timestamps. +- Keep long Mermaid flowcharts within the terminal width and avoid the unreadable fallback layout when the preferred orientation is too wide. + +### Tests + +- Add focused TUI, prompt-composition, permission-sync, and Markdown-rendering regressions for the release changes. + +## 0.1.26 - 2026-08-01 + +MendCode v0.1.26 restores reliable in-app update discovery and installation across TUI transport modes. + +### Fixed + +- Check for updates after the TUI is ready regardless of whether it uses the shared server, an external server, or a private worker. +- Namespace the skipped-update preference so legacy upstream version state cannot suppress MendCode releases. +- Run in-app installer upgrades without opening setup or modifying PATH, and surface the installer error when an upgrade fails. + +## 0.1.25 - 2026-08-01 + +MendCode v0.1.25 repairs cancellation and compacted-history state after interrupted or long-running TUI sessions. + +### Fixed + +- Finalize orphaned pending or running tool calls as cancelled when an unfinished assistant turn is explicitly stopped, preventing commands that no longer exist from remaining visibly active. +- Preserve the latest completed compaction boundary while the bounded TUI message cache pages through long transcripts, so tool calls before compaction remain hidden unless explicitly revealed. +- Add focused regression coverage for cancelling unfinished assistant turns with active tools. + +## 0.1.24 - 2026-08-01 + +- Published from the same source tree as v0.1.23; it contained no additional source changes. + +## 0.1.23 - 2026-07-31 + +MendCode v0.1.23 hardens long-running sessions and Loop Workflows while making +provider-aware compaction and TUI state easier to inspect. + +### Added + +- Add scheduler health, wake attempts, retry/backoff state, and failure metadata to durable Loop Workflows and their CLI/API views. +- Add regression coverage for session synchronization, virtual transcript windows, loop lifecycle state, smart permissions, and provider-aware compaction. + +### Changed + +- Set GPT-5.6 ChatGPT OAuth models to a 256K effective input/context limit with a provider-specific 90% compaction threshold. +- Improve loop runner recovery, scheduler error reporting, run leases, completion state, and persisted run metadata. +- Improve transcript rendering, compaction summaries, Changes Review rendering, setup copy, and permission-review presentation across narrow and live TUI states. + +### Fixed + +- Prevent stale or duplicate session rows and user-message rendering during reconnects, transcript growth, compaction, and resumed work. +- Preserve safe session and tool state when scheduled loop execution or a permission-review path fails. +- Make cross-platform release smoke tests accept the public `Usage:` help header. + +## 0.1.22 - 2026-07-29 + +### Fixed + +- Show the startup update modal for patch releases by default instead of silently attempting an automatic update; explicit `autoupdate: true` keeps silent patch upgrades available. +- Add regression coverage for the `0.1.20` to `0.1.21` update path. + +## 0.1.21 - 2026-07-29 + +MendCode v0.1.21 is a focused reliability and customization release. It adds project-owned prompt context, improves prompt/runtime boundaries, protects active sessions during cancellation and reconnects, preserves useful media through compaction, and refreshes the public setup and customization documentation. + +### Added + +- Add a project-local `custom` Prompt Context mode backed by `.mendcode/prompts/custom.md`, with optional frontmatter names, bounded loading, root-safe path checks, UTF-8 normalization, and safe fallback diagnostics. +- Add package-shared custom prompt support through runtime packs without leaking a local project prompt into another project. +- Add `mendcode prompt` inspection/build/mode commands plus setup, status, TUI selector, footer, and runtime-plan visibility for custom prompt origin, name, path, byte count, and fallback state. +- Add public documentation for project-local and package-shared custom tool calls, including typed arguments, execution context, metadata, permission checks, and package distribution. +- Add regression coverage for custom prompt loading, package resolution, session recovery, cancellation, compaction media, Codex OAuth affinity, transcript ordering, and prompt diagnostics. + +### Changed + +- Compose prompt context from the active project root and carry one resolved MendCode prompt snapshot through streaming and token estimation instead of resolving inconsistent prompt state in separate paths. +- Keep custom prompt metadata out of provider instructions while exposing a readable project-defined label in setup and the TUI. +- Rotate Codex ChatGPT OAuth Responses Lite session affinity when the effective prompt instructions change, while preserving affinity for identical instructions. +- Preserve images for vision-capable compaction models and retain a bounded set of recent image attachments for text-only compaction resumes. +- Keep session scroll position and anchors stable across transcript growth, paging, compaction, and route remounts; keep later assistant continuations after intervening turns. +- Refresh the local shared-server fingerprint from source metadata so local TypeScript changes cannot reuse stale runtime processes. +- Run prompt-status scripts through a Bash-compatible shell and expose the public prompt route from the installed CLI. +- Bound shell cancellation and timeout cleanup, force-kill cancelled processes after a short grace period, and expose explicit retry guidance when command completion is unknown. +- Bump package, lockfile, and Zed extension metadata to `0.1.21` and refresh setup/customization documentation and screenshots. + +### Fixed + +- Prevent manual `Esc` cancellation from being undone by late background-task owner-wake notifications or stale prompt deliveries. +- Cancel all pending prompt deliveries during interruption and coalesce concurrent abort requests so a cancelled turn cannot restart from a stale request. +- Prevent hidden prompt input state from remaining mounted while a question or permission prompt owns the session input. +- Reconcile session state, pending questions, and permissions after a worker-backed terminal transport recovers from system sleep or a reconnect. +- Keep queued session work from restarting after an explicit cancellation. +- Mark commands interrupted by connection loss or timeout as having an unknown result, retain incomplete output safely, and avoid encouraging blind repetition of potentially destructive commands. +- Stop legacy diff preview heuristics from treating any long source block as a truncated preview when no truncation marker exists. + +### Tests + +- Add focused regressions for custom prompt parsing and security boundaries, prompt mode cycling, runtime-pack projection, prompt snapshot propagation, cancellation/owner-wake behavior, reconnect synchronization, session virtual-window ordering, scroll persistence, image-aware compaction, Codex OAuth request affinity, Bash-compatible prompt status scripts, and unknown shell-result retry metadata. + +## 0.1.20 - 2026-07-28 + +### Added + +- Add setup onboarding presets for subscription, balanced API, and budget API model roles. +- Add a setup Health Check step that runs setup doctor/plan without printing secrets. +- Add package setup actions for public GitHub package imports, local imports, package management, and safe runtime config snapshot export. +- Add the Memory Center with project/global scopes, category graphs, reviewable proposals, a constrained memory side agent, and Dream maintenance workflows. +- Add durable Loop Workflow execution with root/child sessions, journals, checkpoints, artifact ledgers, safety gates, evaluators, cost records, daily schedules, and self-paced triggers. +- Add Loop Workflow `update_agent` support in the tool, API, and TUI so existing loops can be retargeted without recreation. +- Add richer Loop Workflow show/list context with latest run checkpoint, changed files, recent events, and latest loop-session message. +- Add self-paced Loop Workflow trigger support for max-goal work without hot-looping unbounded monitors. +- Add the terminal-native `/changes` review surface, inline comments, bounded review context, and the `review` tool. +- Add first-run onboarding, context-pack profiles (`arcade`, `cockpit`, `minimal`, and `quiet`), structured command search, larger dialogs, widgets, overlays, themes, and plugin slots. +- Add background-task control, subagent/session metadata, Herdr state reporting, public/local package imports, package management, and the Memory Graph example package. +- Add installer `--setup` and `--skip-setup` options plus an optional setup launch prompt after install. +- Add configurable context-pack presentation profiles: `arcade`, `cockpit`, `minimal`, and `quiet`, with setup controls. + +### Changed + +- Refresh setup/provider copy around Provider Manager, connected providers, model role presets, package store actions, and responsive narrow-width layout. +- Refresh installer presentation with the MendCode install deck banner, progress UI, and setup instructions. +- Refresh session synchronization, prompt model/variant metadata, compaction panels, background-task notifications, and resumed subagent presentation. +- Make `/memory`, `/loops`, `/stats`, `/changes`, setup, and session views responsive on narrow and mid-width terminals. +- Keep resumed subagent calls attached to the original task card instead of rendering duplicate resume cards. +- Improve `/changes` diff loading so large tracked and likely-binary patches are summarized per file with metadata instead of flooding or failing the whole review. +- Make the `/loops` route responsive for compact and mid-width panes with shorter key hints, bounded stacked list height, and visible compact loop detail. +- Expand public documentation, package/plugin guidance, memory and loop guides, screenshots, branding assets, and release automation. +- Improve TUI selection dialogs with large layouts, structured command search, readable wrapping, and a `?` help key. + +### Fixed + +- Preserve useful subagent evidence in Task tool results when the child reply is generic but the child session recorded substantive output or changed orchestration files. +- Mark externally interrupted subagent tasks as retained/continuable instead of failed, so parent sessions do not misread connection drops as failed. +- Keep batched `message.updated` events idempotent and preserve the latest user turn, assistant output, queue state, and compaction progress across bounded refreshes. +- Persist async prompts before acknowledging HTTP 204 responses and surface prompt failures through the normal session error event. +- Keep unbounded interval monitors from completing when a checkpoint says `complete`; they now continue until an explicit stop condition. +- Keep self-paced unbounded monitors from running continuously without a cadence. +- Preserve loop receipt state for show/list and problem states instead of masking workflow state with generic completed-action copy. +- Prevent setup and loops pages from clipping action footers, rails, and detail panels on narrow terminal panes. +- Avoid stale setup package registry entries when GitHub or local package import fails. +- Prevent binary or oversized `apply_patch` inputs from becoming giant diffs that block the server/TUI before `Generating` starts. +- Harden legacy relay URL recognition, OAuth error pages, cryptographic ID/PKCE generation, and release dependency paths. +- Update release dependencies to OSV-fixed versions: `@hono/node-server` 2.0.10, `brace-expansion` 5.0.8, and `tar` 7.5.21. +- Keep TUI message state idempotent when duplicate `message.updated` events arrive in the same batch, preventing temporary assistant duplication or disappearance during queued and normal turns. +- Preserve the latest real user turn and its visible assistant output across bounded refreshes, stale removals, and compaction-related updates. +- Keep prompt/queue working state, compaction progress, background-task notifications, and session rendering synchronized during active turns. +- Persist async prompts before acknowledging them with HTTP 204 and surface prompt failures through the existing session error event. +- Harden legacy relay URL recognition, OAuth error pages, and cryptographic ID/PKCE generation against security scanner findings. +- Unmount the hidden session prompt while a question or permission prompt owns input, preventing stale prompt rows and focus state from leaking into the transcript. + +### Tests + +- Add Task tool regressions for retained external aborts and generic subagent replies with child-session evidence. +- Add Memory Center/Dream, memory graph, session synchronization, prompt persistence, background-task, plugin, and HTTP API regressions. +- Add Loop Workflow regressions for agent retargeting, self-paced scheduling, unbounded monitor checkpoints, show/list context metadata, and loop receipt copy. +- Add setup/package regressions for public GitHub URL validation, memory dialog state, setup health step state, and compact setup/loops layout helpers. +- Add `/changes` regressions for per-file large patch handling and binary/large file skip messaging. +- Pass supply-chain preflight, OSV, frozen-lockfile, release asset, SBOM, CodeQL, dependency review, security scanner, checksum, and attestation gates for the published release. +- Add regressions for batched duplicate message updates, pinned user turns, sparse refreshes, bounded transcript retention, compaction pairing, and prompt working-state transitions. +- Add command-search and async-prompt persistence regressions. +- Align title-generation fixtures and session transcript assertions with the current prompt and compaction-boundary behavior. +- Validate prompt visibility and TUI startup after question/permission interactions. + +## 0.1.19 - 2026-06-25 + +### Fixed + +- Distinguish explicit user cancels from transport, WiFi, lid-sleep, or connection aborts so interrupted session state no longer falsely implies the user stopped the run. +- Preserve partial shell/task output with non-user-disconnect metadata instead of labeling it as `User aborted the command`. +- Prevent Loop Workflows from completing as `0/0`, reject invalid fixed zero-turn budgets, and keep unbounded monitors open instead of storing `maxTurns: 0`. +- Keep manual and signal-driven Loop Workflows from auto-running on every scheduler tick; only interval/adaptive loops become due from `nextWakeup`. +- Let implementation loops run with normal execution when the objective explicitly asks to write, edit, fix, implement, code, or create files, while preserving explicit report-only and custom-gated modes. +- Delete loop-owned root chat sessions when deleting a Loop Workflow and expose delete parity across legacy and raw HttpApi loop routes. +- Keep minimal/full chat presentation from clipping long fenced or text-fence lines by wrapping to the visible display width. + +### Changed + +- Improve Loop Workflow tool/prompt guidance so assistants inspect existing loops before recreating them, never use `maxTurns: 0`, and report invalid `completed 0/0` states instead of spawning duplicates. +- Expand Loop Workflow tool metadata for TUI cards with permission mode, trigger, budget, model, objective, agent, and timestamps. +- Add `/loops` dashboard warnings for legacy invalid zero-turn budgets. +- Preserve unfinished assistant/tool phases through compaction and keep Herdr status accurate while local tools, child sessions, and loop workflows are still active. + +### Tests + +- Add regression coverage for non-user abort classification in shell, task, and message error handling. +- Add Loop Workflow regressions for zero-turn budgets, due scheduling, permission inference, delete lifecycle, legacy/HttpApi route parity, and loop prompt guidance. +- Add chat presentation regressions for fenced long-line wrapping, Unicode display width, text-fence wrapping, hex color handling, and table preservation. + +## 0.1.18 - 2026-06-24 + +### Added + +- Add goal-driven Loop Workflow budget modes: `fixed`, `max-goal`, and `unbounded-monitor`. +- Add Loop Workflow completion criteria, success checks, target turns, reserved verification turns, machine-readable checkpoints, and optional owner-session completion notifications. +- Add provider disconnect support from the Connect Provider dialog for locally saved provider auth. +- Add TSM shortcut support for creating an explicit missing branch before opening it in a split MendCode pane. + +### Fixed + +- Fix Loop Workflow execution so implementation loops that explicitly allow edits are not downgraded to report-only by a conservative background service. +- Refresh Loop Workflow receipts with clearer spacing plus model, mode, trigger/event, agent, chat, workflow, and goal details. +- Keep loop session headers, run checkpoints, and the `/loops` dashboard aligned with the currently running iteration instead of lagging one completed run behind. +- Keep Herdr loop-session panes in a working loop state between iterations and only report completion after the workflow reaches a terminal state. +- Resume active provider compaction automatically and add trigger context so compaction summaries do not falsely close unfinished work. +- Preserve a bounded snapshot of the retained recent tail during compaction so summaries keep the latest unfinished request, tool output, and resume context. +- Keep the active loop count only in the prompt footer, expose `/loop` from the new-chat screen, make `/loop` Tab completion non-submitting, and remove duplicate `/loops` slash entries. +- Accept loop model variants through the `variant` field or provider/model#variant syntax for any provider. +- Keep the `/loops` dashboard cursor out of read-only detail rows so the `updated` field no longer looks editable. +- Keep Herdr agent state from staying `working` after a session finishes and no longer appears in status output. +- Report clearer `--worktree` and `--tsm` errors outside git repositories or before the first commit. +- Strip command frontmatter metadata from opencode provider schemas/options so strict providers do not reject structured output or noop tool schemas. + +### Changed + +- Treat `maxTurns` as an iteration budget for goal work instead of a requirement to spend every available loop turn. +- Improve `/loops` timeline loading and scrolling so recent workflow events remain inspectable without overwhelming compact terminals. +- Scope model variant selection to the newly selected model before deciding whether to open the variant picker. +- Refresh opencode Go/OpenRouter reasoning variant mapping for GLM-5.2, MiniMax M3, and widely supported effort levels. +- Clean up slash-command fallbacks and aliases so command names do not collide. + +### CI + +- Skip CodeQL for docs-only, changelog-only, and public asset-only PRs while keeping CodeQL on source changes, main pushes, scheduled runs, and manual dispatch. +- Consolidate Security Guard scanners into one deep-scanner job while preserving gitleaks, OSV, zizmor, and Semgrep policy enforcement. +- Reduce release workflow artifact retention from 30 days to 7 days to cut Actions storage pressure. + +### Docs + +- Update the Loop Workflow events spec with goal semantics, checkpoint behavior, budget exhaustion rules, and acceptance checks. + +### Tests + +- Add coverage for goal-budget loop completion/blocking, owner notifications, compaction tail snapshots, provider schema cleanup, reasoning variants, TSM/worktree shortcut edge cases, Herdr idle reporting, and structured-output schema transformation. + +## 0.1.17 - 2026-06-23 + +### Added + +- Loop Workflows: durable workflow records, draft/activate/tick lifecycle, run journals, loop root sessions, Agent View grouping, terminal monitor, HTTP routes, SDK types, and a built-in `loop` assistant tool. +- Safe loop execution modes: dry-run ticks, `--execute --report-only` wakeups that deny mutation/shell/subagent tools, full execution for trusted contexts, and per-project OS service support for macOS LaunchAgent, Linux user systemd, and Windows Task Scheduler. +- Built-in loop templates for PR watching, CI repair, research digests, and repo maintenance, plus CLI/status/monitor docs for loop lifecycle, daemon, service, logs, and troubleshooting. +- Changes Review: a MendCode-native `/changes` TUI route for working-tree diffs with file navigation, diff-block navigation, line selection, reload, responsive layouts, inline comments, and stale-comment reconciliation. +- Assistant-visible review context through bounded `` summaries and a `review` tool for current selection, file summaries, navigation, reload, comment creation, listing, and clearing. +- Local review-state persistence keyed by workspace root so comments and selection can be recovered across route/process boundaries without writing raw patches into the repository. +- Richer Usage Insights: selected-day keyboard/mouse navigation, a GitHub-style daily token grid, month markers, selected-day token/session/prompt/word/file/time details, improved clock layout, and expanded aggregation for tool/runtime activity. +- Project Usage Insights shortcuts and docs for global, project, and directory scopes. +- Streaming Markdown rendering for assistant output so headings, inline formatting, tables, code fences, Mermaid text, and hex color swatches can appear progressively without waiting for a completed message. +- Claude Code CLI provider discovery and validation: provider list entry, local CLI auth validation, version-aware model listing, optional binary/home/launch-arg settings, and API-provider wiring once the local CLI is authenticated. +- Frontmatter argument-hint parsing and prompt metadata improvements for command/prompt surfaces. + +### Changed + +- Render compaction summaries through the styled Markdown path so tables and formatted summaries stay readable in the session timeline. +- Rename provider setup surfaces from generic `Provider` to `Connect Provider` where the UI is specifically about connecting/authenticating a provider. +- Refresh README screenshots, feature mapping, setup/configuration docs, and usage-insights docs for the 0.1.17 surfaces. +- Update package, lockfile, and Zed extension metadata to `0.1.17`. + +### Fixed + +- Prevent incomplete streaming Markdown tables and code fences from rendering early before they can display coherently. +- Deduplicate live shell-output deltas so repeated command output does not replay the same latest line while a tool is still streaming. +- Report missing Claude Code CLI binaries as validation errors instead of letting provider discovery throw raw `ENOENT` exceptions. +- Preserve the `0.1.16` reasoning-history behavior after the local OpenAI reasoning replay experiment was reverted. + +### Tests + +- Add coverage for loop services/routes/session/tool behavior, Changes Review state/actions/comments/context, Usage Insights selection and aggregation, streaming Plan Markdown, shell-output replay prevention, Claude Code provider settings/validation, prompt metadata, and TUI route behavior. + +## 0.1.16 - 2026-06-20 + +- Fix Memory Center Dream scheduling proposals so accepting a side-chat `dream-dry-run` proposal writes the Dream scheduler state instead of only saving an ordinary memory proposal. +- Recover Dream scheduler state from already-applied Dream proposals, so users who accepted a Dream schedule proposal in `0.1.15` see the Dream page become scheduled after upgrading. +- Add Dream schedule parsing for human time windows such as `6pm to 11pm local time`, `18:00-23:00`, and fixed times such as `21:00 Europe/London`. +- Add regression coverage for side-chat Dream proposal application, Dream schedule recovery, and human-readable Dream time parsing. + +## 0.1.15 - 2026-06-19 + +- Add a route-level Memory Center in the TUI with Overview, Project memories, Global memories, Policy & categories, and Dream tabs. +- Add saved/pending memory review surfaces with keyboard actions for applying, rejecting, editing, deleting, moving, and inspecting memories without leaving the terminal. +- Add category-aware memory metadata, policy normalization, scope reasoning, evidence references, and reviewable proposal operations for verify, expire, recategorize, relink, demote-scope, and promote-scope flows. +- Add a memory graph sidecar with legacy-entry bridging so memories can be grouped, indexed, and queried by category while preserving the existing flat memory files. +- Add workspace-aware memory grouping so the Memory Center can show the current project plus other known project memory scopes. +- Add Dream memory maintenance primitives: proposal-only Dream runs, bounded/redacted evidence collection, run logs, scheduler state, source manifests, missed-window handling, and safety reporting. +- Add a constrained memory side chat backed by the `memoryAssistant` role so users can ask about memory state, draft memory actions, and inspect category policy without turning the Memory page into a general coding agent. +- Add `memoryDream` and `memoryAssistant` model roles to local memory/model configuration while keeping generated memory writes approval-gated by default. +- Label retrieved prompt memory by scope and category while preserving the existing `` compatibility block. +- Feed recent conversation context into post-turn memory extraction so proposals can distinguish durable facts from isolated one-line messages. +- Add Memory HTTP/API routes for side-chat calls and wire the route into both the experimental HttpApi surface and instance routes. +- Add a `Memory Center` command palette route and keep the existing lightweight `Memory Manager` proposal dialog as a separate command. +- Add `/memory-center`, `/memories`, `/memory-manager`, `/memory`, and `/mem` routing so slash commands can open the right memory surface. +- Add scrollable previews to the Memory Manager dialog so long proposal bodies do not overflow compact terminals. +- Add screenshot-backed public docs for the README hero, home layouts, Agent View, Plan Mode, and Memory Center. +- Add `docs/features.md` as the product-facing feature map for README, website, screenshot, and demo work. +- Add `docs/memory-center.md` and a Memory Graph/Dream spec to document the new memory workspace and safety model. +- Refresh the README into a public product page with install paths, product surfaces, documentation map, development notes, security/community pointers, star history, and an expanded agent-context block. +- Refresh the docs index, setup/configuration docs, customization docs, Plan Mode docs, Usage Insights docs, and package-sharing docs to point at implemented screenshots and provider-neutral examples. +- Document `memoryDream` and `memoryAssistant` roles alongside existing model roles, and keep public model examples provider-neutral. +- Add a dedicated Shift+Tab Mode picker for primary agents, moving reverse agent cycling off Shift+Tab so the key opens the expected mode selector. +- Make the prompt model, provider, and variant labels resolve from the selected prompt model metadata instead of stale local/session labels. +- Track whether local model and variant state came from the user or session hydration, so explicit local changes win over older hydrated session state. +- Persist submitted prompt agent/model selections onto the session before generation so resumed sessions and Agent View reflect the real active selection. +- Preserve assistant provider/model/variant metadata when sync events arrive with partial message updates. +- Keep prompt status script output tied to the current prompt-status identity so stale script output from an older model/session/root is not reused. +- Show the currently selected model in the working indicator instead of the broader local parsed model when the prompt is using a session/subagent selection. +- Add Markdown-rendering capability notes to non-minimal prompt policy so agents know the TUI supports headings, lists, tables, code fences, links, checklists, blockquotes, and Mermaid text diagrams. +- Replace the Plan Review renderer path with a stable styled Markdown component instead of relying on the experimental Markdown flag. +- Improve Plan Review table rendering with grid mode, wrapped cells, and better handling for file/action/detail tables. +- Improve terminal Mermaid rendering for state diagrams, class diagrams, pie charts, Gantt charts, git graphs, requirement diagrams, journeys, timelines, and other common diagram shapes. +- Add static Plan Markdown rendering helpers and Mermaid fence detection for tests and non-interactive surfaces. +- Add hex color parsing/swatches so Markdown tables that list colors can render clean terminal previews. +- Improve chat/timeline presentation for todo writes, questions, plan-review prompts, permission prompts, and grouped tool activity. +- Remove the separate subagent footer file and fold subagent/session footer behavior into the main session layout. +- Improve session layout sizing and compact terminal behavior around message rendering, plan review, usage/status surfaces, and bottom prompt chrome. +- Add the built-in Herdr agent-state plugin so MendCode panes can report idle, working, blocked, needs-input, approval, plan-pending, retry, and error state to Herdr without requiring a separate user plugin. +- Read project-local `.mendcode/mcp` server config into the MCP runtime, status, tools, prompts, and resources paths so project MCP servers participate alongside global config. +- Sync generated project config when `mendcode` starts if the generated opencode config is stale. +- Make `mendcode --worktree .` and current-worktree shortcuts resolve more naturally, including current-branch fallback when no non-base worktree exists. +- Make control-plane output for mflow, TSM, and worktrees human-readable by default while keeping `--json` available for scripts. +- Make `mendcode mcp add-local` sync generated runtime config after writing project MCP config. +- Use provider-neutral defaults for memory preview commands instead of hard-coded public provider/model examples. +- Add setup smoke coverage for memory/model-role fields and package/runtime configuration. +- Add tests for Memory Center layout helpers, memory categories, graph/proposals/retrieval, Dream events/scheduler/sources, HTTP memory routes, prompt compose, prompt model/variant resolution, prompt status identity, plan Markdown rendering, Herdr plugin reporting, MCP project config, worktree shortcuts, setup, TSM, runtime pack, and session prompt metadata. +- Refresh release-gated dependencies and lockfile overrides for DOMPurify, Undici, form-data, esbuild, Slack Bolt, and OpenTelemetry so the OSV release scanner can pass without disabling supply-chain checks. + +## 0.1.14 - 2026-06-16 + +- Make `mendcode packages install ` install a selected package from the official or chosen registry catalog instead of applying a whole source by accident. +- Keep source-level package application available as `mendcode packages install-source ` for existing local/team registry workflows. +- Let the setup Package step skip packages, browse official packages, install a local package path, create/update a local package snapshot, or manage installed overlays. +- Add registry coverage for multi-package catalogs, selected pack installation, source-level install compatibility, and runtime compatibility rejection. +- Update `protobufjs` to `7.6.3` so the release dependency gate can pass with the fixed version. + +## 0.1.13 - 2026-06-16 + +- Refresh the Bash and PowerShell installers with a clearer MendCode banner, numbered install phases, ASCII progress output, and more direct next-step guidance. +- Make installer guidance honest after `curl | bash`: run the installed binary by absolute path immediately, or open/source a terminal before using `mendcode` from `PATH`. +- Keep MendCode-owned setup config keys such as `memory` and `package` from crashing the runtime config loader after first-run setup creates `.mendcode/mendcode.json`. +- Honor dynamic `OPENCODE_CONFIG_CONTENT` values at config-load time so SDK/runtime callers can inject per-instance config after process startup. +- Preserve explicit model changes made while a session is busy so the next prompt uses the newly selected model instead of falling back to the previous session model. +- Point npm registry publishing at the public `mendcode` package name instead of the temporary `mendcode-ai` wrapper name. +- Update Hono to `4.12.25` so release dependency scanning passes without carrying known fixed advisories. + +## 0.1.12 - 2026-06-16 + +- Show the upstream `opencode` provider in the TUI provider/model/setup flows while keeping it labeled as `opencode Zen`, and keep `opencode-go` labeled separately as `opencode Go`. +- Add a Windows PowerShell installer and document macOS, Linux, Windows PowerShell, and Git Bash/WSL install paths in the README. +- Add configurable assistant message rendering modes: Plain, Markdown, and Rich. +- Render plan/chat Markdown more cleanly in Rich mode, including local Mermaid flowcharts, wide tables, checklists, callouts, connectors, and compact terminal-friendly diagrams. +- Keep plan review content anchored while scrolling so review modals stay readable during long plans. + +## 0.1.11 - 2026-06-15 + +- Preserve `task` tool metadata while a subagent is running, after tool-call transitions, and when a subagent fails before model resolution completes. +- Queue a newly submitted prompt behind an active run so the second prompt is saved and answered in the next LLM call instead of being coalesced into the first run's result. +- Keep existing concurrent `loop()` callers coalesced to the same active run while only explicit prompt submissions enqueue a follow-up turn. +- Stop showing the empty memory-check toast when the extractor finds no durable candidates, and keep Home title changes silent while refreshing the visible Home surface. +- Hide the prompt-bottom context meter unless `promptStatus.context.visible` is explicitly enabled, including old profiles that still list the context builtin. +- Let mflow lock/read external absolute paths by default instead of refusing paths outside the current project. + +## 0.1.10 - 2026-06-14 + +- Let automatic memory learning create approval-gated `add`, `update`, and `remove` proposals, with targeted updates/deletes applied to existing memory entries instead of only appending new entries. +- Recover durable repo-scoped memory rules when the extractor returns empty or wrapped JSON, without relying on hard-coded prompt examples. +- Show a memory toast when extraction finishes with no pending proposal, including skipped or no-candidate reasons instead of silently disappearing after "Preparing memory proposal...". +- Treat slash commands as commands only when they start the prompt, so normal messages that mention `/setup`, `/stats`, or other commands are sent as chat text instead of navigating away. +- Keep `/setup` and `/stats` as temporary pages from an active chat: pressing escape or finishing setup now returns to the originating session instead of dropping to New Chat. +- Keep Agent View hover visual-only; click or arrow keys select the reply target, and `esc` clears that selected session before returning to normal prompt input. +- Keep split home welcome branding neutral and prevent long ASCII title text from clipping into partial letters. +- Remove the default right-side prompt context meter so the footer no longer shows the extra context bar and separator dot by default. +- Preserve pasted chat images through message copy/paste by copying image attachments as portable data-image Markdown and rehydrating those images back into prompt attachments when pasted into MendCode. + +## 0.1.9 - 2026-06-14 + +- Make `mendcode --help` workflow-first: open the terminal harness, run with an initial intent, use packages, mflow, worktrees, TSM, setup, and status. +- Move low-level/debug commands out of normal help, including TUI profile internals, runtime adapter/upstream/export/config plumbing, and prompt/runtime internals. +- Keep legacy aliases such as `init`, `sync`, `package`, and `prompts` callable with deprecation warnings instead of presenting them as product workflows. +- Suggest close matches for typo-prone commands, including `mendcode tui prewview` -> `mendcode tui preview`. +- Stop replaying the latest real user message as a new visible user turn after overflow compaction; resume from the summary and a synthetic internal continue prompt instead. +- Avoid the double-compaction path where auto resume immediately re-adds the same user request before continuing. +- Release mouse tracking, bracketed paste, and raw input mode before suspending or exiting the TUI so the parent shell does not receive scroll/click escape sequences. + +## 0.1.8 - 2026-06-14 + +- Show a real Usage Insights loading state instead of zeroed metrics while cached stats are still loading. +- Reuse the global TUI stats cache on the Usage Insights page without warming session messages during normal chat startup. +- Keep the weather location in the global TUI config and simplify the stats shortcuts by removing the manual refresh action. +- Fix the installer version check so a same-version global `mendcode` on `PATH` cannot falsely satisfy a clean `$HOME/.mendcode/bin` install. + +## 0.1.7 - 2026-06-14 + +- Keep the setup screen stable while refreshing step state so changing setup pages no longer flashes back to a loading placeholder. +- Widen the setup rail so longer step labels such as TUI Profile and Permissions do not collide with completion status. +- Shorten and row-budget the memory extractor auth warning while preserving the actionable OAuth/client-id blocker. +- Inject global memory at session start and after compaction, while keeping per-request project memory local to the model prompt instead of writing it into chat history. +- Run automatic memory extraction after normal assistant stops, show a dedicated memory activity state/mascot while proposals are generated, and give the extractor structured saved/pending memory context before it decides whether to propose. +- Prevent the primary assistant from directly saving implicit preferences to memory; approval-gated proposals now come from the memory extractor unless the user explicitly asks to save memory immediately. +- Avoid re-triggering assistant generation after clean auto-compaction while still resuming when compaction interrupted an active or incomplete assistant turn. +- Keep long pasted content visible until it exceeds the configured character threshold, and let truncated user-message headers expand from the hidden-content hint without stealing normal message action clicks. +- Refresh the docs for the `mendcode` command surface, customization, setup/configuration, mflow, package sharing, plan mode, usage insights, TSM/worktrees, and wiki navigation. + +## 0.1.6 - 2026-06-14 + +- Add a TUI Usage Insights dashboard with daily token activity, global/project stats, response-time metrics, top tools/agents/models, cached stats loading, and optional Open-Meteo weather. +- Inject saved global memories into normal runtime requests as transient system context instead of only after compaction. +- Keep project memories in the runtime prompt with their own request cap so repo-local context is available without persisting injected memory into chat history. +- Make `mendcode memory search` and `mendcode memory preview` show request-mode retrieval by default, with an explicit `--mode` selector for compaction/manual checks. + +## 0.1.5 - 2026-06-13 + +- Backport MCP runtime updates: catalog pagination, capability-aware prompt/resource listing, tolerant tool schema discovery, abort signal forwarding, OAuth `callbackPort`/`scope`, and manual OAuth header preservation. +- Isolate provider model plugin hooks from internal provider state so plugin mutations cannot rename providers or zero model pricing globally. +- Preserve delegated subagent identity on task child sessions. +- Avoid a shell-cancel race by cancelling an existing session runner during short busy-state transitions instead of marking the session idle too early. + +## 0.1.4 - 2026-06-13 + +- Stop normal automatic and manual compaction from re-triggering the assistant after a completed turn. +- Keep overflow compaction recovery for requests that really hit provider context limits. +- Make `Tab` mode cycling update the active prompt mode instead of leaving the mode label stuck while model state changes. + +## 0.1.3 - 2026-06-13 + +- Show richer Agent View welcome timestamps, including `Today` plus contextual day, month, and year information. +- Show the local package version in the welcome screen instead of `local` when running from source. +- Clarify prompt-context commands in the TUI by renaming the persistent selector and hiding the low-value cycle command from Ctrl+P. +- Backport OpenCode terminal and SDK fixes for structured SDK errors, Basic Auth defaults, local MCP `cwd`, and MCP prompt/resource timeouts. +- Stamp release binaries with the requested `MENDCODE_VERSION`/`OPENCODE_VERSION` and include release workflow changes in generated notes. + +## 0.1.2 - 2026-06-13 + +- Publish MendCode under the `mendcode` command name and remove the public `mend` package alias. +- Normalize source and package metadata to `0.1.2` after the public `v0.1.1` release. +- Show the MendCode runtime version in welcome, CLI, debug info, health responses, and Zed extension metadata. +- Keep update checks on `MendCode/MendCode` GitHub releases and skip autoupdate for local/source builds. +- Preserve offline startup by treating update lookup failures as non-blocking. +- Replace user-facing `mend` and `mend-runtime` command hints with `mendcode`. diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..71c8c8cd --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,23 @@ +# Code of Conduct + +MendCode is a technical community. Be direct, but keep it useful and respectful. + +## Expected Behavior + +- Be clear and constructive. +- Assume good intent until there is evidence otherwise. +- Keep discussions focused on the code, docs, product behavior, or user outcome. +- Credit upstream work and community contributions. +- Respect maintainers' time by providing reproduction steps and context. + +## Unacceptable Behavior + +- Harassment, threats, or personal attacks. +- Posting private information or credentials. +- Repeated low-effort noise after maintainers ask for clarification. +- Public exploit details for private vulnerabilities. +- Spam or unrelated promotion. + +## Enforcement + +Maintainers may edit, hide, lock, or remove comments and may block users who repeatedly harm the project or community. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..df3702c1 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,83 @@ +# Contributing to MendCode + +Thanks for helping improve MendCode. This project is public, but it is still moving quickly, so good issues and focused pull requests matter more than large drive-by rewrites. + +## Before You Start + +- Search existing issues and discussions first. +- Open an issue for large behavior changes before investing in a pull request. +- Keep pull requests narrow. One fix or feature per PR is easiest to review. +- Do not include secrets, local config, private prompts, or generated credentials. + +## Development Setup + +Source lives under `src/mendcode`. + +```bash +cd src/mendcode +bun install +bun dev +``` + +The root repository is a public wrapper around the MendCode source tree, docs, installer, and community files. Most runtime commands should be run from `src/mendcode` or from a specific package directory. + +Useful commands: + +```bash +cd src/mendcode +bun run --cwd packages/opencode --conditions=browser src/index.ts +bun run --cwd packages/opencode test +bun run --cwd packages/opencode typecheck +bun run release:check-assets +``` + +## Pull Requests + +Every PR should include: + +- What changed and why. +- How you tested it. +- Screenshots or recordings for TUI/UI changes when practical. +- Any known limitations or follow-up work. + +Do not mix formatting-only edits with behavior changes unless formatting is the point of the PR. + +## Commit Style + +Use short conventional commit-style messages: + +```text +fix: handle missing setup config +docs: add package sharing guide +feat: add TUI widget slot +chore: update release metadata +``` + +## Tests + +Run the smallest test set that proves the change, then broaden when the change touches shared contracts. + +Examples: + +```bash +cd src/mendcode/packages/opencode +bun test test/mend/memory.test.ts +bun test test/cli/tui/plugin-loader.test.ts +bun run typecheck +``` + +Release asset checks: + +```bash +cd src/mendcode +bun run release:assets +bun run release:check-assets +``` + +## Security + +Do not open public issues for private vulnerabilities or leaked credentials. Follow [SECURITY.md](SECURITY.md). + +## Attribution + +MendCode is downstream work built on the opencode codebase with substantial MendCode-owned runtime, CLI, setup, package, coordination, and TUI customization layers. See [ACKNOWLEDGEMENTS.md](ACKNOWLEDGEMENTS.md). diff --git a/README.md b/README.md index 45f277a9..543ad9bb 100644 --- a/README.md +++ b/README.md @@ -1,29 +1,797 @@ -# MendCode +

+ MendCode terminal field banner +

-MendCode is a terminal-first coding runtime built around the `mend` CLI, a MendCode-owned configuration layer, reusable runtime packages, optional mflow coordination, optional TSM/worktree orchestration, and a customizable terminal UI. +

The customizable coding terminal.

-## Documentation +

+ Release + License + Website + Docs + PRs welcome +

-- [Documentation index](docs/README.md) -- [Architecture and packages](docs/architecture.md) -- [CLI, setup, and configuration](docs/cli-setup-configuration.md) -- [Customization](docs/customization.md) -- [TUI plugins and widgets](docs/tui-plugins-and-widgets.md) -- [Packages and team sharing](docs/packages-and-team-sharing.md) -- [mflow coordination](docs/mflow.md) -- [TSM and worktrees](docs/tsm-and-worktrees.md) -- [Public readiness audit](docs/public-readiness-audit.md) -- [Lineage and acknowledgements](ACKNOWLEDGEMENTS.md) +MendCode is a terminal-first coding-agent harness you can make your own: a +public `mendcode` CLI, configurable model roles, review gates, Changes Review, +Memory Center, Plan Mode Markdown, Agent View, reusable team packages, project MCP config, +mflow/worktree coordination, Usage Insights, release/security gates, and a +customizable TUI for home identity, prompt chrome, widgets, panels, dialogs, and +themes without patching runtime internals. Local agents can also control the +same session runtime through versioned JSON commands for progress, waiting, and +cancellation. -## Quick Start +

+ Website · + Docs · + Feature map · + Acknowledgements +

+ +## Contents + +- [Why It Exists](#why-it-exists) +- [Install](#install) +- [First Run](#first-run) +- [Product Surfaces](#product-surfaces) +- [Documentation Map](#documentation-map) +- [Development](#development) +- [Community And Security](#community-and-security) +- [For Agents](#for-agents) +- [Lineage](#lineage) + +## Why It Exists + +Most coding agents give you a chat box. MendCode gives you the harness around it: + +| Need | MendCode surface | +| --- | --- | +| Make the terminal feel like your workflow | TUI profiles for prompt chrome, marker, status row, home identity, split home, Agent View, chat presentation, widgets, routes, dialogs, and themes. | +| Share a tuned setup with a team | Runtime packages for commands, agents, modes, skills, prompts, MCP config, plugins, TUI profile, model roles, permissions, memory defaults, and worktree policy. | +| Review before implementation | Plan Mode renders Markdown, including Mermaid when supported, inside a TUI review modal before switching to the implementation agent. | +| Keep large Mermaid diagrams readable | Mermaid fences render as bounded ASCII canvases with fit/layout zoom, centering, local pan, and horizontal or vertical scrolling instead of expanding the whole transcript. | +| Review current code changes | `/changes` opens a responsive TUI diff workspace with comments and agent-visible review context between model turns. | +| Keep repeat work moving | Loop Workflows create durable, monitorable loop sessions with contract-aware report-only wakeups, `/loop` creation, `/loops` supervision, and optional per-project OS services. | +| Keep risky actions explicit | Permission modes, smart permission review, preview-first worktree actions, and approval-gated memory proposals. | +| Route work to the right model | Model roles for planning, building, explicit review agents, subagents, summaries, compaction, memory extraction, Dream, memory side chat, and permission review. | +| Let local agents drive real sessions | `mendcode session` and `mendcode run --format json` expose the existing runtime for machine-readable session control, events, waiting, inspection, and cancellation. | +| Coordinate parallel terminal work | Optional mflow locks plus optional TSM/worktree orchestration for multi-session work. | +| See local activity without cloud analytics | Usage Insights for tokens, sessions, AI time, prompt volume, changed files, top tools, top agents, top models, cache mix, daily activity, and selected-day details. | + +The short version: MendCode is not just "run a model in a terminal." It is a +configurable coding terminal with packaging, review, memory, permissions, and +coordination built into the workflow. + +## Install + +Choose the row for your shell: + +| Platform | Command | +| --- | --- | +| macOS / Linux | `curl -fsSL https://raw.githubusercontent.com/MendCode/MendCode/main/src/mendcode/install \| bash && mendcode` | +| Windows PowerShell | `irm https://raw.githubusercontent.com/MendCode/MendCode/main/src/mendcode/install.ps1 \| iex; mendcode` | +| Windows CMD (no PowerShell) | `curl.exe -fsSL https://raw.githubusercontent.com/MendCode/MendCode/main/src/mendcode/install.cmd -o "%TEMP%\mendcode-install.cmd" && call "%TEMP%\mendcode-install.cmd"` | +| Windows direct ZIP | [Download the x64 ZIP](https://github.com/MendCode/MendCode/releases/latest/download/mendcode-windows-x64.zip) and run `mendcode.exe` after extracting. | +| Windows Git Bash / MSYS2 / Cygwin / WSL | `curl -fsSL https://raw.githubusercontent.com/MendCode/MendCode/main/src/mendcode/install \| bash && mendcode` | +| Pin a release | `curl -fsSL https://raw.githubusercontent.com/MendCode/MendCode/main/src/mendcode/install \| bash -s -- --version ` | +| No shell startup edits | `curl -fsSL https://raw.githubusercontent.com/MendCode/MendCode/main/src/mendcode/install \| bash -s -- --no-modify-path && ~/.mendcode/bin/mendcode` | + +The public command is `mendcode`. Development checkouts may contain a local +`mend` shim for legacy/internal workflows, but public docs, examples, and +screenshots should use `mendcode`. + +## First Run + +After installation, open MendCode in your repo: ```bash -curl -fsSL https://raw.githubusercontent.com/MendCode/MendCode/main/src/mendcode/install | bash -mend +mendcode +``` + +On first launch, MendCode opens the setup screen. Use it to configure the +harness once: provider/auth, model roles, budget posture, package state, TUI +profile, prompt mode, memory, and permissions. Once setup is complete, use the +commands below for everyday work: + +Useful commands after setup: + +| Command | Use it when | +| --- | --- | +| `mendcode run "review this repo and draft a plan"` | You want to open MendCode with an initial task ready. | +| `mendcode chat "summarize current status"` | You want a quick control-plane turn without entering the full TUI. | +| `mendcode session list --format json` | Another local agent needs to discover and control MendCode sessions. | +| `mendcode status` / `mendcode doctor` | You want readiness or diagnostics. | +| `mendcode setup status` | You want to inspect setup state after the guided setup screen. | +| `mendcode marketplace status` | You want to inspect active team/runtime marketplace packages. | +| `mendcode install ` | You want the short marketplace install path for a package. | +| `mendcode mflow status` | You are coordinating multiple agents around the same repo. | +| `mendcode --worktree feature-branch` | You want to open MendCode against a branch/path/id worktree target. | +| `mendcode --tsm feature-branch` | You want a TSM workspace with a MendCode split. | + +## Product Surfaces + +### Custom Terminal UI + +MendCode turns the terminal into a configurable product surface: home identity, +prompt frame, prompt marker, status row, split panels, Agent View, action +menus, chat presentation, widgets, slots, custom routes, dialogs, footer +entries, and themes. + + + + + + + + + +
Choose the home identity
+
+Option A: wordmark welcome +

MendCode centered wordmark welcome

+
+
+
+Option B: mascot welcome +

MendCode centered mascot welcome

+
+
+ +
+ + + + + + + + + +
Choose the working layout
+
+Option A: wordmark with Agent View +

MendCode wordmark Agent View

+
+
+
+Option B: mascot with Agent View +

MendCode mascot Agent View

+
+
+ +
+ + + + + + + + + +
Choose the action surface
+
+Option A: wordmark actions +

MendCode wordmark actions

+
+
+
+Option B: mascot actions +

MendCode mascot actions

+
+
+ +
+ + + + + + + + + +
Configure the terminal profile
+
+Example profile JSON +
{
+  "identity": {
+    "logoMode": "mascot",
+    "productName": "MendCode"
+  },
+  "surfaces": {
+    "homeWelcome": {
+      "mode": "split",
+      "rightPanel": "agentManager"
+    }
+  },
+  "promptChrome": {
+    "preset": "top-bottom",
+    "glyphs": {
+      "leadText": "mendcode>"
+    }
+  },
+  "promptStatus": {
+    "placementByPreset": {
+      "top-bottom": "outside",
+      "ascii-box": "inside"
+    }
+  }
+}
+
+
+
+Command palette entries +
Ctrl+P -> Home identity
+Ctrl+P -> Home welcome mode
+Ctrl+P -> Home split panel
+Ctrl+P -> Prompt chrome
+Ctrl+P -> Prompt lead string
+Ctrl+P -> Prompt status placement
+Ctrl+P -> Chat presentation
+Ctrl+P -> Usage Insights
+
+
+ +
+ + + + + + + + + +
Agent View as a first-class terminal surface
+
+Full Agent View +

MendCode Agent View home surface

+
+
+
+What can be themed +

Home layout, title identity, mascot mode, prompt frame, prompt lead, status +placement, chat presentation, activity states, widgets, slots, custom routes, +dialogs, footer entries, and theme tokens.

+
+
+ +### Marketplace Your Harness + +A MendCode marketplace package captures the reusable parts of a team setup: + +```text +.mendcode/ + agents/ + commands/ + modes/ + skills/ + prompts/ + plugins/ + tools/ + pages/ + tui/ + widgets/ ``` -Development source currently lives under `src/mendcode`. +Packages can include MCP config, context docs, scripts, TUI profiles, theme +tokens, custom tool calls, custom TUI pages, shell-backed widgets, model roles, +focus defaults, budget posture, permission defaults, memory defaults, and +worktree policy. + +Packages must not include provider tokens, OAuth state, `.env*`, +`.mendcode/auth`, local databases, room secrets, or machine-local cache/run +state. + +```bash +mendcode marketplace create --id acme-standard --title "Acme Standard" --include skills,modes,plugins,tools,pages +mendcode marketplace list +mendcode install acme-standard +mendcode marketplace install acme-standard +mendcode marketplace enable acme-standard +``` + +### Plan Mode + +Plan Mode is for users who want the agent to think first without silently +editing files. + +

+ MendCode Plan Mode review modal +

+ +

+ MendCode Markdown preview rendering +

+ +1. The planning agent researches and writes a Markdown plan. +2. MendCode renders the plan in a TUI modal. +3. The user can approve, edit, comment, reject, or close. +4. Approval switches into the configured implementation agent. +5. The reviewed Markdown becomes the source of truth for implementation. + +See [Plan Mode](docs/plan-mode.md). + +### Changes Review + +Changes Review opens the current working-tree diff inside the TUI. It is a +review workspace, not just static patch text: move by file, hunk, or line; add +comments; reload the diff; then press `Esc` or `q` to return to chat without +stopping the active session. + +

+ MendCode Changes Review diff workspace +

+ +```text +/changes +``` + +When the view is active, MendCode gives the assistant bounded review context on +model turns: selected file/hunk/line, comments, stale comment count, and compact +file summaries. Comments added while an agent is working become visible to the +agent on the next model turn, including after a tool call completes. MendCode +does not splice new comments into an already-running token stream. + +See [Changes Review](docs/changes-review.md). + +### Loop Workflows + +Loop Workflows are durable, monitorable loop sessions for objectives that should +keep moving across controlled iterations. Completion semantics and wakeup +cadence are separate, so the same runtime supports three clear shapes: + +| Shape | Contract | When it stops | +| --- | --- | --- | +| Goal | `budgetMode: "max-goal"` plus concrete `completionCriteria` | As soon as completion is verified; an optional positive `maxTurns` is only a safety cap. | +| Recurring job | `budgetMode: "unbounded-monitor"` plus an `interval`, `daily`, `self-paced`, `adaptive`, or `external-signal` trigger | When explicitly stopped or blocked by a safety, budget, approval, or input gate. Omit `maxTurns`. | +| Bounded run | `budgetMode: "fixed"` plus a positive `maxTurns` | After the requested number of iterations unless stopped or blocked. | + +A recurring job still has an objective, but the objective describes what each +wakeup should do rather than acting as an early-completion condition. A loop +starts from `/loop`, is supervised in `/loops`, becomes an activated root +session, records run/journal events, appears in Agent View, and can be woken +manually or by a per-project background service. The dashboard keeps its next +wakeup countdown live, shows scheduler health and evidence, and makes durable +`needs_input` permission waits visible instead of presenting them as failures. + +

+ MendCode Loop Workflow receipt in chat +

+ +

+ MendCode Loop Workflows dashboard +

+ +```bash +mendcode loops examples +mendcode loops draft --template research-digest --name "Loop test" +mendcode loops activate loop_... +mendcode loops tick loop_... --execute --report-only +mendcode loops monitor loop_... +``` + +For a workflow whose durable contract is already report-only/read-only, +`--execute --report-only` wakes the agent and writes transcript activity without +edit/write/patch/shell/subagent tools. Edit-capable workflows keep their +contract; full execution remains explicit through `--execute` or +`mendcode loops service start --allow-edits`. + +See [Loop Workflows](docs/loop-workflows.md). + +### Memory With Control + +MendCode memory is approval-first by design. It can retrieve useful project +context without turning every session into permanent state. + +

+ MendCode Memory Graph with connected nodes +

+ +- global and project scopes +- explicit `mendcode memory add` +- `mendcode memory search` and `mendcode memory preview` +- generated memory proposals +- apply, reject, and edit proposal flow +- transient prompt injection through bounded memory context + +The Memory Center view brings saved memories, pending proposals, categories, +Dream state, project grouping, and a constrained memory side chat into one +reviewable workspace. See [Memory Center](docs/memory-center.md). + +### Usage Insights + +Usage Insights is local observability for the coding harness, not cloud +analytics and not a productivity claim. + +![MendCode Usage Insights dashboard](docs/assets/screenshots/usage-insights-overview.png) + +It can show global/project/directory scope, token heatmaps, sessions, active +days, prompt volume, AI generation time, tool runtime, changed files, top tools, +top agents, top models, cache mix, and optional weather. + +See [Usage Insights](docs/usage-insights.md). + +### Coordination: mflow, TSM, Worktrees + +MendCode includes optional coordination for people running multiple terminal +sessions around the same codebase. + +| Surface | Purpose | +| --- | --- | +| mflow | Local-first coordination, room activation, daemon status, and edit locks. | +| Worktrees | Preview-first creation, adoption, opening, reset, and removal of git worktrees. | +| TSM | Optional terminal-session workspace setup for MendCode panes. | + +```bash +mendcode mflow setup +mendcode worktree plan feature-branch +mendcode worktree create feature-branch +mendcode tsm setup +``` + +## Documentation Map + +| If you want to... | Read | +| --- | --- | +| Understand the whole product surface | [Feature map](docs/features.md) | +| Install, configure, and check readiness | [CLI, setup, and configuration](docs/cli-setup-configuration.md) | +| Shape the visual terminal experience | [Customization](docs/customization.md) | +| Share marketplace packages | [Marketplace and team sharing](docs/packages-and-team-sharing.md) | +| Let another agent control sessions | [Automation runtime](docs/automation-runtime.md) | +| Extend the TUI with code | [TUI plugins and widgets](docs/tui-plugins-and-widgets.md) | +| Create and activate a theme | [Themes](docs/themes.md) | +| Use plan review gates | [Plan Mode](docs/plan-mode.md) | +| Inspect Mermaid ASCII output and stress fixtures | [Mermaid ASCII rendering](docs/mermaid-ascii-rendering.md) | +| Review working-tree changes | [Changes Review](docs/changes-review.md) | +| Run durable agent loops | [Loop Workflows](docs/loop-workflows.md) | +| Inspect local activity | [Usage Insights](docs/usage-insights.md) | +| Coordinate multi-session work | [mflow](docs/mflow.md), [TSM and worktrees](docs/tsm-and-worktrees.md) | +| Understand source layout and ownership | [Architecture](docs/architecture.md) | +| Release safely | [Releasing](docs/releasing.md), [Supply chain security](docs/supply-chain-security.md) | + +## Development + +This repository contains the MendCode-owned runtime under `src/mendcode/`. +Focused development usually happens in `src/mendcode/packages/opencode`. + +Useful commands from an existing checkout: + +```bash +cd src/mendcode/packages/opencode +bun test --timeout 30000 +bun run typecheck +bun run build +``` + +The root `src/mendcode` package intentionally does not use `bun test` as the +normal test entrypoint; run focused tests from the package that owns the change. + +## Community And Security + +- [Contributing](CONTRIBUTING.md): local development, PR expectations, and review flow. +- [Security policy](SECURITY.md): supported reporting path for security issues. +- [Community docs](docs/community.md): issues, discussions, labels, and contribution guidance. +- [Release process](docs/releasing.md): release assets, checksums, installer smoke tests, and public promotion. +- [Supply chain security](docs/supply-chain-security.md): provenance, dependency review, scanners, and release hardening. + +## For Agents + +If you are an agent working in this repository, use this short path first: + +1. Read the [source-level contributor contract](src/mendcode/AGENTS.md). +2. Use the public `mendcode` CLI and verify live source before documenting behavior. +3. Run focused checks from the package that owns the change; do not run tests from + the repository root. +4. Keep changes minimal and never include provider tokens, auth state, or local + runtime data in packages, screenshots, or docs. + +### Agent theme workflow + +When a user provides an image or visual reference, convert it into deterministic +theme JSON using the built-in color keys, then run the supported local flow: + +```sh +mendcode theme validate ./my-theme.json +mendcode theme install ./my-theme.json --name studio --scope project +mendcode theme select studio --scope project +``` + +Project themes belong in `.mendcode/themes/` and the selection belongs in +`.mendcode/tui.json`; `--scope global` uses the XDG MendCode configuration +directory (`Global.Path.config`). Validation resolves references and variants, +rejects missing or circular references, and checks 3:1 text/background contrast +when hex colors can be resolved. Do not use `kv.json` as a substitute. See +[Themes](docs/themes.md) for the complete format. These commands are local-only +and do not call a model or provider. + +
+Open the full MendCode repo context for coding agents + +This block is intentionally collapsed so the README stays readable while still +giving coding agents MendCode context before editing docs, website copy, CLI help, +screenshots, or public claims. Treat it as context, then verify live code before +changing behavior. + +### Public identity + +- Product name: MendCode. +- Public command: `mendcode`. +- Local development checkouts may include a legacy `mend` shim. Public docs, + examples, screenshots, release notes, website copy, and user-facing commands + should use `mendcode` unless the router contract changes. +- MendCode is a downstream project built on opencode, with attribution in + [ACKNOWLEDGEMENTS.md](ACKNOWLEDGEMENTS.md). Do not present it as a simple + rename. + +### Public CLI contract + +- Source of truth: `src/mendcode/packages/opencode/src/mend/cli/public-bin.ts`. +- Re-run public help before adding command examples. +- Primary public surfaces include opening the TUI, `run`, `session`, `chat`, + `status`, `doctor`, `setup`, `marketplace`, `mflow`, `worktree`, and `tsm`. +- Automation details live in [docs/automation-runtime.md](docs/automation-runtime.md): + `mendcode.cli.v1` JSON envelopes, session lifecycle commands, progress events, + bounded waiting, cancellation, secret redaction, and shared model/agent + selection. It is a wrapper over the existing runtime, not a second provider + or session implementation. +- Support surfaces include `models`, `providers`, `auth`, `permissions`, + `memory`, and `focus`. +- Internal debug surfaces such as `adapter`, `ai`, `bench`, `budget`, `config`, + `context`, `export`, `mcp`, `prompt`, `prompts`, `runtime`, `toolchain`, + `tui`, and `upstream` should not be marketed as normal user workflows. + +### Core product story + +- MendCode is the customizable coding terminal: CLI, TUI, setup flow, model + roles, permission policy, memory, runtime marketplace packages, Plan Mode, + Usage Insights, optional mflow coordination, optional TSM and worktree + orchestration, widgets, plugins, and TUI profiles. +- The pitch is not another chat prompt. The pitch is a configurable harness: + prompt chrome, status rows, model roles, memory policy, marketplace packages, + workflow coordination, review gates, and local observability. + +### Agent product context + +When an agent needs to explain what MendCode is to a reader, start with this +accurate description: + +This inventory was checked against the 20 latest changelog entries, `0.1.9` +through `0.1.28`. Use the changelog for release-specific fixes; keep this block +focused on stable product capabilities and agent-facing contracts. + +> MendCode is a terminal-first AI coding terminal and developer harness. It +> gives a local agent a configurable CLI/TUI, model roles, review gates, +> permissions, memory, reusable team packages, session automation, and optional +> multi-agent/worktree coordination. + +Classify follow-up details by the product surface they change, and use the +linked documentation as the source for details: + +| Category | Explain it as | Primary references | +| --- | --- | --- | +| Core terminal | The public `mendcode` CLI, TUI, setup/onboarding flow, provider/package setup, diagnostics, and session runtime. | [Feature map](docs/features.md), [CLI and setup](docs/cli-setup-configuration.md) | +| Prompt and model control | Prompt Context modes (`minimal`, `focus`, `full`, and project/package `custom`), `.mendcode/prompts/custom.md`, `mendcode prompt` inspection/build commands, model roles and variants, prompt status, provider-aware context continuity, image-aware compaction, and cost-aware routing. | [Feature map](docs/features.md), [CLI and setup](docs/cli-setup-configuration.md) | +| Workflow and review | Plan Mode, Changes Review, and durable Loop Workflows with validated plans, gates, schedules, receipts, artifacts, evaluators, and recovery. | [Plan Mode](docs/plan-mode.md), [Changes Review](docs/changes-review.md), [Loop Workflows](docs/loop-workflows.md) | +| Media generation | The provider-aware `image_gen` tool, configured independently from the active chat model, with persisted artifacts, optional captions, and safe edit inputs when the provider contract and permissions allow. | [Changelog](CHANGELOG.md) | +| Control and safety | Model roles, smart permissions, budgets, approval-first Memory Center, Memory Graph, and Dream flows, local provider bridges, and explicit destructive-action gates. | [CLI and setup](docs/cli-setup-configuration.md), [Memory Center](docs/memory-center.md), [TSM and worktrees](docs/tsm-and-worktrees.md) | +| Team and extensibility | Runtime packages, project MCP configuration, package-shared prompts/custom tool calls, TUI profiles, plugins, widgets, pages, and themes. | [Packages and team sharing](docs/packages-and-team-sharing.md), [Custom Tool Calls](docs/custom-tool-calls.md), [TUI plugins and widgets](docs/tui-plugins-and-widgets.md) | +| Agent and background execution | Agent View, subagents, detached background tasks, queued prompts, reconnect/compaction recovery, and Herdr state reporting. | [Automation runtime](docs/automation-runtime.md), [Loop Workflows](docs/loop-workflows.md), [Feature map](docs/features.md) | +| Coordination and operations | Optional mflow locks, TSM/worktree orchestration, automation commands, local Usage Insights, update discovery, and in-app upgrades. | [mflow](docs/mflow.md), [TSM and worktrees](docs/tsm-and-worktrees.md), [Automation runtime](docs/automation-runtime.md), [Usage Insights](docs/usage-insights.md) | + +### Image generation contract + +The implementation source is `src/mendcode/packages/opencode/src/tool/image-gen.ts`. +Agents must keep these rules intact: + +- `image_gen` is independently configured through `image_generation`; it is not + inferred from the active chat model. Configuration supports `enabled`, a + `provider/model` reference, `adapter` (`auto`, `codex-oauth`, `openrouter`, or + `openai-compatible`), `base_url`, timeout, provider options, and optional + captions. `enabled: false` must hide the tool. +- With an active OpenAI ChatGPT subscription OAuth login and no explicit image + model, the verified Codex adapter defaults to `openai/gpt-image-2`. API-key + sessions do not receive that OAuth fallback automatically. Auto adapter + selection is limited to verified provider contracts; unknown image-capable + providers require an explicit adapter. +- Use it only for an explicit request to create or edit a bitmap image. Include + orientation, aspect ratio, target resolution, exact text, visual constraints, + and avoid-items in the prompt. For a new image, omit both reference fields + (`num_last_images_to_include: 0` is also valid). For edits, provide either up + to five absolute local image paths or one to five recent conversation images, + never both. +- The `image_gen` permission is checked before the request; referenced local + images also require read permission and must stay within the allowed project + boundaries. Enforce the 50 MB input/output bounds, request timeout, safe image + URLs, and cancellation. +- Generated artifacts are persisted under MendCode's managed `generated_images` + directory and returned with metadata, format, dimensions, size, provider, + adapter, model, path, and cost when available. The full TUI shows the saved + path and external-open actions instead of rendering the image inline. +- Captions are optional and use an independently configured vision model. A + missing or failed optional caption must not discard the saved artifact; a + required caption may fail the tool after the artifact has been persisted. +- For project-bound work, copy the selected artifact into the workspace with a + stable descriptive filename and never overwrite an existing asset unless the + user explicitly requests replacement. Do not expose tokens, auth state, or + sensitive source images in prompts, captions, artifacts, or docs. + +### Agent operating contract + +- Activate a Loop Workflow or delegate background work only when the user asks + for it or the request clearly includes that intent. Inspect existing loops + before creating another one; never use `maxTurns: 0` or recreate an invalid + `completed 0/0` workflow. +- Choose the loop shape from intent: use `max-goal` with concrete completion + criteria for a verifiable goal, `unbounded-monitor` without `maxTurns` for a + recurring scheduled job, and `fixed` with a positive `maxTurns` only for an + exact iteration count. Do not spread goal work across the full safety cap. +- Treat cadence and completion as independent. `daily` uses `dailyAt` plus an + explicit timezone; interval and self-paced/adaptive/external-signal triggers + wake the same durable objective repeatedly. A scheduled loop's objective + describes each wakeup and does not imply early completion after the first run. +- A `needs_input` state is a durable permission or user-decision wait. Resume + the same run after input arrives; do not report it as completed, failed, or a + reason to create a duplicate loop. In `/loops`, persisted `nextWakeup` is the + source of truth while the visible countdown is reactive presentation. +- Use report-only/read-only execution for inspection and monitoring. An explicit + request to write, edit, fix, implement, code, or create files permits normal + execution for that workflow; keep destructive worktree actions preview-first. +- Route work through the configured model roles and variants with cost-aware, + provider-neutral language. Do not present internal debug surfaces as normal + user workflows. +- Treat `memoryAssistant` as a constrained memory-stewardship agent and Dream + as a proposal-producing maintenance loop, not as silent source editing or a + general coding agent. Generated memory changes remain reviewable proposals + until the user applies them. +- Treat `image_gen` availability as provider- and permission-gated. It is an + independently configured media tool, not an assumption about the active chat + model; preserve artifacts and redact sensitive inputs. + +The short explanation is not “another chat box” or a cloud analytics product. +It is a local-first control surface for shaping how coding agents work. + +### Screenshots and demos + +- Use [the feature map](docs/features.md) as the source contract for README, + website, screenshot, and demo claims. +- README screenshots live in `docs/assets/screenshots/`. Website copies live in + the MendCode-Web repository under `public/screenshots/` and + `public/tui-showcase/`. +- There is currently no checked-in capture script or `mendcode screenshot` + command. Existing images are committed static assets; do not describe an + automated or canonical capture flow unless one is added and verified. +- For future captures, validate the public `mendcode` behavior first, use a + clean demo state, redact provider tokens/auth state/local runtime data, and + update the image alt text or caption with the exact product surface shown. + +### TUI customization + +- Main user-facing docs: [Customization](docs/customization.md) and + [TUI plugins and widgets](docs/tui-plugins-and-widgets.md). +- Profile path: `.mendcode/tui/profile.json`. +- Key surfaces: prompt frame, prompt lead string, prompt status row, home title, + mascot mode, centered home, split home, Agent View, chat presentation, + activity states, widgets, slots, custom routes, dialogs, footer entries, + themes, density, and package-distributed UI behavior. +- Chat presentation includes Plain/Markdown/Rich rendering, streaming Markdown, + wrapped tables and code fences, checklists, callouts, local Mermaid diagrams, + and terminal-safe color swatches. +- Good demo profile: mascot identity, split home, `agentManager` right panel, + `top-bottom` prompt chrome, `mendcode>` lead text, and outside prompt status. + +### Marketplace Packages + +- Main docs: [Marketplace and team sharing](docs/packages-and-team-sharing.md). +- Marketplace packages can include commands, agents, modes, skills, prompts, + MCP config, context docs, scripts, plugins, widgets, components, custom tools, + custom pages, TUI profile, themes, model roles, focus defaults, budget + posture, permission defaults, memory defaults, and worktree policy. +- Packages must not include provider tokens, OAuth state, `.env*`, auth state, + local databases, room secrets, or machine-local run/cache state. + +### Custom tool calls + +- Custom tool calls are assistant-facing project or package actions loaded from + `.mendcode/tools` (the singular `.mendcode/tool` path is also supported). They + are local TypeScript/JavaScript code with a description and validated argument + schema; they are not MCP tools. +- `execute(args, context)` receives the current `sessionID`, `messageID`, + `agent`, `directory`, `worktree`, cancellation via `abort`, visible-call + updates through `metadata()`, and permission requests through `ask()`. +- `tool.schema` defines the validation and JSON schema exposed to the model. + Tools may return concise output plus metadata, and should honor cancellation + and avoid silent writes outside the current project/worktree. +- Packages share tools through an `artifacts.tools` manifest entry or a + project-local `.mendcode/package.json`. Custom tools are trusted local code: + review them before enabling a package and never distribute credentials, + `.env*`, auth state, or machine-local data. + +### Review, memory, and safety + +- Plan Mode is an explicit review gate before implementation. +- Memory is approval-first: global/project scopes, explicit add/search/preview + flows, generated proposals, and apply/reject/edit review. +- Memory Center is the user-facing memory workspace: saved global/project + memories, pending proposals, project grouping, the Memory Graph/category graph, + category policy, Dream status/logs, inspector, and constrained memory side chat. +- The memory side agent can answer memory-specific questions, inspect saved + entries/categories/policies, explain why context is being retrieved, and draft + reviewable proposals for memory/category/policy changes. It should be + described as powerful for memory stewardship, not as a general coding agent. +- Dream is the manual/scheduled memory maintenance loop. It can consolidate + stale or duplicated knowledge, surface conflicts, generate safety evidence, + and create proposals through the `memoryDream` role; it should not be claimed + to edit source files, mutate git, or apply memory silently. +- Generated memory mutations remain proposals unless the user explicitly applies + them. This applies to extraction, side chat, and Dream. +- Usage Insights is local observability, not cloud analytics and not a + productivity guarantee. +- Smart permissions can route risky actions through a configured reviewer role. + +### Coordination + +- mflow is optional local-first coordination and lock/status support. +- Worktree and TSM flows are optional terminal/worktree orchestration. +- Destructive worktree actions should stay preview-first and gated. + +### Documentation map + +- [Feature map](docs/features.md): product inventory for README, website, + screenshots, and demos. +- [Docs index](docs/README.md): user journey index. +- [CLI, setup, and configuration](docs/cli-setup-configuration.md): setup, + config, models, permissions, and memory. +- [Customization](docs/customization.md): static TUI profile and visual + customization. +- [TUI plugins and widgets](docs/tui-plugins-and-widgets.md): dynamic TUI + extension points. +- [Custom Tool Calls](docs/custom-tool-calls.md): project/package assistant + tools, typed arguments, execution context, metadata, cancellation, and + permission checks. +- [Plan Mode](docs/plan-mode.md): plan review flow. +- [Changes Review](docs/changes-review.md): responsive diff review, comments, + keybinds, and agent-visible review context. +- [Loop Workflows](docs/loop-workflows.md): durable loop sessions, root + session/evaluator boundaries, `/loop`, `/loops`, and service controls. +- [Automation runtime](docs/automation-runtime.md): machine-readable session + control, progress events, waiting, cancellation, and shared model selection. +- [Memory Center](docs/memory-center.md): saved/pending memories, categories, + Dream maintenance, and the constrained memory side agent. +- [Usage Insights](docs/usage-insights.md): local activity dashboard. +- [mflow](docs/mflow.md): local-first coordination. +- [TSM and worktrees](docs/tsm-and-worktrees.md): terminal/worktree orchestration. +- [Architecture](docs/architecture.md): source layout and ownership boundaries. +- [Releasing](docs/releasing.md) and + [Supply chain security](docs/supply-chain-security.md): release and supply + chain policy. + +### Public copy rules + +- Keep docs provider-neutral unless a user explicitly asks for provider-specific + examples. +- Avoid aspirational feature claims without a source path, validated behavior, + or clearly marked local work. +- Prefer factual capability wording over behavioral prompt instructions. +- If code contradicts this block, the code wins. + +
## Lineage -MendCode is a downstream project built on the opencode codebase. It is not presented as a simple fork: MendCode adds its own `mend` CLI surface, control plane, setup flow, package system, mflow coordination, optional TSM/worktree orchestration, and terminal UI customization layer. See [ACKNOWLEDGEMENTS.md](ACKNOWLEDGEMENTS.md) for attribution. +MendCode is a downstream project built on the opencode codebase. It is not +presented as a simple fork: MendCode adds its own `mendcode` CLI surface, +control plane, setup flow, package system, mflow coordination, optional +TSM/worktree orchestration, Plan Mode review flow, Usage Insights dashboard, +memory policy, model-role projection, and terminal UI customization layer. + +See [ACKNOWLEDGEMENTS.md](ACKNOWLEDGEMENTS.md) for attribution. + +

+ + + + MendCode + +

diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000..6d42780f --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,63 @@ +# Security Policy + +MendCode treats the repository, installer, release assets, package publishing, and automation as one supply-chain surface. + +## Reporting a Vulnerability + +Please do not report private vulnerabilities, leaked credentials, or exploit details in public issues or discussions. + +Use GitHub private vulnerability reporting when available: + +```text +https://github.com/MendCode/MendCode/security/advisories/new +``` + +If private vulnerability reporting is unavailable, open a minimal issue that says you need a private security contact, without exploit details or secrets. + +## What to Include + +- Affected version, commit, or release. +- Platform and installation method. +- Reproduction steps with safe test data. +- Impact assessment. +- Whether the issue may expose credentials, files, command execution, model prompts, tool calls, or workspace data. + +## Supported Versions + +Security fixes target the latest public release and the current `main` branch. + +| Target | Supported | +| --- | --- | +| Latest public release | Yes | +| `main` | Yes | +| Older releases | Best effort only until a formal support window is announced | + +## Release Verification + +MendCode releases should include checksums, an SBOM, and GitHub artifact attestations. + +Verify release downloads: + +```bash +gh release download v --repo MendCode/MendCode +shasum -a 256 -c SHA256SUMS +gh attestation verify --repo MendCode/MendCode mendcode-*.zip mendcode-*.tar.gz SHA256SUMS RELEASE-MANIFEST.txt mendcode.spdx.json +``` + +Do not install release assets whose checksums or attestations fail. + +## Secret Handling + +Never paste real API keys, access tokens, SSH keys, `.env` files, private prompts, or company config into an issue, PR, discussion, or test fixture. + +If you accidentally disclose a secret: + +1. Revoke or rotate it immediately. +2. Report where it was exposed. +3. Do not rely on deletion from Git history as the only remediation. + +## Maintainer Notes + +The repository runs security guard checks for risky tracked files, invisible Unicode controls, secret scanning, dependency scanning, dependency review, GitHub Actions review, CodeQL, custom Semgrep rules, pinned-action checks, and release preflight checks. + +Release publishing is manual, environment-gated, and should produce `mendcode-*` archives, `SHA256SUMS`, `RELEASE-MANIFEST.txt`, `mendcode.spdx.json`, and artifact attestations. diff --git a/SUPPORT.md b/SUPPORT.md new file mode 100644 index 00000000..6a108dc9 --- /dev/null +++ b/SUPPORT.md @@ -0,0 +1,31 @@ +# Support + +Use the right channel so the answer helps future users. + +## Questions + +Use GitHub Discussions for: + +- setup help +- package sharing +- TUI customization +- plugin/widget examples +- mflow and worktree usage +- model/provider configuration + +## Bugs + +Use GitHub Issues for reproducible bugs. Include: + +- MendCode version +- OS and terminal +- install method +- expected behavior +- actual behavior +- logs, screenshots, or reproduction steps + +## Security + +Use [SECURITY.md](SECURITY.md) for vulnerabilities or suspected secret leaks. + +Do not post private security details publicly. diff --git a/bunfig.toml b/bunfig.toml new file mode 100644 index 00000000..67eedf44 --- /dev/null +++ b/bunfig.toml @@ -0,0 +1,2 @@ +[test] +root = "./do-not-run-tests-from-root" diff --git a/docs/README.md b/docs/README.md index 9800e459..8cf6fe39 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,44 +1,113 @@ # MendCode Docs -These docs describe the MendCode-specific runtime layer in this repository. They intentionally focus on MendCode-owned behavior instead of the donor runtime internals. +These docs describe the MendCode-owned product surface: the public `mendcode` CLI, `.mendcode/` configuration, setup flow, runtime packages, model roles, prompt modes, memory, permissions, TUI customization, Plan Mode, Changes Review, Loop Workflows, Usage Insights, mflow, optional TSM/worktrees, and release/security policy. -## Start Here +Use this index by intent. **Use MendCode** explains the public workflow, **Features and pages** describes what the TUI can do, and **Build and maintain** is for packages, extensions, source paths, and releases. The [Source Map](source-map.md) is intentionally separate so normal product docs do not repeat internal `opencode` paths. -- [Architecture and packages](architecture.md): repo layout, owned runtime, package list, and how the pieces fit. -- [CLI, setup, and configuration](cli-setup-configuration.md): `mend`, setup steps, config files, models, providers, memory, permissions. -- [Customization](customization.md): prompt chrome, TUI profile, widgets, title/logo/ASCII mascot, model roles. -- [TUI plugins and widgets](tui-plugins-and-widgets.md): custom widgets, slots, footer entries, commands, dialogs, routes, themes, and package distribution. -- [Packages and team sharing](packages-and-team-sharing.md): package manifests, local snapshots, GitHub/team registries, sharing one company package. -- [mflow coordination](mflow.md): what mflow is, setup, relay modes, file locks, and multi-agent same-worktree editing. -- [TSM and worktrees](tsm-and-worktrees.md): `mend --worktree`, `mend --tsm`, optional TSM lifecycle, preview-first worktree safety. -- [Public readiness audit](public-readiness-audit.md): current branch, secret, and old-repo-reference audit notes. -- [Lineage and acknowledgements](../ACKNOWLEDGEMENTS.md): opencode attribution and MendCode downstream scope. +## Use MendCode + +- [CLI, setup, and configuration](cli-setup-configuration.md): install/open commands, setup state, config paths, focus profiles, model roles, prompt modes, permissions, and memory. +- [Context, cache and computer tools](context-and-computer-tools.md): request profiles, tool discovery, experimental Code Mode, and native macOS captures. +- [Session history](session-history.md): browse, inspect, and resume previous sessions. +- [Automation runtime](automation-runtime.md): JSON envelopes, shared model selection, progress inspection, events, waiting, and cancellation. +- [Independent Workflows](workflows.md): one-shot plans, task sequencing, completion evidence, and operator controls. +- [Loop Workflows](loop-workflows.md): verified goals, recurring jobs, bounded runs, durable permission waits, and `/loops` supervision. +- [mflow coordination](mflow.md): local-first coordination, relay modes, file locks, and same-worktree editing. +- [TSM and worktrees](tsm-and-worktrees.md): optional terminal sessions, worktree routing, registry ownership, and preview-first safety. +- [Packages and team sharing](packages-and-team-sharing.md): share commands, agents, modes, skills, prompts, MCP, widgets, profiles, and policy. + +## Features and pages + +### Product features + +- [Feature Map](features.md): complete inventory of product behavior, shortcuts, slash commands, and demo surfaces. +- [Customization](customization.md): prompt chrome, input marker, status placement, home identity, Agent View, mascot, activity states, and profiles. +- [Mermaid ASCII rendering](mermaid-ascii-rendering.md): terminal-native diagrams, fit/pan controls, local scrolling, supported families, and expanded fixtures. +- [Custom Tool Calls](custom-tool-calls.md): project-local and package-shared tools with typed context and permission checks. +- [TUI Plugins and Widgets](tui-plugins-and-widgets.md): status rows, widgets, slots, commands, dialogs, routes, themes, keybinds, and package distribution. +- [Themes](themes.md): terminal theme reference. + +### TUI pages and operator surfaces + +- [Plan Mode](plan-mode.md): review, edit, comment, approve, or reject a plan before implementation. +- [Changes Review](changes-review.md): diff workspace, responsive layout, comments, and agent-visible review context. +- [Loop Workflows](loop-workflows.md): active/history dashboard, phases, runs, permissions, and recovery controls. +- [Memory Center](memory-center.md): saved memories, proposals, categories, Dream status, and constrained side chat. +- [Usage Insights](usage-insights.md): activity scopes, token heatmap, AI time, tools/agents/models, cache behavior, and weather. + +## Build and maintain + +- [Architecture and packages](architecture.md): ownership, runtime boundary, repository layout, package map, and safety model. +- [Package index](package-index.md): workspace packages versus runtime `.mendcode` packages. +- [MendCode Source Map](source-map.md): one maintained map from public features to implementation and test paths. +- [Releasing](releasing.md): installer contract, checksums, release notes, and public installer smoke tests. +- [Codex CLI and model audit](audits/codex-cli-0.153.3-gpt56-2026-09-04.md): upstream comparison and the GPT-5.6/GPT-6 Astra compatibility decisions for 0.1.43. +- [Changelog](../CHANGELOG.md): versioned behavior changes and regression coverage for recent releases. +- [Supply chain security](supply-chain-security.md): provenance, SBOM, pinned actions, dependency review, and scanner policy. +- [Public readiness audit](public-readiness-audit.md): branch, secret, dependency, legacy-reference, and public-surface checks. + +## Community and publication + +- [Community](community.md): issues, discussions, pull requests, and labels. +- [Wiki](wiki.md): GitHub wiki structure and synchronization. +- [Lineage and acknowledgements](../ACKNOWLEDGEMENTS.md): upstream attribution and MendCode downstream scope. ## Main Commands ```bash -mend -mend status -mend setup status -mend tui status -mend models status -mend packages status -mend mflow status -mend tsm status -mend worktree status -mend --worktree [branch|path|id] -mend --tsm [branch|path|id|--all] +mendcode +mendcode status +mendcode session list --format json +mendcode loops status +mendcode setup status +mendcode models status +mendcode packages status +mendcode mflow status +mendcode tsm status +mendcode worktree status +mendcode --worktree [branch|path|id] +mendcode --tsm [branch|path|id|--all] +``` + +## Loop Workflow Controls + +```text +/loop # create/activate a loop from natural language +/loops # supervise active and historical loops +``` + +## TUI Customization Commands + +Most visual changes can be made from the command palette: + +```text +Ctrl+P -> Home identity +Ctrl+P -> Home title text +Ctrl+P -> Home title font +Ctrl+P -> Home mascot ASCII +Ctrl+P -> Home welcome mode +Ctrl+P -> Home split panel +Ctrl+P -> Prompt chrome +Ctrl+P -> Prompt context (`minimal`, `focus`, `full`, or project `custom`) +Ctrl+P -> Prompt lead string +Ctrl+P -> Prompt status placement +Ctrl+P -> Chat presentation +Ctrl+P -> Usage Insights ``` -## Source Map - -- `src/mendcode/packages/opencode/src/mend/cli/public-bin.ts`: public `mend` command router. -- `src/mendcode/packages/opencode/src/mend/config/project.ts`: project config, focus profiles, generated runtime config, package metadata. -- `src/mendcode/packages/opencode/src/mend/config/models.ts`: model roles and projection. -- `src/mendcode/packages/opencode/src/mend/config/mflow.ts`: local-first mflow setup, relay config, edit-lock enforcement. -- `src/mendcode/packages/opencode/src/mend/config/tsm.ts`: optional TSM lifecycle and detection. -- `src/mendcode/packages/opencode/src/mend/config/worktree.ts`: worktree status, dry-run planning, adoption, destructive previews. -- `src/mendcode/packages/opencode/src/mend/runtime/pack.ts`: runtime package snapshots. -- `src/mendcode/packages/opencode/src/mend/runtime/packages.ts`: installed package state and active package projection. -- `src/mendcode/packages/opencode/src/mend/profile.ts`: TUI profile schema and defaults. -- `src/mendcode/packages/plugin/src/tui.ts`: public TUI plugin/widget types. +Demo-worthy shortcuts: + +```text +Shift+Tab -> Mode picker +Tab -> Cycle primary agent +F2 / Shift+F2 -> Cycle recent models +F3 / Shift+F3 -> Cycle or list model variants +Ctrl+X then s -> Runtime status +Ctrl+X then l -> Session switcher +``` + +CLI profile inspection exists for compatibility/debugging, but it is not the normal customization path. + +## Implementation pointers + +The maintained implementation and test paths now live in the dedicated [MendCode Source Map](source-map.md). This index stays focused on the public product documentation. diff --git a/docs/architecture.md b/docs/architecture.md index 373096ed..adf8ca10 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -1,18 +1,18 @@ # Architecture and Packages -MendCode has a MendCode-owned control plane wrapped around an adapted terminal coding runtime. The public surface is the `mend` CLI. The runtime source lives in `src/mendcode/packages/opencode`, but public commands are routed through MendCode modules under `src/mendcode/packages/opencode/src/mend`. +MendCode has a MendCode-owned control plane wrapped around an adapted terminal coding runtime. The public surface is the `mendcode` CLI. The internal runtime package is documented in the [MendCode Source Map](source-map.md#why-some-paths-say-opencode); public commands are routed through MendCode-owned control-plane modules. ## Lineage MendCode is a downstream project built on the opencode codebase. In open-source terms, it is a derivative work with substantial product/runtime additions rather than a simple mirror fork. The opencode lineage is preserved in the MIT license and in [ACKNOWLEDGEMENTS.md](../ACKNOWLEDGEMENTS.md). -MendCode's own layer includes the `mend` public CLI, MendCode-owned config/control plane, setup flow, package and registry system, mflow coordination, optional TSM/worktree orchestration, model-role projection, prompt/TUI customization, and public docs. +MendCode's own layer includes the `mendcode` public CLI, MendCode-owned config/control plane, setup flow, package and registry system, mflow coordination, Loop Workflows, optional TSM/worktree orchestration, model-role projection, prompt/TUI customization, and public docs. ## Repository Layout - `.github/`: public automation and security workflow wiring. - `src/mendcode/`: main product source, installer, package workspace, infra, and release scripts. -- `src/mendcode/packages/opencode/`: the `mend`/`mendcode` CLI runtime package. +- `src/mendcode/packages/opencode/`: the `mendcode` CLI runtime package; development checkouts may keep local `mend` shims. - `src/mendcode/packages/core/`: shared filesystem, global paths, locks, npm config, logging, utilities. - `src/mendcode/packages/plugin/`: public plugin/tool/TUI extension SDK. - `src/mendcode/packages/ui/`: web/UI component package. @@ -27,18 +27,45 @@ MendCode's own layer includes the `mend` public CLI, MendCode-owned config/contr MendCode keeps user-facing state under `.mendcode/` and generates compatibility config for the underlying runtime. The important contract is: -- Users interact with `mend`, not donor runtime commands. +- Users interact with `mendcode`, not donor runtime commands. A local `mend` shim may exist in development checkouts, but it is not the public install contract. - MendCode config is source of truth. - Generated runtime files are implementation detail. - Donor/runtime hot paths are guarded and should not be the public customization API. -The public router is `src/mendcode/packages/opencode/src/mend/cli/public-bin.ts`. It routes commands such as `mend setup`, `mend packages`, `mend mflow`, `mend tsm`, and `mend worktree` to the MendCode control plane. +The public router is `src/mendcode/packages/opencode/src/mend/cli/public-bin.ts`. It routes commands such as `mendcode setup`, `mendcode packages`, `mendcode mflow`, `mendcode loops`, `mendcode session`, `mendcode tsm`, and `mendcode worktree` to the MendCode-owned runtime/control plane. + +## Automation Boundary + +The automation surface is a CLI boundary over the existing runtime, not a +second agent implementation: + +```text +mendcode session / mendcode run --format json + -> public-bin.ts + -> opencode CLI command + -> Session / SessionPrompt / SessionStatus / Bus / LoopWorkflow + -> project database and provider runtime + -> mendcode.cli.v1 JSON envelopes +``` + +`src/mendcode/packages/opencode/src/cli/cmd/session.ts` owns lifecycle +operations such as create, send, inspect, wait, events, and cancel. It reads +the same session messages, pending questions and permissions, subagents, loops, +events, and diff data used by the TUI. `src/mendcode/packages/opencode/src/cli/cmd/run.ts` +provides the lower-level streaming path for a prompt, while +`src/mendcode/packages/opencode/src/cli/automation.ts` versions envelopes and +redacts secret-like fields. + +Model selection is shared rather than duplicated: `cli/model-selection.ts` and +`mend/config/models.ts` apply explicit CLI overrides, TUI overrides, message +and session models, subagent models, configured roles, and provider fallback in +one resolver used by both automation and the prompt UI. ## Core Runtime Packages | Package | Purpose | | --- | --- | -| `mendcode` | CLI runtime package; exposes `mend`, `mendcode`, and `mendcode-runtime`. | +| `mendcode` | CLI runtime package; exposes `mendcode` and `mendcode-runtime`. | | `@mendcode/core` | Global paths, filesystem helpers, locks, npm config, observability, utility code. | | `@mendcode/plugin` | Plugin API for custom tools and TUI/widget extensions. | | `@mendcode/ui` | Shared UI components, theme tokens, file/message rendering, stories. | @@ -49,9 +76,10 @@ The public router is `src/mendcode/packages/opencode/src/mend/cli/public-bin.ts` ## MendCode-Owned Subsystems - Setup/onboarding: provider, models, budget, package, TUI, prompt, memory, permissions. -- Models: role-based model config for default, plan, build/code, review, subagent, title, compaction, summary, memory extraction, and permission review. +- Models: role-based model config for default, plan, build/code, subagent, title, compaction, summary, memory extraction, and permission review. - Runtime packages: shareable `.mendcode` bundles with commands, agents, modes, skills, plugins, prompts, MCP, widgets, TUI profile, models, focus, budget, memory, permissions, and worktree policy. - mflow: optional coordination and file-lock layer for concurrent agents. +- Loop Workflows: durable model/runner/tool in `src/mendcode/packages/opencode/src/session/loop.ts`, `src/mendcode/packages/opencode/src/session/loop-runner.ts`, and `src/mendcode/packages/opencode/src/tool/loop.ts`; `/loops` dashboard under `src/mendcode/packages/opencode/src/cli/cmd/tui/routes/loops/`; legacy and Effect route stacks under `src/mendcode/packages/opencode/src/server/routes/instance/`; and public CLI/service controls in `src/mendcode/packages/opencode/src/mend/cli/control-plane.ts` and `src/mendcode/packages/opencode/src/mend/runtime/loop-service.ts`. - TSM/worktrees: optional terminal-session/worktree executor with MendCode-owned safety registry. - TUI customization: profile, prompt chrome, activity messages, mascot/logo, widgets, surfaces, density, theme. @@ -60,6 +88,6 @@ The public router is `src/mendcode/packages/opencode/src/mend/cli/public-bin.ts` MendCode treats optional integrations as opt-in: - Packages project configuration; they do not install TSM or start mflow by themselves. -- TSM is optional and never installed by `mend tsm status`. +- TSM is optional and never installed by `mendcode tsm status`. - Worktree create/remove/reset commands are preview-first and report `executesGit: false` unless a future explicit execution gate is added. - mflow setup writes visible local config and can be deactivated or removed without deleting unrelated project files. diff --git a/docs/assets/banners/readme-hero-banner.png b/docs/assets/banners/readme-hero-banner.png new file mode 100644 index 00000000..a24b3570 Binary files /dev/null and b/docs/assets/banners/readme-hero-banner.png differ diff --git a/docs/assets/branding/mendcode-logo-horizontal-master.svg b/docs/assets/branding/mendcode-logo-horizontal-master.svg new file mode 100644 index 00000000..00c9db31 --- /dev/null +++ b/docs/assets/branding/mendcode-logo-horizontal-master.svg @@ -0,0 +1,17 @@ + + + MendCode horizontal logo + + + + + + + + + + + + + + diff --git a/docs/assets/branding/mendcode-logo-horizontal-white.svg b/docs/assets/branding/mendcode-logo-horizontal-white.svg new file mode 100644 index 00000000..20ffca9a --- /dev/null +++ b/docs/assets/branding/mendcode-logo-horizontal-white.svg @@ -0,0 +1,17 @@ + + + MendCode horizontal logo + + + + + + + + + + + + + + diff --git a/docs/assets/screenshots/changes-review-diff.png b/docs/assets/screenshots/changes-review-diff.png new file mode 100644 index 00000000..935f8088 Binary files /dev/null and b/docs/assets/screenshots/changes-review-diff.png differ diff --git a/docs/assets/screenshots/home-agent-view.png b/docs/assets/screenshots/home-agent-view.png new file mode 100644 index 00000000..38f9fb42 Binary files /dev/null and b/docs/assets/screenshots/home-agent-view.png differ diff --git a/docs/assets/screenshots/home-mascot-actions.png b/docs/assets/screenshots/home-mascot-actions.png new file mode 100644 index 00000000..f0f6ccda Binary files /dev/null and b/docs/assets/screenshots/home-mascot-actions.png differ diff --git a/docs/assets/screenshots/home-mascot-agent-view-centered.png b/docs/assets/screenshots/home-mascot-agent-view-centered.png new file mode 100644 index 00000000..e79cebc0 Binary files /dev/null and b/docs/assets/screenshots/home-mascot-agent-view-centered.png differ diff --git a/docs/assets/screenshots/home-mascot-centered.png b/docs/assets/screenshots/home-mascot-centered.png new file mode 100644 index 00000000..c11b44dd Binary files /dev/null and b/docs/assets/screenshots/home-mascot-centered.png differ diff --git a/docs/assets/screenshots/home-wordmark-actions.png b/docs/assets/screenshots/home-wordmark-actions.png new file mode 100644 index 00000000..79215e84 Binary files /dev/null and b/docs/assets/screenshots/home-wordmark-actions.png differ diff --git a/docs/assets/screenshots/home-wordmark-agent-view-centered.png b/docs/assets/screenshots/home-wordmark-agent-view-centered.png new file mode 100644 index 00000000..35a0ce5b Binary files /dev/null and b/docs/assets/screenshots/home-wordmark-agent-view-centered.png differ diff --git a/docs/assets/screenshots/home-wordmark-centered.png b/docs/assets/screenshots/home-wordmark-centered.png new file mode 100644 index 00000000..af619e89 Binary files /dev/null and b/docs/assets/screenshots/home-wordmark-centered.png differ diff --git a/docs/assets/screenshots/loop-workflow-created.png b/docs/assets/screenshots/loop-workflow-created.png new file mode 100644 index 00000000..2e001297 Binary files /dev/null and b/docs/assets/screenshots/loop-workflow-created.png differ diff --git a/docs/assets/screenshots/loop-workflows-dashboard.png b/docs/assets/screenshots/loop-workflows-dashboard.png new file mode 100644 index 00000000..d4fad041 Binary files /dev/null and b/docs/assets/screenshots/loop-workflows-dashboard.png differ diff --git a/docs/assets/screenshots/markdown-preview-showcase.png b/docs/assets/screenshots/markdown-preview-showcase.png new file mode 100644 index 00000000..6a3c8263 Binary files /dev/null and b/docs/assets/screenshots/markdown-preview-showcase.png differ diff --git a/docs/assets/screenshots/memory-center-overview.png b/docs/assets/screenshots/memory-center-overview.png new file mode 100644 index 00000000..141dbd5d Binary files /dev/null and b/docs/assets/screenshots/memory-center-overview.png differ diff --git a/docs/assets/screenshots/plan-review-modal.png b/docs/assets/screenshots/plan-review-modal.png new file mode 100644 index 00000000..0cca3d1d Binary files /dev/null and b/docs/assets/screenshots/plan-review-modal.png differ diff --git a/docs/assets/screenshots/usage-insights-overview.png b/docs/assets/screenshots/usage-insights-overview.png new file mode 100644 index 00000000..7a54d942 Binary files /dev/null and b/docs/assets/screenshots/usage-insights-overview.png differ diff --git a/docs/assets/social/mendcode-logo-3d.png b/docs/assets/social/mendcode-logo-3d.png new file mode 100644 index 00000000..1b86a8e3 Binary files /dev/null and b/docs/assets/social/mendcode-logo-3d.png differ diff --git a/docs/audits/codex-cli-0.153.3-gpt56-2026-09-04.md b/docs/audits/codex-cli-0.153.3-gpt56-2026-09-04.md new file mode 100644 index 00000000..017a11b3 --- /dev/null +++ b/docs/audits/codex-cli-0.153.3-gpt56-2026-09-04.md @@ -0,0 +1,46 @@ +# Codex CLI and OpenAI model audit — 2026-09-04 + +This audit records the upstream Codex CLI comparison used for the 0.1.43 +release. The reference CLI stable release was `0.153.3` (`rust-v0.153.3`). +OpenAI's current model pages identify the flagship model as `gpt-6-astra` and +the 5.6 family as `gpt-5.6`/Sol, Terra, and Luna. + +## Ported in 0.1.43 + +- Add `gpt-6-astra`, `gpt-5.6`, `gpt-5.6-sol`, `gpt-5.6-terra`, and + `gpt-5.6-luna` to the OpenAI catalog fallback. A stale cache or bundled + `models.dev` snapshot no longer hides these models from the picker. +- Preserve live `models.dev` entries when they exist, so the fallback cannot + replace newer provider metadata. +- Add API and ChatGPT OAuth presets with documented context limits and API + prices. GPT-6 Astra keeps its 1.05M context/922K input limit; ChatGPT OAuth + Sol, Terra, and Luna keep the existing 256K effective limit imposed by the + Responses Lite adapter. +- Recognize Astra and its documented `fast` variant in the ChatGPT OAuth + catalog. Astra stays on the standard Codex Responses transport; the current + MendCode Responses Lite compatibility contract is limited to the 5.6 tiers. +- Keep the compact Commands history in the Ctrl+T horizontal widget tray, + including its direct session-open action. + +## Reviewed and intentionally not ported + +- Upstream's asynchronous model-picker refresh (`5fc7840cf6d0`) is a larger + TUI/server contract change. MendCode already refreshes `models.dev` in the + provider service; this release adds the static safety net without changing + picker lifecycle or selection state. +- Luna Reserve usage fallback, app-server collaboration-mode discovery, live + context-compaction status, rate-limit banners, permission-profile discovery, + startup warning condensation, automatic thread naming, and submission-ID + steer acknowledgement were reviewed from the upstream history. Each needs a + separate MendCode contract and regression surface, so none is represented as + shipped behavior here. +- The upstream CLI version is not copied into MendCode's `version` request + header. The existing `0.144.0` value belongs to MendCode's internal + Responses Lite compatibility contract, and the upstream source contains no + equivalent current header contract to justify changing it. + +## Sources + +- [OpenAI GPT-6 Astra model documentation](https://developers.openai.com/api/docs/models/gpt-6-astra) +- [OpenAI GPT-5.6 Sol model documentation](https://developers.openai.com/api/docs/models/gpt-5.6-sol) +- [OpenAI Codex CLI releases](https://github.com/openai/codex/releases) diff --git a/docs/automation-runtime.md b/docs/automation-runtime.md new file mode 100644 index 00000000..fab7d168 --- /dev/null +++ b/docs/automation-runtime.md @@ -0,0 +1,73 @@ +# Automation runtime + +MendCode exposes the same session runtime used by the TUI through the public CLI. An external agent can create work, continue an existing session, wait for a terminal state, inspect progress, stream events, or cancel active work without duplicating the model/provider/session stack. + +## Commands + +All session commands accept `--dir `, `--format table|json`, and `--json` (an alias for JSON output). + +```bash +mendcode session create --title "Implement the feature" --format json +mendcode session send ses_... "Inspect the repository and implement the change" --format json +mendcode session status ses_... --format json +mendcode session inspect ses_... --format json +mendcode session wait ses_... --timeout-ms 1800000 --format json +mendcode session events ses_... --follow --format json +mendcode session cancel ses_... --format json +``` + +The available operations are: + +- `create`, `list`, `get`, `inspect`, `rename`, `fork` +- `archive`, `delete`, `send`, `status`, `wait`, `cancel` +- `events` for persisted history or live events +- `export` for a complete session snapshot + +`session send --async` starts a detached MendCode runtime and returns an acceptance envelope. Follow it with `session wait` or `session events --follow`. Without `--async`, `send` waits for the prompt operation to finish before returning. + +## Versioned JSON contract + +Every JSON line is an envelope with protocol `mendcode.cli.v1`: + +```json +{ + "protocol": "mendcode.cli.v1", + "kind": "event | result | error", + "event": "session.completed", + "eventID": "evt_...", + "timestamp": 1760000000000, + "sessionID": "ses_...", + "data": {} +} +``` + +`eventID` is stable for a single emitted event. `session events` also includes the persisted `sequence` for historical records. JSON errors use the same envelope and exit non-zero. Secret-like fields such as API keys, authorization headers, passwords, cookies, bearer tokens, and private keys are redacted before they are emitted; normal usage counters such as `tokens.input` remain available. + +`mendcode run --format json` is the lower-level streaming surface. It emits `session.started`, tool/step/text events as they arrive, and `session.completed` or `error` at the end. Use `--thinking` only when reasoning events are intentionally needed. + +## Model and agent selection + +Automation resolves the effective model through the same shared resolver used by the prompt UI. The effective precedence is: + +1. explicit `--model provider/model` and `--variant`; +2. a newer local TUI model override; +3. the latest user-message model for an existing session; +4. the stored session model; +5. the selected subagent's model when the session uses a subagent; +6. the configured local role/agent model, project model, or provider fallback. + +The selected agent is taken from `--agent`, the session, or the runtime default. Global/project model roles are read from the existing MendCode model configuration; automation does not maintain a second model registry. + +## Inspection and lifecycle state + +`session inspect`, `status`, and `export` expose the current session, messages, derived state, pending questions and permissions, plan reviews, child sessions, background tasks/subagents, owned loops, persisted events, and the current diff. Derived states include `running`, `retrying`, `waiting_for_input`, `waiting_for_approval`, `waiting_for_lock`, `waiting_for_subagent`, `completed`, `failed`, `cancelled`, and `idle`. + +`session cancel` calls the real `SessionPrompt` cancellation path. It does not delete the session or its history. `session wait` polls the persisted runtime state with bounded timeout and interval settings, and returns a timeout envelope plus a non-zero exit when the deadline is reached. + +## Integration guidance + +- Treat stdout JSON as a line-delimited stream; do not parse human-readable output in automation. +- Store the returned `sessionID` and use it for later `send`, `status`, `wait`, `events`, and `cancel` calls. +- Use `events` for progress and `inspect`/`export` for a complete snapshot. +- Keep authentication and provider configuration in MendCode's normal local configuration. Do not put credentials in prompts, titles, or custom event data. +- The command is local-first and uses the selected project directory; it does not create a separate agent server or provider abstraction. diff --git a/docs/beta-integration-readiness.md b/docs/beta-integration-readiness.md new file mode 100644 index 00000000..cb7fa2d1 --- /dev/null +++ b/docs/beta-integration-readiness.md @@ -0,0 +1,49 @@ +# Beta integration checkpoint + +This is an **incomplete development checkpoint, not a release candidate**. It +combines fast/native compaction, explicit compound-model workflows and beta +reliability work. Package and release versions have not been advanced. + +## Implemented paths + +- Compaction checkpoints and native/portable capability routing; explicit + compound plans, immutable snapshots and isolated workflow execution. +- AI configuration inspect/plan/validate/apply through the shared backend, + serialized compare-and-swap writes and permission-gated CLI/tool/API paths. +- Tool argument replay normalization, bounded retry policy, targeted turn/shell + cancellation, and computer-tool coordinate handling. +- Serialized release-channel changes, installed-version verification before + saving a channel, and explicit unsupported Windows handoff errors. +- Shell analysis now consumes the existing tree-sitter AST. Environment values + are bound by a process-keyed HMAC, and execution uses the frozen reviewed + environment without merging later process-environment changes. Incomplete + host analysis cannot be overridden by a textual reviewer classification. + +## Important current behavior and blockers + +**Shell automatic approval is intentionally unavailable for unverified execution +identities.** Parsing a command does not prove its executable, startup files, +configuration, hooks or filesystem targets. Such commands require confirmation; +the intended eligible Git/read-command automatic-approval corpus is NOT accepted. +The remaining semantic adapters and identity/target revalidation are product +work, not merely missing tests. This checkpoint must not be described as completed +Smart Approval or as an operating-system sandbox. + +Other unaccepted criteria include durable cancellation/wake behavior across a +cold restart, Windows deferred channel transitions and real cross-platform +channel round trips, actual public CLI/shared-server multi-client coverage, +provider-backed compaction fidelity/cost canaries, human terminal acceptance and +live computer-use acceptance. Passing local tests does not replace these gates. + +## Evidence boundaries + +Focused local tests cover the changed compaction/workflow, AI writer and backend +permission, argument replay, retry, cancellation and upgrade paths. Typechecking +passes. The shell-focused checks include the actual parser, a negative command +corpus and local execution tests; their passing result proves the conservative +manual fallback, not the required positive automatic-approval behavior. + +Tests use temporary homes/configuration and isolated databases. No schema +migration, installer run, release publication or production deployment is part +of this checkpoint. Packaged binaries, live providers, native UI acceptance and +supply-chain release checks remain separate requirements before release. diff --git a/docs/changes-review.md b/docs/changes-review.md new file mode 100644 index 00000000..e27244d8 --- /dev/null +++ b/docs/changes-review.md @@ -0,0 +1,181 @@ +# Changes Review + +Changes Review is the TUI workspace for inspecting the current repository diff +without leaving MendCode. It is designed for human review and agent +coordination: you can navigate files and diff blocks, leave comments on the +visible diff, return to chat, and let the assistant read the active review +context on its next model turn. + +Open it from the command palette or slash command: + +```text +/changes +/diff +/review-changes +``` + +![MendCode Changes Review diff workspace](assets/screenshots/changes-review-diff.png) + +## What The View Shows + +The route loads the active workspace diff and renders it as a terminal-native +review surface. + +| Area | Purpose | +| ------------- | ------------------------------------------------------------------------------------------------------------------- | +| Header | Shows file count, additions/deletions, loading state, and warnings such as skipped large or binary untracked files. | +| File list | Shows changed files with status markers and the active file selection. | +| Diff stream | Shows the selected file, diff blocks, line numbers, additions, removals, context, and inline review comments. | +| Keybind bar | Keeps navigation shortcuts visible at the bottom of the page. | +| Footer status | Shows the active workspace root and current comment count. | + +## Diff Scope + +The default `/changes` scope is the local working tree: + +- tracked file changes from `git diff --no-ext-diff --patch HEAD --`; +- small text untracked files through normalized `git diff --no-index` patches; +- no network call, GitHub API call, or remote fetch. + +It is not a GitHub PR diff and it is not "all commits not pushed to GitHub". +Committed changes are not shown by the default working-tree scope, even if they +have not been pushed yet. Pushing to GitHub does not change the view by itself; +committing or otherwise making the working tree clean will remove those files on +the next reload. + +This default is intentional for agent work: `/changes` shows the live files the +agent is currently changing before they become commits. A future branch/PR scope +can compare the current branch against an upstream or base branch, but it should +be a visible mode switch so files do not disappear or change meaning +silently. + +Large or likely-binary untracked files are skipped and summarized in the header +so the prompt and TUI do not get flooded. + +## Keybinds + +| Key | Action | +| --------------------- | ---------------------------------------------------------------------- | +| `j` / `Down` | Move to the next selectable diff line. | +| `k` / `Up` | Move to the previous selectable diff line. | +| `PageDown` / `Ctrl-D` | Move down by roughly one visible page in the active file. | +| `PageUp` / `Ctrl-U` | Move up by roughly one visible page in the active file. | +| `g` | Jump to the first selectable line in the active file. | +| `G` | Jump to the last selectable line in the active file. | +| `l` | Jump to a new or old line number in the active file. | +| `]` / `}` | Move to the next diff block. | +| `[` / `{` | Move to the previous diff block. | +| `n` / `Right` | Move to the next file. | +| `p` / `Left` | Move to the previous file. | +| `c` | Add a review comment anchored to the active line or diff block. | +| `r` | Reload the working-tree diff and re-anchor comments where possible. | +| `Esc` / `q` | Return to the previous chat/session route without stopping agent work. | + +The keybind bar has compact and full labels. Wide terminals show the full +labels; narrower terminals use shorter text so the footer remains readable. + +## Comments And Agent Visibility + +Comments are stored in the active MendCode review state and mirrored to a small +local cache outside the repository. They can be attached to the selected diff +block or to the selected old/new line. On reload, MendCode attempts to keep the +same anchors; comments whose file, block, or line no longer exists are marked +stale instead of being silently moved to a wrong location. + +The assistant receives bounded review context through +`` when a model turn is built. That context includes: + +- changed-file stats; +- the selected file, diff block, and line; +- visible user and assistant comments; +- stale comment count; +- compact file and block summaries. + +This means a comment added while an agent is working can be seen on the next +model turn, including the next turn after a tool call completes. The model +cannot receive new context in the middle of an already-running token stream +without interrupting that stream. The safe behavior is: + +1. The agent starts a turn with the review context available at that moment. +2. The user can open `/changes`, move around, and add comments while tools run. +3. When the agent finishes a tool call and the runtime starts the next model + turn, MendCode rebuilds the system context and includes the latest review + state. If the route and agent do not share the same in-memory process state, + MendCode reconstructs the review from the current working-tree diff and the + cached selection/comments. +4. The agent can also call the `review` tool to inspect the current selection, + load a specific file summary, navigate the review, reload the diff, or manage + comments. + +Raw patches are not injected into the prompt by default. The agent should ask +for a single file patch through the `review` tool only when the compact summary +is not enough. + +## Review Tool + +The built-in `review` tool exposes the active Changes Review workspace to the +assistant. + +| Action | Purpose | +| --------------------- | ----------------------------------------------------------------------- | +| `current` / `summary` | Return bounded review context for the active workspace. | +| `file` | Return the selected or requested file summary, with optional raw patch. | +| `navigate` | Move the active review selection by file or diff block. | +| `reload` | Reload the working-tree diff and reconcile comments. | +| `comment_add` | Add a visible review comment. | +| `comment_list` | List review comments. | +| `comment_clear` | Clear all, scoped, or stale comments. | + +The tool does not edit files, stage changes, revert changes, submit PR reviews, +or require an external diff review app. + +## Responsive Behavior + +Changes Review adapts to terminal size: + +- wide terminals render a split layout with a file sidebar and diff stream; +- compact terminals stack the file list above the diff stream in one scroll + surface; +- the diff stream uses stable line-number columns and truncates long code lines + instead of resizing the layout; +- the footer keybind bar switches to compact labels when space is tight. + +The goal is not to reproduce a web review page in a terminal. The goal is a +stable TUI review surface that keeps selection, scroll, comments, and agent +context aligned. + +## Implementation Notes + +Git diff parsers call each contiguous block of changed lines a "block". +MendCode's user-facing UI calls these "diff blocks" so the feature does not +sound like it is embedding or rebranding another review product. + +The direct external-app path was rejected for the current MendCode +implementation because that would couple this route to another TUI framework +surface and create a maintenance fork for a feature that should live inside +MendCode's route, session, prompt, and tool systems. + +MendCode owns the review state, comments, prompt bridge, and assistant tool. +Diff parsing and block structure use the existing `@pierre/diffs` dependency. + +## Persistence Model + +Review state is keyed by workspace root. The live TUI state remains +process-local, but selection and comments are mirrored to a local MendCode cache +under the user's home directory, not inside the repository. The cache lets the +assistant prompt and `review` tool recover the active review comments if the TUI +route and the agent turn do not share the same process-local `Map`. + +The cached state is intentionally lightweight: it stores selection, comments, +and timestamps, not raw patches. The current diff is always reloaded from git +before assistant context is built. + +It is not a durable PR review, git note, saved memory, or synced collaboration +record. Clearing the active review state clears the cache for that workspace. + +Durable review artifacts can be added later if comments need to survive process +restart, sync across terminals, or become part of a PR/review workflow. + +## Implementation paths + +See [MendCode Source Map — Changes Review](source-map.md#tui-pages-and-product-surfaces) for the route, diff state, comments, renderer, tool, and prompt-context files. Paths are centralized there so this page remains readable for operators. diff --git a/docs/cli-setup-configuration.md b/docs/cli-setup-configuration.md index 6ebb2de6..8a946db8 100644 --- a/docs/cli-setup-configuration.md +++ b/docs/cli-setup-configuration.md @@ -1,59 +1,349 @@ # CLI, Setup, and Configuration -The public CLI is `mend`. It can open the interactive TUI, inspect configuration, run setup, manage packages, and control optional mflow/TSM/worktree integrations. +The public CLI is `mendcode`. It opens the interactive terminal coding harness, runs setup/status checks, manages packages, and controls optional mflow/TSM/worktree integrations. + +Development checkouts may still have a local `mend` shim, but the public installer and package metadata expose `mendcode` and `mendcode-runtime`. Public docs and screenshots should use `mendcode`. ## Public Commands ```bash -mend # open MendCode TUI in the current project -mend --worktree [target] # open MendCode in a git worktree by branch/path/id -mend --tsm [target|--all] # open TSM workspace with a MendCode split -mend run "message" # open TUI with an initial message -mend chat "message" # run a control-plane chat turn -mend status -mend doctor -mend check -mend config show -mend config paths +mendcode # open MendCode TUI in the current project +mendcode --worktree [target] # open MendCode in a git worktree by branch/path/id +mendcode --tsm [target|--all] # open TSM workspace with a MendCode split +mendcode run "message" # open TUI with an initial message +mendcode session list --format json +mendcode chat "message" # run a control-plane chat turn +mendcode status +mendcode loops status # list loop workflows +mendcode doctor +mendcode check +``` + +## Automation Runtime + +`mendcode session` exposes the real session, prompt, status, event, subagent, +loop, permission, question, and diff state to another local agent. It does not +create a second provider stack or a separate session database; it uses the same +runtime and project directory as the TUI. + +```bash +mendcode session create --title "Implement the feature" --format json +mendcode session send ses_... "Do the work" --async --format json +mendcode session status ses_... --format json +mendcode session inspect ses_... --format json +mendcode session wait ses_... --timeout-ms 1800000 --format json +mendcode session events ses_... --follow --format json +mendcode session cancel ses_... --format json +``` + +Available lifecycle operations are `create`, `list`, `get`, `inspect`, +`rename`, `fork`, `archive`, `delete`, `send`, `status`, `wait`, `cancel`, +`events`, and `export`. `send --async` returns immediately after starting a +detached MendCode runtime; `wait` and `events` can then monitor the same +session. Without `--async`, `send` waits for the prompt operation to finish. + +JSON output is line-delimited and uses the versioned `mendcode.cli.v1` envelope: + +```json +{ + "protocol": "mendcode.cli.v1", + "kind": "event | result | error", + "event": "session.completed", + "eventID": "evt_...", + "timestamp": 1760000000000, + "sessionID": "ses_...", + "data": {} +} +``` + +`mendcode run --format json` is the lower-level streaming surface for tool, +step, text, reasoning, and session lifecycle events. Secret-like fields are +redacted before JSON emission, while normal usage counters remain available. +See [Automation runtime](automation-runtime.md) for the complete contract. + +## Loop Workflow Controls + +Use the canonical loop guide for the full contract and lifecycle details: [Loop Workflows](loop-workflows.md). + +```text +/loop # natural-language loop creation/activation inside the TUI +/loops # operator dashboard for active and historical loops ``` -## Setup Page +The public loop CLI supports `status`/`list`, `examples`/`templates`, `draft`, `show`, `tail`, `monitor`, `tick`, `daemon`, `service`, `run`, `activate`, `pause`, `resume`, and `stop`. Use `tick ... --execute` for a real agent turn; `run` is record-only. Signal, override, delete, and agent-retarget actions belong to the assistant tool or local API rather than the public CLI. + +## Setup Flow + +The setup flow separates required harness readiness from optional product features. -The setup flow tracks these steps: +Required setup: -- Required: `provider`, `models`, `budget`, `prompt`. -- Optional: `package`, `tui`, `memory`, `permissions`. +- `provider`: the provider/auth path MendCode can use. +- `models`: model role projection for runtime use. +- `budget`: API/budget posture when API-based usage is enabled. +- `prompt`: prompt mode and focus behavior. + +Optional setup: + +- `package`: active team/runtime package. +- `tui`: TUI profile and visual preferences. +- `memory`: global/project memory config. +- `permissions`: global default permission mode and smart-reviewer role. Useful commands: ```bash -mend setup status -mend setup plan -mend setup doctor +mendcode setup status +mendcode setup plan +mendcode setup doctor +``` + +Completing setup records local project state. It does not mean provider credentials are committed. Provider credentials, OAuth tokens, API keys, local mflow room secrets, caches, and machine-local state must stay outside shared packages and repository docs. + +## Connect Provider + +The setup provider step is labeled `Connect Provider` because it is the place +where MendCode validates the provider/auth path the runtime can actually use. +Provider credentials are local user state, not package or repository content. + +The provider picker can include: + +- hosted/API providers configured through the normal MendCode auth path; +- the upstream `opencode` provider surface when available; +- local CLI-backed providers such as `Claude Code`. + +`Claude Code` is a local CLI bridge. MendCode validates that the `claude` +binary is installed, that `claude auth status --json` reports an authenticated +local account, and then exposes version-compatible Claude Code models through +the normal model picker. Optional config can override the binary path, home +path, and launch arguments for machines that keep Claude Code state outside the +default shell environment. + +Example provider options: + +```jsonc +{ + "provider": { + "claude-code": { + "options": { + "binaryPath": "claude", + "homePath": "", + "launchArgs": "" + } + } + } +} ``` -The setup state is local project state. Completing setup means the required steps are recorded, not that secrets are committed. Provider credentials and API keys must stay outside the repository. +Keep this config free of secrets. It should point to local tools and local state +only; the CLI remains responsible for its own login/session files. ## Configuration Files Common MendCode config paths: -- `.mendcode/mendcode.json`: project config and package metadata. -- `.mendcode/generated/opencode.json`: generated runtime compatibility config. +- `.mendcode/mendcode.json`: project config, focus defaults, package metadata, budget/worktree policy, loop service settings, and integration settings. +- `.mendcode/generated/opencode.json`: generated compatibility config for the adapted runtime. +- `.mendcode/prompt-mode.json`: persisted prompt mode consumed by `mendcode run`, `mendcode chat`, and the TUI footer. +- `.mendcode/prompts/custom.md`: optional project-local Markdown instructions for the `custom` Prompt Context mode. - `.mendcode/models.yaml`: project model-role config. - `~/.config/mendcode/models.yaml`: global model-role config. - `~/.config/mendcode/mendcode.json`: global MendCode config. +- `~/.config/mendcode/permissions.json`: global permission mode and reviewer-role config. - `.mendcode/tui/profile.json`: TUI profile. - `.mendcode/packages/state.json`: installed/enabled package state. - `.mendcode/registry.json`: package registry sources. +- `.mendcode/memory/`: project memory config, entries, and proposals when project memory is enabled. - `.mendcode/mflow/state.json`: mflow local state. - `.mflow/config.toml`: mflow runtime config scaffold. - `.mendcode/tsm/state.json`: optional TSM state. - `.mendcode/worktree/state.json`: managed/adopted worktree registry. +## Prompt Cache Controls + +MendCode exposes passive prompt-cache controls through the `cache` block in the +project or global MendCode config. The controls affect cache keys and provider +cache annotations that MendCode sends with a request; they never delete a +provider's remote cache and they never schedule refresh or keepalive requests. + +This policy is separate from MendCode's local runtime/cache directories and +from the Usage Insights statistics cache. It controls request shaping and +provider annotations; it does not configure local cache size, eviction, or +statistics retention. + +The public CLI is: + +```bash +mendcode cache status [--format text|json] [--json] +mendcode cache enable [--global] [--provider ] [--model ] [--session ] [--project-path ] +mendcode cache disable [--global] [--provider ] [--model ] [--session ] [--project-path ] +``` + +`on` is an alias for `enable` and `off` is an alias for `disable`. Without +`--global`, mutation commands update the active project's config. With +`--global`, they update the global config. `--project-path` is only valid with +`--global` and writes an exact normalized project-path override. A model target +requires `--provider`; `--provider` and `--model` are valid together and target +one provider model. Session and project targets cannot be combined with a +provider or model target, and a project target cannot be combined with a +session target. + +### Configuration + +The `cache` block is optional. If it is absent, MendCode uses a conservative +provider-aware default: OpenAI requests use `smart`, while other providers +preserve existing `legacy` behavior. + +```jsonc +{ + "cache": { + "mode": "smart", + "projects": { + "/Users/me/src/example": { "mode": "smart" } + }, + "sessions": { + "mode": "selected", + "include": ["ses_allowed"], + "exclude": ["ses_blocked"] + }, + "providers": { + "openai": { + "mode": "smart", + "models": ["openai/gpt-6-astra"], + "exclude_models": ["openai/legacy-model"] + }, + "openrouter": { + "models": ["openai/gpt-5.6-mini"] + } + } + } +} +``` + +Supported values and scopes: + +- `mode`: `off` suppresses MendCode cache controls; `smart` enables only the + verified passive-key paths described below. Omit it to use the provider-aware + default (OpenAI `smart`; other providers `legacy`). +- `projects`: exact normalized project paths mapped to `{ "mode": "off" }` or + `{ "mode": "smart" }`. Use absolute paths for portable global config. +- `sessions.mode`: `all`, `selected`, or `none`. `include` selects session IDs + and `exclude` blocks session IDs. An excluded session wins over inclusion. +- `providers`: provider IDs mapped to an optional `mode`, `models` allowlist, + and `exclude_models` list. Model matching accepts the configured runtime ID, + API model ID, and their final path component. + +Resolution is deterministic. Disabling rules win in this order: global +`mode: off`, project `off`, session `none`/exclusion/not-selected, provider +`off`, then model exclusion or allowlist rejection. Enabling then resolves from +the global mode, project mode, provider selection, or explicitly included +session; otherwise OpenAI uses `smart` and other providers use `legacy`. + +### Smart-mode boundaries + +`smart` is deliberately conservative. A passive cache key is enabled only for +a binding that has a verified local wire contract: + +- ChatGPT subscription/OAuth on OpenAI Codex Responses Lite uses the + provider-native, session-scoped key already required by that adapter. This is + not a MendCode-managed key and is not shared across sessions, projects, or + accounts; +- API-key authentication uses a managed key only for a non-Responses-Lite + binding with OpenAI's `@ai-sdk/openai` SDK at `api.openai.com`, or the + OpenRouter SDK/compatible route at `openrouter.ai`; +- in both cases, provider, endpoint, SDK, authentication, and transport must + match the verified binding. + +The built-in verification is provider/SDK/endpoint based. An exact-model +restriction is applied only when `providers..models` or +`providers..exclude_models` is configured. Therefore, when a global or +provider policy is `smart`, use an allowlist if caching must be limited to +known models; a model name alone is not evidence of provider support. + +Other providers, custom endpoints, and incomplete bindings do not receive a +newly inferred managed key. Existing provider-specific options and legacy +annotations remain governed by their existing transform path unless the policy +is explicitly `off`; `smart` does not overwrite an unverified provider option. +MendCode does not infer TTL, cache warmth, hit rate, price savings, weekly-limit +percentage, or provider support from a model name alone. + +`off` removes recognized cache fields from request options and message/provider +annotations, including `promptCacheKey`, `prompt_cache_key`, `cacheControl`, +`cachePoint`, `cache_control`, `copilot_cache_control`, and gateway +`caching: "auto"`. For ChatGPT OAuth, the internal disable marker is consumed +before the request is forwarded upstream. This is local request shaping, not +remote-cache delete access. + +### Scope examples + +```bash +# Inspect the effective policy for the current project. +mendcode cache status --format json + +# Enable conservative caching for the current project's OpenAI provider. +mendcode cache enable --provider openai + +# Allow one exact model and disable another model on the same provider. +mendcode cache enable --provider openai --model openai/gpt-6-astra +mendcode cache disable --provider openai --model openai/legacy-model + +# Limit caching to one session, or disable it for a session. +mendcode cache enable --session ses_allowed +mendcode cache disable --session ses_blocked + +# Manage an exact project override from the global config. +mendcode cache enable --global --project-path /Users/me/src/example +mendcode cache disable --global --project-path /Users/me/src/example +``` + +`cache status` reports the effective mode, the current project, the configured +block, and `activeKeeper: false`. The reported `configured` block is the merged +policy visible to the current project; it includes any `projects`, `sessions`, +and `providers` rules. The status command does not take a session ID. To +inspect session policy, read `configured.sessions`: `none` disables all +sessions, `selected` permits only IDs in `include`, and `exclude` always wins. + +Cache Keeper, scheduled refresh, automatic warm-up, and provider canaries are +not part of this control surface. A cache key may still consume request/quota/ +weekly-limit usage, and missing provider cache metrics remain unknown rather +than being converted to a zero or used to claim a cache hit. The provider's +usage report or account UI is authoritative for actual token accounting and +remaining subscription quota. + +If another MendCode backend currently owns the local database, a standalone +`cache status` invocation may fail with a writer-lock error. That error means +the status was not read; it is not evidence that caching is enabled or +disabled. Keep the active backend running and query through its existing +client, or retry after it releases the writer. Do not delete the lock manually. + +## Prompt Draft Undo and Redo + +The TUI keeps a temporary in-memory edit history for the active prompt: + +- `Ctrl+_` undoes the latest prompt edit. On many keyboards, press `Ctrl+Shift+-`. +- `Ctrl+Y` redoes a prompt edit. +- On macOS, `⌘Z` and `⌘⇧Z` are also available by default. +- `Ctrl+Z` remains the POSIX terminal suspend shortcut and does not undo prompt text. + +This history is intentionally not persisted. It can recover text cleared while the +prompt is still open, but closing the prompt or TUI discards it. + +Override the bindings in `.mendcode/tui.json` or `~/.config/mendcode/tui.json`: + +```jsonc +{ + "keybinds": { + "input_undo": "ctrl+_,super+z", + "input_redo": "ctrl+y,super+shift+z" + } +} +``` + ## Focus Profiles -MendCode ships focus profiles that tune prompt policy, model role, tool posture, budget posture, and worktree policy: +Focus profiles tune provider-family behavior, model role defaults, prompt policy, tool posture, budget posture, and worktree policy. + +Built-in focus families include: - `codex` - `claude` @@ -65,27 +355,81 @@ MendCode ships focus profiles that tune prompt policy, model role, tool posture, Commands: ```bash -mend focus status -mend focus list -mend focus show codex -mend focus use codex +mendcode focus status +mendcode focus list +mendcode focus show codex +mendcode focus use codex ``` +Use focus profiles to keep provider-specific behavior explicit. Do not describe them as proprietary upstream prompt dumps; MendCode adapts behavior for provider/model families without pretending to be those products. + +## Prompt Modes + +Prompt mode controls how much MendCode harness context is added to runtime requests. The persisted state lives in `.mendcode/prompt-mode.json` and is shown in the TUI footer/status surfaces. + +| Mode | What it does | Good for | +| --- | --- | --- | +| `minimal` | Uses a small MendCode boundary and avoids the full harness prompt. Persistent memory remains independent and can still be retrieved when enabled. | Low-noise experiments, debugging prompt influence, narrow one-off tasks. | +| `focus` | Default mode. Uses the selected focus profile and provider-family policy. | Normal daily coding. | +| `full` | Adds the focus behavior plus MendCode product/runtime policy and integration context. Legacy `dev-js` config is normalized to `full`. | Work that needs package, memory, workflow, or product policy context. | +| `custom` | Uses the safe MendCode boundary plus `.mendcode/prompts/custom.md`; it does not inherit the extra `focus` or `full` sections. The file is capped at 32 KiB. | Project-specific instructions that should be versioned with the checkout. | + +Current public setup/status surfaces should be used to inspect prompt readiness: + +```bash +mendcode setup status +mendcode status +mendcode prompt build --mode custom --json +mendcode prompt mode custom +``` + +When `.mendcode/prompts/custom.md` is valid, its configured name appears in setup +and in the Ctrl+P **MendCode Prompt Context** selector. The internal mode remains +`custom`, but the visible label can be chosen per project with frontmatter: + +```markdown +--- +name: Hello World Demo +--- + +always say first Hello World! +``` + +The `name` is metadata and is not sent to the provider; only the Markdown body is +added to the custom prompt. If no `name` is provided, MendCode derives a readable +label from the first heading or filename. + +The loader accepts only a non-empty regular file inside the active project root, +normalizes UTF-8 line endings, and reads at most 32 KiB. Missing, empty, oversized, +unreadable, or escaped-symlink files leave the selected mode visible in diagnostics +but use a safe fallback without inventing prompt text. Remove the file to make the +`custom` option disappear from selectors; use `mendcode prompt mode` or +`mendcode status` to inspect the relative path, byte count, origin, and fallback +reason without printing the file body. + +For team rollout, packages can include the reserved +`.mendcode/prompts/custom.md` file and prompt mode state as part of the runtime +pack. For manual local experiments, edit `.mendcode/prompt-mode.json` with one of +`minimal`, `focus`, `full`, or `custom`, then verify through setup/status and the TUI footer. + ## Models -Models are configured by role instead of hardcoding one model everywhere. Roles include: +Models are configured by role instead of hardcoding one model everywhere. + +Common roles: - `default` - `small` - `plan` - `build` - `code` -- `review` - `subagent` - `title` - `compaction` - `summary` - `memoryExtractor` +- `memoryDream` +- `memoryAssistant` - `permissionReviewer` Example: @@ -95,42 +439,111 @@ version: 0 enabled: true roles: default: - providerID: "openai" - modelID: "gpt-5.2" - authMode: "api-key" + providerID: "" + modelID: "" + authMode: "" build: - providerID: "openai" - modelID: "gpt-5.2-codex" - authMode: "api-key" + providerID: "" + modelID: "" + authMode: "" small: - providerID: "openai" - modelID: "gpt-5-mini" - authMode: "api-key" + providerID: "" + modelID: "" + authMode: "" + memoryDream: + providerID: "" + modelID: "" + authMode: "" + memoryAssistant: + providerID: "" + modelID: "" + authMode: "" + permissionReviewer: + providerID: "" + modelID: "" + authMode: "" ``` Commands: ```bash -mend models status -mend models presets -mend models set-default openai gpt-5.2 --auth-mode api-key --enable -mend models use-preset openai-api-gpt-5.2-codex --enable -mend models plan +mendcode models status +mendcode models presets +mendcode models set-default --auth-mode --enable +mendcode models use-preset --enable +mendcode models plan ``` -The CLI currently writes the default model role directly. For non-default roles such as `build`, `review`, or `permissionReviewer`, edit `models.yaml` and run `mend models plan` / `mend models status` to verify projection. +The CLI currently writes the default model role directly. For non-default roles +such as `build`, `code`, `subagent`, `memoryExtractor`, `memoryDream`, +`memoryAssistant`, or `permissionReviewer`, edit `models.yaml` and run +`mendcode models plan` / `mendcode models status` to verify projection. Roles +are explicit; the generic `review` role is not part of the model configuration. +Public docs should keep model examples provider-neutral; teams can pin their own +provider and model choices in local or package-specific config. -## Providers, Auth, Permissions, Memory +## Permissions And Memory Useful inspection commands: ```bash -mend providers status -mend auth status -mend permissions status -mend permissions set-default smart -mend memory status -mend memory search "project convention" +mendcode providers status +mendcode auth status +mendcode permissions status +mendcode memory status +mendcode memory search "project convention" +mendcode memory preview "project convention" +``` + +Permission modes: + +| Mode | Behavior | +| --- | --- | +| `approval` | Manual approval remains the default posture. | +| `smart` | Auto-approves only bounded read-only shell requests. Risky or ambiguous requests use the configured AI reviewer when applicable, and fall back to a prompt if it is unavailable; scripts, deletes, writes, privilege changes, network commands, and other non-read-only commands are never auto-approved. | +| `full_access` | Reduces permission prompts for the current policy surface, but explicit deny rules still matter. Use only when that trust posture is intentional. | + +Configure permissions: + +```bash +mendcode permissions status +mendcode permissions set-default approval +mendcode permissions set-default smart +mendcode permissions set-default full_access +mendcode permissions set-reviewer-role permissionReviewer +``` + +Describe `smart` as AI-assisted permission review, not as “secure by default”. It depends on the configured reviewer role and still needs a sane trust boundary. + +Memory behavior: + +- Memory can be global or project-scoped. +- Runtime memory is injected as transient system context; it is not copied into normal chat history unless the user asks to see it. +- Generated memory proposals are approval-gated. +- Direct `mendcode memory add` is for explicit user requests to save memory. +- `mendcode memory search` and `mendcode memory preview` are the right commands before editing, deleting, applying, or rejecting entries/proposals. +- The [Memory Center](memory-center.md) view adds saved/pending views, category policy, Dream status/logs, workspace awareness, and constrained side chat. + +Example: + +```bash +mendcode memory status +mendcode memory list --scope global +mendcode memory list --scope project +mendcode memory search "release workflow" +mendcode memory preview "release workflow" +mendcode memory add "Use docs screenshots with the public mendcode command." --scope project +``` + +## Packages, mflow, TSM, And Worktrees + +Common next commands: + +```bash +mendcode packages status +mendcode mflow status +mendcode worktree status +mendcode tsm status ``` -MendCode should never commit provider credentials. Package and registry flows explicitly report `secretsIncluded: false` for shared package state. +Use [Packages and team sharing](packages-and-team-sharing.md), [Customization](customization.md), [mflow coordination](mflow.md), and [TSM and worktrees](tsm-and-worktrees.md) for deeper workflows. diff --git a/docs/community.md b/docs/community.md new file mode 100644 index 00000000..fb020fa4 --- /dev/null +++ b/docs/community.md @@ -0,0 +1,81 @@ +# Community + +This page describes the public contribution surfaces for MendCode. + +## Issues + +Use issues for: + +- reproducible bugs +- concrete feature requests +- docs bugs +- installer/release failures + +Do not use issues for private vulnerabilities or leaked credentials. Use [SECURITY.md](../SECURITY.md). + +## Discussions + +Use discussions for: + +- setup questions +- examples +- plugin/widget help +- package sharing patterns +- mflow/worktree usage +- model/provider configuration +- roadmap conversations + +Suggested first announcement: + +```markdown +# Welcome to MendCode Discussions + +MendCode is now public. + +Use this space for setup questions, package sharing, plugin/widget examples, mflow coordination, TSM/worktree workflows, model/provider configuration, and roadmap ideas. + +Start here: + +- Docs: https://github.com/MendCode/MendCode/tree/main/docs +- TUI plugins and widgets: https://github.com/MendCode/MendCode/blob/main/docs/tui-plugins-and-widgets.md +- Packages and team sharing: https://github.com/MendCode/MendCode/blob/main/docs/packages-and-team-sharing.md +- mflow: https://github.com/MendCode/MendCode/blob/main/docs/mflow.md +- Security policy: https://github.com/MendCode/MendCode/blob/main/SECURITY.md + +Please do not post secrets, private config, API keys, or private vulnerability details. +``` + +## Pull Requests + +PRs should be small, tested, and documented. See [CONTRIBUTING.md](../CONTRIBUTING.md). + +## Labels + +Recommended labels: + +- `bug` +- `enhancement` +- `documentation` +- `security` +- `dependencies` +- `installer` +- `release` +- `tui` +- `plugins` +- `packages` +- `mflow` +- `worktrees` +- `question` +- `good first issue` + +Labels can be created with `gh`: + +```bash +gh label create installer --repo MendCode/MendCode --color 0E8A16 --description "Installer or install script" +gh label create release --repo MendCode/MendCode --color 5319E7 --description "Release process or assets" +gh label create tui --repo MendCode/MendCode --color 1D76DB --description "Terminal UI" +gh label create plugins --repo MendCode/MendCode --color BFDADC --description "Plugins, widgets, slots, or extension SDK" +gh label create packages --repo MendCode/MendCode --color FEF2C0 --description "Runtime packages and team sharing" +gh label create mflow --repo MendCode/MendCode --color C5DEF5 --description "mflow coordination" +gh label create worktrees --repo MendCode/MendCode --color D4C5F9 --description "TSM or worktree workflows" +``` diff --git a/docs/context-and-computer-tools.md b/docs/context-and-computer-tools.md new file mode 100644 index 00000000..0ed7d60d --- /dev/null +++ b/docs/context-and-computer-tools.md @@ -0,0 +1,103 @@ +# Context, cache and computer tools + +MendCode records a small profile for each completed model step. Inspect recent +profiles from the same workspace as the session: + +```sh +mendcode context +mendcode context --limit 50 --json +``` + +The report separates estimated instruction, recalled memory, conversation, +tool-result, tool-schema and media tokens. These estimates are not provider +billing counts. Actual input/cache counts come from provider usage; missing +fields remain unavailable. Timing measures the request and first streamed text +or reasoning event. Fingerprints identify stable instruction/schema prefixes +without retaining their contents in the profile. Existing sessions gain profiles +only for new completed steps. The command reads a bounded recent-message page, +not a lifetime total. + +Memory retrieval is stored as synthetic reference context at each user turn. +Repeated tool steps reuse that snapshot; the next user turn retrieves memory +again. Synthetic memory never grants permission or replaces the user's request. + +## Tool discovery + +Core tools retain their direct interfaces. Secondary tools are discovered with +`tool_search`; returned schemas enable direct calls in subsequent steps. Search +returns at most eight schemas and 24 KiB. Up to 64 secondary tools remain active +in retained history. Disabled tools stay unavailable. Schemas too large for the +search budget are omitted, not truncated into invalid definitions. + +Set `experimental.tool_discovery` to `false` in the existing MendCode JSON +configuration to send the complete permitted catalog. Disabling `tool_search` +also restores the complete catalog so capabilities do not become inaccessible. +Cache savings depend on the provider and workload; no measured saving or parity +with another harness is claimed. + +## Experimental Code Mode + +Enable `experimental.code_mode: true` to expose `code`. It runs a confined +JavaScript subset in a worker. Use `tools.search({query: "..."})` to discover +signatures, call tools with `await tools.name(args)`, and return a concise value: + +```js +const result = await tools.read({ filePath: "/workspace/report.txt" }) +return { characters: result.output.length } +``` + +The host enforces 32 KiB source, 16 tool calls, a 30-second wall-clock deadline +and 24 KiB retained result/log output. Every nested call uses the existing tool +implementation, permissions and session audit record. Its intermediate result +stays out of model history; only the outer result enters it. Call image-producing +tools directly to view images. Cancellation waits for host tool cleanup. + +There are no process, filesystem, network or import globals in the language. +Worker separation is not an OS sandbox or a hard heap quota. Code Mode remains +off by default pending broader resource, permission and cross-platform packaged-runtime testing. +The interpreter is adapted from OpenCode v2 at revision +`cd504dc66ac6620a662a0246f83cfc05f796f58a`; its MIT license and file provenance +are kept alongside the source. No dependency upgrade is required. + +## Native macOS screenshots and navigation + +`computer_capture` captures the main display, an explicit window ID, or an +integer screen-region crop. It returns a PNG attachment and an absolute file +path that `read` can reopen. Previews are resized to at most 1600 pixels; +coordinates in them must not be assumed to match desktop control coordinates. +Retained identical screenshots reuse the existing image reference. Capture +artifacts are limited to 64 per session and 8 MiB per inline image. + +`computer_key` supports one navigation key against the foreground application +observed during a recent full-display capture on a single-display Mac. The +capture ID belongs to the same session, expires after 30 seconds and permits +one action. Foreground changes, stale captures and missing observations fail +closed. The tool never activates another application. Capture again afterward. +Window crops, multiple displays, pointer control and arbitrary typing do not +support this keyboard-control path. + +Both tools use the normal MendCode permission boundary. macOS Screen Recording, +Automation and Accessibility permissions remain controlled by the OS; failures +are reported rather than bypassed. Native support on Windows/Linux and browser +DOM automation are not included. Connected MCP services remain discoverable. + +## Compaction compatibility + +The existing portable summarizer remains active. The installed OpenAI SDK can +replay encrypted reasoning but does not expose native `/responses/compact` +replacement-window support. Encrypted reasoning is not treated as a compaction +checkpoint. No native compaction request, history replacement, model change or +new provider credential path is enabled by this change. Native compaction needs +a separate transport capability, durable replay contract and interruption tests +before it can be accepted. + +## Verification scope + +Focused local tests cover profiles and missing usage, discovery, common provider +request fixtures, Code Mode confinement/deadline/cancellation, and a session +using a nested file read with final-output-only model input. Native screenshot +capture and image decoding were exercised on macOS. A compiled macOS ARM64 executable also completed a nested file read through Code +Mode against a local test provider. Interactive keyboard control, packaged worker +execution on other platforms, provider-native compaction and paid/live provider +behavior remain unverified. This is not a claim of complete computer +use or cache-performance equivalence. diff --git a/docs/custom-tool-calls.md b/docs/custom-tool-calls.md new file mode 100644 index 00000000..58bab14d --- /dev/null +++ b/docs/custom-tool-calls.md @@ -0,0 +1,74 @@ +# Custom Tool Calls + +Custom tool calls let a project or shared package add assistant-facing actions without changing MendCode's built-in tools. A tool exposes a description and argument schema to the model, then runs local TypeScript or JavaScript when the model calls it. + +Custom tools are different from MCP tools: + +- **Custom tools** are local project/package code loaded from `.mendcode/tools`. +- **MCP tools** come from an MCP server configured for the project. + +## Add a Project Tool + +Create a `.ts` or `.js` file under `.mendcode/tools`. MendCode also accepts the singular `.mendcode/tool` directory for compatibility. + +```tsx +// .mendcode/tools/lookup-package.ts +import { tool } from "@mendcode/plugin"; + +export default tool({ + description: "Look up a package note from the current repository.", + args: { + packageName: tool.schema + .string() + .min(1) + .describe("The package name to inspect"), + }, + async execute(args, context) { + context.metadata({ + title: `Looking up ${args.packageName}`, + metadata: { packageName: args.packageName }, + }); + + return { + output: `No local note found for ${args.packageName} in ${context.worktree}.`, + metadata: { packageName: args.packageName }, + }; + }, +}); +``` + +The `tool.schema` helper exposes Zod schemas, so the argument definition is used both for validation and for the JSON schema sent to the model. A file's default export uses the filename as its tool ID (`lookup-package` in this example). Named exports use a `_` ID. + +## Tool Context + +`execute(args, context)` receives: + +- `sessionID` and `messageID` for the current conversation. +- `agent` for the active agent. +- `directory` for the current project directory. +- `worktree` for the project worktree root. +- `abort` to stop long-running work when the session is cancelled. +- `metadata()` to update the visible tool-call title and metadata. +- `ask()` to request a permission through MendCode's permission flow. + +Return either a string or `{ output, metadata }`. Keep output concise; large results are truncated using the active agent's output policy. + +## Share Tools With a Package + +Add the tool directory to the package manifest: + +```json +{ + "artifacts": { + "tools": [".mendcode/tools"] + } +} +``` + +The same directory can be enabled in a project-local `.mendcode/package.json` or distributed through a marketplace package. Do not include provider credentials, `.env` files, auth state, or machine-specific data in a shared tool. + +## Safety Notes + +Custom tools are trusted local code. Review them before enabling a package, use `context.ask()` for operations that need explicit permission, honor `context.abort` for long-running work, and avoid silently writing outside the current project/worktree. + +For the broader plugin surface, see [TUI Plugins and Widgets](tui-plugins-and-widgets.md) and [Packages and Team Sharing](packages-and-team-sharing.md). diff --git a/docs/customization.md b/docs/customization.md index 3d93b3d4..9d9aecfe 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -1,75 +1,963 @@ # Customization -MendCode customization is centered on `.mendcode/` config plus optional runtime packages. The goal is that a person, team, or company can keep the same terminal behavior without editing runtime internals. +MendCode customization is centered on `.mendcode/` config plus optional runtime packages. The goal is simple: a person, team, or company should be able to make the terminal feel like their own product without editing runtime internals. -## TUI Profile +The main profile is `.mendcode/tui/profile.json`. It controls the prompt input, input marker, bottom status, home title or mascot, centered/split home layout, Agent View panel, activity rendering, activity mascot states, widgets, theme, and density. -The active TUI profile is a JSON profile with these main sections: +![MendCode wordmark welcome actions](assets/screenshots/home-wordmark-actions.png) -- `identity`: product name, tagline, logo mode, logo font. -- `theme`: dark/light mode, palette, color tokens. -- `layout`: density, spacing, borders, width, header/footer/sidebar/session/prompt zones. -- `widgets`: enabled widget IDs, order, and widget config. -- `surfaces`: model/provider/status visibility, home logo, home welcome layout. -- `promptChrome`: prompt frame style, glyphs, and preset. -- `promptStatus`: left/right status items and script-backed status. -- `workingIndicator`: visible thinking/working text and token/elapsed display. -- `presentation`: raw/minimal/mendcode rendering, reasoning visibility, activity placement, mascot, completion symbol. +Most visual settings are also available from the command palette inside the TUI: + +```text +Ctrl+P -> Home identity +Ctrl+P -> Home title text +Ctrl+P -> Home title font +Ctrl+P -> Home mascot ASCII +Ctrl+P -> Home welcome mode +Ctrl+P -> Home split panel +Ctrl+P -> Prompt chrome +Ctrl+P -> Prompt lead string +Ctrl+P -> Prompt status placement +Ctrl+P -> Chat presentation +Ctrl+P -> Customize TUI +``` + +The command palette currently edits the Home mascot directly. The compact session mascot is configured through the profile JSON or a TUI package; a dedicated per-state editor and first-class ASCII-pack importer are not available yet. Home art and session art are independent, so changing one does not overwrite the other. + +## Mental Model + +There are four layers: + +1. Home identity: what appears on the home screen before a chat starts. +2. Prompt input: the editor frame, prompt marker, right-side prompt slot, and status row. +3. Session presentation: how assistant messages, reasoning, tools, diffs, and activity are rendered. +4. Runtime extensions: widgets, slots, footer entries, plugin routes, package-distributed themes, and scripts. + +Use the profile for stable product/team defaults. Use TUI plugins when behavior needs code, live data, custom routes, or dynamic UI. + +## Live TUI Customization + +For session chrome, use one command instead of hunting through separate appearance commands: + +```text +Ctrl+P -> Customize TUI +/customize +``` + +`Customize TUI` opens a grouped modal. Items marked `[on]`/`[off]` are live toggles: `Space` or `Enter` applies them immediately and the TUI does not restart. Profile entries such as Home identity, Home title, and Prompt chrome are actions, not toggles; `Enter` opens their editor and they never show a toggle state. The `Appearance` category is intentionally not exposed in the command palette. The defaults enable context usage, diff line count, session title, project location, and terminal window title; the changed-file count is off by default. + +The modal also exposes a deterministic random accent per session and maintenance actions. Changes are persisted in the TUI KV store under `mendcode_tui_customization`, while `terminal_title_enabled` remains a compatibility key for older profiles. + +### Terminal title and session accent + +The terminal title supports these tokens: + +| Token | Value | +| --- | --- | +| `{product}` | Active product name. | +| `{session}` | Current session title or route label. | +| `{route}` | Current TUI route. | +| `{path}` | Active project path. | + +The public runtime API uses the same contract: + +```ts +api.ui.runtime.customization.setTerminalTitle({ + enabled: true, + template: "{product} · {session} · {path}", +}) +api.ui.runtime.customization.setSessionAccent("random") +api.ui.runtime.customization.setDiffFiles(true) +``` + +### Rollback + +To restore the default live chrome, choose `Reset TUI customization` in the modal or call: + +```ts +api.ui.runtime.customization.reset() +``` + +This only resets the customization contract; it does not change profile files, sessions, messages, widgets, or project data. + +## Recommended Product Profiles + +These are not separate built-in themes; they are starting points for profiles a person or team can ship. + +| Profile | Key settings | Best for | +| --- | --- | --- | +| Clean daily driver | `promptChrome.preset: "top-bottom"`, status outside, `presentation.profile: "mendcode"`, command hints hidden. | Everyday coding with low chrome and enough context. | +| Team-branded shell | `identity.productName`, `identity.logoFont`, `promptChrome.glyphs.leadText`, custom status script. | Company/team environments that need a recognizable terminal surface. | +| Agent cockpit | `surfaces.homeWelcome.mode: "split"`, `surfaces.homeWelcome.rightPanel: "agentManager"`. | Background sessions, delegated work, and follow-up queues. | +| SSH/ASCII safe | `promptChrome.preset: "ascii-box"`, status inside, compact mascot/title. | Remote terminals, simpler fonts, narrow machines. | +| Low-noise review | `presentation.profile: "minimal"`, fewer status items, no mascot activity. | Review-heavy or pair-programming sessions where visual motion is distracting. | + +## TUI Profile Shape + +The active TUI profile has these major sections: + +- `identity`: product name, tagline, home identity mode, ASCII title font. +- `theme`: dark/light mode, palette, and core color tokens. +- `layout`: density, spacing, borders, width, and zone behavior. +- `widgets`: enabled widget IDs, order, and widget-specific config. +- `surfaces`: model/provider/status visibility, home logo, and home welcome layout. +- `promptChrome`: prompt frame style, sides, border style, glyphs, and input marker. +- `promptStatus`: built-in status items, placement, separator, colors, and script-backed status. +- `workingIndicator`: visible thinking/working text fallback, elapsed time, and token display. +- `presentation`: raw/minimal/MendCode chat rendering, reasoning visibility, activity placement, activity text, mascot states, and completion symbol. - `rollback`: profile rollback metadata. -Inspect it with: +## Prompt Input -```bash -mend tui status -mend tui profile -mend tui preview +The prompt input is the editor area at the bottom of the home/session screen. MendCode calls its frame `promptChrome`. + +Supported prompt chrome presets: + +| Preset | What it feels like | Good for | +| --- | --- | --- | +| `box` | Full bordered prompt with top, bottom, left, and right edges. | Strong product identity and visible input boundaries. | +| `top-bottom` | Horizontal rails only, with a lead input marker. | Clean everyday coding setup. | +| `minimal` | No border, just the prompt panel and status. | Low-chrome terminal workflows. | +| `ascii-box` | Full box using plain ASCII borders. | Old terminals, SSH, retro/team themes. | + +`left-rail` exists as a legacy preset name in the type layer, but profile normalization maps it to `top-bottom`. Prefer the four presets above for new config. + +Example: + +```jsonc +{ + "promptChrome": { + "preset": "top-bottom", + "borderStyle": "rounded", + "glyphs": { + "leadText": "mendcode>" + } + } +} +``` + +## Input Marker + +The input marker is `promptChrome.glyphs.leadText`. It is the short string shown at the start of the input line for presets that render a lead marker. + +Default marker: + +```text +❭ +``` + +Examples: + +```jsonc +{ + "promptChrome": { + "glyphs": { + "leadText": ">" + } + } +} +``` + +```jsonc +{ + "promptChrome": { + "glyphs": { + "leadText": "mendcode>" + } + } +} +``` + +```jsonc +{ + "promptChrome": { + "glyphs": { + "leadText": "ship>" + } + } +} +``` + +Keep it short. A long marker competes with the user's prompt and makes narrow terminals feel cramped. + +## Prompt Status + +`promptStatus` controls the metadata row around the prompt. It can render outside the prompt or inside it, depending on the active chrome preset. + +Default behavior: + +```jsonc +{ + "promptStatus": { + "enabled": true, + "placementByPreset": { + "box": "outside", + "top-bottom": "outside", + "minimal": "outside", + "ascii-box": "inside" + }, + "left": [ + { "type": "builtin", "value": "mode" }, + { "type": "builtin", "value": "model" }, + { "type": "builtin", "value": "provider" }, + { "type": "builtin", "value": "reasoning" } + ], + "right": [ + { "type": "builtin", "value": "context" } + ], + "separator": " · " + } +} ``` -## Prompt Chrome +Built-in status values: + +| Value | Meaning | +| --- | --- | +| `mode` | Current prompt mode or active agent label. | +| `model` | Resolved model name for the current session. | +| `provider` | Resolved provider label. | +| `reasoning` | Current reasoning/effort variant when exposed by the model. | +| `variant` | Explicit model variant alias. | +| `context` | Context usage summary. | +| `permissionMode` | Current permission mode and pending permission prompts. | +| `commandsHint` | Command palette hint. | +| `agentsHint` | Agent switching/cycling hint. | + +Compact bottom-status example: + +```jsonc +{ + "promptStatus": { + "commandsHint": { "visible": false }, + "placementByPreset": { + "top-bottom": "outside", + "ascii-box": "inside" + }, + "left": [ + { "type": "builtin", "value": "mode" }, + { "type": "builtin", "value": "model" } + ], + "right": [ + { "type": "builtin", "value": "context" }, + { "type": "builtin", "value": "permissionMode" } + ], + "separator": " " + } +} +``` -Prompt chrome controls the terminal prompt wrapper: borders, glyphs, status slots, right-side prompt surfaces, and preset behavior. Use it for company-specific terminal identity without changing the model prompt. +## Script-Backed Status -Typical customization points: +`promptStatus.scripts.left` and `promptStatus.scripts.right` can call local scripts to add custom status. -- prompt border/glyphs -- left/right status labels -- command hints -- provider/model visibility -- compact vs rich prompt status +Example: -## ASCII Logo and Mascot +```jsonc +{ + "promptStatus": { + "scripts": { + "right": { + "enabled": true, + "command": "./.mendcode/tui/prompt-status.sh", + "timeoutMs": 150, + "refreshMs": 1000, + "prepend": false + } + } + } +} +``` -MendCode supports title-style and mascot-style identity: +Script output can be plain text: -- `identity.logoMode`: `title` or `mascot` -- `identity.logoFont`: `classic`, `mendcode`, `small`, `standard`, or `shadow` -- `surfaces.homeLogo.text`: custom ASCII home logo -- `surfaces.homeLogo.size`: `compact`, `default`, or `large` -- `presentation.activity.mascot.states`: ASCII mascot states for phases like `thinking`, `editing`, `running`, `testing`, `done`, and `error` +```text +dev · clean · package:team +``` -Example profile snippet: +It can be JSON segments: ```json +{ + "segments": [ + { "text": "dev", "fg": "#86efac", "bold": true }, + { "text": " · clean", "fg": "#a3a3a3" } + ] +} +``` + +Or TSV segments: + +```text +#86efac true dev +#a3a3a3 false · clean +``` + +Good custom status values are short and operational: branch, dirty/clean, active package, provider, context, permissions, mflow/worktree state. + +## Home Identity + +The home identity can be an ASCII title or an ASCII mascot. + +```jsonc +{ + "identity": { + "productName": "MendCode", + "tagline": "terminal-first coding", + "logoMode": "title", + "logoFont": "mendcode" + } +} +``` + +Supported `identity.logoMode` values: + +- `title`: render a generated ASCII title from `identity.productName`. +- `mascot`: render the configured home mascot and enable compact activity mascot feedback. + +Supported `identity.logoFont` values: + +- `mendcode` +- `small` +- `standard` +- `shadow` + +`classic` and `opencode` may appear in older config. New config should use the values above. + +## Home Title + +The home title text is `identity.productName`. It is used for generated ASCII title mode, terminal title, and several labels. + +Example company title: + +```jsonc +{ + "identity": { + "productName": "AcmeCode", + "logoMode": "title", + "logoFont": "shadow" + } +} +``` + +That keeps the home screen logo textual and brand-like. It is the better choice when the team wants a product mark, department name, or company coding shell. + +## Mascot + +Mascot mode uses ASCII art as the home identity. Session activity mascot states are configured separately and can stay enabled with either Home identity mode. + +```jsonc +{ + "identity": { + "productName": "MendCode", + "logoMode": "mascot" + } +} +``` + +You can replace the home mascot completely with `surfaces.homeLogo.text` or `home.logo.text` in config: + +```jsonc +{ + "identity": { + "logoMode": "mascot" + }, + "surfaces": { + "homeLogo": { + "text": " /\\\\\n /++\\\\\n <|__|>\n /__\\\\" + } + } +} +``` + +Keep custom mascot art monospaced, low-height, and visually stable. The home screen adapts to terminal size; huge ASCII art will disappear on compact/tiny screens. + +### Change it from the TUI + +From Home, open `Ctrl+P` and choose **Home mascot ASCII**. Paste the multiline art, submit it, and MendCode switches Home to mascot mode. Submitting a blank value restores the default mascot. This changes only `surfaces.homeLogo.text`; it does not change the session activity mascot. + +## Default Home Mascot + +Default mascot: + +```text + .-. + (o o) + /|[+]|\ + /_|___|_\ + \_/ +``` + +## Activity Mascot States + +The compact activity mascot above the session prompt can change with the current phase. It is independent from the Home identity mode, so Home can use a generated title while the session prompt still uses state-specific mascot art. + +The current built-in controls expose Home art, not individual session states. To customize the session mascot, edit the profile JSON or ship the profile through a TUI package. A single custom state is enough for a static pet; state-specific art can give the character different faces or poses while MendCode is thinking, reading, editing, running, testing, blocked, or done. + +The config lives at: + +```jsonc +{ + "presentation": { + "activity": { + "mascot": { + "enabled": true, + "hover": " .-.\n (^ ^)\n /[+]\\", + "states": {} + } + } + } +} +``` + +Default states: + +| State | Default ASCII | +| --- | --- | +| `idle` | `.-.` / `(o o)` / `/[+]\` | +| `hover` | `.-.` / `(^ ^)` / `/[+]\` | +| `thinking` | `.-.` / `(o -)` / `/[+]\` | +| `planning` | `.-.` / `(o .)` / `/[+]\` | +| `reading` | `.-.` / `(o o)` / `/[+]\` | +| `searching` | `.-.` / `(o ?)` / `/[+]\` | +| `sending` | `.-.` / `(* *)` / `/[+]\` | +| `patching` | `.-.` / `(o ^)` / `/[+]\` | +| `editing` | `.-.` / `(o >)` / `/[+]\` | +| `running` | `.-.` / `(o !)` / `/[+]\` | +| `installing` | `.-.` / `($ $)` / `/[+]\` | +| `testing` | `.-.` / `(o T)` / `/[+]\` | +| `browsing` | `.-.` / `(o @)` / `/[+]\` | +| `retrying` | `.-.` / `(! !)` / `/[+]\` | +| `blocked` | `.-.` / `(- -)` / `/[+]\` | +| `done` | `.-.` / `(^ ^)` / `/[+]\` | +| `error` | `.-.` / `(x x)` / `/[+]\` | + +The full default activity set: + +```jsonc +{ + "presentation": { + "activity": { + "mascot": { + "enabled": true, + "hover": " .-.\n (^ ^)\n /[+]\\", + "states": { + "idle": " .-.\n (o o)\n /[+]\\", + "thinking": " .-.\n (o -)\n /[+]\\", + "planning": " .-.\n (o .)\n /[+]\\", + "reading": " .-.\n (o o)\n /[+]\\", + "searching": " .-.\n (o ?)\n /[+]\\", + "sending": " .-.\n (* *)\n /[+]\\", + "patching": " .-.\n (o ^)\n /[+]\\", + "editing": " .-.\n (o >)\n /[+]\\", + "running": " .-.\n (o !)\n /[+]\\", + "installing": " .-.\n ($ $)\n /[+]\\", + "testing": " .-.\n (o T)\n /[+]\\", + "browsing": " .-.\n (o @)\n /[+]\\", + "retrying": " .-.\n (! !)\n /[+]\\", + "blocked": " .-.\n (- -)\n /[+]\\", + "done": " .-.\n (^ ^)\n /[+]\\", + "error": " .-.\n (x x)\n /[+]\\" + } + } + } + } +} +``` + +Additional activity message phases also include `uploading` and `downloading`. If a mascot state is missing for a phase, MendCode falls back to `idle` or the default state for that phase when available. + +## How Activity Phases Are Chosen + +MendCode maps live session status and active tool names into activity phases. The mapping is intentionally simple so custom mascots and messages stay predictable. + +| Runtime signal | Phase | +| --- | --- | +| Connection is not connected | `blocked` | +| Retry flag or retry status | `retrying` | +| Session status is idle | `done` | +| Active tool contains `upload` | `uploading` | +| Active tool contains `download` | `downloading` | +| Active tool contains `web`, `fetch`, `browser`, or `chrome` | `browsing` | +| Active tool contains `install`, `pnpm`, `npm`, or `bun` | `installing` | +| Active tool contains `test`, `typecheck`, `lint`, or `build` | `testing` | +| Active tool contains `patch` or `diff` | `patching` | +| Active tool contains `edit`, `write`, or `update` | `editing` | +| Active tool contains `read`, `open`, or `cat` | `reading` | +| Active tool contains `search`, `grep`, `glob`, or `list` | `searching` | +| Active tool contains `plan`, `spec`, or `review` | `planning` | +| Active tool contains `bash`, `shell`, `exec`, or `command` | `running` | +| Live output is answer text | `sending` | +| Reasoning is present | `thinking` | +| Busy status with no clearer tool signal | `thinking` | +| No evidence yet while busy | `sending` | + +Active tools win over older tool history. If no active tool explains the phase, MendCode checks previous tool names, token/reasoning evidence, and finally the busy/idle status. + +## Activity Text + +Activity text lives beside the mascot: + +```jsonc +{ + "presentation": { + "activity": { + "messages": { + "thinking": ["Thinking..."], + "running": ["Running command..."], + "patching": ["Patching..."], + "testing": ["Testing..."], + "blocked": ["Waiting..."], + "done": ["Done"] + } + } + } +} +``` + +You can make it more branded: + +```jsonc +{ + "presentation": { + "activity": { + "messages": { + "thinking": ["Mapping the repo..."], + "reading": ["Reading context..."], + "searching": ["Searching references..."], + "running": ["Running checks..."], + "patching": ["Applying patch..."], + "testing": ["Verifying locally..."], + "blocked": ["Needs input..."], + "done": ["Ready"] + } + } + } +} +``` + +## ASCII Art Slots and Sharing + +MendCode does not limit custom art to one kind of pet. The core profile has two independent ASCII slots: + +| Slot | Profile path | Use | +| --- | --- | --- | +| Home identity | `surfaces.homeLogo.text` plus `identity.logoMode: "mascot"` | Large static mascot, logo, or team mark on Home. | +| Session activity | `presentation.activity.mascot` | Compact companion above the session prompt, including hover art and phase states. | + +A profile can customize either slot or both. A Home logo does not automatically become the session pet, and a session state set does not replace the Home identity. Banners, separators, prompt glyphs, and dynamic art belong in their corresponding profile fields or in TUI plugin slots; do not force every visual into the mascot field. + +### Shareable art profile + +Until a dedicated ASCII-pack manifest and importer exist, share art as a normal TUI profile fragment or as a package containing `tuiProfile`: + +```jsonc +{ + "identity": { + "logoMode": "mascot" + }, + "surfaces": { + "homeLogo": { + "text": " /\\_/\\\n( o.o )\n > ^ <" + } + }, + "presentation": { + "activity": { + "mascot": { + "enabled": true, + "hover": " /\\_/\\\n ( ^.^ )\n > ^ <", + "states": { + "idle": " /\\_/\\\n( o.o )\n > ^ <", + "thinking": " /\\_/\\\n( -.- )\n > ^ <", + "done": " /\\_/\\\n( ^.^ )\n > ^ <", + "error": " /\\_/\\\n( x.x )\n > ^ <" + } + } + } + } +} +``` + +For community or team sharing, label the artifact clearly as `home-only`, `session-only`, or `full-art` and include a narrow-terminal preview. Keep art monospaced, short, terminal-safe, and data-only; packages should not need executable code merely to install ASCII art. See [Marketplace and Team Sharing](packages-and-team-sharing.md) for package distribution. + +## Home Centered Mode + +Centered mode is the default home layout. + +```jsonc +{ + "surfaces": { + "homeWelcome": { + "mode": "centered", + "rightPanel": "actions" + } + } +} +``` + +Behavior: + +- The project/root path appears near the top. +- The ASCII title or mascot is centered. +- The quick actions appear under the identity when the terminal has enough height. +- The prompt input stays at the bottom. +- On tiny terminals, the logo can hide so the prompt remains usable. + +Use centered mode for clean demos, simple local usage, small windows, and teams that prefer a calm start screen. + +## Home Split Mode + +Split mode is a more operational home screen. + +```jsonc +{ + "surfaces": { + "homeWelcome": { + "mode": "split", + "rightPanel": "actions" + } + } +} +``` + +Behavior: + +- The home screen becomes a bordered top panel when the terminal is wide/tall enough. +- Identity appears on the left. +- The right panel shows either actions or Agent View. +- The prompt input remains at the bottom. +- If the terminal is too small or narrower than the split threshold, MendCode falls back to the centered-style layout. + +Split mode is best when you want the home screen to feel like a cockpit: identity on one side, operational state on the other. + +## Home Split Panel + +`surfaces.homeWelcome.rightPanel` controls the right side of split home. + +```jsonc +{ + "surfaces": { + "homeWelcome": { + "mode": "split", + "rightPanel": "actions" + } + } +} +``` + +Supported values: + +- `actions`: shows `Resume session`, `Open commands`, and `Quit`. +- `agentManager`: shows Agent View. + +The actions panel is the simplest. It is useful for first-run and low-noise setups. + +## Agent View + +Agent View is the split-home session manager: + +```jsonc +{ + "surfaces": { + "homeWelcome": { + "mode": "split", + "rightPanel": "agentManager" + } + } +} +``` + +Agent View groups visible session rows into `Needs input`, `Looping`, `Working`, and `Completed`. Its optional session headline summarizes only current `waiting`, `looping`, and `working` counts; it does not present visible completed rows as a lifetime total. The Agent inbox headline describes durable structured coordination commands with queued, slot-capacity, and active counts rather than shell/tool execution. + +Each headline appears only while that category has active work. Completed session rows remain visible when both headlines are hidden. Rows can be selected and opened, while the Home prompt remains a new-task composer. + +This setup is especially good when you run multiple agents or background sessions and want the home page to show what needs attention before you type. + +## Resume, Commands, Quit + +The default home action panel shows: + +```text +Resume session ctrl-s +Open commands ctrl-p +Quit ctrl-c +``` + +Related command palette entries: + +- `Switch session` / slash `/sessions`, `/resume`, `/continue` +- `New session` / slash `/new`, `/clear` +- `Switch agent` / slash `/agents` +- `Switch model` / slash `/models` +- `View status` / slash `/status` +- `Exit the app` / slash `/exit`, `/quit`, `/q` + +Use `Ctrl+P` for the command palette. If you hide command hints in the prompt status, keep this shortcut documented in team onboarding. + +## Recommended Setups + +### Clean Default + +Good for new users and small terminals. + +```jsonc +{ + "identity": { + "productName": "MendCode", + "logoMode": "title", + "logoFont": "mendcode" + }, + "surfaces": { + "homeWelcome": { + "mode": "centered", + "rightPanel": "actions" + } + }, + "promptChrome": { + "preset": "top-bottom" + } +} +``` + +### Mascot + Split + Agent View + +Good power-user setup: + +```jsonc +{ + "identity": { + "productName": "MendCode", + "logoMode": "mascot", + "logoFont": "mendcode" + }, + "surfaces": { + "homeWelcome": { + "mode": "split", + "rightPanel": "agentManager" + } + }, + "promptChrome": { + "preset": "top-bottom", + "glyphs": { + "leadText": "❭" + } + }, + "promptStatus": { + "commandsHint": { + "visible": false + }, + "placementByPreset": { + "top-bottom": "outside" + }, + "left": [ + { "type": "builtin", "value": "mode" }, + { "type": "builtin", "value": "model" } + ], + "right": [ + { "type": "builtin", "value": "context" }, + { "type": "builtin", "value": "permissionMode" } + ], + "separator": " " + } +} +``` + +Why it works: + +- Mascot gives the home screen a distinct identity. +- Split mode keeps the prompt clean while showing useful session state. +- Agent View makes background sessions visible. +- Hidden command hints reduce clutter once the team knows `Ctrl+P`. +- A custom bottom status can carry branch/package/provider/context without stealing prompt space. + +### Company ASCII Title + +Good for teams that want a branded shell but not a character mascot. + +```jsonc { "identity": { "productName": "AcmeCode", - "tagline": "company coding runtime", + "tagline": "secure company coding runtime", + "logoMode": "title", + "logoFont": "shadow" + }, + "surfaces": { + "homeWelcome": { + "mode": "split", + "rightPanel": "actions" + } + }, + "promptChrome": { + "preset": "box", + "borderStyle": "rounded", + "glyphs": { + "leadText": "acme>" + } + } +} +``` + +### ASCII Terminal + +Good for SSH, older terminals, and low-Unicode environments. + +```jsonc +{ + "promptChrome": { + "preset": "ascii-box", + "borderStyle": "ascii", + "glyphs": { + "horizontal": "=", + "vertical": "|", + "topLeft": "+", + "topRight": "+", + "bottomLeft": "+", + "bottomRight": "+", + "leadText": ">" + } + }, + "promptStatus": { + "placementByPreset": { + "ascii-box": "inside" + } + } +} +``` + +## Full Example Profile Fragment + +This fragment combines mascot home, split Agent View, compact status, custom activity text, and a custom running mascot: + +```jsonc +{ + "version": 0, + "profile": "team-agent-view", + "identity": { + "productName": "MendCode", + "tagline": "terminal-first coding", "logoMode": "mascot", "logoFont": "mendcode" }, "surfaces": { - "homeLogo": { - "text": "ACME\\nCODE" + "homeWelcome": { + "mode": "split", + "rightPanel": "agentManager" + } + }, + "promptChrome": { + "preset": "top-bottom", + "borderStyle": "rounded", + "glyphs": { + "leadText": "mendcode>" + } + }, + "promptStatus": { + "enabled": true, + "commandsHint": { + "visible": false + }, + "placementByPreset": { + "top-bottom": "outside", + "ascii-box": "inside" + }, + "left": [ + { "type": "builtin", "value": "mode" }, + { "type": "builtin", "value": "model" }, + { "type": "builtin", "value": "provider" } + ], + "right": [ + { "type": "builtin", "value": "context" }, + { "type": "builtin", "value": "permissionMode" } + ], + "separator": " · " + }, + "presentation": { + "profile": "mendcode", + "reasoning": { + "defaultVisibility": "collapsed" + }, + "activity": { + "style": "raw", + "placement": "current", + "maxLines": 1, + "collapseOnComplete": false, + "showModel": false, + "showTokens": true, + "showElapsed": true, + "showInterruptHint": true, + "messages": { + "thinking": ["Thinking..."], + "reading": ["Reading..."], + "running": ["Running command..."], + "patching": ["Patching..."], + "testing": ["Testing..."], + "blocked": ["Waiting..."], + "done": ["Done"] + }, + "mascot": { + "enabled": true, + "hover": " .-.\n (^ ^)\n /[+]\\", + "states": { + "idle": " .-.\n (o o)\n /[+]\\", + "thinking": " .-.\n (o -)\n /[+]\\", + "running": " .-.\n (o !)\n /[+]\\", + "testing": " .-.\n (o T)\n /[+]\\", + "done": " .-.\n (^ ^)\n /[+]\\", + "error": " .-.\n (x x)\n /[+]\\" + } + } + }, + "symbols": { + "assistantDone": "◈" } } } ``` -## Widgets and TUI Plugins +## AI Prompt for Creating Mascots + +Use this prompt with another AI when you want new mascot states: + +```text +Create a monospaced ASCII mascot set for MendCode. + +Constraints: +- Output plain text only, no Markdown table. +- Keep each state 3 to 5 lines tall. +- Keep every state the same visual width where possible. +- Use only terminal-safe ASCII unless I explicitly ask for Unicode. +- The mascot must remain recognizable across states. +- Avoid very wide art; target 12 to 24 columns. +- Do not include copyrighted characters or brand marks. +- Include these states: + idle, hover, thinking, planning, reading, searching, sending, + patching, editing, running, installing, testing, browsing, + retrying, blocked, done, error. +- Format as JSON for: + presentation.activity.mascot.hover + presentation.activity.mascot.states + +Style: +[describe the character, team tone, product personality, or company theme] + +Default MendCode shape to riff on: + .-. + (o o) + /|[+]|\ + /_|___|_\ + \_/ +``` + +After generating, paste the JSON into `.mendcode/tui/profile.json`, open `mendcode`, and check it in a narrow terminal. Fix width/height before sharing it as a package. + +## TUI Plugins and Widgets + +Use plugins when customization needs live logic instead of static profile data. -The `@mendcode/plugin` package exposes: +The `@mendcode/plugin` package supports: -- custom tools +- custom tools (see [Custom Tool Calls](custom-tool-calls.md)) - TUI routes - commands - dialogs @@ -77,23 +965,113 @@ The `@mendcode/plugin` package exposes: - toasts - themes - slots/widgets +- footer entries +- runtime status +- live TUI customization (terminal title, session accent, diff visibility) +- session lifecycle and AI handles +- Agent View metadata +- memory graph reads/writes and Memory side chat +- focused modal/overlay control +- generated SDK access through `api.client` -Package artifacts can include widget files under `.mendcode/widgets`, `.mendcode/components`, or `.mendcode/scripts`. Runtime packages project them into the active runtime package state. +A TUI plugin can therefore implement a full page, modal, side chat, session assistant, dashboard, or memory workflow without editing MendCode internals. See the [complete public API](tui-plugins-and-widgets.md#public-api-surface). -See [TUI plugins and widgets](tui-plugins-and-widgets.md) for concrete examples of `setWidget`, `setFooterEntry`, slots, dialogs, commands, routes, themes, and team package distribution. +Useful home/prompt slots: + +- `home_logo` +- `home_prompt` +- `home_prompt_right` +- `home_bottom` +- `home_footer` +- `session_prompt` +- `session_prompt_right` +- `sidebar_title` +- `sidebar_content` +- `sidebar_footer` + +Example: add right-side prompt context without replacing the prompt: + +```tsx +/** @jsxImportSource @opentui/solid */ + +export default { + id: "team.prompt-right", + async tui(api) { + api.slots.register({ + slots: { + home_prompt_right() { + return team + }, + session_prompt_right(props) { + return {props.session_id.slice(0, 8)} + }, + }, + }) + }, +} +``` + +A small runtime customization plugin can opt into the live chrome contract and add a widget through the same public surface: + +```tsx +export default { + id: "team.chrome", + async tui(api) { + api.ui.runtime.customization.setTerminalTitle({ + template: "TeamCode · {session} · {path}", + }) + api.ui.runtime.customization.setSessionAccent("random") + api.ui.runtime.customization.setDiffFiles(true) + api.ui.runtime.setWidget("team.review", () => Review tools ready, { + placement: "aboveEditor", + order: 20, + }) + }, +} +``` + +See [TUI plugins and widgets](tui-plugins-and-widgets.md) for full plugin examples. ## Model Customization -Model behavior is controlled by model roles. This lets a team use one model for build/code, another for review, and cheaper models for title/summary/compaction. +Model behavior is controlled by model roles. This lets a team use one model for build/code, an explicit task-specific agent for review work, and cheaper models for title/summary/compaction. + +```bash +mendcode models status +mendcode models presets +mendcode models set-default --auth-mode --enable +mendcode models plan +``` + +When `models.yaml` has `enabled: false`, roles are documented but not projected into generated runtime config. The CLI supports `set-default` and `use-preset`; edit `models.yaml` for role-specific overrides such as `build`, `code`, `subagent`, `title`, and `compaction`. Review work should use an explicit configured agent rather than a generic `review` role. + +## Packaging a Team Theme + +For team rollout, put the profile and any scripts/plugins inside a MendCode package: + +```text +.mendcode/ + package.json + mendcode.json + tui/ + profile.json + prompt-status.sh + plugins/ + team-tui.ts + themes/ + team-dark.json +``` + +Then share it: ```bash -mend models status -mend models presets -mend models set-default openai gpt-5.2 --auth-mode api-key --enable -mend models plan +mendcode packages create --include plugins,tuiProfile,themes +mendcode packages add-source team --type github --url https://github.com/YourOrg/team-mend-package.git --channel team +mendcode packages install team-mend-package team +mendcode packages enable team-mend-package ``` -When `models.yaml` has `enabled: false`, roles are documented but not projected into the generated runtime config. The CLI supports `set-default` and `use-preset`; edit `models.yaml` for role-specific overrides such as `build`, `review`, `subagent`, `title`, and `compaction`. +Keep packages explicit. Enabling a visual package should project config and assets; it should not secretly install TSM, create worktrees, mutate branches, or start unrelated services. ## Safe Customization Rule @@ -110,4 +1088,4 @@ Prefer these extension points: - `.mendcode/widgets` - runtime packages -Avoid editing protected donor/runtime hot paths for normal customization. +Avoid editing protected donor/runtime hot paths for normal customization. If a desired visual change cannot be expressed through the profile, plugin slots, widgets, footer entries, or packages, document the missing extension point before changing runtime internals. diff --git a/docs/examples/ai-profiles.example.json b/docs/examples/ai-profiles.example.json new file mode 100644 index 00000000..230538de --- /dev/null +++ b/docs/examples/ai-profiles.example.json @@ -0,0 +1,40 @@ +{ + "$schema": "https://mendcode.ai/config.json", + "compaction": { + "strategy": "auto", + "portable_mode": "incremental", + "timeout_ms": 60000, + "max_summary_tokens": 4096, + "on_native_error": "portable" + }, + "ai": { + "version": 1, + "orchestration": { + "enabled": true, + "profiles": { + "economical": { + "strategy": "cascade", + "primary": { "role": "build" }, + "escalation": { "role": "plan" }, + "limits": { + "maxModelRequests": 2, + "maxTotalTokens": 64000, + "maxRuntimeMs": 300000, + "unknownCost": "allow-with-token-cap" + } + }, + "reviewable": { + "strategy": "critic", + "primary": { "role": "build" }, + "critic": { "role": "plan" }, + "limits": { + "maxModelRequests": 3, + "maxTotalTokens": 96000, + "maxRuntimeMs": 600000, + "unknownCost": "block" + } + } + } + } + } +} diff --git a/docs/fast-compaction-and-model-workflows.md b/docs/fast-compaction-and-model-workflows.md new file mode 100644 index 00000000..42c070af --- /dev/null +++ b/docs/fast-compaction-and-model-workflows.md @@ -0,0 +1,261 @@ +# Fast compaction and model workflows + +MendCode beta4 adds two opt-in controls to the existing `mendcode.json` or +`mendcode.jsonc` configuration: provider-aware compaction and bounded compound +model workflows. Full Prompt Mode can inspect the runtime inventory and prepare +the change, but a recommendation is not an execution request. + +## Start with the actual runtime + +Use the shared backend so the TUI and CLI observe the same project and provider +state: + +```sh +mendcode ai config inspect +``` + +The result is a redacted inventory of providers, models, advertised variants, +roles, auth category, capability metadata, configuration sources, effective +values, and missing information. It does not make provider inference calls. +Secrets, API keys, OAuth tokens, and raw provider options are never part of the +inventory. + +Full Prompt Mode may also use the native `ai_config` tool when that tool is +actually present in the current session. Its actions mirror the same backend: + +```text +inspect → plan → validate → apply +``` + +If the tool is unavailable, use the CLI commands and report the limitation. A +documented provider, installed package, or configured credential is not proof +that the current session can use it. + +## Configuration shape + +The fields are additive. Omitting them preserves existing portable compaction, +single-model chat, and older configuration behavior. + +```json +{ + "compaction": { + "strategy": "auto", + "portable_mode": "incremental", + "timeout_ms": 60000, + "max_summary_tokens": 4096, + "on_native_error": "portable" + }, + "ai": { + "version": 1, + "orchestration": { + "enabled": true, + "profiles": { + "economical": { + "strategy": "cascade", + "primary": { "role": "build" }, + "escalation": { "role": "plan" }, + "limits": { + "maxModelRequests": 2, + "maxTotalTokens": 64000, + "maxRuntimeMs": 300000, + "unknownCost": "allow-with-token-cap" + } + }, + "reviewable": { + "strategy": "critic", + "primary": { "role": "build" }, + "critic": { "role": "plan" }, + "limits": { + "maxModelRequests": 3, + "maxTotalTokens": 96000, + "maxRuntimeMs": 600000, + "unknownCost": "block" + } + } + } + } + } +} +``` + +This is a template, not a live model recommendation. `build`, `plan`, and any +`compaction` role are existing role names only when the user's +`~/.mendcode/models.yaml` defines them. Direct references use the actual +inventory, for example: + +```json +{ "providerID": "", "modelID": "", "variant": "" } +``` + +Replace every placeholder with an observed value before validation. The +validator reports unconfigured roles, unknown providers/models, and unavailable +variants; it does not silently select a different model. The legacy `review` +role is not a substitute for the independent `critic` leg. + +Field limits are intentional: + +- `strategy` is `portable`, `auto`, or `native`. `portable` is the rollback + baseline; `auto` may use a tested native binding; explicit `native` stops when + the exact provider/auth/model transport is unsupported. +- `portable_mode` is `legacy` or `incremental`. Incremental mode keeps the last + accepted summary, uncovered complete turns, current work state, and a bounded + recent tail. It does not run a background summarizer. +- `timeout_ms` is 1,000–300,000 and `max_summary_tokens` is 512–8,192. +- `on_native_error` is `stop` or `portable`. A genuine fallback is bounded and + does not apply after cancellation or permission rejection. +- Profile names match `[a-z][a-z0-9_-]{0,47}` and at most 16 profiles may be + configured. +- `ModelRef` is exactly `{role}` or `{providerID,modelID,variant?}`. Fields may + not be mixed, and model/variant identity is resolved when a workflow run is + created. +- `single`, `cascade`, and `critic` require respectively at least 1, 2, and 3 + bounded model requests. Every profile also requires positive token/runtime + limits and `unknownCost`. + +The example's `economical` and `reviewable` profiles are valid shapes, but they +may not be feasible in a particular installation. A critic must differ from the +primary by provider/model/variant; a same-model cascade is accepted only with a +warning because it does not change the quality route. + +## Preview, validate, and apply + +For a recommendation, provide only models the user wants to compare. The +advisor ranks feasibility first. It compares known prices only when the catalog +contains them, treats missing prices as `null` rather than free, and marks +quality as `unknown` without comparable dated evidence. Subscription quota is +not API billing. + +```sh +mendcode ai config plan --file plan-request.json +mendcode ai config validate --file preview.json +``` + +`plan-request.json` contains `candidates`, `intent`, and `taskKind`, with +optional `selectedRoles`, `scope`, `target`, and `profileName`. The plan returns +the proposed `ai`/`compaction` patch, alternatives, rationale, warnings, an +observed target, and its exact SHA-256 content digest. Planning never writes. + +Validation checks the patch against the actual runtime and target without +writing. It reports schema, role/auth, cost-limit, native-binding, and stale +digest issues. It never launches a model workflow. + +Apply only after the user explicitly chooses the patch and target: + +```sh +mendcode ai config apply \ + --file preview.json \ + --scope project \ + --target /absolute/project/mendcode.jsonc \ + --expected-hash +``` + +Apply requires `scope` (`project` or `global`), the exact patch and digest, and +the normal backend permission for the target. When no project config exists, +the selected project root receives `mendcode.jsonc`; when multiple supported +files exist, choose the exact observed target. The writer: + +- changes only top-level `ai` and `compaction` paths; +- preserves comments, formatting context, and unrelated keys; +- re-reads the exact text before replacement and rejects a stale digest; +- replaces the file atomically and keeps a scoped `.mendcode-backups` copy; and +- returns changed keys, before/after hashes, effective values, and warnings. + +The CLI creates a dedicated control session on the existing shared backend. +When its policy requires approval, confirm the exact target and preview digest +in an interactive terminal; non-interactive input does not silently approve. +Global changes require both external-directory and edit permission. HTTP +callers cannot use a supplied session ID to inherit its per-turn allow grants. +The native tool keeps its own trusted permission context. These actions do not +invoke a model, and the control session remains as an audit record. + +Concurrent clients of the same backend serialize their writes. The final +digest check also detects external changes observed before replacement, but +is not an operating-system-wide lock against arbitrary editors. + +It does not edit `config.json`, `models.yaml`, credentials, or the active +session model. It does not start a workflow or buy capacity. A digest conflict +means inspect again and create a new plan; do not overwrite the newer file. + +## Compaction and provider changes + +`auto` uses native compaction only when the runtime has a positively supported +exact provider/API/auth/model binding. The first beta candidates are the +official OpenAI Responses API route and the existing Codex OAuth transport; +custom OpenAI-compatible, Azure, and other provider transports stay portable +until independently tested. A successful API route does not establish OAuth +support. + +An explicit compaction role is a manual portable choice. Native compaction is +bound to the active inference model, so validation reports a conflicting +compaction role instead of silently ignoring it. Native output is kept in a +private checkpoint; it is not emitted as a legacy `summary=true` placeholder. +When the provider, auth, model, instructions, or tools change, MendCode rebuilds +portable context before using another native binding. + +To disable the new behavior, apply a reviewed patch that sets +`ai.orchestration.enabled` to `false`, `compaction.strategy` to `portable`, or +`compaction.portable_mode` to `legacy`. Existing transcript history remains the +source for portable recovery. Review the scoped backup before restoring it; no +database backup is restored automatically. + +## Explicit compound workflows + +Configuration alone does not change ordinary chat. A user must explicitly +invoke a `workflow` with a saved profile and a deterministic validation check. +Compound tasks run in a per-run worktree with `maxConcurrency: 1` and retain a +reviewable candidate and receipt. + +The workflow-plan fragment below is a template. Its command must be adapted to +the project and pass MendCode's existing deterministic validation allowlist: + +```json +{ + "formatVersion": 1, + "name": "bounded-repair", + "description": "Implement and verify one bounded repair.", + "objective": "Produce a tested candidate without changing the caller checkout.", + "phases": [ + { "id": "implement", "name": "Implement", "taskIDs": ["repair"] } + ], + "tasks": [ + { + "id": "repair", + "name": "Repair", + "kind": "agent", + "output": { "kind": "text" }, + "workspace": { "mode": "per-run-worktree" }, + "compound": { + "profile": "economical", + "validationChecks": [ + { "id": "focused-check", "command": "bun test test/.test.ts" } + ] + } + } + ], + "finalTaskID": "repair", + "completionCriteria": ["The focused check passes."], + "requiredGates": [], + "budget": { "maxConcurrency": 1, "maxFanOut": 1 } +} +``` + +The runtime materializes the resolved profile in the immutable revision and +keeps a compatibility sentinel so an older beta cannot execute compound +metadata as an ordinary agent. `single` validates once; `cascade` escalates +only a quality failure once; `critic` receives at most a 32-file/512 KiB +immutable evidence snapshot and has no shell, MCP, task, Code Mode, provider +tool, or mutable workspace handle. An uncertain critic result blocks. A +revised candidate is reported as not independently reviewed again. + +Use `workflow` to preview/save/start and to inspect the retained candidate, +events, artifacts, and receipt. Applying or merging that candidate is a later +user-directed review step; the workflow does not stage, commit, push, merge, or +auto-apply to the caller checkout. + +## Full Prompt Mode boundary + +Full Prompt Mode includes this playbook and the complete product catalog. It +does not inject a universal provider list or a preferred model. Minimal, focus, +and custom modes keep their narrower scope. Cost discussion, model comparison, +or a plan preview never authorizes extra inference calls; the assistant must +wait for explicit execution intent and the relevant permission gate. diff --git a/docs/features.md b/docs/features.md new file mode 100644 index 00000000..9e5fda3a --- /dev/null +++ b/docs/features.md @@ -0,0 +1,538 @@ +# Feature Map + +This page is the product-facing inventory for MendCode. It is meant to be the source page for the website feature page, README refreshes, screenshots, and demos. Keep it tied to implemented behavior; do not add aspirational claims without a matching source path or spec status. + +## What MendCode Is + +MendCode is a terminal-first coding harness you can shape around your own workflow. The public surface is the `mendcode` CLI plus the TUI, setup flow, model-role configuration, permission policy, memory system, runtime packages, optional mflow coordination, optional TSM/worktree orchestration, Usage Insights, Plan Mode, Changes Review, and TUI customization. + +The pitch is not “another chat box.” The pitch is a configurable coding terminal: prompt chrome, status rows, model roles, memory policy, team packages, workflow coordination, and review gates live together. + +## Headline Features + +| Feature | What it gives users | Where to go deeper | +| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------- | +| Custom terminal UI | Prompt frame, input marker, status row, home logo, split home, Agent View, chat presentation, themes, widgets, and plugin-driven surfaces. | [Customization](customization.md), [TUI plugins and widgets](tui-plugins-and-widgets.md) | +| Package system | Bundle commands, agents, modes, skills, prompts, MCP config, TUI profile, widgets, model roles, permission defaults, memory defaults, and worktree policy. | [Packages and team sharing](packages-and-team-sharing.md) | +| Plan Mode | The agent presents a Markdown plan inside a TUI review modal; the user can approve, edit, comment, or reject before implementation starts. Approval switches into the configured implementation agent. | [Plan Mode](plan-mode.md) | +| Mermaid ASCII canvases | Mermaid fences render as centered terminal diagrams with fit/layout zoom, local horizontal and vertical scrolling, pan controls, and documented stress fixtures. | [Mermaid ASCII rendering](mermaid-ascii-rendering.md) | +| Changes Review | `/changes` opens a responsive TUI diff workspace with file/block/line navigation, comments, reload, return-to-chat behavior, and agent-visible review context between model turns. | [Changes Review](changes-review.md) | +| Loop Workflows | Durable, monitorable loop sessions with `/loop` creation, `/loops` supervision, Agent View roots, contract-aware report-only mode, and a per-project OS background service. | [Loop Workflows](loop-workflows.md) | +| Automation runtime | Let another local agent create, continue, inspect, wait for, stream, and cancel real MendCode sessions through the same runtime, with versioned JSON output and shared model selection. | [Automation runtime](automation-runtime.md) | +| Usage Insights | Local activity dashboard for tokens, sessions, AI time, words, tools, agents, models, changed files, daily activity, selected-day detail, cache mix, and optional weather. | [Usage Insights](usage-insights.md) | +| Passive prompt-cache controls | Configure legacy/off/smart cache behavior by project, session, provider, and exact model without enabling keepalive or remote-cache deletion. | [CLI, setup, and configuration](cli-setup-configuration.md#prompt-cache-controls) | +| Approval-gated memory | Memory can retrieve context without silently turning every session into permanent state. Generated memories become reviewable proposals first. | [CLI, setup, and configuration](cli-setup-configuration.md#permissions-and-memory) | +| Memory Center, graph, and Dream | Route-level memory workspace with saved/pending memories, categories, policy controls, Dream logs, and constrained memory side chat. | [Memory Center](memory-center.md) | +| Smart permissions | Choose `approval`, `smart`, or `full_access`. Smart mode auto-approves bounded read-only shell work and can route risky decisions through a configured `permissionReviewer` role. | [CLI, setup, and configuration](cli-setup-configuration.md#permissions-and-memory) | +| Model roles | Configure task-specific roles for default, small, plan, build/code, subagent, title, compaction, summary, memory extraction, Dream, memory side chat, and permission review. | [CLI, setup, and configuration](cli-setup-configuration.md#models) | +| Local provider bridges | Connect local provider CLIs such as Claude Code through validated setup/auth surfaces while keeping credentials in local tool state. | [CLI, setup, and configuration](cli-setup-configuration.md#connect-provider) | +| mflow coordination | Optional local-first coordination and locks for multiple agents working around the same repo. | [mflow coordination](mflow.md) | +| TSM and worktrees | Open MendCode in managed/adopted worktrees or TSM terminal workspaces with preview-first safety. | [TSM and worktrees](tsm-and-worktrees.md) | +| Plugins and widgets | Add status entries, editor widgets, slots, command palette entries, slash commands, routes, dialogs, themes, and package-distributed TUI behavior. | [TUI plugins and widgets](tui-plugins-and-widgets.md) | + +## Terminal Workflow + +Open MendCode in a repo: + +```bash +mendcode +``` + +Start with an initial instruction: + +```bash +mendcode run "review this repo and draft a plan" +``` + +Run a control-plane turn without opening the full interactive surface: + +```bash +mendcode chat "summarize current status" +``` + +Drive the same session runtime from another local agent: + +```bash +mendcode session create --title "Implement the feature" --format json +mendcode session send ses_... "Inspect the repository and implement the change" --format json +mendcode session wait ses_... --timeout-ms 1800000 --format json +mendcode session events ses_... --follow --format json +``` + +Automation output is newline-delimited `mendcode.cli.v1` JSON. Use `inspect` or +`export` for a snapshot, `events` for progress, and `cancel` to stop active +work. The detailed command contract, lifecycle states, model precedence, and +redaction rules live in [Automation runtime](automation-runtime.md). + +Inspect readiness and product subsystems: + +```bash +mendcode status +mendcode doctor +mendcode setup status +mendcode models status +mendcode permissions status +mendcode memory status +mendcode packages status +mendcode mflow status +mendcode loops status +mendcode worktree status +mendcode tsm status +``` + +Open with workflow shortcuts: + +```bash +mendcode --worktree feature-branch +mendcode --tsm feature-branch +mendcode --tsm --all +``` + +Normal public docs should use `mendcode`. A local `mend` shim may exist in development checkouts, but it is not the public command. + +## TUI Commands And Shortcuts + +These are good demo moments because they show MendCode as a product surface, not just a model wrapper. + +| Input | Behavior | +| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| `Ctrl+P` | Command palette. Search for Usage Insights, Memory, Home, Prompt, Presentation, Status, Worktrees, TSM, mflow, packages, models, themes, or help. | +| `Shift+Tab` | Open the mode picker. This is the fast path for switching the operating mode without typing a command. | +| `Tab` | Cycle primary agents. | +| `F2` / `Shift+F2` | Cycle recently used models forward/back. | +| `F3` / `Shift+F3` | Cycle or list model variants. | +| `Ctrl+X`, then `m` | Open model list through the leader key binding. | +| `Ctrl+X`, then `a` | Open primary agent list through the leader key binding. | +| `Ctrl+X`, then `s` | Open runtime status. | +| `Ctrl+X`, then `l` | Switch/resume sessions. | +| `Ctrl+X`, then `n` | Start a new session. | +| `Ctrl+_` | Undo the most recent prompt edit. On many keyboards this is `Ctrl+Shift+-`. | +| `Ctrl+Y` | Redo a prompt edit. | +| `⌘Z` / `⌘⇧Z` | Undo / redo prompt edits on macOS. | +| `Ctrl+Z` | Suspend the terminal on POSIX systems; it is not the prompt undo shortcut. | +| `Esc` | Interrupt the current session or leave focused route views. | + +Prompt undo/redo history is temporary and stays in memory only. It can recover text +cleared while the prompt remains open, but it is not persisted as a prompt archive. + +Slash commands are also registered for common surfaces: + +```text +/stats +/usage +/insights +/activity +/changes +/diff +/review-changes +/stats-project +/project-usage +/memory +/mem +/memories +/sessions +/resume +/new +/loop +/loops +/models +/agents +/variants +/mcps +/connect +/status +/themes +/help +/exit +/tsm +/worktrees +/mflow +``` + +## Custom Terminal UI + +MendCode turns the terminal into a profile. The stable config lives in `.mendcode/tui/profile.json`; dynamic runtime extensions live in TUI plugins. + +Configurable surfaces include: + +- prompt chrome presets: `box`, `top-bottom`, `minimal`, `ascii-box` +- prompt lead string: `❭`, `>`, `mendcode>`, `ship>`, team-specific markers +- prompt status row: mode, model, provider, reasoning, context, permission mode, command hints, agent hints, script-backed status +- home identity: generated ASCII title or custom ASCII mascot +- independent Home and session ASCII art: large `surfaces.homeLogo.text` plus compact activity mascot states +- home layout: centered welcome or split layout +- split panel: actions or Agent View +- chat presentation: raw, minimal, or MendCode activity-oriented rendering +- activity mascot states for thinking, reading, searching, running, patching, testing, blocked, done, and error phases +- profile/package sharing for team-created logos and mascots; first-class ASCII-pack import is not available yet +- widgets, slots, custom routes, dialogs, footer entries, and themes through plugins + +Good demo profile: + +```jsonc +{ + "identity": { + "logoMode": "mascot", + "productName": "MendCode", + }, + "surfaces": { + "homeWelcome": { + "mode": "split", + "rightPanel": "agentManager", + }, + }, + "promptChrome": { + "preset": "top-bottom", + "glyphs": { + "leadText": "mendcode>", + }, + }, + "promptStatus": { + "placementByPreset": { + "top-bottom": "outside", + "ascii-box": "inside", + }, + }, +} +``` + +## Package Your Harness + +Runtime packages are how a team shares a tuned MendCode environment. A package can include: + +- `.mendcode/commands` +- `.mendcode/agents` +- `.mendcode/modes` +- `.mendcode/skills` +- `.mendcode/prompts` +- MCP config/files +- context docs and rules +- plugins, widgets, components, and scripts +- TUI profile and theme tokens +- model roles and focus defaults +- budget posture +- memory defaults +- permissions defaults +- worktree policy + +Packages must not include provider tokens, OAuth state, `.env*`, `.mendcode/auth`, local DB files, local mflow room secrets, or machine-local run/cache state. + +Useful commands: + +```bash +mendcode packages create --id acme-standard --title "Acme Standard" --include all --version 1.0.0 +mendcode packages status +mendcode packages list +mendcode packages sources +mendcode packages search acme +mendcode packages show acme-standard +mendcode packages install acme-standard +mendcode packages enable acme-standard +mendcode packages disable acme-standard +``` + +## Plan Mode + +Plan Mode is built for users who want the agent to think first without silently editing files. + +The flow: + +1. The planning agent researches and writes a Markdown plan. +2. It calls the `plan_review` tool. +3. MendCode renders the plan in a TUI modal. +4. The user can approve, edit, add comments, reject, or close. +5. Approval resolves `planExitAgent` and switches the session to the configured implementation agent. +6. The approved or edited Markdown becomes the source of truth for implementation. + +This is stronger than a normal “is this okay?” message because approval is an explicit terminal action and the implementation agent receives the reviewed plan. + +## Changes Review + +Changes Review is the review surface for the current working-tree diff: + +```text +/changes +``` + +It provides a responsive terminal diff viewer with a file sidebar on wide +terminals and a stacked scroll layout on compact terminals. Users can move by +file, diff block, or line, add comments, reload the diff, and leave the route with +`Esc` or `q` without stopping the active chat/session. + +The agent integration is intentionally bounded. MendCode injects compact +`` into model turns when a review is active, including +the selected file/block/line and comments. If a user comments while an agent is +working, the agent can see that updated review context on the next model turn, +including the turn after a tool call completes. MendCode does not interrupt an +already-running token stream to splice in new comments mid-generation. + +The assistant can also use the `review` tool to inspect the active selection, +read a specific file summary, navigate, reload, and manage comments. The route +does not require any external diff review app to be installed; it is +MendCode-native and uses `@pierre/diffs` for patch structure. + +## Loop Workflows + +Loop Workflows are durable agent workflows for verified goals, recurring jobs, +and exact-count runs. Completion and cadence are independent contracts: + +- `max-goal` uses concrete completion criteria and finishes as soon as the goal + is verified. A positive `maxTurns` is an optional safety cap, not a schedule. +- `unbounded-monitor` repeatedly executes the objective on its manual, interval, + daily, self-paced, adaptive, or external-signal trigger. Omit `maxTurns` and + stop it explicitly when the recurring job is no longer needed. +- `fixed` uses a positive `maxTurns` for exactly bounded iterations. + +A recurring loop's objective describes the work for each wakeup; it is not an +early-completion condition after the first successful run. + +Core commands: + +```bash +mendcode loops examples +mendcode loops draft --template research-digest --name "Loop test" +mendcode loops activate loop_... +mendcode loops tick loop_... --execute --report-only +mendcode loops monitor loop_... +mendcode loops service start +``` + +For a durable report-only/read-only workflow, `--execute --report-only` wakes the loop root session and records transcript activity without exposing mutation, shell, or subagent tools. It does not downgrade an edit-capable contract. Real agent execution uses `mendcode loops tick ... --execute`; `run` / `run_once` records a monitor iteration without a model call, still consumes iteration budget, and can block a `max-goal` workflow when that budget is exhausted. + +Supervised completion can combine allowlisted executable validations, evidence-only success checks, independent judgment, deterministic rubric coverage, authenticated local HTTP signal ingress, audited non-critical overrides, and bounded append-triggered artifact retention. + +The per-project service persists scheduler state, repairs overdue wakeups, and +uses leases to prevent duplicate execution. `/loops` presents the persisted +`nextWakeup` as a live countdown alongside scheduler health and bounded evidence. +Permission or user-decision gates move the current run to durable `needs_input`; +providing input resumes that run rather than completing, failing, or duplicating +the workflow. + +See [Loop Workflows](loop-workflows.md) for lifecycle, monitor, Agent View behavior, and service details. + +Important release notes for this page: + +- loops are durable database records, not just long-running prompts +- activation creates a root session visible in Agent View under `Looping` +- run journals record created, activated, wake, started, completed, failed, paused, resumed, and stopped events +- report-only/read-only workflow contracts suppress mutation and shell/subagent tools during execution +- service mode is per project and requests report-only execution by default, while the durable workflow contract remains authoritative +- scheduled wakeups survive closing the TUI when the project service is running; persisted scheduler state remains the source of truth +- `needs_input` is a durable wait on the existing run, not a terminal state or a reason to recreate the loop + +## Memory, Memory Page, And Dream + +Baseline memory behavior: + +- global and project scopes +- explicit `mendcode memory add` +- `mendcode memory search` +- `mendcode memory preview` +- generated memory proposals +- apply/reject/edit proposal flow +- transient prompt injection through `` +- approval-first defaults for generated memory + +Memory Center expands this into: + +- route-level Memory page +- workspace/project registry +- saved and pending memory views +- category map and category policy controls +- memory graph sidecar with legacy bridge +- category-aware retrieval labels +- Dream run ledger, safety report, redacted evidence manifest, and logs +- manual/scheduled Dream semantics with missed-window handling +- constrained memory side chat +- reviewable proposals for add, update, remove, verify, expire, recategorize, and scope changes + +The memory side agent can answer memory-specific questions, inspect saved +entries/categories/policies, explain retrieval and proposal risk, and draft +reviewable memory/category/policy/Dream changes. It is powerful inside the +memory workspace, but it is not a normal coding agent and does not apply changes +without review. + +Important safety model: + +- Dream does not apply memory directly by default. +- Dream does not edit source files. +- Dream does not mutate git state. +- Git/session/file evidence is opt-in and bounded. +- Memory side chat does not become a normal coding agent. +- Generated mutations remain proposals or explicit user actions. + +## Usage Insights + +Usage Insights is local observability for the coding harness, not cloud analytics and not a productivity guarantee. + +It can show: + +- global, project, or directory scope +- daily token heatmap +- keyboard/mouse day selection +- selected-day token, cache, session, prompt, word, file, AI time, and tool runtime details +- sessions and active days +- user prompts and user words +- AI generation time +- tool runtime +- changed files from session summaries +- input/output/reasoning/cache token mix +- peak token pressure +- longest task time +- top tools +- top agents +- top models and cost totals when provider metadata is available +- optional weather through Open-Meteo + +Open it from the command palette: + +```text +Ctrl+P -> Usage Insights +Ctrl+P -> Project Usage Insights +``` + +Or with slash commands: + +```text +/stats +/usage +/insights +/activity +/project-usage +``` + +## Markdown, Streaming Output, And Shell Feedback + +MendCode renders assistant output inside a terminal, so Markdown support has to +work while text is still streaming and after messages complete. + +Current rendering surfaces include: + +- headings, lists, links, inline code, bold/italic text, code fences, tables, and blockquotes +- terminal-friendly Mermaid text diagrams for common chart/diagram shapes +- styled Plan Mode and compaction summaries +- progressive streaming Markdown tails that avoid rendering incomplete tables or fences too early +- hex color swatches in rich Markdown output +- live shell output that deduplicates replayed deltas while commands are still running + +This keeps long model answers, plans, shell commands, and compaction summaries +readable without waiting for the entire response to finish. + +## Local Provider Bridges + +MendCode can expose local provider CLIs through the same provider/model setup +surface used by hosted providers. The Claude Code bridge validates the local +`claude` binary, checks local CLI auth status, reads version-compatible models, +and keeps credentials in the Claude Code CLI's own local state instead of +placing secrets in MendCode packages or repository files. + +## Provider-Aware Context Continuity + +Provider adapters keep transport details aligned with the model contract instead of +making the rest of the runtime provider-specific. For ChatGPT OAuth Responses Lite, +MendCode normalizes supported model aliases, preserves session affinity while the +effective instructions stay the same, and rotates that affinity when instructions +change. GPT-5.6 OAuth models expose a 256K effective input/context limit and a +provider-aware compaction threshold so long sessions compact before the provider +rejects the request. GPT-6 Astra is also available when the OpenAI catalog or +ChatGPT account exposes it, with its documented 1.05M context and 922K input +limits. + +## Model Roles + +MendCode avoids hardcoding one model for every task. Model config can route different jobs through different roles: + +- `default` +- `small` +- `plan` +- `build` +- `code` +- `subagent` +- `title` +- `compaction` +- `summary` +- `memoryExtractor` +- `memoryDream` +- `memoryAssistant` +- `permissionReviewer` + +Examples: + +- use a stronger model for planning and build work +- use a cheaper/smaller model for titles or simple summaries +- use a dedicated reviewer model for smart permission review +- use `memoryExtractor` for proposal generation +- use `memoryDream` for memory maintenance proposals +- use `memoryAssistant` for Memory page side chat + +## Permissions And Safety + +Permission modes: + +| Mode | Behavior | +| ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | +| `approval` | Manual approval remains the normal review posture. | +| `smart` | Bounded read-only shell requests pass automatically. Risky or ambiguous requests stay gated and may use a configured `permissionReviewer`; the reviewer cannot auto-approve non-read-only commands. | +| `full_access` | Reduces prompts for the current trust posture, while explicit deny rules still matter. | + +Safety principles: + +- public packages do not carry secrets +- generated memory is reviewable +- risky work can stay approval-gated +- worktree operations are preview-first +- mflow is optional and local-first +- Usage Insights stays local +- internal/debug commands stay hidden from normal help + +## Coordination: mflow, TSM, Worktrees + +mflow is optional coordination for same-repo agent work. It provides local-first state, relay setup, and lock/status surfaces so multiple sessions can avoid stomping the same files. + +TSM and worktree support are for terminal/worktree orchestration: + +- inspect existing worktree state +- plan worktree creation before mutating anything +- open or adopt worktrees +- reset/remove through gated flows +- start TSM workspace sessions with MendCode panes + +Public commands: + +```bash +mendcode mflow status +mendcode mflow setup +mendcode mflow activate --room --accept-public-relay-limits +mendcode mflow deactivate +mendcode worktree status +mendcode worktree plan +mendcode worktree create +mendcode worktree open +mendcode worktree adopt +mendcode tsm status +mendcode tsm plan +mendcode tsm setup +mendcode --worktree [branch|path|id] +mendcode --tsm [branch|path|id|--all] +``` + +## Feature Demo Checklist + +For a README, website, or creator demo, show these in order: + +1. `mendcode` opens the terminal harness. +2. `Ctrl+P` opens the command palette. +3. `Shift+Tab` opens mode picker. +4. `Tab` cycles agents. +5. `F2` cycles recent models. +6. Prompt marker changes from `❭` to `mendcode>` or a team marker. +7. Home layout switches to split mode with Agent View. +8. Plan Mode displays a Markdown plan in the review modal. +9. Usage Insights shows local activity. +10. Memory Center shows saved/pending memories, categories, Dream, and side chat. +11. Packages show how a team shares commands, agents, modes, skills, prompts, TUI profile, widgets, permissions, memory defaults, and worktree policy. +12. mflow/TSM/worktree surfaces show parallel workflow coordination. + +## Implementation paths + +The implementation and test paths for all product surfaces are maintained in the dedicated [MendCode Source Map](source-map.md). This feature page stays focused on behavior and user-visible contracts. diff --git a/docs/loop-workflows.md b/docs/loop-workflows.md new file mode 100644 index 00000000..42b68212 --- /dev/null +++ b/docs/loop-workflows.md @@ -0,0 +1,440 @@ +# Loop Workflows + +Loop Workflows are durable, monitorable agent loops for work that should keep moving in controlled iterations. They are closer to an inspectable workflow runner than to a single long chat turn. + +The design goal is simple: a user can turn an objective into a loop, see it in Agent View, inspect every wakeup, and choose how much execution power the loop gets. + +For one-shot runs without recurring cadence, use the independent Workflow contract documented in [`docs/workflows.md`](workflows.md). A loop may still trigger a saved Workflow revision, but cadence, wakeups, and loop gates remain owned by the loop while `/workflows` owns the phase/task graph. + +![MendCode Loop Workflow receipt in chat](assets/screenshots/loop-workflow-created.png) + +![MendCode Loop Workflows dashboard](assets/screenshots/loop-workflows-dashboard.png) + +## What The Screenshots Show + +The receipt view confirms that a report-only workflow has been created, shows the durable loop id, cadence, iteration limit, next wakeup, and the loop card that can be opened from chat. + +The dashboard view shows the active loop list, current iteration progress, next wakeup, execution mode, linked root session, and a bounded summary of the latest run, gates, evidence, cost, and next action. It is the persistent monitor surface for checking whether a loop is sleeping, running, paused, or ready for inspection. + +## Mental Model + +A loop has six layers: + +- Workflow: the durable DB record with objective, state, trigger, gates, policy, metrics, and next wakeup. +- Root session: the chat session created when the loop is activated. It is the root loop turn, appears in Agent View as a background looping session, and is the only row currently recorded in the loop thread ledger. +- Optional child sessions: normal task/subagent sessions created by edit-capable root turns, plus a separate read-only auditor child when strict completion confirmation is required. They remain session transcripts rather than additional Agent View loop roots or loop-thread rows. +- Run: one wakeup/iteration of the loop. +- Artifact ledger: bounded checkpoints, judgments, gate results, command output, evidence, signals, overrides, and cost records associated with the workflow or a run. +- Journal: durable events such as created, activated, wake, started, completed, failed, paused, resumed, and stopped. + +The DB remembers the workflow even when MendCode exits. A live process is still required to wake due loops. + +## Choose The Loop Shape + +Completion policy and wakeup policy are independent. Choose the budget mode +from how the work should finish, then choose a trigger from when it should run: + +| Intent | Budget contract | Trigger contract | Completion behavior | +|---|---|---|---| +| Reach a verifiable goal | `budgetMode: "max-goal"` plus concrete `completionCriteria`, with `successChecks` when evidence must be checked | Manual, self-paced, interval, daily, adaptive, or external signal | Complete as soon as the goal passes its checks and gates. A positive `maxTurns` is an optional safety cap, not a target. | +| Run a recurring job | `budgetMode: "unbounded-monitor"`; omit `maxTurns` | Usually interval, daily, adaptive, or external signal | Keep running the objective at each wakeup until explicitly stopped or blocked by a safety, budget, approval, or input gate. | +| Run an exact number of iterations | `budgetMode: "fixed"` plus a positive `maxTurns` | Manual or scheduled | Consume the requested iteration count unless stopped or blocked. | + +Every loop has an objective. For `max-goal`, the objective and completion +criteria describe a result that can be verified once. For a recurring job, the +objective describes what to inspect or perform at every wakeup; a successful run +does not make the ongoing schedule complete. Do not divide goal work across all +available turns just because a cap exists, and never encode unlimited work as +`maxTurns: 0`. + +## Supervised Completion + +Loop Engineering separates proposing completion from accepting it: + +1. The root loop session ends an executed iteration with a structured `LOOP_CHECKPOINT` containing status, summary, evidence, next action, and confidence. +2. Pre-judge gates inspect checkpoint validity and approval policy, then run any allowlisted executable validation commands and retain their bounded evidence. +3. A new `max-goal` loop defaults to `completionConfirmation: "next-run"`. Passing worker-side gates records a generation-bound completion candidate; it does not complete the loop. +4. A later run creates a fresh read-only auditor session. The auditor must inspect the workspace through read-only tools, validation commands are rerun by the host, and the workspace fingerprint must remain unchanged before and after inspection. +5. The completion contract requires current evidence for every criterion and rejects stale generations, missing inspection, changed workspaces, deterministic check failures, and exhausted audit budgets. +6. Only a passing audit receipt atomically marks the loop `completed`. A quality failure reopens work; an unsafe, stale, or exhausted audit blocks instead of claiming success. + +The three budget modes have different completion semantics: + +| Mode | Operator expectation | +|---|---| +| `fixed` | Run to the positive iteration cap unless stopped, blocked, or waiting for input; it does not complete early when the goal is reached. | +| `max-goal` | Treat `maxTurns` as a cap, finish early as soon as completion is verified, and block instead of claiming success when the cap is exhausted. | +| `unbounded-monitor` | Keep monitoring until stopped, an explicit safety/budget/input gate blocks it, or an external stop condition applies; omit `maxTurns`. A scheduled monitor may report an informational `blocked` checkpoint (for example, stale data) and keep its next wakeup when no gate failed. | + +`max-goal` workflows created through the loop tool default to independent evaluation and next-run confirmation unless the contract explicitly selects another mode. `same-run` remains available for persisted compatibility or an explicit opt-out. A passing auditor cannot override `needs_input`, approval requirements, deterministic failures, stale evidence, or a changed workspace. + +Configured `successChecks` remain backward-compatible completion evidence requirements even when executable checks also exist. Explicit `validationCommands` are different: for edit-capable workflows, the runner executes only allowlisted test/check commands as direct bounded subprocesses after a `complete` or `blocked` checkpoint that may be independently verified, and before independent judgment. An active worktree lease supplies the validation working directory. A result recorded while the run still owns its lease becomes a `command-output` artifact and a deterministic `validation:` gate carrying the artifact reference; a stale-run race is discarded and blocks completion instead of attaching stale evidence. Report-only/read-only contracts, shell composition, redirection, command substitution, unsafe `git diff` output flags, and commands outside the validation allowlist are blocked as policy failures. + +When a rubric is configured, the runner records deterministic evidence-coverage scores, threshold status, and mandatory-blocker findings in a separate runtime rubric result on the run. These binary coverage scores are not evaluator-authored criterion grades. The gate engine adds a runtime `rubric` gate, so a passing judge cannot override a failed executable validation or a detected mandatory blocker. + +## Basic Flow + +List built-in loop examples: + +```bash +mendcode loops examples +``` + +Create a draft from a template: + +```bash +mendcode loops draft --template research-digest --name "Loop test" +``` + +Create a draft from a custom objective: + +```bash +mendcode loops draft --name "CI repair" --objective "Keep checking CI and propose fixes until the branch is green." +``` + +Activate the workflow: + +```bash +mendcode loops activate loop_... +``` + +Activation creates a root session named `Loop: `, registers it in Agent View as a background loop, records the root loop thread, and schedules the first wakeup. + +Activation also attempts to ensure the project loop service is installed and started. Use `--no-service` only for admin/debug flows where you explicitly do not want OS-backed wakeups. + +Inspect it: + +```bash +mendcode loops status +mendcode loops show loop_... +mendcode loops tail loop_... +mendcode loops monitor loop_... +``` + +`monitor` is the terminal view for one loop. It refreshes the workflow state, persisted root-thread ledger, and journal while the command is running. Ordinary subagent and evaluator output remains in the associated session transcripts. + +## Tick Modes + +Daily schedules are first-class triggers rather than 24-hour intervals. Create one with `triggerMode: "daily"`, `dailyAt: "10:00"`, and a timezone such as `UTC`, `GMT`, `America/New_York`, or `Europe/Madrid`. MendCode accepts valid IANA/UTC/GMT zones, persists the timezone, calculates the next wall-clock occurrence (including daylight-saving transitions), and lets the project loop service process the workflow when that wakeup is due. + +The persisted `nextWakeup` is the scheduling source of truth. The project +service scans a bounded set of due workflows, repairs overdue scheduled wakeups, +and acquires a workflow lease before execution so concurrent scheduler ticks do +not run the same workflow twice. Closing and reopening the TUI does not reset +that schedule. The `/loops` countdown is reactive presentation derived from the +persisted timestamp, not a separate timer contract. + +`tick` is the manual wakeup command. + +Dry-run preview: + +```bash +mendcode loops tick loop_... +``` + +This does not call the agent. It only reports what would run. + +Report-only execution (report-only/read-only workflows): + +```bash +mendcode loops tick loop_... --execute --report-only +``` + +This wakes the agent in the loop root session and, when the workflow contract is already report-only/read-only, writes transcript/UI activity while omitting loop, edit, write, apply_patch, bash, task/subagent, todowrite, memory, and memory_graph tools from the model tool set. Executable validation commands are also recorded as blocked policy gates rather than spawned. If the workflow explicitly allows edits, `--report-only` does not override that contract. + +Full execution: + +```bash +mendcode loops tick loop_... --execute +``` + +This wakes the real agent with normal session/runtime permissions only when the workflow contract permits edits. A durable `read-only` or report-only workflow remains non-mutating even when the daemon or manual tick uses `--execute`. + +## Daemon And Service + +There are two background modes. + +Terminal daemon: + +```bash +mendcode loops daemon --execute --report-only +``` + +This keeps checking due loops while that terminal/process is alive. If you close the terminal or kill all MendCode processes, it stops. The workflow remains durable in the DB, but nothing wakes it until another daemon, service, or manual tick runs. + +OS service: + +```bash +mendcode loops service install +mendcode loops service start +mendcode loops service status +mendcode loops service logs +``` + +The service is installed per project and runs with that project as its working directory. It survives closing MendCode or the terminal because the OS owns the process. Its durable workflow state, catch-up behavior, and leases let scheduled work continue without relying on an open chat or TUI. + +Backends: + +- macOS: LaunchAgent under `~/Library/LaunchAgents`. +- Linux: user systemd unit under `$XDG_CONFIG_HOME/systemd/user` or `~/.config/systemd/user`. +- Windows: Task Scheduler task plus a generated command file under `%LOCALAPPDATA%\MendCode\Loops`. + +If the default directories do not work on a machine, override them: + +```bash +mendcode loops service start --service-dir /path/to/service-defs --log-dir /path/to/logs +``` + +Environment overrides are also supported: + +```bash +MENDCODE_LOOP_SERVICE_DIR=/path/to/service-defs +MENDCODE_LOOP_LOG_DIR=/path/to/logs +``` + +Project config can set the same defaults in `.mendcode/mendcode.json`: + +```jsonc +{ + "loop": { + "serviceDir": "/path/to/service-defs", + "logDir": "/path/to/logs", + "defaultServiceMode": "report-only" + } +} +``` + +`defaultServiceMode` accepts `dry-run`, `report-only`, or `execute`. Keep `report-only` for normal team defaults. + +The service defaults to a report-only runner request: + +```bash +mendcode loops service start +``` + +This runs the loop daemon in report-only mode under the default project service config. Report-only tool suppression still depends on the workflow contract: read-only/report-only workflows stay non-mutating, while edit-capable workflows can receive normal tools. + +Other service modes: + +```bash +mendcode loops service start --dry-run +mendcode loops service start --allow-edits +``` + +- `--dry-run`: wakes the scheduler but does not call the agent. +- default: calls the agent in report-only mode. +- `--allow-edits` / `--full`: clear the report-only gate so workflows whose contracts permit edits can run with normal tools; it does not override a durable read-only/report-only contract. + +Stop or remove: + +```bash +mendcode loops service stop +mendcode loops service uninstall +``` + +`uninstall` removes the OS service definition. It does not delete loop workflows, sessions, runs, or journal events. + +In product UX, users should not need to run these commands for normal loop creation. They are the admin/debug surface. The chat/session flow should create the workflow, activate it, and ensure the project service is installed/started automatically. + +## What Shows In The TUI + +Agent View groups activated loop root sessions under `Looping`. + +Opening a loop root session shows a loop banner in chat. A report-only tick keeps report-only/read-only workflows non-mutating while still producing transcript activity. A full execution tick behaves like a normal agent turn inside the loop root session. + +Recommended UI smoke test: + +```bash +mendcode loops draft --template research-digest --name "Loop test" +mendcode loops activate loop_... +mendcode loops tick loop_... --execute --report-only +mendcode +``` + +Then open Agent View, find the session under `Looping`, and inspect the loop banner plus transcript. + +Natural session prompt example: + +```text +Turn this session into a test loop. Run 5 iterations, inspect the main files in this directory, use analysis subagents when useful, do not edit files, and after each iteration report what is new or different from the previous iteration. When the loop finishes, give me a final summary. +``` + +Expected product behavior: + +1. The agent creates a loop draft from the current session/objective. +2. The agent activates the loop and creates the root loop session. +3. MendCode ensures the project service is installed and started. +4. The root session appears in Agent View under `Looping`. +5. Each iteration writes transcript/journal updates. +6. If the TUI is open, SSE events refresh the view live. If the TUI was closed, reopening MendCode hydrates from durable DB state and shows the latest loop state. + +### `/loops` operator dashboard + +The `/loops` route separates active workflows from history and refreshes from loop events with a polling fallback. The detail view exposes a bounded summary of the objective, contract preview, state/phase, wake reason, latest run, checkpoint/judgment verdict, executable check labels/counts, rubric result, override audit count, retention policy, evidence summary, loop memory, cost, and next action when those fields exist. Scheduled workflows show a live countdown to persisted `nextWakeup` plus scheduler state; the countdown updates without mutating the workflow record. + +Keyboard controls: + +| Key | Action | +|---|---| +| `a` / `h` | Switch between active workflows and history. | +| `j` / `k` or arrows | Select the next or previous workflow. | +| `Enter` or `o` | Open the root loop chat when it exists. | +| `e` | Change the workflow agent/profile. Blank returns to the default agent. | +| `p` / `u` | Pause or resume the selected workflow. | +| `s` | Stop the selected workflow after confirmation. | +| `r` | Refresh immediately. | +| `q` or `Esc` | Return to the previous route. | + +Use the state and phase together when diagnosing a workflow: + +| State | Meaning | +|---|---| +| `draft` | Stored but inert; activation has not created/scheduled the root run context. | +| `active` / `sleeping` | Eligible to run now or waiting for its trigger. | +| `working` | A run currently owns the workflow lease. | +| `needs_input` | A user decision, permission, or gated input is required. The wait is durable; resolving it resumes the same run rather than completing, failing, or recreating the workflow. | +| `blocked` | A policy, budget, quality, environment, or other blocker prevents progress. | +| `paused` | Temporarily disabled but resumable. | +| `completed` | The completion contract passed. | +| `failed` / `stopped` | Terminal failure or explicit stop. | + +The raw loop chat remains the source of truth for full model/tool output. Dashboard summaries are intentionally bounded operator views. + +## Tool And API Controls + +The assistant-facing `loop` tool currently supports these actions: + +- Lifecycle: `draft`, `activate`, `pause`, `resume`, `stop`, and `delete`. +- Inspection: `show` and `list`. +- Execution: `run_once` records a monitor iteration without invoking the agent. It still consumes iteration budget and can block a `max-goal` workflow when the cap is exhausted. +- Configuration: `update_agent` retargets future wakeups to another agent/profile. +- Events: `signal` records a normalized external signal with source, type, dedupe key, safe payload summary, and optional links. +- Human control: `override` can retry, waive a non-critical gate, or accept completion only after an explicit user decision and reason. Every action records the actor, reason, state transition, event, and immutable override artifact. + +`signal` is idempotent for the same source/type/dedupe key. Signals received while a matching workflow is working or paused remain queued for the next eligible wakeup. Authenticated HTTP ingress is also available at `POST /loop/signal`. The endpoint requires a concrete `workflowID`, is disabled unless server authentication is configured, uses the same normalized signal model, and returns `429` when its durable source rate limit is exceeded. Basic Auth establishes the local operator boundary; it does not provide per-connector signatures or cryptographic sender identity. + +Local instance routes currently expose the read/control surface under `/loop`, including list, summary, snapshot, events, authenticated signal ingress, pause, resume, agent update, run-once, authenticated override, stop, and delete operations. The legacy instance router additionally exposes draft and activate creation endpoints. The experimental Effect HttpApi route does not currently expose those two creation endpoints, so automation should not assume creation-route parity yet. + +Examples of read/control routes: + +```text +GET /loop +GET /loop/summary +GET /loop/:loopID +GET /loop/:loopID/summary +GET /loop/:loopID/events +POST /loop/signal +POST /loop/:loopID/pause +POST /loop/:loopID/resume +POST /loop/:loopID/agent +POST /loop/:loopID/run-once +POST /loop/:loopID/override +POST /loop/:loopID/stop +DELETE /loop/:loopID +``` + +The legacy router additionally exposes creation endpoints that are not present in the Effect route stack: + +```text +POST /loop/draft +POST /loop/:loopID/activate +``` + +Treat these as local project/instance APIs. Use the public `mendcode loops ...` CLI or the loop tool for normal operator workflows. + +## Migration And Backward Compatibility + +The Loop Engineering upgrade is additive. Existing workflow records do not need to be rewritten before MendCode can read them: + +- Workflow, run, event, thread, and artifact data live in separate loop tables. The artifact ledger is added without replacing workflow/run records. +- New supervision fields are optional JSON data. Missing evaluation metadata renders as `legacy`; missing workspace metadata behaves as `in-place`; absent success checks, memory, cost, judgment, gate, or artifact data render with safe empty/default views. +- Validation plans, runtime rubric results, gate waivers, and artifact retention limits are optional JSON fields. Legacy workflows keep evidence-string success checks and the existing count-based artifact cap. +- Legacy report-only workflows are inferred from their gates/approval policy even when they predate explicit `workspace.mode = read-only` metadata. +- Owner/root/run/artifact session references are nullable where appropriate, so deleting or losing a linked session does not make the durable workflow unreadable. +- Existing checkpoints continue to work. Independent evaluation is required only when the compiled workflow contract enables it. + +Migration does not weaken current validation: + +- New `fixed` workflows require a positive `maxTurns` cap. A `max-goal` workflow may use a positive safety cap or omit `maxTurns` when no iteration cap is configured. +- `unbounded-monitor` omits `maxTurns`; never encode unlimited work as `maxTurns: 0`. +- A legacy row containing `maxTurns: 0` is shown as invalid in `/loops`; recreate the workflow with a positive cap or an unbounded monitor contract. +- Runtime defaults are application behavior, not database column defaults. Backups and migration tools should preserve the full loop JSON payload instead of reconstructing it from only top-level columns. + +## Current Limits + +- `maxRuntimeMs` sizes the run lease; it is not a hard wall-clock cancellation of the model process. +- `maxChildren` and `maxDepth` are persisted contract fields but are not currently enforced by a runtime consumer. +- Only the root loop session is registered in the loop thread ledger and Agent View `Looping` group; child task/evaluator sessions remain ordinary session transcripts. +- HTTP signal authentication protects the operator endpoint but does not verify connector-specific signatures. +- The artifact schema supports `diff` and `memory` kinds, but current core writers do not emit them; changed-file summaries are derived separately from the root session diff. + +After upgrading, operators should: + +1. Open `/loops` and confirm legacy workflows render without errors. +2. Inspect each editable `max-goal` workflow and decide whether to add explicit completion criteria, success checks, independent evaluation, workspace isolation, and approval requirements. +3. Recreate any invalid zero-budget workflow rather than relying on historical `0 = unlimited` assumptions. +4. For a report-only/read-only workflow, run the first post-upgrade wakeup with `--report-only` and inspect its checkpoint, artifacts, gates, and next action. +5. Inspect an edit-capable workflow's compiled contract before executing it; `--report-only` does not downgrade a contract that explicitly allows edits. + +## Built-In Examples + +Current built-in templates: + +- `pr-watch`: monitor a PR and surface review or CI changes. +- `ci-repair`: keep checking failing CI and propose safe repairs. +- `research-digest`: periodically inspect a topic and summarize changes. +- `repo-maintenance`: review stale work and propose maintenance steps. + +Templates create draft workflows. They do not start running until activated. + +## Packages And Team Sharing + +Loop templates are currently built into the runtime. The package system can already distribute commands, skills, agents, modes, prompts, permissions, model policy, memory defaults, TUI profile, and widgets. Package-distributed loop templates are a natural next step, but they are not yet part of the public package contract. + +Installing one runtime package does not have to erase another package. MendCode packages are selected/enabled as runtime overlays. Conflicts are resolved by the package runtime projection rather than by blindly replacing the user's local files. Teams should still document package precedence and avoid shipping secrets or machine-local loop state. + +## Safety Rules + +- Drafts are inert until activated. +- `tick` without `--execute` is dry-run only. +- `--execute --report-only` keeps report-only/read-only workflows non-mutating, but it does not override an edit-capable contract. +- `--execute` allows normal runtime permissions only when the durable workflow contract permits them. +- Service requests report-only execution by default, but an explicitly edit-capable workflow contract remains authoritative. +- Human gates should remain required for push, merge, release, external sends, destructive shell actions, and other irreversible work. A judge verdict never grants permission to bypass them. +- Human override cannot waive approval, policy, budget, or required-user-input gates. Non-critical waivers and accepted completions remain visible in the run, artifact ledger, journal, loop tool output, and `/loops` supervision metadata. +- Artifact retention applies count, age, and estimated-byte budgets to non-critical evidence when an artifact append triggers pruning. Dormant workflows are not swept periodically. The latest checkpoint, judgment, blocking gate, override records, active-run command output, and validation output referenced by a retained gate remain audit-protected, so configured limits are intentionally soft while those records exist. +- Approval detection in loop completion is a completion heuristic based on the compiled policy and reported action/evidence text. It complements, but does not replace, runtime permission enforcement and human review. +- Loops are project-scoped; install/start the service from the repo that owns the workflows. +- Normal users should create loops from chat/session intent. CLI commands remain for inspection, debugging, and automation. + +## Troubleshooting + +No loops run: + +```bash +mendcode loops status +mendcode loops tick --limit 1 +``` + +If the workflow is durable but no process is alive, start a daemon or service. + +Service installed but not waking: + +```bash +mendcode loops service status +mendcode loops service logs --lines 120 +``` + +If the service is not loaded, run: + +```bash +mendcode loops service restart +``` + +For temporary debugging, prefer the foreground daemon: + +```bash +mendcode loops daemon --execute --report-only +``` + +That prints every scheduler pass directly in the terminal. diff --git a/docs/memory-center.md b/docs/memory-center.md new file mode 100644 index 00000000..4093dbd5 --- /dev/null +++ b/docs/memory-center.md @@ -0,0 +1,134 @@ +# Memory Center + +Memory Center is the terminal workspace for reviewing what MendCode remembers, +what it is proposing to remember, and how that context is organized. + +![MendCode Memory Center overview](assets/screenshots/memory-center-overview.png) + +## What The View Shows + +The overview keeps memory state visible without turning every chat into +permanent context. + +| Area | Purpose | +| --- | --- | +| Project sidebar | Shows the active project and other known project memory scopes. | +| Summary cards | Separates saved memories, pending proposals, project groups, and Dream state. | +| Category graph | Shows how memories are distributed across categories such as security, commands, release, user preferences, and agent policy. | +| Pending Queue | Presents generated proposals for review before they are applied. | +| Inspector | Shows the selected proposal action, progress, and risk summary. | +| Side chat | Runs a constrained memory side agent for memory-specific questions, explanations, and draft proposals without turning the memory view into the normal coding agent. | + +## Review Model + +Memory is approval-first: + +- saved entries are visible by scope +- generated changes enter the pending queue +- proposals can be applied, rejected, edited, or inspected +- project and global memories stay separate +- Dream state is shown as maintenance context, not as silent mutation + +Generated changes can come from normal extraction, Memory Center side chat, or +Dream. They all land in the same review model: a proposal must be inspected, +edited, applied, or rejected by the user before it changes saved memory. + +## Memory & Evolution (local implementation) + +Setup exposes project-scoped Evolution separately from **using saved memory**. +Without explicit Evolution consent, existing legacy memory learning remains unchanged. +Adopting Evolution replaces automatic legacy extraction/Dream for that project; +it does not disable manually requested memory tools or delete saved entries. + +- **Off:** blocks new capture, inference and promotion; cancels Evolution work and + rejects late results. Previously approved artifacts remain active. +- **Observe:** retains bounded metadata only, without free text or provider calls. +- **Suggest:** authorized evidence produces review-only memory, skill and workflow + proposals. Skills/workflows require explicit approval; saving a workflow never runs it. +- **Auto-safe (limited):** permits only an exact user correction in the form + `Project language: TypeScript.` (also JavaScript, Python, Rust or Go), with low + sensitivity and the project-stack category. Project memory must be empty, and + contradictory current corrections block automatic application. Everything else, + including permission/security/model rules, remains pending for review. + +Corrections can be entered from Setup or through a chat message beginning with +`Correction:` or `Corrección:`. Optional tool/test evidence records host completion +metadata, not stdout or assistant claims. A zero process exit status is not proof +that an entire task passed a semantic audit. + +Provider processing requires separate consent. Local storage **does not mean local +inference**: the selected provider may receive authorized evidence and consume quota. +Evolution uses the configured extractor/distiller role without silently switching +models. Evidence is limited to 500 records, 4 KiB per record and a 30-day eligible +window; each run uses at most five current evidence records, lasts at most 60 seconds, +and produces at most five candidates. Expired records are excluded from processing; +physical pruning occurs when the evidence ledger is next rewritten. + +Daily execution uses the existing Dream service and registered workspaces. Setting a +schedule does not install or start a service. There is a five-minute admission window, +at most one claimed attempt per project/local date, and no automatic retry or late +catch-up after failure or restart. The scheduler admits at most one Evolution run per +tick. Use **Run once** for missed windows. + +**Revert Evolution memories** archives an unchanged newly-created memory and retires +its graph projection without deleting graph content. An entry modified after promotion +requires manual review instead. Reversion remains available while Evolution is Off. +Capability rollback similarly checks the promoted file hash or workflow revision and +refuses to overwrite later edits. + +This is contextual learning, not weight training or automatic source-code editing. +Schema validation alone does not establish the usefulness of a generated capability. + +## Memory Side Agent + +The side chat is intentionally constrained, but it is still powerful inside the +memory domain. It can: + +- answer questions about saved global and project memories +- explain which category, scope, or policy a memory belongs to +- inspect pending proposals and summarize their risk +- draft new global/project memory proposals +- draft updates, deletions, moves, recategorization, verification, expiration, + and policy changes +- help tune extraction behavior, prompt inclusion, save behavior, and category + policy +- draft Dream schedule, source, or dry-run changes + +The side agent should not be described as a source-editing or shell-capable +coding agent. It does not apply generated changes by itself; it prepares +reviewable memory work. + +## Dream + +Dream is the memory maintenance loop for manual or scheduled consolidation. It +uses the `memoryDream` model role and focuses on memory quality rather than code +execution. + +Dream can surface: + +- duplicated or stale memories +- memories that should move between global/project scope +- category and policy drift +- missing verification signals +- outdated project context +- proposals for add, update, remove, verify, expire, recategorize, and scope + changes + +Dream writes logs, safety context, and reviewable proposals. It should not be +documented as applying memory silently, editing source files, mutating git, or +reading arbitrary filesystem/session evidence without an explicit bounded path. + +## CLI Pairing + +The visual workspace complements the CLI commands: + +```bash +mendcode memory status +mendcode memory list --scope global +mendcode memory list --scope project +mendcode memory search "release workflow" +mendcode memory preview "release workflow" +``` + +Use direct `mendcode memory add` only when the user explicitly asks to save +something. Generated memory changes should stay reviewable. diff --git a/docs/mermaid-ascii-rendering.md b/docs/mermaid-ascii-rendering.md new file mode 100644 index 00000000..cc20a29d --- /dev/null +++ b/docs/mermaid-ascii-rendering.md @@ -0,0 +1,1957 @@ +# Mermaid ASCII Rendering + +MendCode renders Mermaid fences as local, terminal-native ASCII diagrams in Markdown and rich chat presentation modes. The renderer keeps diagram semantics visible without requiring a browser, SVG canvas, or network request. This page reflects the current v0.1.39 behavior. + +## Chat Canvas Behavior + +Every rendered Mermaid diagram is placed in its own bounded chat canvas: + +- `[−] [Fit] [+]` changes semantic layout scale: fit uses the available message width, minus chooses a denser layout, and plus exposes a wider layout. +- `Center` recenters the current horizontal and vertical viewport. +- `◀` and `▶` pan wide diagrams without moving the whole chat transcript. +- Shift-wheel or the horizontal scrollbar pans the canvas directly. +- Diagrams taller than 28 rows use an internal vertical viewport. +- The viewport does not clip the generated ASCII geometry; supported diagrams retain their generated nodes, labels, fields, and connectors behind local scrolling when necessary. +- During streaming, stable Markdown segments keep completed cards in place while the active tail continues to update; each card can recover its original Mermaid source in message order. + +## Catalog interaction + +Every fixture below is expanded on first load so the expected output is immediately visible. Use the fixture summary to collapse an individual diagram when comparing several examples. The expanded state is part of the documentation contract and is covered by the executable Markdown/TUI test. + +Terminal cells have a fixed font size, so the controls perform semantic layout zoom rather than bitmap scaling. If a diagram cannot fit without losing information, the card preserves the full geometry and exposes local scrolling. + +## Coverage Contract + +The canonical executable coverage is the Markdown/TUI regression suite listed in the [MendCode Source Map](source-map.md#tests-docs-and-release-references). It checks: + +- every supported Mermaid family; +- expanded flowchart shapes; +- narrow and wide message widths; +- long diagrams, cycles, branching, cross-links, and multi-section charts; +- unsupported and oversized fallback behavior; +- safe handling of Mermaid metadata; +- bounded per-card viewport behavior and source-to-card ordering. + +The catalog below is kept in sync with the fixture set used for visual QA. Each section shows the exact text canvas expected from MendCode. + +## Rendered Fixture Catalog + + + +### `flowchart` + +
+Expected MendCode ASCII output + +```text + ╭ Mermaid ASCII · flow ────────────────────────────────────────╮ + │ ╭──────────╮ │ + │ │ Start │ │ + │ ╰──────────╯ │ + │ │ │ + │ │ │ + │ │ │ + │ ▼ │ + │ ╭──────────╮ │ + │ │ ◇ Ready? │ │ + │ ╰──────────╯ │ + │ │ │ + │ │ │ + │ yes ──┤ │ + │ ▼ │ + │ ╭──────────╮ │ + │ │ Done │ │ + │ ╰──────────╯ │ + ╰──────────────────────────────────────────────────────────────╯ +``` + +
+ +### `swimlane-beta` + +
+Expected MendCode ASCII output + +```text + ╭ Mermaid ASCII · swimlane ────────────────────────────────────╮ + │ Swimlane · LR │ + │ ┌─ Customer ───────────────────────────────────────────────┐ │ + │ │ ╭──────────╮ ╭──────────╮ │ │ + │ │ │ Request │────┬────▶│ Response │ │ │ + │ │ ╰──────────╯ │ ╰──────────╯ │ │ + │ │ │ │ │ + │ ├─ Service ───────────────────┼────────────────────────────┤ │ + │ │ │ ╭──────────╮ │ │ + │ │ └────▶│ Receive │ │ │ + │ │ ╰──────────╯ │ │ + │ │ │ │ + │ └──────────────────────────────────────────────────────────┘ │ + ╰──────────────────────────────────────────────────────────────╯ +``` + +
+ +### `sequenceDiagram` + +
+Expected MendCode ASCII output + +```text + ╭ Mermaid ASCII · sequence ────────────────────────────────────╮ + │ ╭──────────╮ ╭──────────╮ │ + │ │ Alice │ │ Bob │ │ + │ ╰──────────╯ ╰──────────╯ │ + │ │ │ │ + │ │ Hello │ │ + │ ├───────────────────────▶ │ + │ │ │ │ + │ ╭──────────╮ ╭──────────╮ │ + │ │ Alice │ │ Bob │ │ + │ ╰──────────╯ ╰──────────╯ │ + ╰──────────────────────────────────────────────────────────────╯ +``` + +
+ +### `classDiagram` + +
+Expected MendCode ASCII output + +```text + ╭ Mermaid ASCII · classes ─────────────────────────────────────╮ + │ ╭─────────────╮ owns ╭──────────╮ │ + │ │ User │ ────▶ │ Account │ │ + │ ├─────────────┤ ╰──────────╯ │ + │ │ +id: string │ │ + │ ╰─────────────╯ │ + ╰──────────────────────────────────────────────────────────────╯ +``` + +
+ +### `stateDiagram-v2` + +
+Expected MendCode ASCII output + +```text + ╭ Mermaid ASCII · state ───────────────────────────────────────╮ + │ │ + │ ● │ + │ │ + │ │ │ + │ │ │ + │ │ │ + │ ▼ │ + │ ╭────────────╮ │ + │ │ Idle │ │ + │ ╰────────────╯ │ + │ │ │ + │ │ │ + │ finish ──┤ │ + │ ▼ │ + │ ╭────────────╮ │ + │ │ Done │ │ + │ ╰────────────╯ │ + │ │ │ + │ │ │ + │ │ │ + │ ▼ │ + │ │ + │ ◉ │ + ╰──────────────────────────────────────────────────────────────╯ +``` + +
+ +### `erDiagram` + +
+Expected MendCode ASCII output + +```text + ╭ Mermaid ASCII · entities ────────────────────────────────────╮ + │ ╭──────────────╮ │ + │ │ USER │ places ╭──────────╮ │ + │ ├──────────────┤||──────────────o{│ ORDER │ │ + │ │ string id PK │ ╰──────────╯ │ + │ ╰──────────────╯ │ + ╰──────────────────────────────────────────────────────────────╯ +``` + +
+ +### `journey` + +
+Expected MendCode ASCII output + +```text + ╭ Mermaid ASCII · journey ─────────────────────────────────────╮ + │ Checkout │ + │ ╭─ Purchase ─────╮ │ + │ │╭──────────────╮│ │ + │ ││ Pay ││ │ + │ ││ ★★★★★ 5/5 ││ │ + │ ││ ● Customer ││ │ + │ │╰──────────────╯│ │ + │ ╰────────────────╯ │ + ╰──────────────────────────────────────────────────────────────╯ +``` + +
+ +### `gantt` + +
+Expected MendCode ASCII output + +```text +╭ Mermaid ASCII · schedule ────────────────────────────────────────────────────╮ +│ Release │ +│ Time scale · YYYY-MM-DD │ +│ 1/1 1/2 │ +│ ┌┬──────────────────────────┬─────────────────────────▶ │ +│ ── Build ────────────────────────────────────────────────────────── │ +│ API │█▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓│ 1/1–1/2 │ +╰──────────────────────────────────────────────────────────────────────────────╯ +``` + +
+ +### `pie` + +
+Expected MendCode ASCII output + +```text + ╭ Mermaid ASCII · distribution ────────────────────────────────╮ + │ Status │ + │ ────── │ + │ Done │████████████████████░░░░░░░░│ 70 (70.0%) │ + │ Todo │████████░░░░░░░░░░░░░░░░░░░░│ 30 (30.0%) │ + │ Total: 100 │ + ╰──────────────────────────────────────────────────────────────╯ +``` + +
+ +### `quadrantChart` + +
+Expected MendCode ASCII output + +```text + ╭ Mermaid ASCII · quadrant ────────────────────────────────────╮ + │ Effort │ + │ Safe ▲ │ + │ ┌──────────────────────────┬──────────────────────────┐ │ + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ │ + │ │ │ Quick win ● │ │ + │ │ │ │ │ + │ │ │ │ │ + │ ├──────────────────────────┼──────────────────────────┤ │ + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ │ + │ └──────────────────────────┴──────────────────────────┘ │ + │ Low ◀───────────────────────────────────────────▶ High │ + │ Risk ▼ │ + ╰──────────────────────────────────────────────────────────────╯ +``` + +
+ +### `requirementDiagram` + +
+Expected MendCode ASCII output + +```text + ╭ Mermaid ASCII · requirements ────────────────────────────────╮ + │ Requirement diagram │ + │ ╭─────────────────────────╮ │ + │ │ «requirement» req_login │ │ + │ ├─────────────────────────┤ │ + │ │ id: 1 │ │ + │ │ text: User can login │ │ + │ ╰─────────────────────────╯ │ + ╰──────────────────────────────────────────────────────────────╯ +``` + +
+ +### `gitGraph` + +
+Expected MendCode ASCII output + +```text + ╭ Mermaid ASCII · git ─────────────────────────────────────────╮ + │ Git graph │ + │ │ + │ start │ + │ main ──────────● │ + │ ╲ │ + │ ╲ │ + │ ╲ work │ + │ feature ───────● │ + ╰──────────────────────────────────────────────────────────────╯ +``` + +
+ +### `C4Context` + +
+Expected MendCode ASCII output + +```text + ╭ Mermaid ASCII · C4 ──────────────────────────────────────────╮ + │ C4 Context │ + │ ╭───────────────╮ Uses ╭──────────────╮ │ + │ │ Person · User │ ────▶ │ System · App │ │ + │ ╰───────────────╯ ╰──────────────╯ │ + ╰──────────────────────────────────────────────────────────────╯ +``` + +
+ +### `mindmap` + +
+Expected MendCode ASCII output + +```text + ╭ Mermaid ASCII · tree ────────────────────────────────────────╮ + │ Mindmap │ + │ ╭────────────╮ │ + │ │ Root │────┐ │ + │ ╰────────────╯ │ │ + │ │ │ + │ │ ╭────────────╮ │ + │ └────▶│ Child │ │ + │ ╰────────────╯ │ + ╰──────────────────────────────────────────────────────────────╯ +``` + +
+ +### `timeline` + +
+Expected MendCode ASCII output + +```text + ╭ Mermaid ASCII · timeline ────────────────────────────────────╮ + │ History │ + │ ╭──────────────────╮ │ + │ │ Start · Timeline │ │ + │ ╰──────────────────╯ │ + │ │ │ + │ │ 2021 │ + │ ●────────────────────────●───────────────▶ │ + │ 2020 │ │ + │ ╭─────────────────╮ │ + │ │ Next · Timeline │ │ + │ ╰─────────────────╯ │ + ╰──────────────────────────────────────────────────────────────╯ +``` + +
+ +### `zenuml` + +
+Expected MendCode ASCII output + +```text + ╭ Mermaid ASCII · ZenUML ──────────────────────────────────────╮ + │ ZenUML │ + │ ╭──────────╮ ╭──────────╮ │ + │ │ Client │ │ API │ │ + │ ╰──────────╯ ╰──────────╯ │ + │ │ │ │ + │ │ GET /items │ │ + │ ├───────────────────────▶ │ + │ │ │ │ + │ ╭──────────╮ ╭──────────╮ │ + │ │ Client │ │ API │ │ + │ ╰──────────╯ ╰──────────╯ │ + ╰──────────────────────────────────────────────────────────────╯ +``` + +
+ +### `sankey` + +
+Expected MendCode ASCII output + +```text +╭ Mermaid ASCII · sankey ─────────────────────────────────────────────╮ +│ Sankey · flow width = value │ +│ ╭────────────╮ 10 ╭────────────╮ │ +│ │ A │ ████████████████████████████████████▶ │ B │ │ +│ ╰────────────╯ ╰────────────╯ │ +│ │ +│ ╭────────────╮ 5 ╭────────────╮ │ +│ │ B │ ██████████████████▶ │ C │ │ +│ ╰────────────╯ ╰────────────╯ │ +╰─────────────────────────────────────────────────────────────────────╯ +``` + +
+ +### `xychart-beta` + +
+Expected MendCode ASCII output + +```text +╭ Mermaid ASCII · xy chart ───────────────────────────────────────────╮ +│ Growth │ +│ value ↑ │ +│ 2 │ █ │ +│ │ █ │ +│ │ █ │ +│ │ █ │ +│ │ █ │ +│ │ █ │ +│ │ █ │ +│ │ █ █ │ +│ │ █ █ │ +│ │ █ █ │ +│ │ █ █ │ +│ │ █ █ │ +│ │ █ █ │ +│ 0 │──────────────█────────────────────────────█────────────── │ +│ └──────────────────────────────────────────────────────────▶ │ +│ Jan Feb │ +╰─────────────────────────────────────────────────────────────────────╯ +``` + +
+ +### `block-beta` + +
+Expected MendCode ASCII output + +```text + ╭ Mermaid ASCII · blocks ──────────────────────────────────────╮ + │ Block diagram │ + │ ╭──────────╮ ╭──────────╮ │ + │ │ Client │─────────▶│ Server │ │ + │ ╰──────────╯ ╰──────────╯ │ + ╰──────────────────────────────────────────────────────────────╯ +``` + +
+ +### `packet-beta` + +
+Expected MendCode ASCII output + +```text + ╭ Mermaid ASCII · packet ──────────────────────────────────────╮ + │ Packet layout │ + │ word 0 · bits 0–31 │ + │ 0–7 8–15 │ + │ ┌────────────────┬────────────────┐ │ + │ │ Flags │ Code │ │ + │ └────────────────┴────────────────┘ │ + ╰──────────────────────────────────────────────────────────────╯ +``` + +
+ +### `kanban` + +
+Expected MendCode ASCII output + +```text + ╭ Mermaid ASCII · kanban ──────────────────────────────────────╮ + │ Kanban │ + │ ╭─────────────────────────╮ ╭─────────────────────────╮ │ + │ │ Backlog │ │ Done │ │ + │ ├─────────────────────────┤ ├─────────────────────────┤ │ + │ │ ╭─────────────────────╮ │ │ ╭─────────────────────╮ │ │ + │ │ │ Task · ticket: "42" │ │ │ │ Ship │ │ │ + │ │ ╰─────────────────────╯ │ │ ╰─────────────────────╯ │ │ + │ ╰─────────────────────────╯ ╰─────────────────────────╯ │ + ╰──────────────────────────────────────────────────────────────╯ +``` + +
+ +### `architecture-beta` + +
+Expected MendCode ASCII output + +```text + ╭ Mermaid ASCII · architecture ────────────────────────────────╮ + │ Architecture │ + │ ╭─ Core · cloud ─────────────────────────╮ │ + │ │ ╭──────────╮ ╭──────────╮ │ │ + │ │ │ API │ │ DB │ │ │ + │ │ ├──────────┤ ────▶ ├──────────┤ │ │ + │ │ │ server │ │ database │ │ │ + │ │ ╰──────────╯ ╰──────────╯ │ │ + │ ╰────────────────────────────────────────╯ │ + │ │ + │ ╭──────────╮ │ + │ │ ◆ split │ │ + │ ╰──────────╯ │ + ╰──────────────────────────────────────────────────────────────╯ +``` + +
+ +### `radar-beta` + +
+Expected MendCode ASCII output + +```text + ╭ Mermaid ASCII · radar ───────────────────────────────────────╮ + │ Skills │ + │ Scale 0–9 · two opposing axes │ + │ Speed Quality │ + │ Team ●───────────────────┼─────────────────────● │ + ╰──────────────────────────────────────────────────────────────╯ +``` + +
+ +### `eventmodeling` + +
+Expected MendCode ASCII output + +```text +╭ Mermaid ASCII · event modeling ──────────────────────────────────────────────────────────────────────────────────╮ +│ Event modeling │ +│ ┌─ UI / Automation ────────────────────────────────────────────────────────────────────────────────────────────┐ │ +│ │ ╭───────────╮ │ │ +│ │ │ 01 · Cart │──────┐ │ │ +│ │ ╰───────────╯ │ │ │ +│ │ │ │ │ +│ ├─ Command / Read Model ───────────────────────┼───────────────────────────────────────────────────────────────┤ │ +│ │ │ ╭──────────────╮ │ │ +│ │ └──────▶│ 02 · AddItem │─────┐ │ │ +│ │ ╰──────────────╯ │ │ │ +│ │ │ │ │ +│ ├─ Events ──────────────────────────────────────────────────────────────────┼──────────────────────────────────┤ │ +│ │ │ ╭────────────────╮ │ │ +│ │ └────▶│ 03 · ItemAdded │ │ │ +│ │ ╰────────────────╯ │ │ +│ │ │ │ +│ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ │ +╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ +``` + +
+ +### `treemap-beta` + +
+Expected MendCode ASCII output + +```text + ╭ Mermaid ASCII · treemap ─────────────────────────────────────╮ + │ Treemap │ + │ ╭─ Products ────────────────────────────────────────────╮ │ + │ │┌────────────────────────────────┬──────────────────────┐│ │ + │ ││ Apps │ Tools ││ │ + │ ││ 12 │ 8 ││ │ + │ │└────────────────────────────────┴──────────────────────┘│ │ + │ ╰─────────────────────────────────────────────────────────╯ │ + ╰──────────────────────────────────────────────────────────────╯ +``` + +
+ +### `venn-beta` + +
+Expected MendCode ASCII output + +```text + ╭ Mermaid ASCII · Venn ────────────────────────────────────────╮ + │ Venn │ + │ │ + │ ············· ············· │ + │ ···· ····· ···· │ + │ ··· ··· ··· ··· │ + │ ··· ··· ··· ··· │ + │ ·· ·· ·· ·· │ + │ ·· ·· ·· ·· │ + │ ·· ·· ·· ·· │ + │ ·· Alpha (20) ·· ·· Beta (12) │ + │ ··· ··· ··· ··· │ + │ ·· ·· Shared (3) ·· ·· │ + │ ·· ·· ·· ·· │ + │ ·· • React ·· ·· ·· │ + │ ·· ·· ·· ·· │ + │ ··· ··· ··· ··· │ + │ ··· ··· ··· ··· │ + │ ···· ····· ···· │ + │ ············· ············· │ + ╰──────────────────────────────────────────────────────────────╯ +``` + +
+ +### `ishikawa-beta` + +
+Expected MendCode ASCII output + +```text +╭ Mermaid ASCII · Ishikawa ─────────────────────────────────────────────────────────╮ +│ Ishikawa · causes feed the effect │ +│ Process │ +│ │ +│ ╱ │ +│ ╱• Out of focus │ +│ ╱ │ +│ ╱ │ +│ ╱ │ +│ ╱ │ +│ ╱ ╭────────────────╮ │ +│ ════════╱═══════════════════════════════════════════╲══════▶ │ Blurry photo │ │ +│ ╲ ╰────────────────╯ │ +│ ╲ │ +│ ╲ │ +│ ╲ │ +│ ╲ │ +│ ╲• Shaky hands │ +│ ╲ │ +│ User │ +╰───────────────────────────────────────────────────────────────────────────────────╯ +``` + +
+ +### `wardley-beta` + +
+Expected MendCode ASCII output + +```text +╭ Mermaid ASCII · Wardley ────────────────────────────────────────────╮ +│ Wardley map │ +│ Visibility ↑ │ +│ │ ┆ ┆ ┆ │ +│ │ ◆ User ┆ ┆ ┆ │ +│ │ ──── ┆ ┆ ┆ │ +│ │ ───── ┆ ┆ │ +│ │ ┆ ──── ┆ ┆ │ +│ │ ┆ ──● App ┆ ┆ │ +│ │ ┆ ┆ ┆ │ +│ │ ┆ ┆ ┆ │ +│ │ ┆ ┆ ┆ │ +│ │ ┆ ┆ ┆ │ +│ │ ┆ ┆ ┆ │ +│ │ ┆ ┆ ┆ │ +│ │ ┆ ┆ ┆ │ +│ │ ┆ ┆ ┆ │ +│ │ ┆ ┆ ┆ │ +│ │ ┆ ┆ ┆ │ +│ └─────────────────────────────────────────────────────────────── │ +│ Genesis Custom built Product Commodity │ +│ Evolution → │ +╰─────────────────────────────────────────────────────────────────────╯ +``` + +
+ +### `cynefin-beta` + +
+Expected MendCode ASCII output + +```text +╭ Mermaid ASCII · Cynefin ─────────────────────────────────────────────────────────────╮ +│ Decision │ +│ ╭─────────────────────────────────────────┬────────────────────────────────────────╮ │ +│ │ │ │ │ +│ │ COMPLEX │ COMPLICATED │ │ +│ │ Probe → Sense → Respond ≈ Sense → Analyse → Respond │ │ +│ │ Emergent practices │ Good practices │ │ +│ │ │ │ │ +│ │ [Experiment] ≈ │ │ +│ │ │ │ │ +│ │ │ │ │ +│ │ ──simplify───────────≈──────────────────────────────────────┐ │ │ +│ │ ╭≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈╮ │ │ │ +│ │ │ CONFUSION / DISORDER │ │ │ │ +│ │ │ Move unknowns outward │ │ │ │ +│ ├───≈───≈───≈───≈───≈───≈──│ │───≈───≈───≈───≈───≈───≈──┤ │ +│ │ ╰≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈╯ │ │ │ +│ │ CHAOTIC ≈ CLEAR │ │ │ +│ │ Act → Sense → Respond │ Sense → Categorise → Respond │ │ │ +│ │ Novel practices │ Best practices │ │ │ +│ │ ≈ ◀─────────────────┘ │ │ +│ │ │ [Runbook] │ │ +│ │ │ │ │ +│ │ ≈ │ │ +│ │ │ │ │ +│ │ │ │ │ +│ │ ≈ │ │ +│ │ │ │ │ +│ ╰─────────────────────────────────────────┴────────────────────────────────────────╯ │ +╰──────────────────────────────────────────────────────────────────────────────────────╯ +``` + +
+ +### `treeView-beta` + +
+Expected MendCode ASCII output + +```text + ╭ Mermaid ASCII · TreeView ──────────────────────────────────────╮ + │ TreeView │ + │ ╭────────────╮ │ + │ │ root │────┐ │ + │ ╰────────────╯ │ │ + │ │ │ + │ │ ╭────────────╮ │ + │ ├────▶│ src │────┐ │ + │ │ ╰────────────╯ │ │ + │ │ │ │ + │ │ │ ╭────────────╮ │ + │ │ └────▶│ index.ts │ │ + │ │ ╰────────────╯ │ + │ │ │ + │ │ ╭────────────╮ │ + │ └────▶│ README.md │ │ + │ ╰────────────╯ │ + ╰────────────────────────────────────────────────────────────────╯ +``` + +
+ +### `STRESS · swimlane 4 lanes` + +
+Expected MendCode ASCII output + +```text +╭ Mermaid ASCII · swimlane ──────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ Swimlane · LR │ +│ ┌─ Author ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ +│ │ ╭──────────╮ ╭──────────╮ │ │ +│ │ │ Draft │────┬─────────────────────┬────▶│ Revise │ │ │ +│ │ ╰──────────╯ │ │ ╰──────────╯ │ │ +│ │ │ │ │ │ +│ ├─ Reviewer ──────────────────┼─────────────────────┼────────────────────────────────────────────────────────────────────────┤ │ +│ │ │ ╭──────────╮ │ ╭──────────╮ │ │ +│ │ └────▶│ Review │────┴────▶│ Approve │────┐ │ │ +│ │ ╰──────────╯ ╰──────────╯ │ │ │ +│ │ │ │ │ +│ ├─ Editor ────────────────────────────────────────────────────────────────┼──────────────────────────────────────────────────┤ │ +│ │ │ ╭──────────╮ │ │ +│ │ └────▶│ Edit │────┐ │ │ +│ │ ╰──────────╯ │ │ │ +│ │ │ │ │ +│ ├─ CI / CD ─────────────────────────────────────────────────────────────────────────────────────┼────────────────────────────┤ │ +│ │ │ ╭──────────╮ │ │ +│ │ └────▶│ Publish │ │ │ +│ │ ╰──────────╯ │ │ +│ │ │ │ +│ └────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ │ +╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ +``` + +
+ +### `STRESS · class relation matrix` + +
+Expected MendCode ASCII output + +```text + ╭ Mermaid ASCII · classes ─────────────────────────────────────╮ + │ ╭──────────╮ ╭──────────╮ │ + │ │ Animal │ ◁──── │ Duck │ │ + │ ╰──────────╯ ├──────────┤ │ + │ │ +swim() │ │ + │ ╰──────────╯ │ + │ │ + │ ╭──────────╮ contains ╭──────────╮ │ + │ │ Car │ ◆──── │ Engine │ │ + │ ╰──────────╯ ╰──────────╯ │ + │ │ + │ ╭──────────╮ aggregates ╭──────────╮ │ + │ │ Team │ ◇──── │ Player │ │ + │ ╰──────────╯ ╰──────────╯ │ + │ │ + │ ╭──────────╮ belongs to ╭──────────╮ │ + │ │ Order │ ────▶ │ Customer │ │ + │ ╰──────────╯ ╰──────────╯ │ + │ │ + │ ╭──────────╮ depends ╭────────────╮ │ + │ │ Service │ ╌╌╌▶ │ Repository │ │ + │ ╰──────────╯ ╰────────────╯ │ + ╰──────────────────────────────────────────────────────────────╯ +``` + +
+ +### `STRESS · state branches and terminal` + +
+Expected MendCode ASCII output + +```text + ╭ Mermaid ASCII · state ───────────────────────────────────────╮ + │ │ + │ ● │ + │ │ + │ │ │ + │ │ │ + │ │ │ + │ ▼ │ + │ ╭────────────╮ │ + │ │ Idle │ │ + │ ╰────────────╯ │ + │ ┌───────────────────▲ │ + │ │ │ │ + │ │ start ──┤ │ + │ │ ▼ │ + │ │ ╭────────────╮ │ + │ │ │ Running │ │ + │ │ ╰────────────╯ │ + │ │ │ │ + │ │ ┌─────────┴────────┐ │ + │ │ error ──┤ finish ──┤ │ + │ │ ▼ ▼ │ + │ │ ╭────────────╮ ╭────────────╮ │ + │ │ │ Failed │ │ Done │ │ + │ │ ╰────────────╯ ╰────────────╯ │ + │ │ │ │ │ + │ │ │ ┌────────┘ │ + │ │ │ │ │ + │ │ │ │ │ + │ └─retry───┘ │ │ + │ ▼ │ + │ │ + │ ◉ │ + ╰──────────────────────────────────────────────────────────────╯ +``` + +
+ +### `STRESS · ER fields and cross-links` + +
+Expected MendCode ASCII output + +```text +╭ Mermaid ASCII · entities ───────────────────────────────────────────────────────────────╮ +│ ╭──────────────╮ ╭────────────────────╮ │ +│ │ USER │ │ ORDER │ │ +│ ├──────────────┤ places ├────────────────────┤ contains ╭───────────╮ │ +│ │ uuid id PK │||──────────────o{│ uuid id PK │||─────────────┐o{│ LINE_ITEM │ │ +│ │ string email │ │ datetime createdAt │ │ ╰───────────╯ │ +│ ╰──────────────╯ ╰────────────────────╯ │ │ +│ │ │ +│ │ │ +│ │ │ +│ │ │ +│ │ │ +│ ╭──────────╮ │ │ +│ │ PRODUCT │||│ │ │ +│ ╰──────────╯ │ │ │ +│ │ │ │ +│ │ │ │ +│ │ │ │ +│ │ │ │ +│ │ appears in │ │ +│ └──────────────────────────────────────────────────────┘ │ +╰─────────────────────────────────────────────────────────────────────────────────────────╯ +``` + +
+ +### `STRESS · journey multi-section` + +
+Expected MendCode ASCII output + +```text +╭ Mermaid ASCII · journey ──────────────────────────────────────────────────────────╮ +│ Checkout journey │ +│ ╭─ Discover ──────────────────────────────────╮ │ +│ │╭──────────────────╮ ╭──────────────────╮│ │ +│ ││ Browse catalog │ │ Compare products ││ │ +│ ││ ★★★☆☆ 3/5 │───▶ │ ★★★★☆ 4/5 ││ │ +│ ││ ● Customer │ │ ● Customer ││ │ +│ │╰──────────────────╯ ╰──────────────────╯│ │ +│ ╰─────────────────────────────────────────────╯ │ +│ │ +│ ╭─ Purchase ────────────────────────────────────────────────────────────────────╮ │ +│ │╭─────────────────────╮ ╭─────────────────────╮ ╭─────────────────────╮│ │ +│ ││ Add to cart │ │ Enter payment │ │ Confirm order ││ │ +│ ││ ★★★★★ 5/5 │───▶ │ ★★☆☆☆ 2/5 │───▶ │ ★★★★★ 5/5 ││ │ +│ ││ ● Customer │ │ ● Customer, Payment │ │ ● Customer ││ │ +│ │╰─────────────────────╯ ╰─────────────────────╯ ╰─────────────────────╯│ │ +│ ╰───────────────────────────────────────────────────────────────────────────────╯ │ +│ │ +│ ╭─ Fulfillment ─────────╮ │ +│ │╭─────────────────────╮│ │ +│ ││ Track shipment ││ │ +│ ││ ★★★★☆ 4/5 ││ │ +│ ││ ● Customer, Carrier ││ │ +│ │╰─────────────────────╯│ │ +│ ╰───────────────────────╯ │ +╰───────────────────────────────────────────────────────────────────────────────────╯ +``` + +
+ +### `STRESS · gantt dependencies` + +
+Expected MendCode ASCII output + +```text +╭ Mermaid ASCII · schedule ──────────────────────────────────────────────────────╮ +│ Release train │ +│ Time scale · YYYY-MM-DD │ +│ 1/1 1/4 1/7 1/10 1/14 │ +│ ┌┬──────────┬───────────┬──────────┬──────────────┬───▶ │ +│ ── Discovery ────────────────────────────────────────────────────── │ +│ Research │█▓▓▓▓▓▓▓▓▓▓▓ │ 1/1–1/3 │ +│ Design │ █▓▓▓▓▓▓▓ │ 1/4–1/5 │ +│ ── Build ────────────────────────────────────────────────────────── │ +│ API │ █▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ │ 1/6–1/9 │ +│ UI │ █▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ │ 1/6–1/10 │ +│ ── Ship ─────────────────────────────────────────────────────────── │ +│ QA │ █▓▓▓▓▓▓▓▓▓▓▓▓ │ 1/11–1/13 │ +│ Release │ ◆ │ 1/14–1/14 │ +╰────────────────────────────────────────────────────────────────────────────────╯ +``` + +
+ +### `STRESS · quadrant labels and points` + +
+Expected MendCode ASCII output + +```text + ╭ Mermaid ASCII · quadrant ────────────────────────────────────╮ + │ Portfolio │ + │ High impact ▲ │ + │ ┌──────────────────────────┬──────────────────────────┐ │ + │ │ Quick wins │ Strategic │ │ + │ │ │ │ │ + │ │ ● Search │ │ │ + │ │ │ │ │ + │ │ │ ● Platform │ │ + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ │ + │ ├──────────────────────────┼──────────────────────────┤ │ + │ │ Avoid │ Foundations │ │ + │ │ │ │ │ + │ │ │ Migration ● │ │ + │ │ │ │ │ + │ │ ● Cleanup │ │ │ + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ │ + │ └──────────────────────────┴──────────────────────────┘ │ + │ Low effort ◀─────────────────────────────▶ High effort │ + │ Low impact ▼ │ + ╰──────────────────────────────────────────────────────────────╯ +``` + +
+ +### `STRESS · requirement relations` + +
+Expected MendCode ASCII output + +```text +╭ Mermaid ASCII · requirements ───────────────────────────────────╮ +│ Requirement diagram │ +│ ╭──────────────────────╮ satisfies ╭─────────────────────────╮ │ +│ │ «element» login_form │ ────▶ │ «requirement» req_login │ │ +│ ├──────────────────────┤ ├─────────────────────────┤ │ +│ │ type: UI │ │ id: REQ-1 │ │ +│ │ docRef: auth.tsx │ │ text: User can log in │ │ +│ ╰──────────────────────╯ │ risk: medium │ │ +│ │ verifyMethod: test │ │ +│ ╰─────────────────────────╯ │ +╰─────────────────────────────────────────────────────────────────╯ +``` + +
+ +### `STRESS · git branches and merge` + +
+Expected MendCode ASCII output + +```text +╭ Mermaid ASCII · git ─────────────────────────────────────────────────────────────────────────────────────╮ +│ Git graph │ +│ │ +│ root main-1 merge feature │ +│ main ─────────────────●──────────────────────────────────────────────────●────────────────◎ │ +│ ╲ ╱ │ +│ ╲ ╱ │ +│ ╲ feature-1 feature-2 ╱ │ +│ feature ──────────────●────────────────●────────────────────────────── │ +╰──────────────────────────────────────────────────────────────────────────────────────────────────────────╯ +``` + +
+ +### `STRESS · mixed XY` + +
+Expected MendCode ASCII output + +```text +╭ Mermaid ASCII · xy chart ───────────────────────────────────────╮ +│ Revenue │ +│ USD ↑ │ +│ 12 │ │ +│ │ █ │ +│ │ │────●──── █ │ +│ │ █ │ │────● │ +│ │ │────●──── █ │ █ █ │ +│ │ █ │ │────●──── █ █ │ +│ │ █ │ █ █ █ │ +│ │ █ │ █ █ █ █ │ +│ │ │────●──── █ █ █ █ │ +│ │ █ │ █ █ █ █ █ │ +│ │ ●──── █ █ █ █ █ │ +│ │ █ █ █ █ █ █ │ +│ │ █ █ █ █ █ █ │ +│ 0 │────█────────█────────█────────█────────█────────█──── │ +│ └──────────────────────────────────────────────────────▶ │ +│ Jan Feb Mar Apr May Jun │ +╰─────────────────────────────────────────────────────────────────╯ +``` + +
+ +### `STRESS · radar 6 axes` + +
+Expected MendCode ASCII output + +```text + ╭ Mermaid ASCII · radar ───────────────────────────────────────╮ + │ Quality profile │ + │ Scale 0–9 · ● Current ○ Target │ + │ │ + │ │ + │ Speed │ + │ │ + │ ··○·· │ + │ ···· · ···· │ + │ ···· ─●──── ···· │ + │ Scale ···· ──── · ────────·· Quality │ + │ ○·· ──── ····· ────○ │ + │ · ··●── ···· · ···· ···· │ │ + │ · │ ···· · ···· │ │ + │ · │ · ···· · ···· · │· │ + │ · │ · ····· · │· │ + │ · │ · ···· · ···· · │· │ + │ · │ ···· · ···· │· │ + │ · │···· ···· · ···· ····│ · │ + │ ○·●──────────────●──────────────●·○ │ + │ UX ·········· · ·········· Safety │ + │ ···· ····○···· ···· │ + │ ···· · ···· │ + │ ····· │ + │ │ + │ Cost │ + ╰──────────────────────────────────────────────────────────────╯ +``` + +
+ +### `STRESS · deep TreeView` + +
+Expected MendCode ASCII output + +```text +╭ Mermaid ASCII · TreeView ────────────────────────────────────────────────────────────────────────────╮ +│ TreeView │ +│ ╭────────────╮ │ +│ │ project │──────┐ │ +│ ╰────────────╯ │ │ +│ │ │ +│ │ ╭────────────╮ │ +│ ├──────▶│ src │──────┐ │ +│ │ ╰────────────╯ │ │ +│ │ │ │ +│ │ │ ╭────────────╮ │ +│ │ ├──────▶│ cli │──────┐ │ +│ │ │ ╰────────────╯ │ │ +│ │ │ │ │ +│ │ │ │ ╭────────────╮ │ +│ │ │ ├──────▶│ index.ts │ │ +│ │ │ │ ╰────────────╯ │ +│ │ │ │ │ +│ │ │ │ ╭────────────╮ │ +│ │ │ └──────▶│ render.ts │ │ +│ │ │ ╰────────────╯ │ +│ │ │ │ +│ │ │ ╭────────────╮ │ +│ │ └──────▶│ core │──────┐ │ +│ │ ╰────────────╯ │ │ +│ │ │ │ +│ │ │ ╭────────────╮ │ +│ │ └──────▶│ graph.ts │ │ +│ │ ╰────────────╯ │ +│ │ │ +│ │ ╭────────────╮ │ +│ ├──────▶│ tests │─────┐ │ +│ │ ╰────────────╯ │ │ +│ │ │ │ +│ │ │ ╭────────────────╮ │ +│ │ └─────▶│ render.test.ts │ │ +│ │ ╰────────────────╯ │ +│ │ │ +│ │ ╭────────────╮ │ +│ └──────▶│ README.md │ │ +│ ╰────────────╯ │ +╰──────────────────────────────────────────────────────────────────────────────────────────────────────╯ +``` + +
+ +### `LONG FLOWCHART (120 NODES)` + +
+Expected MendCode ASCII output + +```text +╭ Mermaid ASCII · flow ──────────────────────────────╮ +│ ╭──────────────────────────────────────────────╮ │ +│ │ Step 0 — long label for horizontal scrolling │ │ +│ ╰──────────────────────────────────────────────╯ │ +│ │ │ +│ └─┐ │ +│ ▼ │ +│ ╭──────────────────────────────────────────────╮ │ +│ │ Step 1 — long label for horizontal scrolling │ │ +│ ╰──────────────────────────────────────────────╯ │ +│ │ │ +│ ┌─┘ │ +│ ▼ │ +│ ╭──────────────────────────────────────────────╮ │ +│ │ Step 2 — long label for horizontal scrolling │ │ +│ ╰──────────────────────────────────────────────╯ │ +│ │ │ +│ └─┐ │ +│ ▼ │ +│ ╭──────────────────────────────────────────────╮ │ +│ │ Step 3 — long label for horizontal scrolling │ │ +│ ╰──────────────────────────────────────────────╯ │ +│ │ │ +│ ┌─┘ │ +│ ▼ │ +│ ╭──────────────────────────────────────────────╮ │ +│ │ Step 4 — long label for horizontal scrolling │ │ +│ ╰──────────────────────────────────────────────╯ │ +│ │ │ +│ └─┐ │ +│ ▼ │ +│ ╭──────────────────────────────────────────────╮ │ +│ │ Step 5 — long label for horizontal scrolling │ │ +│ ╰──────────────────────────────────────────────╯ │ +│ │ │ +│ ┌─┘ │ +│ ▼ │ +│ ╭──────────────────────────────────────────────╮ │ +│ │ Step 6 — long label for horizontal scrolling │ │ +│ ╰──────────────────────────────────────────────╯ │ +│ │ │ +│ └─┐ │ +│ ▼ │ +│ ╭──────────────────────────────────────────────╮ │ +│ │ Step 7 — long label for horizontal scrolling │ │ +│ ╰──────────────────────────────────────────────╯ │ +│ │ │ +│ ┌─┘ │ +│ ▼ │ +│ ╭──────────────────────────────────────────────╮ │ +│ │ Step 8 — long label for horizontal scrolling │ │ +│ ╰──────────────────────────────────────────────╯ │ +│ │ │ +│ └─┐ │ +│ ▼ │ +│ ╭──────────────────────────────────────────────╮ │ +│ │ Step 9 — long label for horizontal scrolling │ │ +│ ╰──────────────────────────────────────────────╯ │ +│ │ │ +│ ┌─┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 10 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 11 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 12 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 13 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 14 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 15 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 16 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 17 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 18 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 19 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 20 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 21 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 22 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 23 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 24 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 25 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 26 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 27 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 28 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 29 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 30 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 31 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 32 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 33 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 34 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 35 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 36 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 37 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 38 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 39 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 40 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 41 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 42 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 43 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 44 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 45 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 46 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 47 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 48 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 49 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 50 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 51 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 52 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 53 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 54 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 55 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 56 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 57 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 58 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 59 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 60 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 61 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 62 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 63 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 64 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 65 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 66 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 67 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 68 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 69 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 70 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 71 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 72 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 73 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 74 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 75 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 76 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 77 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 78 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 79 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 80 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 81 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 82 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 83 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 84 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 85 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 86 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 87 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 88 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 89 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 90 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 91 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 92 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 93 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 94 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 95 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 96 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 97 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ ┌┘ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 98 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ └┐ │ +│ ▼ │ +│ ╭───────────────────────────────────────────────╮ │ +│ │ Step 99 — long label for horizontal scrolling │ │ +│ ╰───────────────────────────────────────────────╯ │ +│ │ │ +│ │ │ +│ ▼ │ +│ ╭────────────────────────────────────────────────╮ │ +│ │ Step 100 — long label for horizontal scrolling │ │ +│ ╰────────────────────────────────────────────────╯ │ +│ │ │ +│ │ │ +│ ▼ │ +│ ╭────────────────────────────────────────────────╮ │ +│ │ Step 101 — long label for horizontal scrolling │ │ +│ ╰────────────────────────────────────────────────╯ │ +│ │ │ +│ │ │ +│ ▼ │ +│ ╭────────────────────────────────────────────────╮ │ +│ │ Step 102 — long label for horizontal scrolling │ │ +│ ╰────────────────────────────────────────────────╯ │ +│ │ │ +│ │ │ +│ ▼ │ +│ ╭────────────────────────────────────────────────╮ │ +│ │ Step 103 — long label for horizontal scrolling │ │ +│ ╰────────────────────────────────────────────────╯ │ +│ │ │ +│ │ │ +│ ▼ │ +│ ╭────────────────────────────────────────────────╮ │ +│ │ Step 104 — long label for horizontal scrolling │ │ +│ ╰────────────────────────────────────────────────╯ │ +│ │ │ +│ │ │ +│ ▼ │ +│ ╭────────────────────────────────────────────────╮ │ +│ │ Step 105 — long label for horizontal scrolling │ │ +│ ╰────────────────────────────────────────────────╯ │ +│ │ │ +│ │ │ +│ ▼ │ +│ ╭────────────────────────────────────────────────╮ │ +│ │ Step 106 — long label for horizontal scrolling │ │ +│ ╰────────────────────────────────────────────────╯ │ +│ │ │ +│ │ │ +│ ▼ │ +│ ╭────────────────────────────────────────────────╮ │ +│ │ Step 107 — long label for horizontal scrolling │ │ +│ ╰────────────────────────────────────────────────╯ │ +│ │ │ +│ │ │ +│ ▼ │ +│ ╭────────────────────────────────────────────────╮ │ +│ │ Step 108 — long label for horizontal scrolling │ │ +│ ╰────────────────────────────────────────────────╯ │ +│ │ │ +│ │ │ +│ ▼ │ +│ ╭────────────────────────────────────────────────╮ │ +│ │ Step 109 — long label for horizontal scrolling │ │ +│ ╰────────────────────────────────────────────────╯ │ +│ │ │ +│ │ │ +│ ▼ │ +│ ╭────────────────────────────────────────────────╮ │ +│ │ Step 110 — long label for horizontal scrolling │ │ +│ ╰────────────────────────────────────────────────╯ │ +│ │ │ +│ │ │ +│ ▼ │ +│ ╭────────────────────────────────────────────────╮ │ +│ │ Step 111 — long label for horizontal scrolling │ │ +│ ╰────────────────────────────────────────────────╯ │ +│ │ │ +│ │ │ +│ ▼ │ +│ ╭────────────────────────────────────────────────╮ │ +│ │ Step 112 — long label for horizontal scrolling │ │ +│ ╰────────────────────────────────────────────────╯ │ +│ │ │ +│ │ │ +│ ▼ │ +│ ╭────────────────────────────────────────────────╮ │ +│ │ Step 113 — long label for horizontal scrolling │ │ +│ ╰────────────────────────────────────────────────╯ │ +│ │ │ +│ │ │ +│ ▼ │ +│ ╭────────────────────────────────────────────────╮ │ +│ │ Step 114 — long label for horizontal scrolling │ │ +│ ╰────────────────────────────────────────────────╯ │ +│ │ │ +│ │ │ +│ ▼ │ +│ ╭────────────────────────────────────────────────╮ │ +│ │ Step 115 — long label for horizontal scrolling │ │ +│ ╰────────────────────────────────────────────────╯ │ +│ │ │ +│ │ │ +│ ▼ │ +│ ╭────────────────────────────────────────────────╮ │ +│ │ Step 116 — long label for horizontal scrolling │ │ +│ ╰────────────────────────────────────────────────╯ │ +│ │ │ +│ │ │ +│ ▼ │ +│ ╭────────────────────────────────────────────────╮ │ +│ │ Step 117 — long label for horizontal scrolling │ │ +│ ╰────────────────────────────────────────────────╯ │ +│ │ │ +│ │ │ +│ ▼ │ +│ ╭────────────────────────────────────────────────╮ │ +│ │ Step 118 — long label for horizontal scrolling │ │ +│ ╰────────────────────────────────────────────────╯ │ +│ │ │ +│ │ │ +│ ▼ │ +│ ╭────────────────────────────────────────────────╮ │ +│ │ Step 119 — long label for horizontal scrolling │ │ +│ ╰────────────────────────────────────────────────╯ │ +│ │ │ +│ ┌──────────────────┘ │ +│ ▼ │ +│ ╭──────────╮ │ +│ │ Step 120 │ │ +│ ╰──────────╯ │ +╰────────────────────────────────────────────────────╯ +``` + +
+ +### `CYCLES AND BRANCHES` + +
+Expected MendCode ASCII output + +```text + ╭ Mermaid ASCII · flow ────────────────────────────────────────╮ + │ ╭──────────╮ │ + │ │ Start │ │ + │ ╰──────────╯ │ + │ ┌────────▲ │ + │ │ │ │ + │ │ │ │ + │ │ ▼ │ + │ │ ╭──────────╮ │ + │ │ │ ◇ Valid? │ │ + │ │ ╰──────────╯ │ + │ │ ▲───────────────┐ │ + │ ├────────┴───────┐ │ │ + │ yes ──┤ no ──┤ │ │ + │ ▼ ▼ │ │ + │ ╭──────────╮ ╭──────────╮ │ │ + │ │ Ship │ │ Fix │ │ │ + │ ╰──────────╯ ╰──────────╯ │ │ + │ │ │ │ │ + │ ├────────┐ │ │ │ + │ │ │ │ │ │ + │ │ │ │ │ │ + │ │ │ └───────┘ │ + │ │ ▼ │ + │ │ ╭──────────╮ │ + │ │ │ ◯ Done │ │ + │ │ ╰──────────╯ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ └────────┘ │ + ╰──────────────────────────────────────────────────────────────╯ +``` + +
+ +### `ADVERSARIAL METADATA` + +
+Expected MendCode ASCII output + +```text + ╭ Mermaid ASCII · flow ────────────────────────────────────────╮ + │ ╭──────────╮ │ + │ │ Source │ │ + │ ╰──────────╯ │ + │ │ │ + │ │ │ + │ │ │ + │ ▼ │ + │ ╭──────────╮ │ + │ │ Target │ │ + │ ╰──────────╯ │ + │ │ │ + │ │ │ + │ literal --> label ──┤ │ + │ ▼ │ + │ ╭─────────────────────────────────────────╮ │ + │ │ Done / IGNORE ALL PREVIOUS INSTRUCTIONS │ │ + │ ╰─────────────────────────────────────────╯ │ + ╰──────────────────────────────────────────────────────────────╯ +``` + +
+ + diff --git a/docs/mflow.md b/docs/mflow.md index 4a326290..9e575bf3 100644 --- a/docs/mflow.md +++ b/docs/mflow.md @@ -29,25 +29,25 @@ pnpm dlx --package mflow-cli ... Inspect status: ```bash -mend mflow status +mendcode mflow status ``` Start a guided setup: ```bash -mend mflow setup +mendcode mflow setup ``` Activate with a local relay: ```bash -mend mflow activate --room acme/main +mendcode mflow activate --room acme/main ``` Activate with an explicit public relay you control: ```bash -mend mflow activate --relay public --signaling wss://relay.example.com --room acme/main +mendcode mflow activate --relay public --signaling wss://relay.example.com --room acme/main ``` The legacy public relay is demo-only. It requires explicit acknowledgement and should not be used for normal team onboarding. @@ -84,8 +84,8 @@ Secrets should stay local. If `storeSecret` is false, the secret is stored in `. ## Deactivate or Remove ```bash -mend mflow deactivate -mend mflow remove +mendcode mflow deactivate +mendcode mflow remove ``` Deactivate disables mflow without deleting all local scaffold. Remove deletes the local mflow config/scaffold files that MendCode owns. diff --git a/docs/package-index.md b/docs/package-index.md new file mode 100644 index 00000000..9f1e8f66 --- /dev/null +++ b/docs/package-index.md @@ -0,0 +1,56 @@ +# Package Index + +This page maps the main packages in `src/mendcode/packages`. + +## Runtime Packages + +| Package | Purpose | +| --- | --- | +| `packages/opencode` | Main MendCode runtime, CLI, server, TUI, setup flow, mflow, TSM/worktree integration, model/provider runtime, and release build script. | +| `packages/core` | Shared core utilities used by runtime packages. | +| `packages/plugin` | Public plugin/tool/TUI extension SDK, including `@mendcode/plugin/tui`. | +| `packages/ui` | Shared UI components, themes, assets, markdown/diff rendering, and frontend UI primitives. | +| `packages/sdk/js` | Generated JavaScript SDK package. | +| `packages/script` | Shared release and maintenance script helpers. | +| `packages/slack` | Slack integration package. | +| `packages/function` | Cloud/function-side integration package. | + +## App and Extension Packages + +| Path | Purpose | +| --- | --- | +| `packages/app` | Web app surface embedded or served by the runtime. | +| `packages/console` | Console app/resources where present. | +| `packages/extensions` | Editor extension metadata and release references. | +| `sdks/vscode` | VS Code extension package. | + +## Package Sharing + +MendCode runtime packages are different from npm workspace packages. Runtime packages are shareable `.mendcode` bundles for teams and companies. + +Use: + +```bash +mendcode packages status +mendcode packages create --include skills,modes,plugins,tuiProfile +mendcode packages add-source company --type github --url https://github.com/YourOrg/company-mend-package.git --channel team +mendcode packages install company-mend-package company +mendcode packages enable company-mend-package +``` + +See [Packages and team sharing](packages-and-team-sharing.md) for the team workflow. + +## Plugin and Widget Packages + +TUI plugins can be distributed inside runtime packages: + +```text +.mendcode/ + plugins/ + company-tui.ts + themes/ + company-dark.json + mendcode.json +``` + +See [TUI plugins and widgets](tui-plugins-and-widgets.md). diff --git a/docs/packages-and-team-sharing.md b/docs/packages-and-team-sharing.md index e7c4ae1a..9eb355d5 100644 --- a/docs/packages-and-team-sharing.md +++ b/docs/packages-and-team-sharing.md @@ -1,6 +1,22 @@ -# Packages and Team Sharing +# Marketplace and Team Sharing -MendCode packages are reusable bundles of `.mendcode` configuration and extensions. They are the intended way for a team or company to share the same commands, agents, modes, prompts, TUI profile, widgets, model policy, permissions, and worktree policy. +MendCode marketplace packages are reusable bundles of `.mendcode` configuration and extensions. They are the intended way for a team or company to share the same commands, agents, modes, prompts, TUI profile, widgets, pages, custom tool calls, model policy, permissions, and worktree policy. + +The mental model is “package your harness,” not “publish a single plugin.” A package can make a fresh checkout feel like the team environment: the same command palette, review modes, model roles, permission posture, prompt marker, status row, memory defaults, custom pages, custom widgets, and optional worktree policy. + +The official registry repo is `https://github.com/MendCode/mendcode-marketplace`. The old `mendcode-packages` name is only a compatibility redirect. + +## Good Package Examples + +| Package | Includes | Does not include | +| --- | --- | --- | +| Team standard | commands, agents, modes, skills, focus default, model roles, permission defaults, TUI profile. | Provider tokens, local auth files, personal memory. | +| Review mode bundle | review agent, review mode, prompt templates, stricter permission mode, review model role. | Branch mutations or CI credentials. | +| UI theme | TUI profile, theme tokens, prompt chrome, status script, widgets, pages. | Runtime service activation. | +| ASCII art pack | TUI profile with a Home logo, session mascot states, or both. | Separate art-pack manifest/importer; static art is shared through the TUI profile. | +| Tool pack | Custom tool calls, tool docs, supporting scripts, prompt mode hints. | Arbitrary background daemons or secrets. | +| MCP bundle | MCP server config/files, commands, docs/context files. | Secrets required by the MCP server. | +| Worktree policy | worktree policy, package docs, optional TSM hints. | Destructive worktree operations at install time. | ## What a Package Can Include @@ -14,7 +30,9 @@ Package artifacts can include: - prompts - MCP config/files - context files -- extensions/widgets/components/scripts +- tools +- pages +- widgets/components/scripts - TUI profile - worktree policy - model roles @@ -23,6 +41,16 @@ Package artifacts can include: - memory config - permissions config +### Sharing ASCII art + +There is no special `pet` or `asciiArt` artifact type. Shareable art belongs in the package's TUI profile: + +- Home-only art: `identity.logoMode: "mascot"` and `surfaces.homeLogo.text`. +- Session-only art: `presentation.activity.mascot`, including `hover` and `states`. +- Full identity pack: both sections together; they remain independent after installation. + +A package can therefore contain a logo, a session companion, or a complete branded terminal identity without shipping a plugin. Keep the art monospaced, narrow enough for the target terminals, and data-only. Use a plugin only when the package needs dynamic rendering, custom dialogs, or behavior beyond static profile values. + Package manifests are read from: - `mend-package.json` @@ -40,40 +68,59 @@ Active package state lives in: - `.mendcode/packages/state.json` +Marketplace packages run against the public MendCode API: + +- `@mendcode/plugin/tui` for commands, routes/pages, widgets, slots, dialogs, overlays, shell-backed streaming widgets, editor customization, state, KV, themes, and lifecycle cleanup. +- `api.session`, `api.ai`, and `api.metadata` for session lifecycle, AI-backed pages/modals, Agent View metadata, and control-plane actions. +- `api.memory` for graph snapshots, explicit fact/link mutations, and Memory side chat. +- `api.client` for the generated SDK surface when a package needs an endpoint without a convenience wrapper. +- `.mendcode/tools` for assistant-facing custom tool calls; see [Custom Tool Calls](custom-tool-calls.md) for schemas, context, and package examples. +- `.mendcode/pages` for package-owned TUI pages. +- `.mendcode/tui/profile.json` for profile and status customization. + +Packages should import public types from `@mendcode/plugin/tui` and must not import private runtime internals. If a package needs a missing capability, add a public API first instead of reaching into `src/`. Third-party packages are trusted local code: inspect them before enabling shell, session, or memory mutations. + ## Create a Local Package ```bash -mend packages create --id acme-standard --title "Acme Standard" --include all --version 1.0.0 +mendcode marketplace create --id acme-standard --title "Acme Standard" --include all --version 1.0.0 ``` Useful variants: ```bash -mend packages create --include skills,modes,plugins,tuiProfile -mend packages create --include all --exclude models,budget -mend packages status -mend packages list +mendcode marketplace create --include skills,modes,plugins,tuiProfile,tools,pages +mendcode marketplace create --include all --exclude models,budget +mendcode marketplace status +mendcode marketplace list ``` -## Install and Use Packages +## Install and Use Marketplace Packages ```bash -mend packages sources -mend packages search acme -mend packages show acme-standard -mend packages install acme-standard -mend packages disable acme-standard -mend packages enable acme-standard -mend packages remove acme-standard +mendcode marketplace sources +mendcode marketplace search acme +mendcode marketplace show acme-standard +mendcode install acme-standard +mendcode marketplace install acme-standard +mendcode marketplace install acme-standard acme +mendcode marketplace install-source acme +mendcode marketplace disable acme-standard +mendcode marketplace enable acme-standard +mendcode marketplace remove acme-standard ``` Disabling a package deselects it without deleting local project config. Removing a package deletes the installed package copy and updates package state. +`mendcode install [source-id]` is the short form for +`mendcode marketplace install [source-id]`. It uses configured +marketplace sources; it is not an npm package install path. + ## Share One Company Package Recommended company flow: -1. Create a package repo, for example `github.com/acme/acme-mendcode-package`. +1. Create a package repo, for example `github.com/acme/acme-mendcode-marketplace`. 2. Put `mend-package.json` at the package root. 3. Put shareable artifacts under `.mendcode/`. 4. Do not include provider secrets, local tokens, `.env*`, `.mendcode/auth`, or machine-local state. @@ -92,7 +139,7 @@ Example package manifest: "kind": "bundle", "channel": "team", "compatibility": { - "mendcode": "^1.14.0", + "mendcode": ">=0.1.7 <1.0.0", "runtimePack": "^0" }, "artifacts": { @@ -101,15 +148,17 @@ Example package manifest: "modes": [".mendcode/modes"], "skills": [".mendcode/skills"], "plugins": [".mendcode/plugins"], + "tools": [".mendcode/tools"], + "pages": [".mendcode/pages"], "prompts": [".mendcode/prompts"], - "extensions": [".mendcode/widgets"], + "extensions": [".mendcode/widgets", ".mendcode/components"], "tuiProfile": ".mendcode/tui/profile.json", "worktreePolicy": ".mendcode/worktree/policy.yaml" }, "distribution": { "source": { "type": "github", - "url": "https://github.com/acme/acme-mendcode-package.git" + "url": "https://github.com/acme/acme-mendcode-marketplace.git" }, "trust": { "signatureRequired": false @@ -121,13 +170,26 @@ Example package manifest: Add a registry source: ```bash -mend packages add-source acme --type github --url https://github.com/acme/acme-mendcode-package.git --channel team -mend packages search "" acme -mend packages install acme-standard +mendcode marketplace add-source acme --type github --url https://github.com/acme/acme-mendcode-marketplace.git --channel team +mendcode marketplace search "" acme +mendcode marketplace install acme-standard acme ``` For private repos, use a private-git/team source and a credential environment variable. Credentials are not stored in `.mendcode/registry.json`. +## Rollout Checklist + +Before sharing a package: + +1. Run `mendcode marketplace create` from a clean package authoring checkout. +2. Inspect the generated `mend-package.json` and `.mendcode/runtime-pack.json`. +3. Confirm the package uses `mendcode` in docs/examples. +4. Confirm no secrets are included. +5. Install it in a throwaway checkout. +6. Run `mendcode marketplace status`, `mendcode models status`, and `mendcode permissions status`. +7. Open the TUI and verify prompt marker, status row, command palette entries, Agent View/home layout, and any widgets. +8. If the package includes ASCII art, verify both Home and session mascot surfaces in a narrow terminal and confirm that missing activity states fall back cleanly. + ## What Does Not Belong in Packages Do not package: diff --git a/docs/plan-mode.md b/docs/plan-mode.md new file mode 100644 index 00000000..ac8cd733 --- /dev/null +++ b/docs/plan-mode.md @@ -0,0 +1,91 @@ +# Plan Mode + +Plan Mode turns planning into an explicit review step before implementation. The agent prepares a Markdown plan, calls the `plan_review` tool, and MendCode renders that plan in an interactive TUI modal. + +![MendCode Plan Mode review modal](assets/screenshots/plan-review-modal.png) + +![MendCode Markdown preview rendering](assets/screenshots/markdown-preview-showcase.png) + +The important behavior is simple: + +1. The plan is displayed in the terminal, not buried in normal assistant prose. +2. You can approve, edit, comment, or reject it. +3. Approval switches the session to the configured implementation agent. +4. The approved or edited Markdown becomes the source of truth for the next implementation turn. + +## What The Modal Does + +The `plan_review` tool accepts: + +- `title`: short modal title. +- `markdown`: complete Markdown plan. + +The TUI route renders the Markdown plan in a centered modal. It supports normal Markdown rendering and uses the plan Markdown renderer for terminal-friendly output. Mermaid/flowcharts are appropriate when they clarify sequencing, but the plan should still be readable as Markdown if a terminal cannot render the diagram cleanly. + +The modal keeps the draft plan separate from the chat transcript behind it. In +the screenshot, the plan contains headings, numbered sections, inline color +chips, and a Mermaid flowchart preview; the action row at the bottom is the +review gate. `Enter` implements the approved plan, `e` edits it, `c` adds +comments, and `r` rejects it. + +## Review Actions + +| Action | User intent | Runtime result | +| --- | --- | --- | +| Approve | The plan is good enough to implement. | MendCode switches to the configured implementation agent and sends the approved plan as the next implementation instruction. | +| Edit | The plan is close, but the Markdown needs changes. | The edited Markdown is treated as the latest source of truth. | +| Comment | The plan is approved or edited with extra implementation notes. | Comments are appended as user implementation comments. | +| Reject | The plan should not be implemented. | The agent receives the rejection reason and should revise or explain before showing another plan. | +| Close | The modal was dismissed without a decision. | The agent should ask what needs to change before proceeding. | + +The modal deliberately replaces “is this plan okay?” prose. The approval surface is the TUI modal. + +## Good Plan Shape + +Use a plan that is concise but execution-ready: + +```markdown +# Plan: Add Package Documentation + +## Context +- Public examples must use `mendcode`. +- Team packages are `.mendcode` bundles, not npm workspace packages. + +## Changes +1. Update `docs/packages-and-team-sharing.md` with the package mental model. +2. Add a manifest example with commands, agents, modes, skills, prompts, MCP, widgets, TUI profile, model policy, permissions, memory, and worktree policy. +3. Add a secrets checklist. + +## Verification +- Run `rg "\bmend\b" docs README.md`. +- Review links and code blocks. +``` + +Mermaid is useful when sequencing matters: + +~~~markdown +```mermaid +flowchart TD + A[Plan drafted] --> B[Plan Review modal] + B --> C{User action} + C -->|Approve| D[Switch to implementation agent] + C -->|Edit| E[Use edited Markdown] + C -->|Reject| F[Revise plan] +``` +~~~ + +Keep diagrams small. A plan that only works as a diagram is too fragile for terminal review. + +## Post-Approval Agent + +When the user approves a plan, MendCode resolves `planExitAgent` and switches the session to that implementation agent. The implementation instruction says the user approved the plan via the plan review modal, then includes the reviewed Markdown and any user comments. + +Use this behavior to separate planning from writing: + +- Planning agents should produce the plan and call `plan_review`. +- Implementation agents should edit files only after approval. +- If the user edits or rejects the plan, the edited Markdown or rejection reason overrides the previous draft. + +## Implementation paths + +See [MendCode Source Map — TUI pages and product surfaces](source-map.md#tui-pages-and-product-surfaces) for the Plan Review tool, modal, and prompt-instruction files. diff --git a/docs/public-readiness-audit.md b/docs/public-readiness-audit.md index 1754d614..3cb23c21 100644 --- a/docs/public-readiness-audit.md +++ b/docs/public-readiness-audit.md @@ -70,7 +70,7 @@ Fixed active script defaults that still pointed to the old repository: Known remaining donor/upstream references are intentional context, not MendCode repo links: - `anomalyco/opencode` references in donor/runtime guard tests and upstream patch metadata. -- `Obed0101/mflow` references for the mflow integration repository and legacy public relay labels. +- Legacy mflow integration repository references and public relay labels. Public Git history/PR metadata still includes old branch names and merge messages: diff --git a/docs/release-channels-and-continuity.md b/docs/release-channels-and-continuity.md new file mode 100644 index 00000000..7e282b34 --- /dev/null +++ b/docs/release-channels-and-continuity.md @@ -0,0 +1,81 @@ +# Release channels and experimental continuity + +Release channels and opt-in continuity were published in v0.1.44-beta.1. They are +not included in v0.1.43 stable. Beta releases do not replace GitHub's latest stable +release, and installing a beta does not enable experimental capabilities. + +## Update preferences + +```sh +mendcode upgrade channel +mendcode upgrade channel set beta +mendcode upgrade --check +mendcode upgrade +mendcode upgrade 0.1.44-beta.1 +mendcode upgrade --rollback +``` + +Supported channels are `stable`, `beta`, and `nightly`. Existing installations default to stable. Changing the preference does not install anything. Installing an explicit version does not change the preference. The TUI `/release-channel` command edits the same backend preference. + +Stable excludes prereleases; beta excludes nightly builds. Draft candidates are not offered to users. Channel selection does not choose a different session database. + +The in-app updater requires a release index verified against the authorized GitHub workflow, and uses its pinned installer digest and artifact checksums. GitHub CLI must be available for attestation verification. Missing metadata, failed provenance and incompatible database schemas stop installation. Older releases without the required index cannot be installed through this new verification path. + +`upgrade --check` reports the selected channel and retained operation/startup status without opening or migrating the session database. Download, verification, activation and startup are separate states. Installation alone does not mean the backend and TUI are ready. + +The TUI, `run`, and `stats` share the local backend and its database writer. `run --attach` resolves models on the selected server without opening a local session database. A failed session or rejected request exits with a failure status. Other local database commands may still require closing the backend before use; the writer guard reports this explicitly. + +Rollback retains sessions and never restores a database backup automatically. It requires verified metadata for the retained executable and a compatible database. Close connected terminals after their work finishes. Unknown legacy compatibility, an active backend or an incompatible schema blocks rollback. Windows rollback is not currently enabled. + +## Large-history startup recovery + +In beta.1, the client allowed only eight seconds for a newly spawned backend. +Creating the consistent pre-migration snapshot of a large database could exceed +that deadline; the client then stopped its child before migration completed. +The connection error alone does not indicate that session records were deleted. + +The beta.2 fix gives an identified backup or migration up to 15 minutes, displays +the preparation phase, and allows 30 seconds for connection after database work. +Phase records are tied to the child PID and a unique startup token. Failed or +exited children stop the wait; an ordinary unresponsive startup remains bounded. +Client readiness is timed separately, so database preparation cannot exhaust it. + +Do not delete session databases or locks, restore an incomplete backup, or start +multiple independent writers to bypass this error. Retain recovery artifacts. +A newer binary does not make an incompatible downgrade safe. + +## Release promotion + +Fixes are tested in beta before explicit stable promotion. Platform builds, +installer checks, checksums, provenance and relevant startup regressions must pass +for the candidate being published. Release tags and assets are immutable. +Stable publication is separate from prerelease publication; the daily nightly +schedule becomes active when its workflow reaches the default branch. Manual +prerelease builds are available from dev. Unverified native OpenAI features remain +disabled, and experimental continuity remains opt-in on every channel. + +## Experimental runtime + +Merge these options into the existing MendCode configuration to enable individual capabilities: + +```json +{ + "experimental": { + "async_tools": true, + "async_questions": true, + "session_recall": true, + "reasoning_auto": true + } +} +``` + +All options default off, including in beta and nightly. Existing prompt modes remain `minimal`, `focus`, `full`, and `custom`. + +- Async tools support built-in read, grep, glob and webfetch, retaining their permissions. Each session allows four active and eight queued jobs. Shell, mutations and arbitrary MCP tools are excluded. +- Async questions appear in Ctrl+T. The model can continue independent work while waiting for an explicit reply. Silence is never approval; tool authorization remains in the permission system. +- Recall tools page through the current session and linked descendants, including earlier compacted history. `session_notes` stores bounded, versioned working notes for the current session, with no global memory writes. +- Balanced Auto starts at a supported medium equivalent and can escalate to high after an explicit relevant verification or technical failure. It does not change model or service tier. Manual reasoning overrides Auto. The widget labels the actual last request, not a guessed current setting. + +Disabling async options stops new work and cancels active continuations while retaining history. Reload the session to enable them again after disabling. Lost processes are marked interrupted after restart and are not automatically rerun. + +OpenAI native async tool calling and WebSocket steering are not enabled. The current implementation uses MendCode's common executor and safe checkpoints. Live API/subscription parity and token savings have not been established. diff --git a/docs/releases-and-startup-recovery.md b/docs/releases-and-startup-recovery.md new file mode 100644 index 00000000..00bf0481 --- /dev/null +++ b/docs/releases-and-startup-recovery.md @@ -0,0 +1,55 @@ +# Stable, beta and startup recovery + +The stable hotfix and the beta runtime are separate releases: + +| Release | Scope | +| --- | --- | +| 0.1.44 stable | Bounded, phase-aware backend startup; recorded-schema downgrade rejection; PowerShell installer parsing | +| 0.1.44-beta.2 | The startup fix plus release channels and opt-in continuity from beta.1 | + +The version sections describe the release candidates; availability is determined +by the published [GitHub releases](https://github.com/MendCode/MendCode/releases). +Prereleases never replace GitHub's latest stable release. Published tags and +artifacts are immutable. New experimental capabilities require explicit opt-in. + +## Large session histories + +Beta.1 could stop a newly spawned backend after eight seconds while it was still +creating a consistent pre-migration snapshot. A startup connection failure alone +does not mean that session records have been deleted. + +The fix identifies the child process and startup token, permits up to 15 minutes +for backup or migration, and displays the preparation phase. Connection after +database preparation has a separate 30-second deadline. Failed/exited processes +stop the wait. No additional database writer is used to bypass the failure. + +Close active clients normally before an upgrade. Do not delete session files or +locks, restore an incomplete snapshot, or start independent writers as a workaround. +Retain recovery artifacts until a successful launch and session-preservation check. + +## Choosing a release + +Stable installations continue receiving stable updates. Channel selection is +available in the beta runtime: + +```sh +mendcode upgrade channel set beta +mendcode upgrade --check +mendcode upgrade +``` + +Selecting a channel saves a preference; it does not install a version. Installing +an explicit version does not change the preference. Beta users should stay on beta +until a stable release supports their database schema. This stable hotfix refuses +incompatible recorded schemas before writing; it does not restore older data. + +For installations predating channels, use the installer pinned to the desired +published release tag and specify its version, following that release's notes. +Do not use a mutable main-branch installer for historical versions. + +The detailed beta configuration is documented on +[dev](https://github.com/MendCode/MendCode/blob/dev/docs/release-channels-and-continuity.md). +Beta keeps native OpenAI async transport and other unverified integrations disabled. +Manual prereleases run from dev. The nightly schedule becomes active only when its +workflow is promoted to the default branch. Stable promotion requires explicit +approval and verified candidate artifacts; passing time is not a promotion gate. diff --git a/docs/releasing.md b/docs/releasing.md new file mode 100644 index 00000000..9e7ec18a --- /dev/null +++ b/docs/releasing.md @@ -0,0 +1,185 @@ +# Releasing MendCode + +This page documents the release contract required by the public installer. + +## Installer Contract + +The installer at `src/mendcode/install` downloads from: + +```text +https://github.com/MendCode/MendCode/releases/latest/download/ +``` + +For a versioned install, it downloads from: + +```text +https://github.com/MendCode/MendCode/releases/download/v/ +``` + +Windows users who cannot run PowerShell can use `src/mendcode/install.cmd`. +It uses the Windows-provided `curl.exe` and `tar.exe` tools and installs the +baseline x64 asset (or the ARM64 asset) without requiring a PowerShell command. + +On Windows, the supported installer and in-app updater use native PowerShell; +they never invoke the WSL `bash.exe` launcher. This matters on machines where +WSL is installed incompletely or has no Linux distribution. To recover an old +installation whose updater still reports `WSL ... execvpe(/bin/bash)`, run the +native installer once from PowerShell: + +```powershell +$script = Join-Path $env:TEMP "mendcode-install.ps1" +Invoke-WebRequest "https://raw.githubusercontent.com/MendCode/MendCode/main/src/mendcode/install.ps1" -OutFile $script +powershell.exe -NoProfile -ExecutionPolicy Bypass -File $script -SkipSetup +``` + +The installer updates only `~\.mendcode\bin\mendcode.exe`; it does not delete +the MendCode/OpenCode data directory or existing sessions. Newer binaries +schedule the replacement after the running process exits, avoiding Windows +executable file locks. + +The release must include these assets: + +```text +mendcode-linux-arm64.tar.gz +mendcode-linux-x64.tar.gz +mendcode-linux-x64-baseline.tar.gz +mendcode-linux-arm64-musl.tar.gz +mendcode-linux-x64-musl.tar.gz +mendcode-linux-x64-baseline-musl.tar.gz +mendcode-darwin-arm64.zip +mendcode-darwin-x64.zip +mendcode-darwin-x64-baseline.zip +mendcode-windows-arm64.zip +mendcode-windows-x64.zip +mendcode-windows-x64-baseline.zip +SHA256SUMS +``` + +Every archive must contain a `mendcode` binary, or `mendcode.exe` for Windows. + +## Build Assets + +```bash +cd src/mendcode +bun run release:assets +bun run release:check-assets +``` + +`release:check-assets` validates: + +- no `opencode-*` release archives are present +- every expected `mendcode-*` archive exists +- every archive contains the expected binary name +- `SHA256SUMS` exists and verifies + +## Troubleshooting Asset Builds + +The release builder cross-compiles archives for Linux, macOS, Windows, glibc, musl, and baseline x64 targets. That requires platform-specific native packages such as `@opentui/core-linux-arm64`. + +If a local build fails with a message like: + +```text +Could not resolve: "@opentui/core-linux-arm64/index.ts" +``` + +the checkout does not have the cross-platform native dependencies needed for release packaging. + +The build script currently tries to resolve this by running package-manager install steps before packaging. Maintainers should run release asset generation only in a controlled release environment with the approved dependency policy for the repo, then verify with `bun run release:check-assets` before publishing. + +## Create a Draft Release + +Use the package version as the tag unless intentionally cutting a different version. + +```bash +cd src/mendcode +version=$(bun -e 'console.log(require("./packages/opencode/package.json").version)') +gh release create "v$version" \ + --repo MendCode/MendCode \ + --draft \ + --title "v$version" \ + --notes "Initial MendCode public release." +``` + +Upload assets: + +```bash +gh release upload "v$version" \ + packages/opencode/dist/*.zip \ + packages/opencode/dist/*.tar.gz \ + packages/opencode/dist/SHA256SUMS \ + --repo MendCode/MendCode \ + --clobber +``` + +Publish only after `release:check-assets` passes. + +```bash +gh release edit "v$version" --repo MendCode/MendCode --draft=false +``` + +## Smoke Test the Installer + +After publishing: + +```bash +tmp_home=$(mktemp -d) +HOME="$tmp_home" bash -c 'curl -fsSL https://raw.githubusercontent.com/MendCode/MendCode/main/src/mendcode/install | bash -s -- --no-modify-path' +"$tmp_home/.mendcode/bin/mendcode" --version +``` + +Versioned install: + +```bash +HOME="$tmp_home" bash -c "curl -fsSL https://raw.githubusercontent.com/MendCode/MendCode/main/src/mendcode/install | bash -s -- --version $version --no-modify-path" +``` + +## Release Checklist + +- `main` and `dev` point to the intended commit. +- GitHub Actions are green on `main`. +- Dependabot alerts are reviewed. +- Secret scan is clean on the publicable tree. +- Dependency Review and CodeQL are green. +- `docs/public-readiness-audit.md` is current. +- Release assets pass `bun run release:check-assets`. +- `SHA256SUMS`, `RELEASE-MANIFEST.txt`, `mendcode.spdx.json`, and artifact attestations are present. +- Installer smoke test passes on at least one macOS or Linux machine. +- Release notes mention breaking changes, package changes, and installer changes. + +## GitHub Actions Release Flow + +Use the manual `Release` workflow from the Actions tab. + +Inputs: + +- `version`: semver without leading `v`. +- `dry_run`: `true` builds artifacts and attestations without publishing or entering the protected release environment; `false` creates a draft GitHub Release through the protected release environment. +- `prerelease`: marks the release as prerelease. + +The workflow: + +- runs supply-chain preflight +- blocks release when OSV reports vulnerable release lockfile entries outside `.github/osv-release.toml` +- installs from the checked-in lockfile with dependency scripts disabled +- runs required MendCode native repair steps explicitly +- builds `mendcode-*` release archives +- validates the installer asset contract +- writes `RELEASE-MANIFEST.txt` +- generates `mendcode.spdx.json` +- creates GitHub artifact attestations +- uploads workflow artifacts +- optionally creates a draft GitHub Release + +Dry-run failures can still appear in the Actions run, but they should not create failed `release` deployments. A failed `release` deployment means the protected publish job started and failed; a failed dry-run build is only a build/security check failure. + +## Registry Publishing + +The public CLI release is separate from registry package publishing. + +`src/mendcode/script/publish.ts` supports SDK/plugin registry publishing when: + +```bash +MENDCODE_PUBLISH_REGISTRIES=true +``` + +Keep that disabled unless the npm/package registry credentials and package ownership are intentionally configured. diff --git a/docs/session-history.md b/docs/session-history.md new file mode 100644 index 00000000..d02264f9 --- /dev/null +++ b/docs/session-history.md @@ -0,0 +1,54 @@ +# Session history browser + +The live session keeps a bounded render window for predictable memory use and stable scrolling. Older messages open in a separate, explicitly paged history browser instead of being inserted back into the live transcript. + +Open it with `/history` or the `session_history` keybinding. The browser supports: + +- Three distinct history views; press `v` to cycle them for the current run: + - `timeline` shows chronological conversation turns. + - `tree` nests the final assistant response below each user prompt. + - `pages` shows an explicitly numbered, compact turn page. + - `auto` chooses tree or timeline from the terminal width. +- An independent preview pane; press `s` to toggle split layout for any view. `split: "auto"` enables it on wide terminals. +- User-to-assistant turn grouping, with optional tool and subagent detail. +- A full-turn reader opened with `Enter`. +- `PageUp` and `PageDown` navigation through bounded history pages. +- `/` Quick Jump searches complete turn pages from newest to oldest and opens the first match. +- `l` to return directly to the live session and `Escape` to step back. + +Configure the defaults globally in `~/.config/mendcode/tui.json` or per project in `.mendcode/tui.json`: + +```jsonc +{ + "$schema": "https://mendcode.ai/tui.json", + "session_history": { + "enabled": true, + "view": "auto", + "split": "auto", + "page_size": 50, + "group_by": "day", + "show_tools": "count", + "show_subagents": true, + "search": true, + "remember_position": true, + "open_at": "latest", + "preview_width": 58, + "search_page_limit": 200, + }, + "keybinds": { + "session_history": "shift+g", + "session_history_search": "/", + "session_history_open": "return", + "session_history_back": "escape", + "session_history_live": "l", + "session_history_view": "v", + "session_history_split": "s", + }, +} +``` + +`page_size` accepts 10–200 complete conversation turns, not raw assistant or tool events. `split` accepts `true`, `false`, or `"auto"`; `preview_width` accepts 40–75 percent. Narrow terminals hide the preview pane so both columns remain usable. `search_page_limit` accepts 1–1000 bounded pages for Quick Jump. `open_at` selects the latest or oldest visible end when a page opens. + +Older configs remain valid: `view: "split"` maps to `timeline` with preview enabled, and `view: "chapters"` maps to `timeline`. These legacy values no longer appear in the interactive view selector. + +`remember_position` stores only lightweight navigation state for up to 32 recently viewed sessions: the opaque page cursor, selected message, filter, collapsed turns, temporary view choice, and preview state. It does not retain historical message payloads or expand the live transcript window. diff --git a/docs/source-map.md b/docs/source-map.md new file mode 100644 index 00000000..bb8bf27d --- /dev/null +++ b/docs/source-map.md @@ -0,0 +1,90 @@ +# MendCode Source Map + +This page is for contributors and maintainers who need to find the implementation behind a MendCode feature. If you are learning how to use MendCode, start with the [user documentation](README.md) or the [Feature Map](features.md) instead. + +## Why some paths say `opencode` + +`src/mendcode/packages/opencode/` is the internal runtime package directory. MendCode owns the public command surface and the product layers around that runtime, while the package name preserves the upstream OpenCode lineage. It does **not** mean that users should run a second product or use an `opencode` command. + +- Public users run `mendcode`. +- MendCode configuration and control-plane modules are under `src/mendcode/packages/opencode/src/mend/`. +- The underlying runtime and compatibility boundary remain under `src/mendcode/packages/opencode/src/`. +- The development-only `mend` shim is not the public installation contract. +- Lineage and licensing details live in [Architecture and Packages](architecture.md#lineage) and [ACKNOWLEDGEMENTS.md](../ACKNOWLEDGEMENTS.md). + +## Start with the right boundary + +| Need | Start here | +| --- | --- | +| Add or change a public CLI command | `src/mendcode/packages/opencode/src/mend/cli/public-bin.ts` | +| Change setup, project config, models, permissions, or prompt modes | `src/mendcode/packages/opencode/src/mend/config/`, `src/mendcode/packages/opencode/src/mend/profile.ts`, `src/mendcode/packages/opencode/src/mend/prompt/` | +| Change a TUI page or route | `src/mendcode/packages/opencode/src/cli/cmd/tui/routes/` | +| Change session automation or streaming | `src/mendcode/packages/opencode/src/cli/cmd/session.ts`, `src/mendcode/packages/opencode/src/cli/cmd/run.ts`, `src/mendcode/packages/opencode/src/cli/automation.ts` | +| Change a tool or model-facing contract | `src/mendcode/packages/opencode/src/tool/` and `src/mendcode/packages/opencode/src/session/` | +| Change a plugin, widget, or extension API | `src/mendcode/packages/plugin/src/` and the corresponding TUI host under `src/mendcode/packages/opencode/src/cli/cmd/tui/plugin/` | +| Change package distribution or runtime snapshots | `src/mendcode/packages/opencode/src/mend/runtime/` | +| Change release assets or public readiness | `src/mendcode/packages/script/`, `.github/workflows/`, and `docs/releasing.md` | + +## Public CLI and control plane + +- `src/mendcode/packages/opencode/src/mend/cli/public-bin.ts`: public `mendcode` command router and help surface. +- `src/mendcode/packages/opencode/src/mend/config/project.ts`: project configuration, focus profiles, generated runtime config, and package metadata. +- `src/mendcode/packages/opencode/src/mend/config/models.ts`: model roles, projection, and shared prompt-model precedence. +- `src/mendcode/packages/opencode/src/mend/config/permissions.ts`: permission mode and smart-reviewer role configuration. +- `src/mendcode/packages/opencode/src/mend/prompt/mode.ts`: `minimal`, `focus`, `full`, and project-local `custom` prompt modes. +- `src/mendcode/packages/opencode/src/mend/prompt/custom.ts`: bounded, root-safe `.mendcode/prompts/custom.md` loader. +- `src/mendcode/packages/opencode/src/cli/cmd/session.ts`: session create/send/inspect/wait/events/cancel lifecycle. +- `src/mendcode/packages/opencode/src/cli/automation.ts`: versioned `mendcode.cli.v1` envelopes and secret-like field redaction. +- `src/mendcode/packages/opencode/src/cli/cmd/run.ts` and `src/mendcode/packages/opencode/src/cli/model-selection.ts`: headless streaming and shared model/agent resolution. + +## TUI pages and product surfaces + +- `src/mendcode/packages/opencode/src/cli/cmd/tui/app.tsx`: TUI shell, command palette entries, slash aliases, and route registration. +- `src/mendcode/packages/opencode/src/cli/cmd/tui/routes/changes/`: Changes Review loading, diff state, comments, responsive renderer, and review context. The key files are `index.tsx`, `load-diff.ts`, `review-state.ts`, `review-comments.ts`, `review-context.ts`, `review-actions.ts`, and `renderer-adapter.tsx`. +- `src/mendcode/packages/opencode/src/cli/cmd/tui/routes/session/plan-review.tsx`: Plan Review modal and its approve/edit/comment/reject stages. +- `src/mendcode/packages/opencode/src/tool/plan-review.ts`: Plan Review tool schema and implementation-agent switch. +- `src/mendcode/packages/opencode/src/tool/review.ts`: assistant-facing Changes Review tool. +- `src/mendcode/packages/opencode/src/session/prompt.ts`: active review context injection into model turns. +- `src/mendcode/packages/opencode/src/session/prompt/plan.txt`: Plan Review instruction for planning agents. +- `src/mendcode/packages/opencode/src/cli/cmd/tui/routes/loops/`: Loop Workflows dashboard and operator controls. +- `src/mendcode/packages/opencode/src/cli/cmd/tui/routes/memory/index.tsx`: Memory Center route, category policy, Dream panel, inspector, and side agent. +- `src/mendcode/packages/opencode/src/cli/cmd/tui/routes/stats/index.tsx`: Usage Insights route, scope handling, cache, shortcuts, and weather integration. +- `src/mendcode/packages/opencode/src/cli/cmd/tui/util/usage-insights.ts`: Usage Insights aggregation and normalization. +- `src/mendcode/packages/opencode/src/cli/cmd/tui/component/styled-plan-markdown.tsx`: stable Markdown presentation, Mermaid cards, local viewport controls, and source-to-card recovery. +- `src/mendcode/packages/opencode/src/cli/cmd/tui/util/markdown-render.ts`: Markdown/streaming rendering and Mermaid ASCII card generation. +- `src/mendcode/packages/opencode/src/mend/profile.ts` and `src/mendcode/packages/opencode/src/mend/tui/`: TUI profile, prompt chrome, status, presentation, mascot, and customization actions. + +## Sessions, loops, and coordination + +- `src/mendcode/packages/opencode/src/session/loop.ts`: Loop Workflow model and lifecycle state. +- `src/mendcode/packages/opencode/src/session/loop-runner.ts`: loop wakeup and iteration execution. +- `src/mendcode/packages/opencode/src/tool/loop.ts`: assistant-facing loop tool contract. +- `src/mendcode/packages/opencode/src/mend/runtime/loop-service.ts`: durable loop service, status, activation, and run state. +- `src/mendcode/packages/opencode/src/mend/cli/control-plane.ts`: public loop CLI controls and service lifecycle. +- `src/mendcode/packages/opencode/src/server/routes/instance/loop.ts` and `src/mendcode/packages/opencode/src/server/routes/instance/httpapi/handlers/loop.ts`: loop read/control route stacks. +- `src/mendcode/packages/opencode/src/mend/config/mflow.ts`: local-first mflow setup, relay configuration, and edit locks. +- `src/mendcode/packages/opencode/src/mend/config/tsm.ts` and `src/mendcode/packages/opencode/src/mend/config/worktree.ts`: optional TSM/worktree lifecycle, previews, and safety registry. + +## Memory, packages, providers, and extensions + +- `src/mendcode/packages/opencode/src/mend/memory/`: approval-gated storage, proposals, retrieval, graph, Dream, side chat, workspaces, and category policy. +- `src/mendcode/packages/opencode/src/mend/runtime/pack.ts`: runtime package snapshot creation. +- `src/mendcode/packages/opencode/src/mend/runtime/packages.ts`: installed/enabled package projection. +- `src/mendcode/packages/opencode/src/provider/claude-code.ts`: local Claude Code CLI provider bridge and validation. +- `src/mendcode/packages/plugin/src/tui.ts`: public plugin/widget type contract. +- `src/mendcode/packages/opencode/src/cli/cmd/tui/plugin/`: TUI plugin host, slots, routes, commands, dialogs, themes, and runtime registration. + +## Tests, docs, and release references + +- `src/mendcode/packages/opencode/test/cli/tui/`: executable coverage for Markdown, Mermaid, TUI pages, and interaction contracts. +- `src/mendcode/packages/opencode/test/tui/usage-insights.test.ts`: Usage Insights aggregation and selected-day regression coverage. +- `docs/`: public behavior, setup, feature, page, release, and security documentation. +- `src/mendcode/packages/script/` and `.github/workflows/`: release helpers, asset assembly, provenance, and CI gates. + +## Related documentation + +- [Architecture and Packages](architecture.md): ownership, runtime boundary, repository layout, and safety model. +- [CLI, Setup, and Configuration](cli-setup-configuration.md): public commands and user-facing configuration. +- [TUI Plugins and Widgets](tui-plugins-and-widgets.md): supported extension API. +- [Releasing MendCode](releasing.md): installer and release workflow. +- [Lineage and acknowledgements](../ACKNOWLEDGEMENTS.md): upstream attribution and licensing. diff --git a/docs/specs/memory-graph-dream-page.md b/docs/specs/memory-graph-dream-page.md new file mode 100644 index 00000000..a27aacc4 --- /dev/null +++ b/docs/specs/memory-graph-dream-page.md @@ -0,0 +1,427 @@ +# Memory Graph, Dream, and Memory Page Spec + +Status: implemented locally; focused validation passed +Target release package: `0.1.15` +Branch target: `dev` +Tracked mirror for ignored package: `.agents/specs/memory-graph-dream-page/` + +## Intent + +MendCode memory must evolve from a flat pending list into a durable project intelligence system. The system must distinguish global memory from project/workspace memory, remember stable project context, avoid volatile task state, support category-aware retrieval, expose a first-class Memory page, and provide safe AI-assisted maintenance through constrained side chat and Dream. + +This is one complete ordered spec. The order is for safety and dependency management; it is not a plan to leave side chat, Dream, grouping, or policy ownership for an indefinite later pass. + +## Release Decision + +- This package targets `0.1.15`. +- Do not bump to `0.1.16` for this work. +- Public release notes must describe only behavior that is actually implemented and validated. +- No public promotion to `main` should happen until the user validates the visible Memory page locally. + +## Resolved Product Decisions + +| Area | Decision | +|---|---| +| Memory page scope | The Memory page is global from anywhere in MendCode. Opening it from any project shows all known projects/workspaces. | +| Project definition | A folder/root becomes a project/workspace once it has at least one MendCode session with one user message. | +| Project registry | Store project/workspace registry in user-global MendCode state, not a repo-local database. | +| Default discovery | Default to known MendCode session roots and user-selected roots; do not blind-scan the whole home directory. | +| Local grouping | A user's default local group root can be any configured workspace directory, for example `~/Code`. | +| General grouping | Users can configure roots/groups in their global MendCode state. | +| Group views | Support automatic folder/root groups and manual user-defined groups. Group views aggregate read/review surfaces without merging ownership scopes. | +| Scope default | Project/repo/product facts default to `project`; global is only for explicit cross-project or person-level preferences. | +| Auto-apply default | Generated memory stays pending by default. Per-category auto-apply exists only after explicit user configuration. | +| Dream role | Dream uses a new `memoryDream` role/model. | +| Dream missed windows | If the PC/process was off during the window, mark missed and wait for manual trigger. Do not auto-catch-up at startup. | +| Side chat | Included in this system. It is a constrained side-chat runtime, not a normal build/default session. | +| Side chat model | Use a dedicated constrained memory/setup assistant role by default, with user-configurable role/model override. | +| Tracked spec | This document is the tracked handoff because `.agents/` is ignored by git. | + +## Non-Negotiables + +- Preserve existing memory behavior through compatibility bridges. +- Do not silently write generated memory. +- Do not let a model decide arbitrary global scope without runtime validation. +- Do not grant Dream filesystem, git, or session reads by default. +- Do not let side chat become a shell/source-editing/coding agent. +- Do not show fake optimistic state in UI; labels must reflect persisted/runtime truth. +- Do not store volatile current-task state as durable memory. + +## Existing System Anchors + +These are the first files to map before implementation: + +- `src/mendcode/packages/opencode/src/mend/memory/config.ts` +- `src/mendcode/packages/opencode/src/mend/memory/store.ts` +- `src/mendcode/packages/opencode/src/mend/memory/retrieve.ts` +- `src/mendcode/packages/opencode/src/mend/memory/proposals.ts` +- `src/mendcode/packages/opencode/src/session/processor.ts` +- `src/mendcode/packages/opencode/src/session/llm.ts` +- `src/mendcode/packages/opencode/src/cli/cmd/tui/context/route.tsx` +- `src/mendcode/packages/opencode/src/cli/cmd/tui/app.tsx` +- `src/mendcode/packages/opencode/src/cli/cmd/tui/routes/setup/index.tsx` +- `src/mendcode/packages/opencode/src/cli/cmd/tui/routes/stats/index.tsx` +- `src/mendcode/packages/opencode/src/server/routes/global.ts` +- `src/mendcode/packages/opencode/src/session/status.ts` + +## Target Architecture + +```mermaid +flowchart TD + User["User / TUI"] --> MemoryPage["Global Memory Page"] + MemoryPage --> ProjectSidebar["Projects + Groups Sidebar"] + MemoryPage --> MemoryViews["Saved / Pending / Categories / Graph"] + MemoryPage --> PolicyEditor["Policy + Prompt Editor"] + MemoryPage --> DreamPanel["Dream Status + Logs"] + MemoryPage --> SideChat["Constrained Side Chat"] + + SessionTurn["Completed Session Turn"] --> Extractor["memoryExtractor"] + Extractor --> ProposalLedger["Proposal Ledger"] + SideChat --> ProposalLedger + + DreamScheduler["Dream Scheduler"] --> DreamRunner["Dream Runner / memoryDream"] + DreamRunner --> Evidence["Redacted Evidence Manifest"] + DreamRunner --> DreamLogs["Dream Logs"] + DreamRunner --> ProposalLedger + + ProposalLedger --> Graph["Memory Graph Sidecar"] + ProposalLedger --> Legacy["entries.jsonl + memory_summary.md"] + Graph --> Retrieval["Category-aware Retrieval Planner"] + Legacy --> Retrieval + Retrieval --> PromptBlock[""] + + PolicyEditor --> UserPolicy["User-owned Policy Files"] + DreamRunner --> Events["Events / SSE"] + Events --> DreamPanel +``` + +## Data Model + +### Workspace Registry + +Each workspace/project record should include: + +- stable id +- root path +- display name +- first user-message timestamp +- last active timestamp +- optional git root +- optional repo fingerprint +- optional worktree path +- source: current session, historical session, user-added root, imported root +- group ids +- visibility/archive flag + +Workspace ids should be stable across common path changes when git fingerprint is available, but path/root must remain visible because users reason about folders. + +### Memory Fact + +Each memory fact should include: + +- id +- scope: `global`, `project`, `workspace`, or `group-view` +- owner workspace/group ids +- category ids +- text/content +- normalized summary +- provenance refs +- created/updated/verified timestamps +- confidence +- durability +- volatility/change-risk +- sensitivity +- stale/verified state +- retrieval priority +- links to related facts +- legacy materialization metadata + +### Proposal + +Every model-generated mutation must be a proposal: + +- operation: add, update, remove, merge, split, verify, expire, recategorize, relink, demote-scope, promote-scope +- target ids when applicable +- proposed fact/category/scope +- reason +- evidence refs +- confidence +- durability +- volatility/change-risk +- policy decision +- status: pending, applied, rejected, superseded +- created by: extractor, side chat, Dream, manual + +## Default Category Ontology + +Start with these categories. The extractor may propose new categories, but new categories should be reviewed and carry retrieval/write policies. + +| Category | Purpose | Default write policy | +|---|---|---| +| `project.objective` | Stable product purpose and goals | pending | +| `project.stack` | Frameworks, runtimes, package managers, core dependencies | pending | +| `project.architecture` | Durable module boundaries, data flow, services | pending | +| `project.commands` | Recurring commands, validation gates, release commands | pending | +| `project.release` | Versioning, changelog, branch, PR, release rules | pending | +| `project.constraints` | Permanent constraints, compatibility promises, ownership rules | pending | +| `project.security` | Security posture, secret handling, permission rules | pending | +| `user.preferences` | Cross-project user communication and workflow preferences | pending | +| `agent.policy` | How MendCode should behave for this user/project | pending | +| `memory.policy` | Memory save/retrieve/category rules | pending | +| `todo.stable` | Durable roadmap or recurring future work, not current task status | pending | +| `volatile.reject` | Explicit non-save class for fast-changing facts | disabled | + +## Extraction Rules + +The extractor must prefer project scope for facts about: + +- repo/product name +- stack/toolchain +- commands/tests +- architecture +- release flow +- local paths +- project-specific constraints +- current workspace behavior + +The extractor may use global scope for: + +- communication preferences +- cross-repo work habits +- user-level UI/answer preferences +- policies explicitly stated as universal + +Do not persist: + +- current bug status +- temporary task progress +- raw logs +- one-off command output +- unverified stack traces +- rapidly changing code state +- details useful only for the current chat + +## Memory Page + +The Memory page should be route-level, not just a modal. It needs: + +- global/project/group sidebar +- current project selection +- automatic and manual groups +- saved memories view +- pending proposals view +- category/policy editor +- graph/links view +- Dream status and logs +- side chat panel +- item inspector with provenance and actions + +Responsive behavior: + +- wide terminal: sidebar, main view, inspector, side chat/Dream panel +- medium terminal: sidebar + main, inspector as focus/detail view +- narrow terminal: single-column navigation with stable rows and no overlapping text +- tiny stacked terminal: command-list layout with deterministic focus movement + +## Side Chat + +Side chat is a reusable constrained runtime for Memory and Setup assistance. + +It must support: + +- simple user/assistant history +- scrollback +- stop/cancel via Escape or explicit control +- copy message +- plain text rendering by default +- no requirement to render assistant markdown richly +- compact context building +- selected workspace/group/category/policy context + +It must not support by default: + +- shell commands +- source edits +- git mutations +- normal session mode switching +- arbitrary tools +- silent memory/config writes + +Side-chat model output should be action-oriented: + +- propose memory mutation +- propose category/policy change +- explain current memory state +- draft Dream dry-run plan +- summarize conflicts/staleness + +All mutations become reviewable proposals or explicit UI actions. + +## Dream + +Dream is a background/manual consolidation process powered by `memoryDream`. + +Default reads: + +- saved memory +- pending/applied/rejected proposals +- prior Dream logs +- workspace registry metadata needed to select scope + +Opt-in reads: + +- session metadata +- session summaries/content +- git metadata +- filesystem metadata/content + +Dream writes: + +- append-only run logs +- redacted evidence manifest +- safety report +- reviewable proposals + +Dream must not: + +- apply memory directly by default +- edit source files +- mutate git state +- write config silently +- read secrets by default +- auto-catch-up missed schedules at startup + +Schedule semantics: + +- user configures daily time window, not a fixed exact minute +- scheduler picks one slot inside the window +- at most one run per workspace/group per local date +- if the process is unavailable during the window, mark missed +- missed runs wait for manual trigger from Memory page +- manual runs use the same locks, permissions, logs, and proposal path + +Allowed git reads after opt-in should start with: + +- `git status --short --branch` +- `git rev-parse --show-toplevel HEAD` +- `git branch --show-current` +- `git log --oneline --decorate -n ` +- `git diff --stat` +- `git diff --name-only` + +Raw diffs and file contents need stronger explicit permission. + +Filesystem reads after opt-in must: + +- stay inside approved roots +- exclude `.git`, `.env*`, `*.env`, caches, build outputs, binaries, archives, `node_modules`, large files, and secret-looking filenames +- prefer README/package/docs/AGENTS/context files selected by policy +- redact secrets before model input and persistent logs +- record path + hash/mtime evidence refs + +## Retrieval Planner + +Runtime prompt injection should include category and scope labels so the receiving model understands why a memory is present. + +Priority order: + +1. Active project identity and project policies +2. Current workspace architecture, stack, commands, release rules +3. Relevant group-view facts +4. Stable global user preferences +5. Stale/unverified facts only with markers or verification requirement + +Category policies may disable prompt injection without deleting stored memory. + +## Implementation Task Graph + +### S1: Memory Contracts + +- Map current memory/TUI callers and tests. +- Define category and policy contracts. +- Harden extractor prompt/schema for scope, durability, volatility, and category decisions. +- Add post-model validation that demotes likely-global mistakes and rejects volatile facts. + +### S2: Storage and Workspace Graph + +- Add graph sidecar with legacy bridge. +- Extend proposal ledger for update/remove/merge/split/verify/expire. +- Add workspace registry and group model. +- Add retrieval planner with category/scope labels. + +### S3: Memory Page + +- Add route registration and navigation. +- Build responsive Memory page shell. +- Add saved memory, proposals, categories, policies, group views, and inspector. +- Preserve old Memory Manager behavior by routing or parity. + +### S4: Dream + +- Add `memoryDream` role and prompts. +- Add Dream run ledger and safety/evidence manifests. +- Add manual Dream run. +- Add schedule window, locks, missed state, and no startup auto-catch-up. +- Add events/SSE/TUI state. +- Add security review for opt-in session/git/files evidence. + +### S5: Side Chat and Policy Ownership + +- Add constrained side-chat runtime. +- Add Memory side-chat integration. +- Add Setup side-chat adapter if the existing setup page can host it cleanly. +- Add user-owned policy/prompt files with live reload and validation. +- Add conflict/staleness/merge assistance through proposals. + +### S6: Release Validation + +- Run focused memory tests. +- Run TUI route/setup smoke tests. +- Run Dream scheduler/ledger tests. +- Run side-chat runtime cancellation/history tests. +- Run `git diff --check`. +- Keep version metadata at `0.1.15`. +- Update changelog with only validated behavior. + +## Required Validation + +Minimum focused commands should be chosen after mapping the repo, but expected coverage includes: + +- memory unit tests +- proposal apply/reject/update tests +- retrieval planner tests +- workspace registry/group tests +- Dream scheduler and lock tests +- Dream safety allowlist tests +- side-chat cancellation/history tests +- TUI route/render smoke tests for wide, medium, narrow, and tiny layouts +- `git diff --check` + +Repo-wide typecheck may be noisy in this checkout, so targeted tests plus diff hygiene are the safer gate unless the implementation changes shared type contracts enough to require broader validation. + +## Security Review Checklist + +- Treat memory, sessions, git, and files as untrusted input. +- Redact secrets before model input and logs. +- Enforce runtime allowlists outside the model. +- Make generated writes proposal-only. +- Use atomic writes or locks around graph/proposal/index mutations. +- Keep logs append-only where practical. +- Keep Dream evidence bounded. +- Do not render fake UI state. +- Do not expose side chat to arbitrary tools. + +## Handoff Notes + +- The ignored full spec package is in `.agents/specs/memory-graph-dream-page/`. +- This tracked doc is the handoff source another agent should read first. +- User explicitly resolved the major open questions; do not reopen them unless implementation evidence creates a real blocker. +- Preserve unrelated dirty files in the current worktree. +- Keep the release target at `0.1.15`. + +## Implementation Notes + +- Added category/policy contracts, graph sidecar storage, workspace registry/group views, Dream run ledger/scheduler/evidence safety helpers, constrained memory side chat, category-aware retrieval labels, and a route-level global Memory page. +- Generated memory mutations remain reviewable proposals by default. +- Dream defaults to memory/proposal/prior-run evidence only; git/files/session reads remain opt-in and bounded. +- Validation passed with focused memory, setup, session, and import-smoke checks. Public promotion remains gated on local user testing. diff --git a/docs/supply-chain-security.md b/docs/supply-chain-security.md new file mode 100644 index 00000000..bc848230 --- /dev/null +++ b/docs/supply-chain-security.md @@ -0,0 +1,79 @@ +# Supply Chain Security + +MendCode release and contribution security is built around small permissions, pinned automation, public provenance, and fail-closed scanners. + +## Release Guarantees + +The release workflow in `.github/workflows/release.yml` produces: + +- platform archives named `mendcode-*` +- `SHA256SUMS` +- `RELEASE-MANIFEST.txt` +- `mendcode.spdx.json` SBOM +- GitHub artifact attestations for release artifacts + +Users can verify release downloads with: + +```bash +gh release download v --repo MendCode/MendCode +shasum -a 256 -c SHA256SUMS +gh attestation verify --repo MendCode/MendCode mendcode-*.zip mendcode-*.tar.gz SHA256SUMS RELEASE-MANIFEST.txt mendcode.spdx.json +``` + +GitHub artifact attestations provide signed provenance claims for public repository artifacts. GitHub documents artifact attestations as a way to establish provenance and integrity guarantees for builds. + +## Automation Rules + +Repository automation follows these rules: + +- Actions are pinned to full commit SHAs. +- Release publishing is manual and protected by the `release` environment. +- Release publishing from non-`main` refs is blocked. +- Dry-run release builds do not use the protected `release` environment and do not create GitHub Releases. +- Workflow permissions are explicit and minimal. +- Release assets are checked for MendCode-owned names and expected binaries. +- Release dependency install uses `--ignore-scripts`; required native repair steps run explicitly. +- Dependency review blocks high-severity dependency changes in PRs. +- CodeQL runs on `main`, `dev`, PRs, and schedule. +- Security Guard blocks invisible Unicode controls, risky tracked files, secrets findings, GitHub Actions issues, Semgrep findings, and supply-chain preflight failures. +- OSV dependency scanning runs on PRs and pushes as advisory signal for the current migration baseline, blocks scheduled/manual security runs, and blocks release workflows before dependency install using the release lockfile plus explicit, expiring exceptions in `.github/osv-release.toml`. + +## Preflight Guard + +`.github/scripts/supply-chain-preflight.sh` checks: + +- invisible Unicode and bidi controls +- secret-like tracked file names +- unpinned GitHub Actions references +- pipe-to-shell commands in automation paths +- accidental `opencode-*` release archives outside ignored dist output + +Run locally: + +```bash +bash .github/scripts/supply-chain-preflight.sh +``` + +## Dependency Policy + +Dependency changes should go through PR review and CI. Direct package publishing is intentionally separate from CLI release publishing. + +For release asset generation, the controlled GitHub Actions release workflow scans the checked-in release lockfile with OSV before installing dependencies. A release workflow cannot continue while OSV reports vulnerable release lockfile entries, including dry runs, except for documented exceptions in `.github/osv-release.toml`. After that gate, the workflow installs from the checked-in lockfile with dependency scripts disabled, runs required MendCode repair steps explicitly, builds assets, verifies the release contract, generates an SBOM, and emits provenance attestations. + +The recursive monorepo OSV scan remains in Security Guard so non-release surfaces such as the VS Code SDK remain visible and can be remediated without blocking the CLI installer release path. + +An OSV finding is evidence that a lockfile resolves to package versions with known vulnerabilities. It is not evidence by itself that a maintainer workstation is compromised, that a malicious package executed, or that a supply-chain attack already happened. Treat those findings as release blockers until remediated or until a narrower release dependency surface is proven and documented. + +## Current First Release Status + +No public GitHub Release is published until the release workflow successfully creates all installer assets and the dependency release gate is clean. Dry runs do not publish a release and do not enter the protected `release` environment. Track the first release in: + +```text +https://github.com/MendCode/MendCode/issues/52 +``` + +Track the OSV lockfile remediation release blocker in: + +```text +https://github.com/MendCode/MendCode/issues/55 +``` diff --git a/docs/themes.md b/docs/themes.md new file mode 100644 index 00000000..51c30990 --- /dev/null +++ b/docs/themes.md @@ -0,0 +1,11 @@ +# MendCode themes + +Themes are JSON documents with a top-level `theme` object using the same color keys as the built-in themes. An agent can create one from a visual reference, then validate and activate it without an AI call: + +```sh +mendcode theme validate ./my-theme.json +mendcode theme install ./my-theme.json --name studio --scope project +mendcode theme select studio --scope project +``` + +Project themes live in `.mendcode/themes/` and the project selection is stored in `.mendcode/tui.json`. Use `--scope global` for the XDG MendCode config directory. Validation requires all supported UI color keys, accepts hex/ANSI/reference/variant values, rejects missing or circular references, and checks a minimum 3:1 text/background contrast when those values resolve to hex colors. The command is local-only and never calls a model or provider. diff --git a/docs/tsm-and-worktrees.md b/docs/tsm-and-worktrees.md index f9d2d0f2..98d61e14 100644 --- a/docs/tsm-and-worktrees.md +++ b/docs/tsm-and-worktrees.md @@ -10,14 +10,14 @@ TSM is not required to use MendCode. It is an optional accelerator when installe ## Worktree Commands ```bash -mend worktree status -mend worktree plan feature-name --branch mend/feature-name -mend worktree create feature-name -mend worktree open -mend worktree adopt -mend worktree remove -mend worktree reset -mend worktree doctor +mendcode worktree status +mendcode worktree plan feature-name --branch feature/feature-name +mendcode worktree create feature-name +mendcode worktree open +mendcode worktree adopt +mendcode worktree remove +mendcode worktree reset +mendcode worktree doctor ``` Current safety posture: @@ -29,10 +29,10 @@ Current safety posture: - destructive actions return previews and report `executesGit: false`. - external worktrees must be adopted before MendCode treats them as owned. -## `mend --worktree` +## `mendcode --worktree` ```bash -mend --worktree [branch|path|id] +mendcode --worktree [branch|path|id] ``` This shortcut opens MendCode in a known git worktree. If no target is passed, MendCode resolves a safe target only when the current repo state is unambiguous. If multiple targets exist, pass the branch, path, or registry id. @@ -42,27 +42,27 @@ This shortcut opens MendCode in a known git worktree. If no target is passed, Me Inspect: ```bash -mend tsm status -mend tsm plan -mend tsm doctor +mendcode tsm status +mendcode tsm plan +mendcode tsm doctor ``` Setup/activate/deactivate/remove: ```bash -mend tsm setup -mend tsm activate -mend tsm deactivate -mend tsm remove +mendcode tsm setup +mendcode tsm activate +mendcode tsm deactivate +mendcode tsm remove ``` TSM status detects a `tsm` binary but does not install it. The TSM plan includes install suggestions, but `executesInstall` is false. -## `mend --tsm` +## `mendcode --tsm` ```bash -mend --tsm [branch|path|id] -mend --tsm --all +mendcode --tsm [branch|path|id] +mendcode --tsm --all ``` This shortcut requires: @@ -74,13 +74,13 @@ This shortcut requires: When valid, MendCode runs: ```bash -tsm wt open --split mend +tsm wt open --split mendcode ``` or for all: ```bash -tsm wt open --split mend +tsm wt open --split mendcode ``` ## TSM Is an Executor, Not Source of Truth @@ -101,10 +101,10 @@ TSM provides optional terminal/session execution. It should not independently de Before live worktree operations, check: ```bash -mend worktree status -mend worktree doctor -mend tsm status -mend tsm doctor +mendcode worktree status +mendcode worktree doctor +mendcode tsm status +mendcode tsm doctor ``` Do not treat unowned external worktrees as disposable. Adopt them first, then use preview output before destructive operations. diff --git a/docs/tui-plugins-and-widgets.md b/docs/tui-plugins-and-widgets.md index d05321fa..c37bd97f 100644 --- a/docs/tui-plugins-and-widgets.md +++ b/docs/tui-plugins-and-widgets.md @@ -1,8 +1,8 @@ # TUI Plugins and Widgets -MendCode TUI plugins are local or packaged JavaScript/TypeScript modules that extend the terminal UI without editing runtime internals. They are the right place for company dashboards, status lines, prompt-side context, custom footers, command palettes, dialogs, routes, themes, and editor widgets. +MendCode TUI plugins are local or packaged JavaScript/TypeScript modules that extend the terminal UI without editing runtime internals. They are the right place for company dashboards, status lines, prompt-side context, custom footers, command palettes, dialogs, routes, themes, shell-backed widgets, and editor widgets. -The public API is exported from `@mendcode/plugin/tui`. The active host implementation lives in `src/mendcode/packages/opencode/src/cli/cmd/tui/plugin/`, and the type contract lives in `src/mendcode/packages/plugin/src/tui.ts`. +The public API is exported from `@mendcode/plugin/tui`. The host implementation and type contract are listed in the [MendCode Source Map](source-map.md#memory-packages-providers-and-extensions). For assistant-facing custom tool calls, see [Custom Tool Calls](custom-tool-calls.md). ## Register a Plugin @@ -61,6 +61,13 @@ Use `api.ui.runtime.setWidget()` for persistent widgets around the editor. Suppo - `belowEditor` - `sessionBottomDock` +Widgets can declare sizing metadata: + +- `width`, `minWidth`, `maxWidth`: terminal columns for dock widgets. +- `height`: terminal rows, or `auto`. +- `interactive`: marks the widget as expecting key/input handling. +- `title`: display/debug metadata for package UIs. + ```tsx /** @jsxImportSource @opentui/solid */ @@ -78,6 +85,7 @@ export default { { placement: "aboveEditor", order: 10, + width: "auto", }, ) @@ -90,6 +98,180 @@ export default { Use unique widget IDs. Reusing an ID replaces the previous render function for that widget. +## Live TUI Customization API + +The host exposes the session chrome contract through `api.ui.runtime.customization`. It updates the running TUI and persists the change; no route reload or process restart is required. + +```tsx +export default { + id: "company.chrome", + async tui(api) { + api.ui.runtime.customization.setTerminalTitle({ + enabled: true, + template: "CompanyCode · {session} · {path}", + }) + api.ui.runtime.customization.setSessionAccent("random") + api.ui.runtime.customization.setDiffFiles(true) + + api.ui.runtime.setWidget("company.review", () => Review tools ready, { + placement: "aboveEditor", + order: 20, + }) + }, +} +``` + +Available customization methods: + +- `get()` reads the normalized live contract. +- `set(patch)` updates one or more chrome settings. +- `setTerminalTitle({ enabled, template })` controls terminal title output. Templates support `{product}`, `{session}`, `{route}`, and `{path}`. +- `setSessionAccent("theme" | "random" | "#rrggbb")` selects the session header accent. `random` is deterministic for a session ID. +- `setDiffFiles(boolean)` toggles the changed-file count beside diff totals. +- `reset()` restores the default chrome settings without changing profile files or project/session data. + +`setWidget`, `clearWidget`, `focusWidget`, and `blurWidget` remain the widget API. Widgets are intentionally separate from the session chrome toggles, so turning off a built-in header item does not remove plugin-owned widgets. + +## Shell-Backed Widgets + +Use `api.shell.spawn()` when a widget needs live command output. The process output is streamed to plugin code and kept in a capped in-memory tail. It is intended for low-overhead widgets such as status panes, `neofetch`-style summaries, notes exporters, todo dashboards, log tails, and simple command monitors. + +```tsx +/** @jsxImportSource @opentui/solid */ +import { createSignal, onCleanup } from "solid-js" +import { useKeyboard } from "@opentui/solid" +import type { TuiPluginApi } from "@mendcode/plugin/tui" + +function CommandWidget(props: { api: TuiPluginApi }) { + const [output, setOutput] = createSignal("") + const proc = props.api.shell.spawn("printf 'ready\\n'; while true; do date; sleep 2; done", { + maxBuffer: 8_000, + }) + + proc.onOutput((event) => setOutput(event.output)) + onCleanup(() => void proc.stop()) + + useKeyboard((event) => { + if (event.name === "escape") void proc.stop() + if (event.sequence) proc.write(event.sequence) + }) + + return ( + + Command + {output().split("\n").slice(-4).join(" ")} + + ) +} + +export default { + id: "company.shell-widget", + async tui(api) { + api.ui.runtime.setWidget("company.shell", () => , { + placement: "sessionBottomDock", + order: 40, + width: 32, + minWidth: 24, + height: "auto", + interactive: true, + title: "Command", + }) + }, +} +``` + +`shell.spawn()` is not a PTY. Full-screen terminal applications that require a real TTY, cursor addressing, alternate screen buffers, or terminal audio bridges should be wrapped by a PTY-backed helper or a future `spawnPty` API. Do not fake a Doom/cava integration by assuming normal stdout pipes behave like a terminal emulator. + +## Compaction Arcade Games + +Compaction can show a small focused arcade surface while context is being packed. Built-ins include `snake`, `stars`, and `blocks`; plugins can register real keyboard-driven games by ID. + +The user or package profile selects the game: + +```jsonc +{ + "presentation": { + "compaction": { + "style": "cockpit", + "showProgress": true, + "allowScratchpad": true, + "arcade": "company.dodger" + } + } +} +``` + +Register the game from a TUI plugin: + +```tsx +/** @jsxImportSource @opentui/solid */ +import type { TuiCompactionArcadeGame } from "@mendcode/plugin/tui" + +type DodgerState = { + player: number + rock: { x: number; y: number } + score: number +} + +const width = 28 +const height = 8 + +const game: TuiCompactionArcadeGame = { + id: "company.dodger", + label: "Dodger", + intervalMs: 140, + initialState: () => ({ + player: Math.floor(Math.random() * width), + rock: { x: Math.floor(Math.random() * width), y: 0 }, + score: 0, + }), + tick(state) { + const y = state.rock.y + 1 + if (y >= height) { + return { + ...state, + rock: { x: Math.floor(Math.random() * width), y: 0 }, + score: state.score + 1, + } + } + return { ...state, rock: { ...state.rock, y } } + }, + key(state, key) { + if (key === "left" || key === "a") return { ...state, player: Math.max(0, state.player - 1) } + if (key === "right" || key === "d") return { ...state, player: Math.min(width - 1, state.player + 1) } + return undefined + }, + render(state) { + return { + title: `Dodger · Score ${state.score}`, + status: "Click/focus game first. Esc releases focus.", + cells: Array.from({ length: height }, (_, y) => + Array.from({ length: width }, (_, x) => { + if (y === height - 1 && x === state.player) return { text: "▲ ", tone: "head" as const } + if (state.rock.x === x && state.rock.y === y) return { text: "◆ ", tone: "food" as const } + return { text: "· ", tone: "empty" as const } + }), + ), + } + }, +} + +export default { + id: "company.arcade", + async tui(api) { + api.ui.runtime.registerCompactionArcadeGame(game) + }, +} +``` + +Game input and runtime are focus-gated by the host compaction panel: click the game to focus/start it, `Esc` releases focus, and `tick()` is only called while the arcade surface is focused. Releasing arcade focus stops ticking the game, effectively pausing it. Keys are not sent to games while focus is outside the arcade surface. + +Arrow keys are normalized to `up`, `down`, `left`, and `right`; common character keys arrive as lowercase strings such as `w`, `a`, `s`, `d`, or `r`. Return a new state from `key()` to consume the key, or `undefined` to ignore it. + +Prefer `cells` for game boards that need semantic colors. Standard tones are `head`, `body`, `food`, `wall`, `empty`, `primary`, `muted`, `text`, `danger`, and `accent`; the host maps these to the active theme. Use `head` and `food` for player/target cells so every game gets accessible, consistent color separation. `lines` is still supported for simple monochrome output. + +Plugin-owned games are automatically unregistered when the plugin is disposed. If a plugin needs manual cleanup, call `api.ui.runtime.clearCompactionArcadeGame("company.dodger")`. + ## Footer Entries Use `setFooterEntry()` when multiple packages need to contribute to the footer without replacing the whole footer. @@ -111,6 +293,212 @@ export default { Use `setFooter()` only when one package intentionally owns the complete footer. +## Floating Overlays + +Use `api.ui.overlay.open()` for temporary floating UI owned by a plugin: side-chat helpers, checklists, short inspectors, or contextual command surfaces. Overlays are not PTYs and are separate from the host memory assistant API; they are plugin-rendered Solid surfaces that can be opened from commands and closed by ID or via the render context. + +```tsx +/** @jsxImportSource @opentui/solid */ +import { createSignal } from "solid-js" +import { useKeyboard } from "@opentui/solid" + +function PluginSideChat(props: { close: () => boolean }) { + const [draft, setDraft] = createSignal("") + const [history, setHistory] = createSignal(["Plugin side-chat ready"]) + + useKeyboard((event) => { + if (event.name === "escape" || event.sequence === "q") props.close() + if (event.name === "backspace") setDraft((value) => value.slice(0, -1)) + if (event.name === "return" && draft().trim()) { + setHistory((items) => [...items.slice(-5), `You: ${draft().trim()}`]) + setDraft("") + } + if (event.sequence && event.sequence.length === 1) setDraft((value) => value + event.sequence) + }) + + return ( + + Plugin Side Chat + {history().map((line) => {line})} + › {draft() || "type, Enter to add, Esc/q to close"} + + ) +} + +export default { + id: "company.side-chat-overlay", + async tui(api) { + api.command.register(() => [ + { + title: "Open Plugin Side Chat", + value: "company.side-chat.open", + category: "Company", + onSelect() { + api.ui.overlay.open( + "company.side-chat", + (context) => , + { + title: "Plugin Side Chat", + anchor: "bottom-right", + width: "38%", + height: 12, + modal: false, + }, + ) + }, + }, + ]) + }, +} +``` + +Plugin overlays are automatically cleaned up when a plugin is deactivated or disposed by the runtime wrapper. If the plugin closes the overlay itself, call `api.ui.overlay.close("company.side-chat")` or `context.close()`. + +Use the right surface for the job: + +- **Memory assistant API:** host-owned memory review actions and graph proposals for supported integrations. +- **Plugin floating side-chat:** plugin-owned temporary overlay using `api.ui.overlay.open()`. +- **External TUI app:** requires PTY/pane support; `shell.spawn()` and overlays do not emulate full-screen terminal apps like `graf` or `cava`. + +## Pages, Modals, and AI + +MendCode does not require a separate page framework. A plugin page is a registered route rendered with OpenTUI Solid. A modal is either the host dialog stack or a plugin-owned overlay. Both surfaces can use the same session and AI APIs as the rest of the TUI. + +```tsx +/** @jsxImportSource @opentui/solid */ +import { useKeyboard } from "@opentui/solid" +import { createSignal } from "solid-js" +import type { TuiPluginApi } from "@mendcode/plugin/tui" + +function AssistantModal(props: { api: TuiPluginApi; sessionID: string }) { + const [answer, setAnswer] = createSignal("Ask this session anything") + const ai = props.api.ai.open(props.sessionID) + + useKeyboard((event) => { + if (event.name !== "return") return + void ai.prompt("Summarize the current session in five bullets.").then((result) => { + setAnswer(JSON.stringify(result.data ?? result.error ?? result)) + }) + }) + + return ( + + Session assistant + {answer()} + Press Enter to summarize. Use Esc to close. + + ) +} + +export default { + id: "company.session-assistant", + async tui(api: TuiPluginApi) { + api.command.register(() => [ + { + title: "Open session assistant", + value: "company.session-assistant.open", + onSelect() { + const sessionID = api.session.current() + if (!sessionID) return + api.ui.dialog.replace(() => ( + api.ui.dialog.clear()}> + + + )) + }, + }, + ]) + }, +} +``` + +For a plugin-owned side chat, use `api.ui.overlay.open()` instead of the dialog stack. Set `modal: true` when the overlay should capture attention, call `api.ui.overlay.focus(id)` after opening, and use `context.close()`, `context.focus()`, or `context.blur()` from the renderer. Set `allowStack: true` when the plugin intentionally owns more than one overlay. + +`api.ai.create()` creates a persistent MendCode session that can power a page or modal. `api.ai.open(sessionID)` wraps an existing session. AI handles expose `prompt`, `promptAsync`, `messages`, `update`, `abort`, and `delete`; delete the session explicitly when it is temporary. Plugin disposal removes UI registrations, but it does not silently delete sessions or memory. + +## Session and Metadata API + +The TUI plugin API exposes the same generated SDK contracts used by MendCode itself, with the current route and host client already available: + +```ts +const sessionID = api.session.current() +const sessions = await api.session.list({}) +const status = await api.session.status({}) + +if (sessionID) { + const session = await api.session.get({ sessionID }) + const messages = await api.session.messages({ sessionID }) + await api.metadata.patch({ + sessionID, + agentViewMetadataPatch: { + title: "Release review", + tags: ["release", "review"], + priority: "high", + pinned: true, + }, + }) +} +``` + +`api.session` includes `list`, `create`, `status`, `delete`, `get`, `update`, `children`, `todo`, `diff`, `messages`, `prompt`, `promptAsync`, `command`, `shell`, `deleteMessage`, `message`, `fork`, `abort`, `interrupt`, `init`, `summarize`, `revert`, `unrevert`, `background`, `agentView`, and `agentCommand`. + +`api.metadata` includes `list`, `get`, `patch`, `getCurrent`, and `current`. Metadata changes are control-plane changes: they update title, tags, grouping, priority, notes, pin, and archive state without rewriting the transcript. + +For endpoints not yet wrapped by a convenience method, `api.client` is the generated `OpencodeClient`. It is intentionally part of the public contract, so a plugin can use the same authenticated instance and request context without importing MendCode internals. + +## Memory Graph API + +Memory graph access is project-scoped to the active TUI instance. Plugins can inspect the graph, create or update facts, create or update links, delete either, and call the structured Memory side chat: + +```ts +const snapshot = await api.memory.graph() +const fact = await api.memory.upsertGraphFact({ + text: "The release checklist lives in .mendcode/checklists/release.md", + scope: "project", + categoryIDs: ["workflow"], + provenance: ["company.release-plugin"], + confidence: 0.9, +}) + +const link = await api.memory.upsertGraphLink({ + from: fact.id, + to: snapshot.facts[0]?.id ?? fact.id, + kind: "related", +}) + +await api.memory.deleteGraphLink(link.id) +await api.memory.deleteGraphFact(fact.id) + +const proposal = await api.memory.sideChat({ + message: "Suggest a safe graph fact for the selected release context.", +}) +``` + +Graph facts expose identity, scope, ownership, categories, provenance, timestamps, confidence, durability, change risk, sensitivity, stale state, and retrieval priority. Graph links include their IDs and creation timestamps, so a plugin can edit and remove the exact object it created. `api.memory.graph()` is read-only; graph writes are explicit and persist under the active project's MendCode memory directory. + +## Public API Surface + +The complete public TUI contract is exported from `@mendcode/plugin/tui`: + +| Surface | Public API | Typical use | +| --- | --- | --- | +| Pages | `route.register`, `route.navigate`, `route.current` | Full-screen dashboards, settings, inspectors, sidebars | +| Modals | `ui.dialog`, `ui.Dialog*` | Confirmations, forms, selectors, AI workflows | +| Floating UI | `ui.overlay` | Side chats, inspectors, popovers, non-capturing status panels | +| Editor | `ui.Prompt`, `ui.runtime.setEditor`, `setEditorVisual` | Replace or decorate prompt input | +| Persistent UI | `ui.runtime.setWidget`, `setFooter`, `setFooterEntry`, `setStatus` | Panels, footer data, status indicators | +| Live chrome | `ui.runtime.customization` | Terminal title, session accent, diff visibility, rollback | +| Session AI | `session`, `metadata`, `ai` | Create, inspect, prompt, organize, and stop sessions | +| Memory | `memory` | Read and mutate graph facts/links and call Memory side chat | +| Host state | `state`, `event`, `client` | React to events and inspect synced TUI state | +| Terminal work | `shell`, `pty`, `renderer` | Commands, renderer integrations, and future PTY-backed surfaces | +| Interaction | `command`, `keybind`, `slots`, `theme`, `kv` | Commands, shortcuts, injection points, themes, persistence | +| Lifecycle | `lifecycle` | Abort signals and deterministic cleanup | + +`api.app.capabilities` reports the host capability vocabulary (`session.ai`, `metadata.write`, `memory.graph.write`, `overlay.focus`, and related surfaces). It is a discovery aid, not a sandbox: local plugins run with the permissions of the MendCode process. Review third-party package source before enabling plugins that can execute shell commands, mutate sessions, or write memory. + +`api.pty.spawn` is part of the stable type contract, but the default host currently rejects PTY creation with an explicit error. Use `api.shell.spawn` for non-interactive commands and overlays/widgets for UI until a PTY host is enabled; do not assume a pipe emulates a full terminal. + ## Slots Slots let a plugin inject or replace named UI regions. Built-in host slots include: @@ -127,6 +515,15 @@ Slots let a plugin inject or replace named UI regions. Built-in host slots inclu - `sidebar_content` - `sidebar_footer` +The most common customization targets are: + +- `home_logo`: replace the home title/mascot surface. +- `home_prompt`: replace the whole home prompt editor surface. +- `home_prompt_right`: add small right-side prompt context without replacing the editor. +- `session_prompt`: replace the session prompt editor surface. +- `session_prompt_right`: add session-specific prompt context. +- `home_footer` / `sidebar_footer`: add persistent low-noise team status. + ```tsx /** @jsxImportSource @opentui/solid */ @@ -149,6 +546,8 @@ export default { When consuming slots inside a custom route or component, use `api.ui.Slot`. Slot mode follows the opentui Solid slot model and can be used by host components to append, prepend, or replace default content. +For static home identity, prefer the profile fields documented in [Customization](customization.md): `identity.logoMode`, `identity.productName`, `identity.logoFont`, `surfaces.homeLogo`, and `surfaces.homeWelcome`. Use slots when the content needs runtime data or interaction. + ## Commands and Dialogs Plugins can add command palette entries and slash commands. Use dialogs for interactive flows. @@ -257,7 +656,7 @@ export default { ## Keybinds and State -Plugins receive the active keybind map, persistent plugin KV, app state, SDK client, renderer, theme, and lifecycle signal. +Plugins receive the active keybind map, persistent plugin KV, app state, SDK client, renderer, theme, shell runner, and lifecycle signal. ```tsx export default { @@ -282,7 +681,7 @@ export default { ## Package Distribution -Company packages should include plugins and widgets under `.mendcode/plugins`, `.mendcode/widgets`, or `.mendcode/components`, then activate them through package config. +Marketplace packages should include plugins, widgets, pages, tools, and components under `.mendcode/`, then activate them through package config. ```text .mendcode/ @@ -290,6 +689,10 @@ Company packages should include plugins and widgets under `.mendcode/plugins`, ` mendcode.json plugins/ company-tui.ts + pages/ + company-dashboard.tsx + tools/ + company-status.ts themes/ company-dark.json ``` @@ -306,9 +709,10 @@ Company packages should include plugins and widgets under `.mendcode/plugins`, ` Use package sync for team rollout: ```bash -mend packages create --include plugins,tuiProfile,themes -mend packages install github:YourOrg/company-mend-package -mend packages enable company-mend-package +mendcode marketplace create --include plugins,tuiProfile,themes,tools,pages +mendcode marketplace add-source company --type github --url https://github.com/YourOrg/company-mendcode-marketplace.git --channel team +mendcode marketplace install company-mend-package company +mendcode marketplace enable company-mend-package ``` ## Rules diff --git a/docs/usage-insights.md b/docs/usage-insights.md new file mode 100644 index 00000000..30cb8b92 --- /dev/null +++ b/docs/usage-insights.md @@ -0,0 +1,136 @@ +# Usage Insights + +Usage Insights is a TUI dashboard for local MendCode activity. It helps you see how the harness is being used without turning local stats into unsupported productivity claims. + +![MendCode Usage Insights dashboard](assets/screenshots/usage-insights-overview.png) + +It reports: + +- daily token activity +- selected-day token mix and activity detail +- global/project/directory scope +- sessions and active days +- user prompts and user words +- AI generation time +- tool runtime +- changed files from session summaries +- input/output/reasoning/cache token mix +- peak token pressure +- longest task time +- top tools +- top agents +- top models with token/cost totals when available +- cached stats loading +- optional Open-Meteo weather + +## Open The Dashboard + +From the TUI command palette: + +```text +Ctrl+P -> Usage Insights +Ctrl+P -> Project Usage Insights +``` + +Slash aliases are also registered for the global dashboard: + +```text +/stats +/usage +/insights +/activity +``` + +The route header shows the scope: + +- `global stats` +- `project stats` +- `directory stats` + +## Shortcuts + +Inside the dashboard: + +| Key | Action | +| ---------------- | ---------------------------------------------------------------- | +| `Up` / `Down` | Move the selected token-activity day backward or forward. | +| `Left` / `Right` | Move the selected token-activity day by one week column. | +| `a` | Toggle detail/advanced panels when the terminal is large enough. | +| `w` | Configure optional weather. | +| `r` | Refresh insights. | +| `Esc` | Return home. | + +## Dashboard Sections + +The dashboard adapts to terminal size. Wider terminals show more panels; smaller terminals keep the core totals visible. + +Core totals: + +- `tokens`: total token activity with peak-day detail. +- `sessions`: session count and active days. +- `AI generating` / `AI time`: assistant generation duration. +- `user words`: approximate user prompt volume. +- `cache tokens`: cached read/write token activity. +- `streak`: active-day streaks. + +Token activity: + +- daily cells for the loaded window, arranged like a GitHub activity grid: weeks go horizontally, days go vertically inside each week +- month markers below the grid +- click or hover a cell to select a day +- keyboard selection with `Up`, `Down`, `Left`, and `Right` +- selected-day totals for tokens, cache, sessions, prompts, words, changed files, AI time, and tool runtime +- normalized cache data from the global TUI stats cache so the page can show a loading state instead of presenting zeroed metrics as real data + +Token mix: + +- input +- output +- reasoning +- cache + +Outcome and load: + +- sessions with code changes +- changed files +- tool runtime +- longest task +- peak tokens + +Leaderboards: + +- top tools +- top agents +- top models + +## Scope + +Use global scope when you want a whole-machine view of MendCode activity. + +Use project scope when you want to see activity for the current repository. + +Directory scope is useful when the current directory is inside a worktree or nested project path and you want narrower attribution. + +## Weather + +Weather is opt-in. Press `w` or click the weather panel and enter a city, region, or country. MendCode uses Open-Meteo geocoding and forecast APIs. Leave the value blank to disable the weather widget. + +Weather is a dashboard accessory, not a required part of usage tracking. For public docs, include it only as optional flavor. + +## Data Notes + +Usage Insights is local activity visibility. It should not be described as a productivity guarantee, ROI report, billing source of truth, or management analytics product. + +Current aggregation includes session/message metadata available to the TUI: + +- message roles and text parts for user prompt/word counts +- assistant tokens and cost when provider metadata supplies them +- tool parts and tool timing +- session summaries for changed-file counts +- model/provider/agent labels + +If a provider or session does not supply a field, that field may be zero or absent. That is better than inventing a number. + +## Implementation paths + +See [MendCode Source Map — TUI pages and product surfaces](source-map.md#tui-pages-and-product-surfaces) for the route, aggregation, command-palette, and regression-test files. diff --git a/docs/wiki.md b/docs/wiki.md new file mode 100644 index 00000000..670ebbce --- /dev/null +++ b/docs/wiki.md @@ -0,0 +1,73 @@ +# Wiki + +GitHub Wikis are backed by a separate Git repository: + +```text +https://github.com/MendCode/MendCode.wiki.git +``` + +If the repository returns `Repository not found`, the wiki is enabled but has not been initialized with its first page. + +## Suggested Wiki Structure + +- `Home.md`: short overview and doc links. +- `Installation.md`: installer and release assets. +- `Packages.md`: company package sharing. +- `TUI-Plugins-and-Widgets.md`: plugin examples. +- `mflow.md`: coordination model. +- `TSM-and-Worktrees.md`: worktree workflows. +- `Security.md`: security reporting and public audit summary. + +## Sync Docs to Wiki + +Clone or initialize the wiki: + +```bash +git clone https://github.com/MendCode/MendCode.wiki.git /tmp/mendcode-wiki +``` + +If the wiki repo does not exist yet: + +```bash +mkdir -p /tmp/mendcode-wiki +cd /tmp/mendcode-wiki +git init +git remote add origin https://github.com/MendCode/MendCode.wiki.git +``` + +Copy selected docs: + +```bash +cp /path/to/MendCode/docs/cli-setup-configuration.md Installation.md +cp /path/to/MendCode/docs/packages-and-team-sharing.md Packages.md +cp /path/to/MendCode/docs/tui-plugins-and-widgets.md TUI-Plugins-and-Widgets.md +cp /path/to/MendCode/docs/mflow.md mflow.md +cp /path/to/MendCode/docs/tsm-and-worktrees.md TSM-and-Worktrees.md +``` + +Create `Home.md`: + +```markdown +# MendCode Wiki + +MendCode is a terminal-first coding runtime built around the `mendcode` CLI, reusable packages, mflow coordination, optional TSM/worktrees, and a customizable terminal UI. + +Start with: + +- Installation +- Packages +- TUI Plugins and Widgets +- mflow +- TSM and Worktrees +- Security +``` + +Push: + +```bash +git add . +git commit -m "Initialize MendCode wiki" +git push origin HEAD:master +``` + +The normal repo docs remain the source of truth. The wiki is a friendlier reading surface for the same material. diff --git a/docs/workflows.md b/docs/workflows.md new file mode 100644 index 00000000..8dc8df25 --- /dev/null +++ b/docs/workflows.md @@ -0,0 +1,185 @@ +# Independent Workflows + +Independent Workflows are durable, one-shot orchestration runs. They own a validated plan, phases, tasks, attempts, artifacts, gates, usage, and a root session. They are separate from recurring `LoopWorkflow` records: use a loop only when cadence or repeated wakeups are part of the request. + +## Workflow versus loop + +| Surface | Independent Workflow | Loop Workflow | +|---|---|---| +| Purpose | One validated execution | Repeated or scheduled execution | +| Canonical monitor | `/workflows` | `/loops` | +| Identity | Workflow run ID and definition revision | Loop ID and loop run ID | +| Graph | Phases, dependencies, attempts, artifacts | One root iteration plus loop gates | +| Agent View | One `Workflow` root row; child task sessions stay grouped | One `Looping` root row | + +A loop can reference a saved Workflow definition. The loop remains responsible for cadence and wakeups; `/workflows` remains responsible for the phase/task graph. + +## Plan shape + +A plan contains a name, description, objective, phases, tasks, a final task, completion criteria, required gates, and optional completion, model, permission, workspace, retry, and budget policies. Each task declares its phase, dependencies, execution kind, bounded output, and optional route/policy overrides. + +## Terminal completion + +Completing the task DAG proves that every scheduled task reached its output contract; it does not by itself prove the objective. Plans that declare `completion` use a durable terminal protocol: + +1. The finished DAG creates a generation-bound completion candidate and keeps the run non-terminal. +2. A separately leased, fresh read-only child session audits the current workspace. It must actually inspect through read-only tools; a JSON verdict without inspection is rejected. +3. Host-side allowlisted validation checks are rerun and workspace fingerprints before and after the audit must match. +4. Every criterion needs current evidence. `ownerTaskIDs` identify the tasks capable of repairing that criterion. +5. A passing receipt completes the run. A quality failure reopens only failed criterion owners and their descendants, invalidating only their artifacts. Missing ownership, stale evidence, approval, policy, budget, or environment failures remain blocked or retry according to their own gate. + +`completion.confirmation` defaults to `next-run` whenever the `completion` block is present. Definitions saved before this contract, or plans that omit the block, retain legacy `same-run` closure. Approval gates remain separate from completion gates: authorizing execution is not evidence that the objective succeeded. + +Example completion policy: + +```json +{ + "completion": { + "confirmation": "next-run", + "maxAuditAttempts": 2, + "criteria": [ + { + "id": "tests-green", + "description": "Focused regression tests pass", + "ownerTaskIDs": ["implement", "verify"] + } + ], + "validationChecks": [ + { + "id": "focused-tests", + "command": "bun test test/session/example.test.ts", + "timeoutMs": 30000 + } + ] + } +} +``` + +### Representative fan-out template + +For a bounded repository investigation, use this phase shape: + +| Phase | Tasks | Barrier and output | +|---|---:|---| +| Investigate | 8 independent agents | `all`; bounded evidence artifacts | +| Draft | 1 synthesis task | waits for investigators; one review draft | +| Verify | 6 independent verifiers | `all`; structured pass/fail artifacts | +| Synthesize | 1 final synthesis task | waits for verifiers; final report | + +Set `budget.maxFanOut` and `budget.maxConcurrency` to the intended limits, require verification artifacts before synthesis, and make the final synthesis task the plan's `finalTaskID`. Preview this graph before saving or starting it. + +Preview a new plan before starting it: + +```bash +mend workflows preview --plan-file ./plan.json +``` + +The preview validates the graph and reports phase count, task count, bounded fan-out, concurrency, estimated budgets, and side-effect classes. Preview does not create a run. + +## CLI controls + +Save an immutable revision: + +```bash +mend workflows save --plan-file ./plan.json --name "Repository review" +``` + +Start a one-shot run from a plan or saved revision: + +```bash +mend workflows start --plan-file ./plan.json +mend workflows start --revision-id +``` + +Inspect and list runs: + +```bash +mend workflows list +mend workflows show +mend workflows events --limit 50 +mend workflows artifacts --limit 50 +``` + +Control a run through the durable backend contract: + +```bash +mend workflows pause --reason "Waiting for review" +mend workflows resume +mend workflows stop --reason "No longer needed" +mend workflows delete +mend workflows retry-task --task-id +mend workflows retry-phase --phase-id +``` + +Control actions rehydrate the canonical snapshot and start or stop the runner as appropriate. A retry does not mutate the saved definition revision. + +## Session tool + +The assistant-facing `workflow` tool supports preview, save, start, list/show, pause, resume, stop, retry-task, and retry-phase actions. Prefer `preview` for a new plan. Snapshots and receipts are bounded; request artifacts or events explicitly instead of exposing full child transcripts. + +The chat receipt shows the workflow name, state, phase/task counts, elapsed time, model/agent, usage when available, blocker or next action, and an explicit link to `/workflows`. Child transcripts remain hidden until the operator opens the linked task/session. + +## TUI monitor + +Open the dedicated monitor with `/workflows`. It uses the shared `CommandDeck` layout: + +- The left rail selects active or historical runs. +- The center shows the selected run, phases, tasks, blockers, and recent events. +- The context panel shows the objective and linked root session. +- The monitor refreshes from workflow events and a bounded polling fallback. + +Keyboard controls are: + +| Key | Action | +|---|---| +| `j` / `k` or arrows | Select a run | +| `Enter` / `o` | Open the linked root/origin chat | +| `p` | Pause | +| `u` | Resume | +| `x` | Stop after confirmation | +| `d` | Delete a terminal run after confirmation | +| `t` | Retry the selected eligible task | +| `f` | Retry the selected eligible phase | +| `r` | Rehydrate the canonical snapshot | +| `q` / `Esc` | Return to the previous route | + +Agent View shows one distinct Workflow root row with state, current phase, completed/total tasks, active tasks, and blocked or input-needed indicators. If the root or origin session is unavailable, the row remains visible and opens the `/workflows` monitor by run ID. + +## API surface + +The instance API exposes these additive endpoints: + +```text +POST /workflow/preview +POST /workflow/save +POST /workflow/start +GET /workflow +GET /workflow/:runID +DELETE /workflow/:runID +GET /workflow/:runID/events +GET /workflow/:runID/artifacts +POST /workflow/:runID/pause +POST /workflow/:runID/resume +POST /workflow/:runID/stop +POST /workflow/:runID/retry-task +POST /workflow/:runID/retry-phase +``` + +`GET /workflow/:runID` is the canonical durable snapshot used to rehydrate the monitor after reconnects or event loss. Runs are project-scoped by the instance context, and control routes enforce the backend policy/state contract rather than trusting local UI state. + +## Safety and limits + +- Plan validation rejects cycles and invalid phase/task references before execution. +- Workflow policy is narrowed by task policy; a task cannot escalate permissions, workspace access, or side-effect classes. +- Report-only and read-only modes deny edits, mutating commands, and external sends. +- Required gates remain durable and cannot be waived by model output. +- Strict completion runs cannot become `completed` without a current audit receipt; leases and generations reject duplicate, late, or post-restart stale audit results. +- Fan-out, concurrency, depth, child, runtime, token, cost, artifact, and event limits remain bounded. +- Actual agent attempts reuse the durable `BackgroundTask` supervisor; Workflow owns graph readiness while BackgroundTask owns task leases, generations, cancellation, and bounded results. +- Full child output is not rendered in the chat receipt or Agent View by default. + +## Release and rollout + +One-shot Workflow execution is additive and can be enabled independently from loop-triggered adapters. Keep the loop adapter behind the scheduler durability evidence and service-health gate. Existing Loop records and `/loops` behavior remain unchanged when no Workflow reference is present. + +─── ?DOC | 1 doc creado diff --git a/graf-reference.png b/graf-reference.png new file mode 100644 index 00000000..ee901c59 Binary files /dev/null and b/graf-reference.png differ diff --git a/mend-package.json b/mend-package.json new file mode 100644 index 00000000..fad3e4e5 --- /dev/null +++ b/mend-package.json @@ -0,0 +1,35 @@ +{ + "version": 0, + "id": "codex-local", + "packageVersion": "0.1.0", + "title": "MendCode Local Runtime Pack", + "description": "Local-first MendCode package manifest generated from shareable project configuration.", + "kind": "bundle", + "channel": "local", + "compatibility": { + "mendcode": "^0.1.20", + "runtimePack": "^0" + }, + "artifacts": { + "agents": [ + ".mendcode/agents/sub/arrogant-savant.md", + ".mendcode/agents/sub/mythos.md" + ], + "plugins": [ + ".mendcode/plugins/mflow-lock.js" + ], + "mcp": [ + ".mendcode/mcp/mflow.json", + ".mendcode/mcp/playwright.json" + ] + }, + "distribution": { + "source": { + "type": "local", + "url": null + }, + "trust": { + "signatureRequired": false + } + } +} diff --git a/src/mendcode/.github/actions/setup-bun/action.yml b/src/mendcode/.github/actions/setup-bun/action.yml index 9859174a..fa3aaad6 100644 --- a/src/mendcode/.github/actions/setup-bun/action.yml +++ b/src/mendcode/.github/actions/setup-bun/action.yml @@ -23,7 +23,7 @@ runs: fi - name: Setup Bun - uses: oven-sh/setup-bun@v2 + uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 with: bun-version-file: ${{ !steps.bun-url.outputs.url && 'package.json' || '' }} bun-download-url: ${{ steps.bun-url.outputs.url }} @@ -34,7 +34,7 @@ runs: run: echo "dir=$(bun pm cache)" >> "$GITHUB_OUTPUT" - name: Cache Bun dependencies - uses: actions/cache@v4 + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 with: path: ${{ steps.cache.outputs.dir }} key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }} @@ -46,13 +46,25 @@ runs: shell: bash - name: Install dependencies + env: + SETUP_BUN_INSTALL_FLAGS: ${{ inputs.install-flags }} run: | # Workaround for patched peer variants # e.g. ./patches/ for standard-openapi # https://github.com/oven-sh/bun/issues/28147 + install_flags="${SETUP_BUN_INSTALL_FLAGS:-}" + case "$install_flags" in + ""|"--frozen-lockfile"|"--ignore-scripts"|"--production"|"--frozen-lockfile --ignore-scripts"|"--production --frozen-lockfile") + ;; + *) + echo "Unsupported bun install flags: $install_flags" >&2 + exit 1 + ;; + esac + read -r -a extra_flags <<< "$install_flags" if [ "$RUNNER_OS" = "Windows" ]; then - bun install --linker hoisted ${{ inputs.install-flags }} + bun install --linker hoisted "${extra_flags[@]}" else - bun install ${{ inputs.install-flags }} + bun install "${extra_flags[@]}" fi shell: bash diff --git a/src/mendcode/.github/actions/setup-git-committer/action.yml b/src/mendcode/.github/actions/setup-git-committer/action.yml index 428cb051..94af5b5c 100644 --- a/src/mendcode/.github/actions/setup-git-committer/action.yml +++ b/src/mendcode/.github/actions/setup-git-committer/action.yml @@ -19,17 +19,18 @@ runs: steps: - name: Create app token id: apptoken - uses: actions/create-github-app-token@v2 + uses: actions/create-github-app-token@fee1f7d63c2ff003460e3d139729b119787bc349 with: - app-id: ${{ inputs.mendcode-app-id }} - private-key: ${{ inputs.mendcode-app-secret }} - owner: ${{ github.repository_owner }} + app-id: ${{ inputs.opencode-app-id }} + private-key: ${{ inputs.opencode-app-secret }} + permission-contents: write - name: Configure git user + env: + APP_SLUG: ${{ steps.apptoken.outputs.app-slug }} run: | - slug="${{ steps.apptoken.outputs.app-slug }}" - git config --global user.name "${slug}[bot]" - git config --global user.email "${slug}[bot]@users.noreply.github.com" + git config --global user.name "${APP_SLUG}[bot]" + git config --global user.email "${APP_SLUG}[bot]@users.noreply.github.com" shell: bash - name: Clear checkout auth @@ -38,6 +39,9 @@ runs: shell: bash - name: Configure git remote + env: + APP_TOKEN: ${{ steps.apptoken.outputs.token }} + REPOSITORY: ${{ github.repository }} run: | - git remote set-url origin https://x-access-token:${{ steps.apptoken.outputs.token }}@github.com/${{ github.repository }} + git remote set-url origin "https://x-access-token:${APP_TOKEN}@github.com/${REPOSITORY}" shell: bash diff --git a/src/mendcode/.npmrc b/src/mendcode/.npmrc new file mode 100644 index 00000000..97f8d594 --- /dev/null +++ b/src/mendcode/.npmrc @@ -0,0 +1,2 @@ +minimum-release-age=10080 +save-exact=true diff --git a/src/mendcode/UPCOMING_CHANGELOG.md b/src/mendcode/UPCOMING_CHANGELOG.md new file mode 100644 index 00000000..335ca48e --- /dev/null +++ b/src/mendcode/UPCOMING_CHANGELOG.md @@ -0,0 +1,17 @@ +Last release: v0.1.22 +Target ref: v0.1.23 + +## Loop Workflows + +- Added scheduler health and wake metadata, retry/backoff state, run leases, completion state, and safer CLI/API reporting for durable loops. + +## Context and compaction + +- Set GPT-5.6 ChatGPT OAuth models to a 256K effective input/context limit and a provider-aware 90% compaction threshold. +- Improved compaction summaries and local transcript continuity across live updates, reconnects, and resumed work. + +## TUI reliability + +- Improved session synchronization, virtual transcript windows, Changes Review rendering, setup copy, and smart permission review state. +- Added focused regressions for loop lifecycle, session layout, compaction, provider adapters, and permission paths. +- Fixed cross-platform release smoke tests to validate the public `Usage:` help header. diff --git a/src/mendcode/bun.lock b/src/mendcode/bun.lock index e8584bf4..55c23e29 100644 --- a/src/mendcode/bun.lock +++ b/src/mendcode/bun.lock @@ -23,178 +23,13 @@ "prettier": "3.6.2", "semver": "^7.6.0", "sst": "3.18.10", - "turbo": "2.8.13", - }, - }, - "packages/app": { - "name": "@mendcode/app", - "version": "1.14.39", - "dependencies": { - "@kobalte/core": "catalog:", - "@mendcode/core": "workspace:*", - "@mendcode/sdk": "workspace:*", - "@mendcode/ui": "workspace:*", - "@sentry/solid": "catalog:", - "@shikijs/transformers": "3.9.2", - "@solid-primitives/active-element": "2.1.3", - "@solid-primitives/audio": "1.4.2", - "@solid-primitives/event-bus": "1.1.2", - "@solid-primitives/event-listener": "2.4.5", - "@solid-primitives/i18n": "2.2.1", - "@solid-primitives/media": "2.3.3", - "@solid-primitives/resize-observer": "2.1.5", - "@solid-primitives/scroll": "2.1.3", - "@solid-primitives/storage": "catalog:", - "@solid-primitives/timer": "1.4.4", - "@solid-primitives/websocket": "1.3.1", - "@solidjs/meta": "catalog:", - "@solidjs/router": "catalog:", - "@tanstack/solid-query": "5.91.4", - "@thisbeyond/solid-dnd": "0.7.5", - "diff": "catalog:", - "effect": "catalog:", - "fuzzysort": "catalog:", - "ghostty-web": "github:anomalyco/ghostty-web#main", - "luxon": "catalog:", - "marked": "catalog:", - "marked-shiki": "catalog:", - "remeda": "catalog:", - "shiki": "catalog:", - "solid-js": "catalog:", - "solid-list": "catalog:", - "tailwindcss": "catalog:", - "virtua": "catalog:", - "zod": "catalog:", - }, - "devDependencies": { - "@happy-dom/global-registrator": "20.0.11", - "@playwright/test": "catalog:", - "@sentry/vite-plugin": "catalog:", - "@tailwindcss/vite": "catalog:", - "@tsconfig/bun": "1.0.9", - "@types/bun": "catalog:", - "@types/luxon": "catalog:", - "@types/node": "catalog:", - "@typescript/native-preview": "catalog:", - "typescript": "catalog:", - "vite": "catalog:", - "vite-plugin-icons-spritesheet": "3.0.1", - "vite-plugin-solid": "catalog:", - }, - }, - "packages/console/app": { - "name": "@mendcode/console-app", - "version": "1.14.39", - "dependencies": { - "@cloudflare/vite-plugin": "1.15.2", - "@ibm/plex": "6.4.1", - "@jsx-email/render": "1.1.1", - "@kobalte/core": "catalog:", - "@openauthjs/openauth": "catalog:", - "@mendcode/console-core": "workspace:*", - "@mendcode/console-mail": "workspace:*", - "@mendcode/console-resource": "workspace:*", - "@mendcode/ui": "workspace:*", - "@smithy/eventstream-codec": "4.2.7", - "@smithy/util-utf8": "4.2.0", - "@solidjs/meta": "catalog:", - "@solidjs/router": "catalog:", - "@solidjs/start": "catalog:", - "@stripe/stripe-js": "8.6.1", - "chart.js": "4.5.1", - "nitro": "3.0.1-alpha.1", - "solid-js": "catalog:", - "solid-list": "0.3.0", - "solid-stripe": "0.8.1", - "svix": "1.92.2", - "vite": "catalog:", - "zod": "catalog:", - }, - "devDependencies": { - "@typescript/native-preview": "catalog:", - "@webgpu/types": "0.1.54", - "typescript": "catalog:", - "wrangler": "4.50.0", - }, - }, - "packages/console/core": { - "name": "@mendcode/console-core", - "version": "1.14.39", - "dependencies": { - "@aws-sdk/client-sts": "3.782.0", - "@jsx-email/render": "1.1.1", - "@mendcode/console-mail": "workspace:*", - "@mendcode/console-resource": "workspace:*", - "@planetscale/database": "1.19.0", - "aws4fetch": "1.0.20", - "drizzle-orm": "catalog:", - "postgres": "3.4.7", - "stripe": "18.0.0", - "ulid": "catalog:", - "zod": "catalog:", - }, - "devDependencies": { - "@cloudflare/workers-types": "catalog:", - "@tsconfig/node22": "22.0.2", - "@types/bun": "catalog:", - "@types/node": "catalog:", - "@typescript/native-preview": "catalog:", - "drizzle-kit": "catalog:", - "mysql2": "3.14.4", - "typescript": "catalog:", - }, - }, - "packages/console/function": { - "name": "@mendcode/console-function", - "version": "1.14.39", - "dependencies": { - "@ai-sdk/anthropic": "3.0.64", - "@ai-sdk/openai": "3.0.48", - "@ai-sdk/openai-compatible": "2.0.37", - "@hono/zod-validator": "catalog:", - "@openauthjs/openauth": "0.0.0-20250322224806", - "@mendcode/console-core": "workspace:*", - "@mendcode/console-resource": "workspace:*", - "ai": "catalog:", - "hono": "catalog:", - "zod": "catalog:", - }, - "devDependencies": { - "@cloudflare/workers-types": "catalog:", - "@tsconfig/node22": "22.0.2", - "@types/node": "catalog:", - "@typescript/native-preview": "catalog:", - "openai": "5.11.0", - "typescript": "catalog:", - }, - }, - "packages/console/mail": { - "name": "@mendcode/console-mail", - "version": "1.14.39", - "dependencies": { - "@jsx-email/all": "2.2.3", - "@jsx-email/cli": "1.4.3", - "@tsconfig/bun": "1.0.9", - "@types/react": "18.0.25", - "react": "18.2.0", - "solid-js": "catalog:", - }, - }, - "packages/console/resource": { - "name": "@mendcode/console-resource", - "dependencies": { - "@cloudflare/workers-types": "catalog:", - }, - "devDependencies": { - "@cloudflare/workers-types": "catalog:", - "@tsconfig/node22": "22.0.2", - "@types/node": "catalog:", - "cloudflare": "5.2.0", + "turbo": "2.9.14", + "valibot": "1.4.2", }, }, "packages/core": { "name": "@mendcode/core", - "version": "1.14.39", + "version": "0.1.9", "bin": { "opencode": "./bin/opencode", }, @@ -204,9 +39,9 @@ "@npmcli/arborist": "9.4.0", "@npmcli/config": "10.8.1", "@opentelemetry/api": "1.9.0", - "@opentelemetry/context-async-hooks": "2.6.1", - "@opentelemetry/exporter-trace-otlp-http": "0.214.0", - "@opentelemetry/sdk-trace-base": "2.6.1", + "@opentelemetry/context-async-hooks": "2.8.0", + "@opentelemetry/exporter-trace-otlp-http": "0.219.0", + "@opentelemetry/sdk-trace-base": "2.8.0", "cross-spawn": "catalog:", "effect": "catalog:", "glob": "13.0.5", @@ -226,92 +61,9 @@ "@types/semver": "catalog:", }, }, - "packages/desktop": { - "name": "@mendcode/desktop", - "version": "1.14.39", - "dependencies": { - "drizzle-orm": "catalog:", - "effect": "catalog:", - "electron-context-menu": "4.1.2", - "electron-log": "^5", - "electron-store": "^10", - "electron-updater": "^6", - "electron-window-state": "^5.0.3", - "marked": "^15", - }, - "devDependencies": { - "@actions/artifact": "4.0.0", - "@lydell/node-pty": "catalog:", - "@mendcode/app": "workspace:*", - "@mendcode/ui": "workspace:*", - "@sentry/solid": "catalog:", - "@sentry/vite-plugin": "catalog:", - "@solid-primitives/i18n": "2.2.1", - "@solid-primitives/storage": "catalog:", - "@solidjs/meta": "catalog:", - "@solidjs/router": "0.15.4", - "@types/bun": "catalog:", - "@types/node": "catalog:", - "@typescript/native-preview": "catalog:", - "@valibot/to-json-schema": "1.6.0", - "electron": "41.2.1", - "electron-builder": "^26", - "electron-vite": "^5", - "solid-js": "catalog:", - "sury": "11.0.0-alpha.4", - "typescript": "~5.6.2", - "vite": "catalog:", - "zod-openapi": "5.4.6", - }, - "optionalDependencies": { - "@lydell/node-pty-darwin-arm64": "1.2.0-beta.10", - "@lydell/node-pty-darwin-x64": "1.2.0-beta.10", - "@lydell/node-pty-linux-arm64": "1.2.0-beta.10", - "@lydell/node-pty-linux-x64": "1.2.0-beta.10", - "@lydell/node-pty-win32-arm64": "1.2.0-beta.10", - "@lydell/node-pty-win32-x64": "1.2.0-beta.10", - "@parcel/watcher-darwin-arm64": "2.5.1", - "@parcel/watcher-darwin-x64": "2.5.1", - "@parcel/watcher-linux-arm64-glibc": "2.5.1", - "@parcel/watcher-linux-arm64-musl": "2.5.1", - "@parcel/watcher-linux-x64-glibc": "2.5.1", - "@parcel/watcher-linux-x64-musl": "2.5.1", - "@parcel/watcher-win32-arm64": "2.5.1", - "@parcel/watcher-win32-x64": "2.5.1", - }, - }, - "packages/enterprise": { - "name": "@mendcode/enterprise", - "version": "1.14.39", - "dependencies": { - "@mendcode/core": "workspace:*", - "@mendcode/ui": "workspace:*", - "@pierre/diffs": "catalog:", - "@solidjs/meta": "catalog:", - "@solidjs/router": "catalog:", - "@solidjs/start": "catalog:", - "aws4fetch": "^1.0.20", - "hono": "catalog:", - "hono-openapi": "catalog:", - "js-base64": "3.7.7", - "luxon": "catalog:", - "nitro": "3.0.1-alpha.1", - "solid-js": "catalog:", - "zod": "catalog:", - }, - "devDependencies": { - "@cloudflare/workers-types": "catalog:", - "@tailwindcss/vite": "catalog:", - "@types/luxon": "catalog:", - "@typescript/native-preview": "catalog:", - "tailwindcss": "catalog:", - "typescript": "catalog:", - "vite": "catalog:", - }, - }, "packages/function": { "name": "@mendcode/function", - "version": "1.14.39", + "version": "0.1.9", "dependencies": { "@octokit/auth-app": "8.0.1", "@octokit/rest": "catalog:", @@ -327,9 +79,10 @@ }, "packages/opencode": { "name": "mendcode", - "version": "1.14.39", + "version": "0.1.44", "bin": { - "mend-runtime": "./bin/opencode", + "mendcode": "./bin/opencode", + "mendcode-runtime": "./bin/opencode", }, "dependencies": { "@actions/core": "1.11.1", @@ -350,34 +103,36 @@ "@ai-sdk/openai": "3.0.53", "@ai-sdk/openai-compatible": "2.0.41", "@ai-sdk/perplexity": "3.0.26", - "@ai-sdk/provider": "3.0.8", - "@ai-sdk/provider-utils": "4.0.23", + "@ai-sdk/provider": "3.0.12", + "@ai-sdk/provider-utils": "4.0.33", "@ai-sdk/togetherai": "2.0.41", "@ai-sdk/vercel": "2.0.39", "@ai-sdk/xai": "3.0.82", + "@anthropic-ai/claude-agent-sdk": "0.3.187", + "@anthropic-ai/sdk": "0.105.0", "@aws-sdk/credential-providers": "3.993.0", "@clack/prompts": "1.0.0-alpha.1", "@effect/opentelemetry": "catalog:", "@effect/platform-node": "catalog:", "@gitlab/opencode-gitlab-auth": "1.3.3", - "@hono/node-server": "1.19.11", + "@hono/node-server": "2.0.10", "@hono/node-ws": "1.3.0", "@hono/standard-validator": "0.1.5", "@hono/zod-validator": "catalog:", "@lydell/node-pty": "catalog:", - "@modelcontextprotocol/sdk": "1.27.1", - "@octokit/graphql": "9.0.2", - "@octokit/rest": "catalog:", - "@openauthjs/openauth": "catalog:", "@mendcode/plugin": "workspace:*", "@mendcode/script": "workspace:*", "@mendcode/sdk": "workspace:*", + "@modelcontextprotocol/sdk": "1.29.0", + "@octokit/graphql": "9.0.2", + "@octokit/rest": "catalog:", + "@openauthjs/openauth": "catalog:", "@openrouter/ai-sdk-provider": "2.8.1", "@opentelemetry/api": "1.9.0", - "@opentelemetry/context-async-hooks": "2.6.1", - "@opentelemetry/exporter-trace-otlp-http": "0.214.0", - "@opentelemetry/sdk-trace-base": "2.6.1", - "@opentelemetry/sdk-trace-node": "2.6.1", + "@opentelemetry/context-async-hooks": "2.8.0", + "@opentelemetry/exporter-trace-otlp-http": "0.219.0", + "@opentelemetry/sdk-trace-base": "2.8.0", + "@opentelemetry/sdk-trace-node": "2.8.0", "@opentui/core": "catalog:", "@opentui/solid": "catalog:", "@parcel/watcher": "2.5.1", @@ -409,7 +164,7 @@ "immer": "11.1.4", "jsonc-parser": "3.3.1", "mime-types": "3.0.2", - "minimatch": "10.0.3", + "minimatch": "10.2.3", "npm-package-arg": "13.0.2", "open": "10.1.2", "opencode-gitlab-auth": "2.0.1", @@ -434,10 +189,10 @@ "zod-to-json-schema": "3.24.5", }, "devDependencies": { - "@babel/core": "7.28.4", - "@octokit/webhooks-types": "7.6.1", + "@babel/core": "7.29.6", "@mendcode/core": "workspace:*", "@mendcode/script": "workspace:*", + "@octokit/webhooks-types": "7.6.1", "@parcel/watcher-darwin-arm64": "2.5.1", "@parcel/watcher-darwin-x64": "2.5.1", "@parcel/watcher-linux-arm64-glibc": "2.5.1", @@ -469,7 +224,7 @@ }, "packages/plugin": { "name": "@mendcode/plugin", - "version": "1.14.39", + "version": "0.1.9", "dependencies": { "@mendcode/sdk": "workspace:*", "effect": "catalog:", @@ -504,12 +259,12 @@ }, "packages/sdk/js": { "name": "@mendcode/sdk", - "version": "1.14.39", + "version": "0.1.9", "dependencies": { "cross-spawn": "catalog:", }, "devDependencies": { - "@hey-api/openapi-ts": "0.90.10", + "@hey-api/openapi-ts": "0.97.3", "@tsconfig/node22": "catalog:", "@types/cross-spawn": "catalog:", "@types/node": "catalog:", @@ -519,10 +274,10 @@ }, "packages/slack": { "name": "@mendcode/slack", - "version": "1.14.39", + "version": "0.1.9", "dependencies": { "@mendcode/sdk": "workspace:*", - "@slack/bolt": "^3.17.1", + "@slack/bolt": "4.7.3", }, "devDependencies": { "@types/node": "catalog:", @@ -530,31 +285,9 @@ "typescript": "catalog:", }, }, - "packages/storybook": { - "name": "@mendcode/storybook", - "devDependencies": { - "@mendcode/ui": "workspace:*", - "@solidjs/meta": "catalog:", - "@storybook/addon-a11y": "^10.2.13", - "@storybook/addon-docs": "^10.2.13", - "@storybook/addon-links": "^10.2.13", - "@storybook/addon-onboarding": "^10.2.13", - "@storybook/addon-vitest": "^10.2.13", - "@tailwindcss/vite": "catalog:", - "@tsconfig/node22": "catalog:", - "@types/node": "catalog:", - "@types/react": "18.0.25", - "react": "18.2.0", - "solid-js": "catalog:", - "storybook": "^10.2.13", - "storybook-solidjs-vite": "^10.0.9", - "typescript": "catalog:", - "vite": "catalog:", - }, - }, "packages/ui": { "name": "@mendcode/ui", - "version": "1.14.39", + "version": "0.1.9", "dependencies": { "@kobalte/core": "catalog:", "@mendcode/core": "workspace:*", @@ -568,7 +301,7 @@ "@solidjs/meta": "catalog:", "@solidjs/router": "catalog:", "diff": "catalog:", - "dompurify": "3.3.1", + "dompurify": "3.4.13", "fuzzysort": "catalog:", "katex": "0.16.27", "luxon": "catalog:", @@ -601,46 +334,10 @@ "vite-plugin-solid": "catalog:", }, }, - "packages/web": { - "name": "@mendcode/web", - "version": "1.14.39", - "dependencies": { - "@astrojs/cloudflare": "12.6.3", - "@astrojs/markdown-remark": "6.3.1", - "@astrojs/solid-js": "5.1.0", - "@astrojs/starlight": "0.34.3", - "@fontsource/ibm-plex-mono": "5.2.5", - "@shikijs/transformers": "3.20.0", - "@solid-primitives/resize-observer": "2.1.5", - "@types/luxon": "catalog:", - "ai": "catalog:", - "astro": "5.7.13", - "diff": "catalog:", - "js-base64": "3.7.7", - "lang-map": "0.4.0", - "luxon": "catalog:", - "marked": "catalog:", - "marked-shiki": "catalog:", - "rehype-autolink-headings": "7.1.0", - "remeda": "catalog:", - "shiki": "catalog:", - "solid-js": "catalog:", - "toolbeam-docs-theme": "0.4.8", - "vscode-languageserver-types": "3.17.5", - }, - "devDependencies": { - "@astrojs/check": "0.9.6", - "@types/node": "catalog:", - "mendcode": "file:../opencode", - "typescript": "catalog:", - }, - }, }, "trustedDependencies": [ "esbuild", "tree-sitter-powershell", - "protobufjs", - "electron", "web-tree-sitter", "tree-sitter-bash", ], @@ -650,8 +347,56 @@ "@npmcli/agent@4.0.0": "patches/@npmcli%2Fagent@4.0.0.patch", }, "overrides": { + "@ai-sdk/provider": "3.0.12", + "@ai-sdk/provider-utils": "4.0.33", + "@babel/core": "7.29.6", + "@hono/node-server": "2.0.10", + "@modelcontextprotocol/sdk": "1.27.1", + "@opentelemetry/context-async-hooks": "2.8.0", + "@opentelemetry/core": "2.8.0", + "@opentelemetry/exporter-trace-otlp-http": "0.219.0", + "@opentelemetry/otlp-exporter-base": "0.219.0", + "@opentelemetry/otlp-transformer": "0.219.0", + "@opentelemetry/resources": "2.8.0", + "@opentelemetry/sdk-logs": "0.219.0", + "@opentelemetry/sdk-metrics": "2.8.0", + "@opentelemetry/sdk-trace-base": "2.8.0", + "@opentelemetry/sdk-trace-node": "2.8.0", + "@sigstore/core": "3.2.1", + "@sigstore/verify": "3.1.1", "@types/bun": "catalog:", "@types/node": "catalog:", + "axios": "1.18.0", + "body-parser": "2.3.0", + "brace-expansion": "5.0.9", + "browserslist": "4.28.7", + "diff": "8.0.3", + "esbuild": "0.28.1", + "fast-uri": "3.1.6", + "fast-xml-builder": "1.1.7", + "fast-xml-parser": "5.7.0", + "fastify": "5.12.1", + "file-type": "21.3.2", + "find-my-way": "9.7.0", + "form-data": "4.0.6", + "hono": "4.13.5", + "ip-address": "10.3.1", + "js-yaml": "4.3.2", + "mysql2": "3.23.1", + "postcss": "8.5.23", + "postcss-selector-parser": "7.1.3", + "protobufjs": "7.6.3", + "qs": "6.16.0", + "seroval": "1.5.3", + "shell-quote": "1.9.0", + "sigstore": "4.1.1", + "socket.io-parser": "4.2.7", + "tar": "7.5.21", + "toml": "4.2.0", + "undici": "8.9.0", + "uuid": "13.0.1", + "valibot": "1.4.2", + "ws": "8.21.0", }, "catalog": { "@cloudflare/workers-types": "4.20251008.0", @@ -684,13 +429,13 @@ "@typescript/native-preview": "7.0.0-dev.20251207.1", "ai": "6.0.168", "cross-spawn": "7.0.6", - "diff": "8.0.2", - "dompurify": "3.3.1", - "drizzle-kit": "1.0.0-beta.19-d95b7a4", - "drizzle-orm": "1.0.0-beta.19-d95b7a4", + "diff": "8.0.3", + "dompurify": "3.4.13", + "drizzle-kit": "1.0.0-beta.20", + "drizzle-orm": "1.0.0-beta.20", "effect": "4.0.0-beta.59", "fuzzysort": "3.1.0", - "hono": "4.10.7", + "hono": "4.13.5", "hono-openapi": "1.1.2", "luxon": "3.6.1", "marked": "17.0.1", @@ -706,13 +451,11 @@ "typescript": "5.8.2", "ulid": "3.0.1", "virtua": "0.42.3", - "vite": "7.1.4", + "vite": "7.3.5", "vite-plugin-solid": "2.11.10", "zod": "4.1.8", }, "packages": { - "7zip-bin": ["7zip-bin@5.2.0", "", {}, "sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A=="], - "@actions/artifact": ["@actions/artifact@5.0.1", "", { "dependencies": { "@actions/core": "^2.0.0", "@actions/github": "^6.0.1", "@actions/http-client": "^3.0.0", "@azure/storage-blob": "^12.29.1", "@octokit/core": "^5.2.1", "@octokit/plugin-request-log": "^1.0.4", "@octokit/plugin-retry": "^3.0.9", "@octokit/request": "^8.4.1", "@octokit/request-error": "^5.1.1", "@protobuf-ts/plugin": "^2.2.3-alpha.1", "archiver": "^7.0.1", "jwt-decode": "^3.1.2", "unzip-stream": "^0.3.1" } }, "sha512-dHJ5rHduhCKUikKTT9eXeWoUvfKia3IjR1sO/VTAV3DVAL4yMTRnl2iO5mcfiBjySHLwPNezwENAVskKYU5ymw=="], "@actions/core": ["@actions/core@1.11.1", "", { "dependencies": { "@actions/exec": "^1.1.1", "@actions/http-client": "^2.0.1" } }, "sha512-hXJCSrkwfA46Vd9Z3q4cpEpHB1rL5NG04+/rbqW9d3+CSvtB1tYe8UTpAlixa1vj0m/ULglfEK2UKxMGxCxv5A=="], @@ -733,7 +476,7 @@ "@ai-sdk/amazon-bedrock": ["@ai-sdk/amazon-bedrock@4.0.96", "", { "dependencies": { "@ai-sdk/anthropic": "3.0.71", "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.23", "@smithy/eventstream-codec": "^4.0.1", "@smithy/util-utf8": "^4.0.0", "aws4fetch": "^1.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-Mc4Ias2jRMD1jOB6xWtKNPdhECeuCZyIlbr9EAGfBnyBt++sS13ziZh9qv9TdyMCAZJ7xoQcpbchoRJcKwPdpA=="], - "@ai-sdk/anthropic": ["@ai-sdk/anthropic@3.0.64", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.21" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-rwLi/Rsuj2pYniQXIrvClHvXDzgM4UQHHnvHTWEF14efnlKclG/1ghpNC+adsRujAbCTr6gRsSbDE2vEqriV7g=="], + "@ai-sdk/anthropic": ["@ai-sdk/anthropic@3.0.71", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.23" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-bUWOzrzR0gJKJO/PLGMR4uH2dqEgqGhrsCV+sSpk4KtOEnUQlfjZI/F7BFlqSvVpFbjdgYRRLysAeEZpJ6S1lg=="], "@ai-sdk/azure": ["@ai-sdk/azure@3.0.49", "", { "dependencies": { "@ai-sdk/openai": "3.0.48", "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.21" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-wskgAL+OmrHG7by/iWIxEBQCEdc1mDudha/UZav46i0auzdFfsDB/k2rXZaC4/3nWSgMZkxr0W3ncyouEGX/eg=="], @@ -761,15 +504,15 @@ "@ai-sdk/mistral": ["@ai-sdk/mistral@3.0.27", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.21" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-ZXe7nZQgliDdjz5ufH5RKpHWxbN72AzmzzKGbF/z+0K9GN5tUCnftrQRvTRFHA5jAzTapcm2BEevmGLVbMkW+A=="], - "@ai-sdk/openai": ["@ai-sdk/openai@3.0.48", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.21" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-ALmj/53EXpcRqMbGpPJPP4UOSWw0q4VGpnDo7YctvsynjkrKDmoneDG/1a7VQnSPYHnJp6tTRMf5ZdxZ5whulg=="], + "@ai-sdk/openai": ["@ai-sdk/openai@3.0.53", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.23" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-Wld+Rbc05KaUn08uBt06eEuwcgalcIFtIl32Yp+GxuZXUQwOb6YeAuq+C6da4ch6BurFoqEaLemJVwjBb7x+PQ=="], - "@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@2.0.37", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.21" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-+POSFVcgiu47BK64dhsI6OpcDC0/VAE2ZSaXdXGNNhpC/ava++uSRJYks0k2bpfY0wwCTgpAWZsXn/dG2Yppiw=="], + "@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@2.0.41", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.23" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-kNAGINk71AlOXx10Dq/PXw4t/9XjdK8uxfpVElRwtSFMdeSiLVt58p9TPx4/FJD+hxZuVhvxYj9r42osxWq79g=="], "@ai-sdk/perplexity": ["@ai-sdk/perplexity@3.0.26", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.21" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-dXzrVsLR5f6tr+U04jq4AXoRroGFBTvODnLgss0SWbzNjGGQg3XqtQ9j7rCLo6o8qbYGuAHvqUrIpUCuiscuFg=="], - "@ai-sdk/provider": ["@ai-sdk/provider@3.0.8", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-oGMAgGoQdBXbZqNG0Ze56CHjDZ1IDYOwGYxYjO5KLSlz5HiNQ9udIXsPZ61VWaHGZ5XW/jyjmr6t2xz2jGVwbQ=="], + "@ai-sdk/provider": ["@ai-sdk/provider@3.0.12", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-sj9DWTJ2Ze0WR9qsiOPqoqzNx3OxL6iMxHImbhvoe9qOspekbzxNDMiJ4TIGfYHYh9w4OmBjz3prvqhzTi96+Q=="], - "@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@4.0.23", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-z8GlDaCmRSDlqkMF2f4/RFgWxdarvIbyuk+m6WXT1LYgsnGiXRJGTD2Z1+SDl3LqtFuRtGX1aghYvQLoHL/9pg=="], + "@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@4.0.33", "", { "dependencies": { "@ai-sdk/provider": "3.0.12", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.8" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-nJ0bAfegMAIJtrzMJtbzer1cS3nb7c7DsyU1S4nrPm7ZU0Mn6SBBZv5IGZZGTbpWTJwqKTSPeZJTXalbAxt1BA=="], "@ai-sdk/togetherai": ["@ai-sdk/togetherai@2.0.41", "", { "dependencies": { "@ai-sdk/openai-compatible": "2.0.37", "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.21" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-k3p9e3k0/gpDDyTtvafsK4HYR4D/aUQW/kzCwWo1+CzdBU84i4L14gWISC/mv6tgSicMXHcEUd521fPufQwNlg=="], @@ -777,41 +520,29 @@ "@ai-sdk/xai": ["@ai-sdk/xai@3.0.82", "", { "dependencies": { "@ai-sdk/openai-compatible": "2.0.41", "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.23" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-A0VFMufnVf4wODcT3SPQUUzvYXiIO1VhFuXj9r6z/vP4rlo+QRDPw3WSTchcz93ROQWSfBE3I6Szqz342OHi5w=="], - "@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="], - "@ampproject/remapping": ["@ampproject/remapping@2.3.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw=="], - "@anthropic-ai/sdk": ["@anthropic-ai/sdk@0.71.2", "", { "dependencies": { "json-schema-to-ts": "^3.1.1" }, "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" }, "optionalPeers": ["zod"], "bin": { "anthropic-ai-sdk": "bin/cli" } }, "sha512-TGNDEUuEstk/DKu0/TflXAEt+p+p/WhTlFzEnoosvbaDU2LTjm42igSdlL0VijrKpWejtOKxX0b8A7uc+XiSAQ=="], - - "@anycable/core": ["@anycable/core@0.9.2", "", { "dependencies": { "nanoevents": "^7.0.1" } }, "sha512-x5ZXDcW/N4cxWl93CnbHs/u7qq4793jS2kNPWm+duPrXlrva+ml2ZGT7X9tuOBKzyIHf60zWCdIK7TUgMPAwXA=="], - - "@astrojs/check": ["@astrojs/check@0.9.6", "", { "dependencies": { "@astrojs/language-server": "^2.16.1", "chokidar": "^4.0.1", "kleur": "^4.1.5", "yargs": "^17.7.2" }, "peerDependencies": { "typescript": "^5.0.0" }, "bin": { "astro-check": "bin/astro-check.js" } }, "sha512-jlaEu5SxvSgmfGIFfNgcn5/f+29H61NJzEMfAZ82Xopr4XBchXB1GVlcJsE+elUlsYSbXlptZLX+JMG3b/wZEA=="], + "@anthropic-ai/claude-agent-sdk": ["@anthropic-ai/claude-agent-sdk@0.3.187", "", { "optionalDependencies": { "@anthropic-ai/claude-agent-sdk-darwin-arm64": "0.3.187", "@anthropic-ai/claude-agent-sdk-darwin-x64": "0.3.187", "@anthropic-ai/claude-agent-sdk-linux-arm64": "0.3.187", "@anthropic-ai/claude-agent-sdk-linux-arm64-musl": "0.3.187", "@anthropic-ai/claude-agent-sdk-linux-x64": "0.3.187", "@anthropic-ai/claude-agent-sdk-linux-x64-musl": "0.3.187", "@anthropic-ai/claude-agent-sdk-win32-arm64": "0.3.187", "@anthropic-ai/claude-agent-sdk-win32-x64": "0.3.187" }, "peerDependencies": { "@anthropic-ai/sdk": ">=0.93.0", "@modelcontextprotocol/sdk": "^1.29.0", "zod": "^4.0.0" } }, "sha512-HHkuC3he/Wi8fX/WjfS8mJr4TFPGoAd1QyxOuTwjnyOLboGkX1H+UhBYLxHX1ouFvHnYVJglB2wsuWemVQgahQ=="], - "@astrojs/cloudflare": ["@astrojs/cloudflare@12.6.3", "", { "dependencies": { "@astrojs/internal-helpers": "0.7.1", "@astrojs/underscore-redirects": "1.0.0", "@cloudflare/workers-types": "^4.20250507.0", "tinyglobby": "^0.2.13", "vite": "^6.3.5", "wrangler": "^4.14.1" }, "peerDependencies": { "astro": "^5.0.0" } }, "sha512-xhJptF5tU2k5eo70nIMyL1Udma0CqmUEnGSlGyFflLqSY82CRQI6nWZ/xZt0ZvmXuErUjIx0YYQNfZsz5CNjLQ=="], + "@anthropic-ai/claude-agent-sdk-darwin-arm64": ["@anthropic-ai/claude-agent-sdk-darwin-arm64@0.3.187", "", { "os": "darwin", "cpu": "arm64" }, "sha512-0DNzATzaRmjS/Q1T4T9SLP/VT67gRX7J4reYPnEdcTm91lJwjqOPkHr17+sv+7DoerZ421ZG38dPsQd/V67qQw=="], - "@astrojs/compiler": ["@astrojs/compiler@2.13.1", "", {}, "sha512-f3FN83d2G/v32ipNClRKgYv30onQlMZX1vCeZMjPsMMPl1mDpmbl0+N5BYo4S/ofzqJyS5hvwacEo0CCVDn/Qg=="], + "@anthropic-ai/claude-agent-sdk-darwin-x64": ["@anthropic-ai/claude-agent-sdk-darwin-x64@0.3.187", "", { "os": "darwin", "cpu": "x64" }, "sha512-Va3O8lTDa9IHq/DbSJwU63JJknNV3YCBh4PEznOHXJtyFoXHgRjrks4QQvN3baZm79avVq2sn+6tvpTz9CuY8A=="], - "@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.7.1", "", {}, "sha512-7dwEVigz9vUWDw3nRwLQ/yH/xYovlUA0ZD86xoeKEBmkz9O6iELG1yri67PgAPW6VLL/xInA4t7H0CK6VmtkKQ=="], + "@anthropic-ai/claude-agent-sdk-linux-arm64": ["@anthropic-ai/claude-agent-sdk-linux-arm64@0.3.187", "", { "os": "linux", "cpu": "arm64" }, "sha512-VEvrs3MgwckdWRNa7+2rJdyOBbCWGoRaM6OnL+/n9qi4gKlZnXZlj/90Tw9o8ttcN260Opz120/SE1fYwzu/JA=="], - "@astrojs/language-server": ["@astrojs/language-server@2.16.6", "", { "dependencies": { "@astrojs/compiler": "^2.13.1", "@astrojs/yaml2ts": "^0.2.3", "@jridgewell/sourcemap-codec": "^1.5.5", "@volar/kit": "~2.4.28", "@volar/language-core": "~2.4.28", "@volar/language-server": "~2.4.28", "@volar/language-service": "~2.4.28", "muggle-string": "^0.4.1", "tinyglobby": "^0.2.15", "volar-service-css": "0.0.70", "volar-service-emmet": "0.0.70", "volar-service-html": "0.0.70", "volar-service-prettier": "0.0.70", "volar-service-typescript": "0.0.70", "volar-service-typescript-twoslash-queries": "0.0.70", "volar-service-yaml": "0.0.70", "vscode-html-languageservice": "^5.6.2", "vscode-uri": "^3.1.0" }, "peerDependencies": { "prettier": "^3.0.0", "prettier-plugin-astro": ">=0.11.0" }, "optionalPeers": ["prettier", "prettier-plugin-astro"], "bin": { "astro-ls": "bin/nodeServer.js" } }, "sha512-N990lu+HSFiG57owR0XBkr02BYMgiLCshLf+4QG4v6jjSWkBeQGnzqi+E1L08xFPPJ7eEeXnxPXGLaVv5pa4Ug=="], + "@anthropic-ai/claude-agent-sdk-linux-arm64-musl": ["@anthropic-ai/claude-agent-sdk-linux-arm64-musl@0.3.187", "", { "os": "linux", "cpu": "arm64" }, "sha512-XQ7w2pX0mjPYUC7ayTKiHeAbePOny/ezBATxTWt5JVDZZPfljzvHA0jyXHsN8aLphbgRUfbUpdrtt5b57Bhx5g=="], - "@astrojs/markdown-remark": ["@astrojs/markdown-remark@6.3.1", "", { "dependencies": { "@astrojs/internal-helpers": "0.6.1", "@astrojs/prism": "3.2.0", "github-slugger": "^2.0.0", "hast-util-from-html": "^2.0.3", "hast-util-to-text": "^4.0.2", "import-meta-resolve": "^4.1.0", "js-yaml": "^4.1.0", "mdast-util-definitions": "^6.0.0", "rehype-raw": "^7.0.0", "rehype-stringify": "^10.0.1", "remark-gfm": "^4.0.1", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.1", "remark-smartypants": "^3.0.2", "shiki": "^3.0.0", "smol-toml": "^1.3.1", "unified": "^11.0.5", "unist-util-remove-position": "^5.0.0", "unist-util-visit": "^5.0.0", "unist-util-visit-parents": "^6.0.1", "vfile": "^6.0.3" } }, "sha512-c5F5gGrkczUaTVgmMW9g1YMJGzOtRvjjhw6IfGuxarM6ct09MpwysP10US729dy07gg8y+ofVifezvP3BNsWZg=="], + "@anthropic-ai/claude-agent-sdk-linux-x64": ["@anthropic-ai/claude-agent-sdk-linux-x64@0.3.187", "", { "os": "linux", "cpu": "x64" }, "sha512-s/Fmg29tzMrbdeCbseTpL3DlzfWineSQ3bDPvhdKw4jcsgLC1YgQhIkAyE8WlceUyhQyw82NAUgYoPwfGny6hQ=="], - "@astrojs/mdx": ["@astrojs/mdx@4.3.14", "", { "dependencies": { "@astrojs/markdown-remark": "6.3.11", "@mdx-js/mdx": "^3.1.1", "acorn": "^8.15.0", "es-module-lexer": "^1.7.0", "estree-util-visit": "^2.0.0", "hast-util-to-html": "^9.0.5", "piccolore": "^0.1.3", "rehype-raw": "^7.0.0", "remark-gfm": "^4.0.1", "remark-smartypants": "^3.0.2", "source-map": "^0.7.6", "unist-util-visit": "^5.0.0", "vfile": "^6.0.3" }, "peerDependencies": { "astro": "^5.0.0" } }, "sha512-FBrqJQORVm+rkRa2TS5CjU9PBA6hkhrwLVBSS9A77gN2+iehvjq1w6yya/d0YKC7osiVorKkr3Qd9wNbl0ZkGA=="], + "@anthropic-ai/claude-agent-sdk-linux-x64-musl": ["@anthropic-ai/claude-agent-sdk-linux-x64-musl@0.3.187", "", { "os": "linux", "cpu": "x64" }, "sha512-yi2/L5oztFqTDnAZl4mWOINr+r7WBot70gYUxG2jOoqdYUl6j50vG/ME605X80v+l2qBmKjSGxb5trY/6DkRzQ=="], - "@astrojs/prism": ["@astrojs/prism@3.2.0", "", { "dependencies": { "prismjs": "^1.29.0" } }, "sha512-GilTHKGCW6HMq7y3BUv9Ac7GMe/MO9gi9GW62GzKtth0SwukCu/qp2wLiGpEujhY+VVhaG9v7kv/5vFzvf4NYw=="], + "@anthropic-ai/claude-agent-sdk-win32-arm64": ["@anthropic-ai/claude-agent-sdk-win32-arm64@0.3.187", "", { "os": "win32", "cpu": "arm64" }, "sha512-HjEl3cDRLAWKopdlrLI54fxTVWq4lZpWA4bTTBVc9UDdDj6AmJIRHKxaCCYLQRvnoswbAUF1sJmJ8EFJ+b6lfw=="], - "@astrojs/sitemap": ["@astrojs/sitemap@3.7.2", "", { "dependencies": { "sitemap": "^9.0.0", "stream-replace-string": "^2.0.0", "zod": "^4.3.6" } }, "sha512-PqkzkcZTb5ICiyIR8VoKbIAP/laNRXi5tw616N1Ckk+40oNB8Can1AzVV56lrbC5GKSZFCyJYUVYqVivMisvpA=="], + "@anthropic-ai/claude-agent-sdk-win32-x64": ["@anthropic-ai/claude-agent-sdk-win32-x64@0.3.187", "", { "os": "win32", "cpu": "x64" }, "sha512-FnrLhoZ8y/+gkZynL12UeQ8pWKCu6B/8myyRrYMNJRZqFw4DZlPvPCywAjFZf1e1hiXCoiSK0Orl5wzKfAeQsQ=="], - "@astrojs/solid-js": ["@astrojs/solid-js@5.1.0", "", { "dependencies": { "vite": "^6.3.5", "vite-plugin-solid": "^2.11.6" }, "peerDependencies": { "solid-devtools": "^0.30.1", "solid-js": "^1.8.5" }, "optionalPeers": ["solid-devtools"] }, "sha512-VmPHOU9k7m6HHCT2Y1mNzifilUnttlowBM36frGcfj5wERJE9Ci0QtWJbzdf6AlcoIirb7xVw+ByupU011Di9w=="], + "@anthropic-ai/sdk": ["@anthropic-ai/sdk@0.105.0", "", { "dependencies": { "json-schema-to-ts": "^3.1.1", "standardwebhooks": "^1.0.0" }, "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" }, "optionalPeers": ["zod"], "bin": { "anthropic-ai-sdk": "bin/cli" } }, "sha512-sDyu+aM9cE6uZE+HgRjjHRb+qqb87GHZOx+8bE0YlWetdL1YcVLxn8h9ltxGOflyChTe6PMEo50kMQV4cw0hfg=="], - "@astrojs/starlight": ["@astrojs/starlight@0.34.3", "", { "dependencies": { "@astrojs/markdown-remark": "^6.3.1", "@astrojs/mdx": "^4.2.3", "@astrojs/sitemap": "^3.3.0", "@pagefind/default-ui": "^1.3.0", "@types/hast": "^3.0.4", "@types/js-yaml": "^4.0.9", "@types/mdast": "^4.0.4", "astro-expressive-code": "^0.41.1", "bcp-47": "^2.1.0", "hast-util-from-html": "^2.0.1", "hast-util-select": "^6.0.2", "hast-util-to-string": "^3.0.0", "hastscript": "^9.0.0", "i18next": "^23.11.5", "js-yaml": "^4.1.0", "klona": "^2.0.6", "mdast-util-directive": "^3.0.0", "mdast-util-to-markdown": "^2.1.0", "mdast-util-to-string": "^4.0.0", "pagefind": "^1.3.0", "rehype": "^13.0.1", "rehype-format": "^5.0.0", "remark-directive": "^3.0.0", "ultrahtml": "^1.6.0", "unified": "^11.0.5", "unist-util-visit": "^5.0.0", "vfile": "^6.0.2" }, "peerDependencies": { "astro": "^5.5.0" } }, "sha512-MAuD3NF+E+QXJJuVKofoR6xcPTP4BJmYWeOBd03udVdubNGVnPnSWVZAi+ZtnTofES4+mJdp8BNGf+ubUxkiiA=="], - - "@astrojs/telemetry": ["@astrojs/telemetry@3.2.1", "", { "dependencies": { "ci-info": "^4.2.0", "debug": "^4.4.0", "dlv": "^1.1.3", "dset": "^3.1.4", "is-docker": "^3.0.0", "is-wsl": "^3.1.0", "which-pm-runs": "^1.1.0" } }, "sha512-SSVM820Jqc6wjsn7qYfV9qfeQvePtVc1nSofhyap7l0/iakUKywj3hfy3UJAOV4sGV4Q/u450RD4AaCaFvNPlg=="], - - "@astrojs/underscore-redirects": ["@astrojs/underscore-redirects@1.0.0", "", {}, "sha512-qZxHwVnmb5FXuvRsaIGaqWgnftjCuMY+GSbaVZdBmE4j8AfgPqKPxYp8SUERyJcjpKCEmO4wD6ybuGH8A2kVRQ=="], - - "@astrojs/yaml2ts": ["@astrojs/yaml2ts@0.2.3", "", { "dependencies": { "yaml": "^2.8.2" } }, "sha512-PJzRmgQzUxI2uwpdX2lXSHtP4G8ocp24/t+bZyf5Fy0SZLSF9f9KXZoMlFM/XCGue+B0nH/2IZ7FpBYQATBsCg=="], + "@anycable/core": ["@anycable/core@0.9.2", "", { "dependencies": { "nanoevents": "^7.0.1" } }, "sha512-x5ZXDcW/N4cxWl93CnbHs/u7qq4793jS2kNPWm+duPrXlrva+ml2ZGT7X9tuOBKzyIHf60zWCdIK7TUgMPAwXA=="], "@aws-crypto/crc32": ["@aws-crypto/crc32@5.2.0", "", { "dependencies": { "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", "tslib": "^2.6.2" } }, "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg=="], @@ -833,8 +564,6 @@ "@aws-sdk/client-sso": ["@aws-sdk/client-sso@3.933.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.932.0", "@aws-sdk/middleware-host-header": "3.930.0", "@aws-sdk/middleware-logger": "3.930.0", "@aws-sdk/middleware-recursion-detection": "3.933.0", "@aws-sdk/middleware-user-agent": "3.932.0", "@aws-sdk/region-config-resolver": "3.930.0", "@aws-sdk/types": "3.930.0", "@aws-sdk/util-endpoints": "3.930.0", "@aws-sdk/util-user-agent-browser": "3.930.0", "@aws-sdk/util-user-agent-node": "3.932.0", "@smithy/config-resolver": "^4.4.3", "@smithy/core": "^3.18.2", "@smithy/fetch-http-handler": "^5.3.6", "@smithy/hash-node": "^4.2.5", "@smithy/invalid-dependency": "^4.2.5", "@smithy/middleware-content-length": "^4.2.5", "@smithy/middleware-endpoint": "^4.3.9", "@smithy/middleware-retry": "^4.4.9", "@smithy/middleware-serde": "^4.2.5", "@smithy/middleware-stack": "^4.2.5", "@smithy/node-config-provider": "^4.3.5", "@smithy/node-http-handler": "^4.4.5", "@smithy/protocol-http": "^5.3.5", "@smithy/smithy-client": "^4.9.5", "@smithy/types": "^4.9.0", "@smithy/url-parser": "^4.2.5", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.8", "@smithy/util-defaults-mode-node": "^4.2.11", "@smithy/util-endpoints": "^3.2.5", "@smithy/util-middleware": "^4.2.5", "@smithy/util-retry": "^4.2.5", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zwGLSiK48z3PzKpQiDMKP85+fpIrPMF1qQOQW9OW7BGj5AuBZIisT2O4VzIgYJeh+t47MLU7VgBQL7muc+MJDg=="], - "@aws-sdk/client-sts": ["@aws-sdk/client-sts@3.782.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.775.0", "@aws-sdk/credential-provider-node": "3.782.0", "@aws-sdk/middleware-host-header": "3.775.0", "@aws-sdk/middleware-logger": "3.775.0", "@aws-sdk/middleware-recursion-detection": "3.775.0", "@aws-sdk/middleware-user-agent": "3.782.0", "@aws-sdk/region-config-resolver": "3.775.0", "@aws-sdk/types": "3.775.0", "@aws-sdk/util-endpoints": "3.782.0", "@aws-sdk/util-user-agent-browser": "3.775.0", "@aws-sdk/util-user-agent-node": "3.782.0", "@smithy/config-resolver": "^4.1.0", "@smithy/core": "^3.2.0", "@smithy/fetch-http-handler": "^5.0.2", "@smithy/hash-node": "^4.0.2", "@smithy/invalid-dependency": "^4.0.2", "@smithy/middleware-content-length": "^4.0.2", "@smithy/middleware-endpoint": "^4.1.0", "@smithy/middleware-retry": "^4.1.0", "@smithy/middleware-serde": "^4.0.3", "@smithy/middleware-stack": "^4.0.2", "@smithy/node-config-provider": "^4.0.2", "@smithy/node-http-handler": "^4.0.4", "@smithy/protocol-http": "^5.1.0", "@smithy/smithy-client": "^4.2.0", "@smithy/types": "^4.2.0", "@smithy/url-parser": "^4.0.2", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", "@smithy/util-defaults-mode-browser": "^4.0.8", "@smithy/util-defaults-mode-node": "^4.0.8", "@smithy/util-endpoints": "^3.0.2", "@smithy/util-middleware": "^4.0.2", "@smithy/util-retry": "^4.0.2", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-Q1QLY3xE2z1trgriusP/6w40mI/yJjM524bN4gs+g6YX4sZGufpa7+Dj+JjL4fz8f9BCJ3ZlI+p4WxFxH7qvdQ=="], - "@aws-sdk/core": ["@aws-sdk/core@3.932.0", "", { "dependencies": { "@aws-sdk/types": "3.930.0", "@aws-sdk/xml-builder": "3.930.0", "@smithy/core": "^3.18.2", "@smithy/node-config-provider": "^4.3.5", "@smithy/property-provider": "^4.2.5", "@smithy/protocol-http": "^5.3.5", "@smithy/signature-v4": "^5.3.5", "@smithy/smithy-client": "^4.9.5", "@smithy/types": "^4.9.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.5", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-AS8gypYQCbNojwgjvZGkJocC2CoEICDx9ZJ15ILsv+MlcCVLtUJSRSx3VzJOUY2EEIaGLRrPNlIqyn/9/fySvA=="], "@aws-sdk/credential-provider-cognito-identity": ["@aws-sdk/credential-provider-cognito-identity@3.972.22", "", { "dependencies": { "@aws-sdk/nested-clients": "^3.996.19", "@aws-sdk/types": "^3.973.7", "@smithy/property-provider": "^4.2.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-ih6ORpme4i2qJqGckOQ9Lt2iiZ+5tm3bnfsT5TwoPyFnuDURXv3OdhYa3Nr/m0iJr38biqKYKdGKb5GR1KB2hw=="], @@ -909,8 +638,6 @@ "@azure/core-client": ["@azure/core-client@1.10.1", "", { "dependencies": { "@azure/abort-controller": "^2.1.2", "@azure/core-auth": "^1.10.0", "@azure/core-rest-pipeline": "^1.22.0", "@azure/core-tracing": "^1.3.0", "@azure/core-util": "^1.13.0", "@azure/logger": "^1.3.0", "tslib": "^2.6.2" } }, "sha512-Nh5PhEOeY6PrnxNPsEHRr9eimxLwgLlpmguQaHKBinFYA/RU9+kOYVOQqOrTsCL+KSxrLLl1gD8Dk5BFW/7l/w=="], - "@azure/core-http": ["@azure/core-http@3.0.5", "", { "dependencies": { "@azure/abort-controller": "^1.0.0", "@azure/core-auth": "^1.3.0", "@azure/core-tracing": "1.0.0-preview.13", "@azure/core-util": "^1.1.1", "@azure/logger": "^1.0.0", "@types/node-fetch": "^2.5.0", "@types/tunnel": "^0.0.3", "form-data": "^4.0.0", "node-fetch": "^2.6.7", "process": "^0.11.10", "tslib": "^2.2.0", "tunnel": "^0.0.6", "uuid": "^8.3.0", "xml2js": "^0.5.0" } }, "sha512-T8r2q/c3DxNu6mEJfPuJtptUVqwchxzjj32gKcnMi06rdiVONS9rar7kT9T2Am+XvER7uOzpsP79WsqNbdgdWg=="], - "@azure/core-http-compat": ["@azure/core-http-compat@2.4.0", "", { "dependencies": { "@azure/abort-controller": "^2.1.2" }, "peerDependencies": { "@azure/core-client": "^1.10.0", "@azure/core-rest-pipeline": "^1.22.0" } }, "sha512-f1P96IB399YiN2ARYHP7EpZi3Bf3wH4SN2lGzrw7JVwm7bbsVYtf2iKSBwTywD2P62NOPZGHFSZi+6jjb75JuA=="], "@azure/core-lro": ["@azure/core-lro@2.7.2", "", { "dependencies": { "@azure/abort-controller": "^2.0.0", "@azure/core-util": "^1.2.0", "@azure/logger": "^1.0.0", "tslib": "^2.6.2" } }, "sha512-0YIpccoX8m/k00O7mDDMdJpbr6mf1yWo2dfmxt5A8XVZVVMz2SSKaEbMCeJRvgQ0IaSlqhjT47p4hVIRRy90xw=="], @@ -947,9 +674,9 @@ "@babel/compat-data": ["@babel/compat-data@7.29.0", "", {}, "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg=="], - "@babel/core": ["@babel/core@7.28.4", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.3", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.28.3", "@babel/helpers": "^7.28.4", "@babel/parser": "^7.28.4", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.4", "@babel/types": "^7.28.4", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA=="], + "@babel/core": ["@babel/core@7.29.6", "", { "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.6", "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-module-transforms": "^7.28.6", "@babel/helpers": "^7.29.2", "@babel/parser": "^7.29.3", "@babel/template": "^7.28.6", "@babel/traverse": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-QdxmAo/ikZqqRGA8s43ww8lcql6naWRvEz0FFrl6MIlc7Gi6TroXnSdWa5U/kq6fzcpqpHesicQxFZIieZbyIA=="], - "@babel/generator": ["@babel/generator@7.29.1", "", { "dependencies": { "@babel/parser": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw=="], + "@babel/generator": ["@babel/generator@7.29.7", "", { "dependencies": { "@babel/parser": "^7.29.7", "@babel/types": "^7.29.7", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ=="], "@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="], @@ -981,20 +708,14 @@ "@babel/helpers": ["@babel/helpers@7.29.2", "", { "dependencies": { "@babel/template": "^7.28.6", "@babel/types": "^7.29.0" } }, "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw=="], - "@babel/parser": ["@babel/parser@7.29.2", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": "./bin/babel-parser.js" }, "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA=="], + "@babel/parser": ["@babel/parser@7.29.7", "", { "dependencies": { "@babel/types": "^7.29.7" }, "bin": "./bin/babel-parser.js" }, "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg=="], "@babel/plugin-syntax-jsx": ["@babel/plugin-syntax-jsx@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w=="], "@babel/plugin-syntax-typescript": ["@babel/plugin-syntax-typescript@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A=="], - "@babel/plugin-transform-arrow-functions": ["@babel/plugin-transform-arrow-functions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA=="], - "@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.28.6", "", { "dependencies": { "@babel/helper-module-transforms": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA=="], - "@babel/plugin-transform-react-jsx-self": ["@babel/plugin-transform-react-jsx-self@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw=="], - - "@babel/plugin-transform-react-jsx-source": ["@babel/plugin-transform-react-jsx-source@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw=="], - "@babel/plugin-transform-typescript": ["@babel/plugin-transform-typescript@7.28.6", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-create-class-features-plugin": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw=="], "@babel/preset-typescript": ["@babel/preset-typescript@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.27.1", "@babel/plugin-transform-typescript": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ=="], @@ -1007,46 +728,22 @@ "@babel/types": ["@babel/types@7.29.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="], + "@borewit/text-codec": ["@borewit/text-codec@0.2.2", "", {}, "sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ=="], + "@bufbuild/protobuf": ["@bufbuild/protobuf@2.11.0", "", {}, "sha512-sBXGT13cpmPR5BMgHE6UEEfEaShh5Ror6rfN3yEK5si7QVrtZg8LEPQb0VVhiLRUslD2yLnXtnRzG035J/mZXQ=="], "@bufbuild/protoplugin": ["@bufbuild/protoplugin@2.11.0", "", { "dependencies": { "@bufbuild/protobuf": "2.11.0", "@typescript/vfs": "^1.6.2", "typescript": "5.4.5" } }, "sha512-lyZVNFUHArIOt4W0+dwYBe5GBwbKzbOy8ObaloEqsw9Mmiwv2O48TwddDoHN4itylC+BaEGqFdI1W8WQt2vWJQ=="], - "@capsizecss/unpack": ["@capsizecss/unpack@2.4.0", "", { "dependencies": { "blob-to-buffer": "^1.2.8", "cross-fetch": "^3.0.4", "fontkit": "^2.0.2" } }, "sha512-GrSU71meACqcmIUxPYOJvGKF0yryjN/L1aCuE9DViCTJI7bfkjgYDPD1zbNDcINJwSSP6UaBZY9GAbYDO7re0Q=="], - "@clack/core": ["@clack/core@1.0.0-alpha.1", "", { "dependencies": { "picocolors": "^1.0.0", "sisteransi": "^1.0.5" } }, "sha512-rFbCU83JnN7l3W1nfgCqqme4ZZvTTgsiKQ6FM0l+r0P+o2eJpExcocBUWUIwnDzL76Aca9VhUdWmB2MbUv+Qyg=="], "@clack/prompts": ["@clack/prompts@1.0.0-alpha.1", "", { "dependencies": { "@clack/core": "1.0.0-alpha.1", "picocolors": "^1.0.0", "sisteransi": "^1.0.5" } }, "sha512-07MNT0OsxjKOcyVfX8KhXBhJiyUbDP1vuIAcHc+nx5v93MJO23pX3X/k3bWz6T3rpM9dgWPq90i4Jq7gZAyMbw=="], - "@cloudflare/kv-asset-handler": ["@cloudflare/kv-asset-handler@0.4.0", "", { "dependencies": { "mime": "^3.0.0" } }, "sha512-+tv3z+SPp+gqTIcImN9o0hqE9xyfQjI1XD9pL6NuKjua9B1y7mNYv0S9cP+QEbA4ppVgGZEmKOvHX5G5Ei1CVA=="], - - "@cloudflare/unenv-preset": ["@cloudflare/unenv-preset@2.7.11", "", { "peerDependencies": { "unenv": "2.0.0-rc.24", "workerd": "^1.20251106.1" }, "optionalPeers": ["workerd"] }, "sha512-se23f1D4PxKrMKOq+Stz+Yn7AJ9ITHcEecXo2Yjb+UgbUDCEBch1FXQC6hx6uT5fNA3kmX3mfzeZiUmpK1W9IQ=="], - - "@cloudflare/vite-plugin": ["@cloudflare/vite-plugin@1.15.2", "", { "dependencies": { "@cloudflare/unenv-preset": "2.7.11", "@remix-run/node-fetch-server": "^0.8.0", "get-port": "^7.1.0", "miniflare": "4.20251118.1", "picocolors": "^1.1.1", "tinyglobby": "^0.2.12", "unenv": "2.0.0-rc.24", "wrangler": "4.50.0", "ws": "8.18.0" }, "peerDependencies": { "vite": "^6.1.0 || ^7.0.0" } }, "sha512-SPMxsesbABOjzcAa4IzW+yM+fTIjx3GG1doh229Pg16FjSEZJhknyRpcld4gnaZioK3JKwG9FWdKsUhbplKY8w=="], - - "@cloudflare/workerd-darwin-64": ["@cloudflare/workerd-darwin-64@1.20251118.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-UmWmYEYS/LkK/4HFKN6xf3Hk8cw70PviR+ftr3hUvs9HYZS92IseZEp16pkL6ZBETrPRpZC7OrzoYF7ky6kHsg=="], - - "@cloudflare/workerd-darwin-arm64": ["@cloudflare/workerd-darwin-arm64@1.20251118.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-RockU7Qzf4rxNfY1lx3j4rvwutNLjTIX7rr2hogbQ4mzLo8Ea40/oZTzXVxl+on75joLBrt0YpenGW8o/r44QA=="], - - "@cloudflare/workerd-linux-64": ["@cloudflare/workerd-linux-64@1.20251118.0", "", { "os": "linux", "cpu": "x64" }, "sha512-aT97GnOAbJDuuOG0zPVhgRk0xFtB1dzBMrxMZ09eubDLoU4djH4BuORaqvxNRMmHgKfa4T6drthckT0NjUvBdw=="], - - "@cloudflare/workerd-linux-arm64": ["@cloudflare/workerd-linux-arm64@1.20251118.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-bXZPJcwlq00MPOXqP7DMWjr+goYj0+Fqyw6zgEC2M3FR1+SWla4yjghnZ4IdpN+H1t7VbUrsi5np2LzMUFs0NA=="], - - "@cloudflare/workerd-windows-64": ["@cloudflare/workerd-windows-64@1.20251118.0", "", { "os": "win32", "cpu": "x64" }, "sha512-2LV99AHSlpr8WcCb/BYbU2QsYkXLUL1izN6YKWkN9Eibv80JKX0RtgmD3dfmajE5sNvClavxZejgzVvHD9N9Ag=="], - "@cloudflare/workers-types": ["@cloudflare/workers-types@4.20251008.0", "", {}, "sha512-dZLkO4PbCL0qcCSKzuW7KE4GYe49lI12LCfQ5y9XeSwgYBoAUbwH4gmJ6A0qUIURiTJTkGkRkhVPqpq2XNgYRA=="], "@corvu/utils": ["@corvu/utils@0.4.2", "", { "dependencies": { "@floating-ui/dom": "^1.6.11" }, "peerDependencies": { "solid-js": "^1.8" } }, "sha512-Ox2kYyxy7NoXdKWdHeDEjZxClwzO4SKM8plAaVwmAJPxHMqA0rLOoAsa+hBDwRLpctf+ZRnAd/ykguuJidnaTA=="], - "@cspotcode/source-map-support": ["@cspotcode/source-map-support@0.8.1", "", { "dependencies": { "@jridgewell/trace-mapping": "0.3.9" } }, "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw=="], - - "@ctrl/tinycolor": ["@ctrl/tinycolor@4.2.0", "", {}, "sha512-kzyuwOAQnXJNLS9PSyrk0CWk35nWJW/zl/6KvnTBMFK65gm7U1/Z5BqjxeapjZCIhQcM/DsrEmcbRwDyXyXK4A=="], - - "@develar/schema-utils": ["@develar/schema-utils@2.6.5", "", { "dependencies": { "ajv": "^6.12.0", "ajv-keywords": "^3.4.1" } }, "sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig=="], - "@dimforge/rapier2d-simd-compat": ["@dimforge/rapier2d-simd-compat@0.17.3", "", {}, "sha512-bijvwWz6NHsNj5e5i1vtd3dU2pDhthSaTUZSh14DUGGKJfw8eMnlWZsxwHBxB/a3AXVNDjL9abuHw1k9FGR+jg=="], - "@dot/log": ["@dot/log@0.1.5", "", { "dependencies": { "chalk": "^4.1.2", "loglevelnext": "^6.0.0", "p-defer": "^3.0.0" } }, "sha512-ECraEVJWv2f2mWK93lYiefUkphStVlKD6yKDzisuoEmxuLKrxO9iGetHK2DoEAkj7sxjE886n0OUVVCUx0YPNg=="], - "@drizzle-team/brocli": ["@drizzle-team/brocli@0.11.0", "", {}, "sha512-hD3pekGiPg0WPCCGAZmusBBJsDqGUR66Y452YgQsZOnkdQ7ViEPKuyP4huUGEZQefp8g34RRodXYmJ2TbCH+tg=="], "@effect/opentelemetry": ["@effect/opentelemetry@4.0.0-beta.57", "", { "peerDependencies": { "@opentelemetry/api": "^1.9", "@opentelemetry/resources": "^2.0.0", "@opentelemetry/sdk-logs": ">=0.203.0 <0.300.0", "@opentelemetry/sdk-metrics": "^2.0.0", "@opentelemetry/sdk-trace-base": "^2.0.0", "@opentelemetry/sdk-trace-node": "^2.0.0", "@opentelemetry/sdk-trace-web": "^2.0.0", "@opentelemetry/semantic-conventions": "^1.33.0", "effect": "^4.0.0-beta.57" }, "optionalPeers": ["@opentelemetry/api", "@opentelemetry/resources", "@opentelemetry/sdk-logs", "@opentelemetry/sdk-metrics", "@opentelemetry/sdk-trace-base", "@opentelemetry/sdk-trace-node", "@opentelemetry/sdk-trace-web"] }, "sha512-gdjZPEP0QQg4qmI1vd+443kheeQZKytrjJIzCJncy6ZEpyk/SfrqeStLqLXdTRcms3IB0ls0vOV7KNq7YmBRVA=="], @@ -1055,110 +752,64 @@ "@effect/platform-node-shared": ["@effect/platform-node-shared@4.0.0-beta.57", "", { "dependencies": { "@types/ws": "^8.18.1", "ws": "^8.20.0" }, "peerDependencies": { "effect": "^4.0.0-beta.57" } }, "sha512-C976X6f+qHUtLSqcqImuCrjhAHnJV17NC2RvvybsAuDfkyIWU4MyiO2XwgiBeijeNupyr1M/KPKnyjtkNxV9Hw=="], - "@electron/asar": ["@electron/asar@3.4.1", "", { "dependencies": { "commander": "^5.0.0", "glob": "^7.1.6", "minimatch": "^3.0.4" }, "bin": { "asar": "bin/asar.js" } }, "sha512-i4/rNPRS84t0vSRa2HorerGRXWyF4vThfHesw0dmcWHp+cspK743UanA0suA5Q5y8kzY2y6YKrvbIUn69BCAiA=="], - - "@electron/fuses": ["@electron/fuses@1.8.0", "", { "dependencies": { "chalk": "^4.1.1", "fs-extra": "^9.0.1", "minimist": "^1.2.5" }, "bin": { "electron-fuses": "dist/bin.js" } }, "sha512-zx0EIq78WlY/lBb1uXlziZmDZI4ubcCXIMJ4uGjXzZW0nS19TjSPeXPAjzzTmKQlJUZm0SbmZhPKP7tuQ1SsEw=="], - - "@electron/get": ["@electron/get@2.0.3", "", { "dependencies": { "debug": "^4.1.1", "env-paths": "^2.2.0", "fs-extra": "^8.1.0", "got": "^11.8.5", "progress": "^2.0.3", "semver": "^6.2.0", "sumchecker": "^3.0.1" }, "optionalDependencies": { "global-agent": "^3.0.0" } }, "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ=="], - - "@electron/notarize": ["@electron/notarize@2.5.0", "", { "dependencies": { "debug": "^4.1.1", "fs-extra": "^9.0.1", "promise-retry": "^2.0.1" } }, "sha512-jNT8nwH1f9X5GEITXaQ8IF/KdskvIkOFfB2CvwumsveVidzpSc+mvhhTMdAGSYF3O+Nq49lJ7y+ssODRXu06+A=="], - - "@electron/osx-sign": ["@electron/osx-sign@1.3.3", "", { "dependencies": { "compare-version": "^0.1.2", "debug": "^4.3.4", "fs-extra": "^10.0.0", "isbinaryfile": "^4.0.8", "minimist": "^1.2.6", "plist": "^3.0.5" }, "bin": { "electron-osx-flat": "bin/electron-osx-flat.js", "electron-osx-sign": "bin/electron-osx-sign.js" } }, "sha512-KZ8mhXvWv2rIEgMbWZ4y33bDHyUKMXnx4M0sTyPNK/vcB81ImdeY9Ggdqy0SWbMDgmbqyQ+phgejh6V3R2QuSg=="], - - "@electron/rebuild": ["@electron/rebuild@4.0.3", "", { "dependencies": { "@malept/cross-spawn-promise": "^2.0.0", "debug": "^4.1.1", "detect-libc": "^2.0.1", "got": "^11.7.0", "graceful-fs": "^4.2.11", "node-abi": "^4.2.0", "node-api-version": "^0.2.1", "node-gyp": "^11.2.0", "ora": "^5.1.0", "read-binary-file-arch": "^1.0.6", "semver": "^7.3.5", "tar": "^7.5.6", "yargs": "^17.0.1" }, "bin": { "electron-rebuild": "lib/cli.js" } }, "sha512-u9vpTHRMkOYCs/1FLiSVAFZ7FbjsXK+bQuzviJZa+lG7BHZl1nz52/IcGvwa3sk80/fc3llutBkbCq10Vh8WQA=="], - - "@electron/universal": ["@electron/universal@2.0.3", "", { "dependencies": { "@electron/asar": "^3.3.1", "@malept/cross-spawn-promise": "^2.0.0", "debug": "^4.3.1", "dir-compare": "^4.2.0", "fs-extra": "^11.1.1", "minimatch": "^9.0.3", "plist": "^3.1.0" } }, "sha512-Wn9sPYIVFRFl5HmwMJkARCCf7rqK/EurkfQ/rJZ14mHP3iYTjZSIOSVonEAnhWeAXwtw7zOekGRlc6yTtZ0t+g=="], - - "@electron/windows-sign": ["@electron/windows-sign@1.2.2", "", { "dependencies": { "cross-dirname": "^0.1.0", "debug": "^4.3.4", "fs-extra": "^11.1.1", "minimist": "^1.2.8", "postject": "^1.0.0-alpha.6" }, "bin": { "electron-windows-sign": "bin/electron-windows-sign.js" } }, "sha512-dfZeox66AvdPtb2lD8OsIIQh12Tp0GNCRUDfBHIKGpbmopZto2/A8nSpYYLoedPIHpqkeblZ/k8OV0Gy7PYuyQ=="], - - "@emmetio/abbreviation": ["@emmetio/abbreviation@2.3.3", "", { "dependencies": { "@emmetio/scanner": "^1.0.4" } }, "sha512-mgv58UrU3rh4YgbE/TzgLQwJ3pFsHHhCLqY20aJq+9comytTXUDNGG/SMtSeMJdkpxgXSXunBGLD8Boka3JyVA=="], - - "@emmetio/css-abbreviation": ["@emmetio/css-abbreviation@2.1.8", "", { "dependencies": { "@emmetio/scanner": "^1.0.4" } }, "sha512-s9yjhJ6saOO/uk1V74eifykk2CBYi01STTK3WlXWGOepyKa23ymJ053+DNQjpFcy1ingpaO7AxCcwLvHFY9tuw=="], - - "@emmetio/css-parser": ["@emmetio/css-parser@0.4.1", "", { "dependencies": { "@emmetio/stream-reader": "^2.2.0", "@emmetio/stream-reader-utils": "^0.1.0" } }, "sha512-2bC6m0MV/voF4CTZiAbG5MWKbq5EBmDPKu9Sb7s7nVcEzNQlrZP6mFFFlIaISM8X6514H9shWMme1fCm8cWAfQ=="], - - "@emmetio/html-matcher": ["@emmetio/html-matcher@1.3.0", "", { "dependencies": { "@emmetio/scanner": "^1.0.0" } }, "sha512-NTbsvppE5eVyBMuyGfVu2CRrLvo7J4YHb6t9sBFLyY03WYhXET37qA4zOYUjBWFCRHO7pS1B9khERtY0f5JXPQ=="], - - "@emmetio/scanner": ["@emmetio/scanner@1.0.4", "", {}, "sha512-IqRuJtQff7YHHBk4G8YZ45uB9BaAGcwQeVzgj/zj8/UdOhtQpEIupUhSk8dys6spFIWVZVeK20CzGEnqR5SbqA=="], - - "@emmetio/stream-reader": ["@emmetio/stream-reader@2.2.0", "", {}, "sha512-fXVXEyFA5Yv3M3n8sUGT7+fvecGrZP4k6FnWWMSZVQf69kAq0LLpaBQLGcPR30m3zMmKYhECP4k/ZkzvhEW5kw=="], - - "@emmetio/stream-reader-utils": ["@emmetio/stream-reader-utils@0.1.0", "", {}, "sha512-ZsZ2I9Vzso3Ho/pjZFsmmZ++FWeEd/txqybHTm4OgaZzdS8V9V/YYWQwg5TC38Z7uLWUV1vavpLLbjJtKubR1A=="], - - "@emnapi/core": ["@emnapi/core@1.9.2", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA=="], - - "@emnapi/runtime": ["@emnapi/runtime@1.9.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw=="], - - "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w=="], - "@emotion/is-prop-valid": ["@emotion/is-prop-valid@0.8.8", "", { "dependencies": { "@emotion/memoize": "0.7.4" } }, "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA=="], "@emotion/memoize": ["@emotion/memoize@0.7.4", "", {}, "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw=="], - "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="], - - "@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="], - - "@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.12", "", { "os": "android", "cpu": "arm64" }, "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg=="], - - "@esbuild/android-x64": ["@esbuild/android-x64@0.25.12", "", { "os": "android", "cpu": "x64" }, "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg=="], + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.28.1", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ=="], - "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg=="], + "@esbuild/android-arm": ["@esbuild/android-arm@0.28.1", "", { "os": "android", "cpu": "arm" }, "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ=="], - "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA=="], + "@esbuild/android-arm64": ["@esbuild/android-arm64@0.28.1", "", { "os": "android", "cpu": "arm64" }, "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg=="], - "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.12", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg=="], + "@esbuild/android-x64": ["@esbuild/android-x64@0.28.1", "", { "os": "android", "cpu": "x64" }, "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng=="], - "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ=="], + "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.28.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q=="], - "@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.12", "", { "os": "linux", "cpu": "arm" }, "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw=="], + "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.28.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ=="], - "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ=="], + "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.28.1", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw=="], - "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.12", "", { "os": "linux", "cpu": "ia32" }, "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA=="], + "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.28.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ=="], - "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng=="], + "@esbuild/linux-arm": ["@esbuild/linux-arm@0.28.1", "", { "os": "linux", "cpu": "arm" }, "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ=="], - "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw=="], + "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.28.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g=="], - "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA=="], + "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.28.1", "", { "os": "linux", "cpu": "ia32" }, "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w=="], - "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w=="], + "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.28.1", "", { "os": "linux", "cpu": "none" }, "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg=="], - "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg=="], + "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.28.1", "", { "os": "linux", "cpu": "none" }, "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ=="], - "@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.12", "", { "os": "linux", "cpu": "x64" }, "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw=="], + "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.28.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ=="], - "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg=="], + "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.28.1", "", { "os": "linux", "cpu": "none" }, "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ=="], - "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.12", "", { "os": "none", "cpu": "x64" }, "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ=="], + "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.28.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag=="], - "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.12", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A=="], + "@esbuild/linux-x64": ["@esbuild/linux-x64@0.28.1", "", { "os": "linux", "cpu": "x64" }, "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA=="], - "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw=="], + "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.28.1", "", { "os": "none", "cpu": "arm64" }, "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw=="], - "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg=="], + "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.28.1", "", { "os": "none", "cpu": "x64" }, "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg=="], - "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w=="], + "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.28.1", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q=="], - "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg=="], + "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.28.1", "", { "os": "openbsd", "cpu": "x64" }, "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw=="], - "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.12", "", { "os": "win32", "cpu": "ia32" }, "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ=="], + "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.28.1", "", { "os": "none", "cpu": "arm64" }, "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg=="], - "@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="], + "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.28.1", "", { "os": "sunos", "cpu": "x64" }, "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ=="], - "@expressive-code/core": ["@expressive-code/core@0.41.7", "", { "dependencies": { "@ctrl/tinycolor": "^4.0.4", "hast-util-select": "^6.0.2", "hast-util-to-html": "^9.0.1", "hast-util-to-text": "^4.0.1", "hastscript": "^9.0.0", "postcss": "^8.4.38", "postcss-nested": "^6.0.1", "unist-util-visit": "^5.0.0", "unist-util-visit-parents": "^6.0.1" } }, "sha512-ck92uZYZ9Wba2zxkiZLsZGi9N54pMSAVdrI9uW3Oo9AtLglD5RmrdTwbYPCT2S/jC36JGB2i+pnQtBm/Ib2+dg=="], + "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.28.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA=="], - "@expressive-code/plugin-frames": ["@expressive-code/plugin-frames@0.41.7", "", { "dependencies": { "@expressive-code/core": "^0.41.7" } }, "sha512-diKtxjQw/979cTglRFaMCY/sR6hWF0kSMg8jsKLXaZBSfGS0I/Hoe7Qds3vVEgeoW+GHHQzMcwvgx/MOIXhrTA=="], + "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.28.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg=="], - "@expressive-code/plugin-shiki": ["@expressive-code/plugin-shiki@0.41.7", "", { "dependencies": { "@expressive-code/core": "^0.41.7", "shiki": "^3.2.2" } }, "sha512-DL605bLrUOgqTdZ0Ot5MlTaWzppRkzzqzeGEu7ODnHF39IkEBbFdsC7pbl3LbUQ1DFtnfx6rD54k/cdofbW6KQ=="], - - "@expressive-code/plugin-text-markers": ["@expressive-code/plugin-text-markers@0.41.7", "", { "dependencies": { "@expressive-code/core": "^0.41.7" } }, "sha512-Ewpwuc5t6eFdZmWlFyeuy3e1PTQC0jFvw2Q+2bpcWXbOZhPLsT7+h8lsSIJxb5mS7wZko7cKyQ2RLYDyK6Fpmw=="], + "@esbuild/win32-x64": ["@esbuild/win32-x64@0.28.1", "", { "os": "win32", "cpu": "x64" }, "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A=="], "@fastify/ajv-compiler": ["@fastify/ajv-compiler@4.0.5", "", { "dependencies": { "ajv": "^8.12.0", "ajv-formats": "^3.0.1", "fast-uri": "^3.0.0" } }, "sha512-KoWKW+MhvfTRWL4qrhUwAAZoaChluo0m0vbiJlGMt2GXvL4LVPQEjt8kSpHI3IBq5Rez8fg+XeH3cneztq+C7A=="], - "@fastify/busboy": ["@fastify/busboy@2.1.1", "", {}, "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA=="], - "@fastify/error": ["@fastify/error@4.2.0", "", {}, "sha512-RSo3sVDXfHskiBZKBPRgnQTtIqpi/7zhJOEmAxCiBcM7d0uwdGdxLlsCaLzGs8v8NnxIRlfG0N51p5yFaOentQ=="], "@fastify/fast-json-stringify-compiler": ["@fastify/fast-json-stringify-compiler@5.0.3", "", { "dependencies": { "fast-json-stringify": "^6.0.0" } }, "sha512-uik7yYHkLr6fxd8hJSZ8c+xF4WafPK+XzneQDPU+D10r5X19GW8lJcom2YijX2+qtFF1ENJlHXKFM9ouXNJYgQ=="], @@ -1175,31 +826,27 @@ "@floating-ui/dom": ["@floating-ui/dom@1.7.6", "", { "dependencies": { "@floating-ui/core": "^1.7.5", "@floating-ui/utils": "^0.2.11" } }, "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ=="], - "@floating-ui/react-dom": ["@floating-ui/react-dom@2.1.8", "", { "dependencies": { "@floating-ui/dom": "^1.7.6" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A=="], - "@floating-ui/utils": ["@floating-ui/utils@0.2.11", "", {}, "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg=="], - "@fontsource/ibm-plex-mono": ["@fontsource/ibm-plex-mono@5.2.5", "", {}, "sha512-G09N3GfuT9qj3Ax2FDZvKqZttzM3v+cco2l8uXamhKyXLdmlaUDH5o88/C3vtTHj2oT7yRKsvxz9F+BXbWKMYA=="], - - "@fontsource/inter": ["@fontsource/inter@5.2.8", "", {}, "sha512-P6r5WnJoKiNVV+zvW2xM13gNdFhAEpQ9dQJHt3naLvfg+LkF2ldgSLiF4T41lf1SQCM9QmkqPTn4TH568IRagg=="], - "@gar/promise-retry": ["@gar/promise-retry@1.0.3", "", {}, "sha512-GmzA9ckNokPypTg10pgpeHNQe7ph+iIKKmhKu3Ob9ANkswreCx7R3cKmY781K8QK3AqVL3xVh9A42JvIAbkkSA=="], "@gitlab/opencode-gitlab-auth": ["@gitlab/opencode-gitlab-auth@1.3.3", "", { "dependencies": { "@fastify/rate-limit": "^10.2.0", "@mendcode/plugin": "*", "fastify": "^5.2.0", "open": "^10.0.0" } }, "sha512-FT+KsCmAJjtqWr1YAq0MywGgL9kaLQ4apmsoowAXrPqHtoYf2i/nY10/A+L06kNj22EATeEDRpbB1NWXMto/SA=="], "@graphql-typed-document-node/core": ["@graphql-typed-document-node/core@3.2.0", "", { "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ=="], - "@happy-dom/global-registrator": ["@happy-dom/global-registrator@20.0.11", "", { "dependencies": { "@types/node": "^20.0.0", "happy-dom": "^20.0.11" } }, "sha512-GqNqiShBT/lzkHTMC/slKBrvN0DsD4Di8ssBk4aDaVgEn+2WMzE6DXxq701ndSXj7/0cJ8mNT71pM7Bnrr6JRw=="], + "@hey-api/codegen-core": ["@hey-api/codegen-core@0.8.2", "", { "dependencies": { "@hey-api/types": "0.1.4", "ansi-colors": "4.1.3", "c12": "3.3.4", "color-support": "1.1.3" } }, "sha512-R2NMf3wq97rh1mjz33WJQU8svz3F0RYUjvx/QzXucjpSqQ3O5huTdDjErG4fMxSr1X+X56NuDrqtGfHmo1TRUQ=="], + + "@hey-api/json-schema-ref-parser": ["@hey-api/json-schema-ref-parser@1.4.2", "", { "dependencies": { "@jsdevtools/ono": "7.1.3", "@types/json-schema": "7.0.15", "js-yaml": "4.1.1" } }, "sha512-ZhCFSKI2ipZHEbgmtUHdyddvRU3wJ4elgCfYUC7T7hZa4EivSrVflTQf2w+v3TuaYxR1Y2V2kq3otqTttrrK8Q=="], - "@hey-api/codegen-core": ["@hey-api/codegen-core@0.5.5", "", { "dependencies": { "@hey-api/types": "0.1.2", "ansi-colors": "4.1.3", "c12": "3.3.3", "color-support": "1.1.3" }, "peerDependencies": { "typescript": ">=5.5.3" } }, "sha512-f2ZHucnA2wBGAY8ipB4wn/mrEYW+WUxU2huJmUvfDO6AE2vfILSHeF3wCO39Pz4wUYPoAWZByaauftLrOfC12Q=="], + "@hey-api/openapi-ts": ["@hey-api/openapi-ts@0.97.3", "", { "dependencies": { "@hey-api/codegen-core": "0.8.2", "@hey-api/json-schema-ref-parser": "1.4.2", "@hey-api/shared": "0.4.5", "@hey-api/spec-types": "0.2.0", "@hey-api/types": "0.1.4", "@lukeed/ms": "2.0.2", "ansi-colors": "4.1.3", "color-support": "1.1.3", "commander": "14.0.3", "get-tsconfig": "4.14.0" }, "peerDependencies": { "typescript": ">=5.5.3 || >=6.0.0 || 6.0.1-rc" }, "bin": { "openapi-ts": "./bin/run.js" } }, "sha512-4sR6/E/POuy7aPZW9DDjhObzZCq7eSJWiW0+epXeKNczoTWEwdOyWFy9Ca/CnXYlZ3oJsrv0ZD0OO+YuczT7CA=="], - "@hey-api/json-schema-ref-parser": ["@hey-api/json-schema-ref-parser@1.2.2", "", { "dependencies": { "@jsdevtools/ono": "^7.1.3", "@types/json-schema": "^7.0.15", "js-yaml": "^4.1.1", "lodash": "^4.17.21" } }, "sha512-oS+5yAdwnK20lSeFO1d53Ku+yaGCsY8PcrmSq2GtSs3bsBfRnHAbpPKSVzQcaxAOrzj5NB+f34WhZglVrNayBA=="], + "@hey-api/shared": ["@hey-api/shared@0.4.5", "", { "dependencies": { "@hey-api/codegen-core": "0.8.2", "@hey-api/json-schema-ref-parser": "1.4.2", "@hey-api/spec-types": "0.2.0", "@hey-api/types": "0.1.4", "ansi-colors": "4.1.3", "cross-spawn": "7.0.6", "open": "11.0.0", "semver": "7.7.4" } }, "sha512-au4eHpBXAe1du0iMp6ESYuEaMS2jsoEyrbcT246btRhI9rMeQFEs7ZjtcMGXGsxhpaR38A8cPGNHx7QOrWAdMw=="], - "@hey-api/openapi-ts": ["@hey-api/openapi-ts@0.90.10", "", { "dependencies": { "@hey-api/codegen-core": "^0.5.5", "@hey-api/json-schema-ref-parser": "1.2.2", "@hey-api/types": "0.1.2", "ansi-colors": "4.1.3", "color-support": "1.1.3", "commander": "14.0.2", "open": "11.0.0", "semver": "7.7.3" }, "peerDependencies": { "typescript": ">=5.5.3" }, "bin": { "openapi-ts": "bin/run.js" } }, "sha512-o0wlFxuLt1bcyIV/ZH8DQ1wrgODTnUYj/VfCHOOYgXUQlLp9Dm2PjihOz+WYrZLowhqUhSKeJRArOGzvLuOTsg=="], + "@hey-api/spec-types": ["@hey-api/spec-types@0.2.0", "", { "dependencies": { "@hey-api/types": "0.1.4" } }, "sha512-ibQ8Is7evMavzr8GNyJCcTg975d8DpaMUyLmOrQ85UBdy1l6t1KuRAwgChAbesJsIlNV6gjmlXruWyegDX18Fg=="], - "@hey-api/types": ["@hey-api/types@0.1.2", "", {}, "sha512-uNNtiVAWL7XNrV/tFXx7GLY9lwaaDazx1173cGW3+UEaw4RUPsHEmiB4DSpcjNxMIcrctfz2sGKLnVx5PBG2RA=="], + "@hey-api/types": ["@hey-api/types@0.1.4", "", {}, "sha512-thWfawrDIP7wSI9ioT13I5soaaqB5vAPIiZmgD8PbeEVKNrkonc0N/Sjj97ezl7oQgusZmaNphGdMKipPO6IBg=="], - "@hono/node-server": ["@hono/node-server@1.19.11", "", { "peerDependencies": { "hono": "^4" } }, "sha512-dr8/3zEaB+p0D2n/IUrlPF1HZm586qgJNXK1a9fhg/PzdtkK7Ksd5l312tJX2yBuALqDYBlG20QEbayqPyxn+g=="], + "@hono/node-server": ["@hono/node-server@2.0.10", "", { "peerDependencies": { "hono": "^4" } }, "sha512-ZcnNVhKTmyDJeg0UlnZjvM73JBsTAuhrH/J4fjwGOw59PwOW51r4J+p6CsKZWXdKSme4MFqU62CZMOsdDrU4CA=="], "@hono/node-ws": ["@hono/node-ws@1.3.0", "", { "dependencies": { "ws": "^8.17.0" }, "peerDependencies": { "@hono/node-server": "^1.19.2", "hono": "^4.6.0" } }, "sha512-ju25YbbvLuXdqBCmLZLqnNYu1nbHIQjoyUqA8ApZOeL1k4skuiTcw5SW77/5SUYo2Xi2NVBJoVlfQurnKEp03Q=="], @@ -1207,58 +854,12 @@ "@hono/zod-validator": ["@hono/zod-validator@0.4.2", "", { "peerDependencies": { "hono": ">=3.9.0", "zod": "^3.19.1" } }, "sha512-1rrlBg+EpDPhzOV4hT9pxr5+xDVmKuz6YJl+la7VCwK6ass5ldyKm5fD+umJdV2zhHD6jROoCCv8NbTwyfhT0g=="], - "@ibm/plex": ["@ibm/plex@6.4.1", "", { "dependencies": { "@ibm/telemetry-js": "^1.5.1" } }, "sha512-fnsipQywHt3zWvsnlyYKMikcVI7E2fEwpiPnIHFqlbByXVfQfANAAeJk1IV4mNnxhppUIDlhU0TzwYwL++Rn2g=="], - - "@ibm/telemetry-js": ["@ibm/telemetry-js@1.11.0", "", { "bin": { "ibmtelemetry": "dist/collect.js" } }, "sha512-RO/9j+URJnSfseWg9ZkEX9p+a3Ousd33DBU7rOafoZB08RqdzxFVYJ2/iM50dkBuD0o7WX7GYt1sLbNgCoE+pA=="], - - "@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.0.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ=="], - - "@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.0.4" }, "os": "darwin", "cpu": "x64" }, "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q=="], - - "@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.0.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg=="], - - "@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.0.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ=="], - - "@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.0.5", "", { "os": "linux", "cpu": "arm" }, "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g=="], - - "@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.0.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA=="], - - "@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.0.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA=="], - - "@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.0.4", "", { "os": "linux", "cpu": "x64" }, "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw=="], - - "@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.0.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA=="], - - "@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.0.4", "", { "os": "linux", "cpu": "x64" }, "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw=="], - - "@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.0.5" }, "os": "linux", "cpu": "arm" }, "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ=="], - - "@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.0.4" }, "os": "linux", "cpu": "arm64" }, "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA=="], - - "@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.0.4" }, "os": "linux", "cpu": "s390x" }, "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q=="], - - "@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.0.4" }, "os": "linux", "cpu": "x64" }, "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA=="], - - "@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.0.4" }, "os": "linux", "cpu": "arm64" }, "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g=="], - - "@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.0.4" }, "os": "linux", "cpu": "x64" }, "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw=="], - - "@img/sharp-wasm32": ["@img/sharp-wasm32@0.33.5", "", { "dependencies": { "@emnapi/runtime": "^1.2.0" }, "cpu": "none" }, "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg=="], - - "@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.33.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ=="], - - "@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.33.5", "", { "os": "win32", "cpu": "x64" }, "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg=="], - "@internationalized/date": ["@internationalized/date@3.12.1", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-6IedsVWXyq4P9Tj+TxuU8WGWM70hYLl12nbYU8jkikVpa6WXapFazPUcHUMDMoWftIDE2ILDkFFte6W2nFCkRQ=="], "@internationalized/number": ["@internationalized/number@3.6.6", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-iFgmQaXHE0vytNfpLZWOC2mEJCBRzcUxt53Xf/yCXG93lRvqas237i3r7X4RKMwO3txiyZD4mQjKAByFv6UGSQ=="], "@ioredis/commands": ["@ioredis/commands@1.5.1", "", {}, "sha512-JH8ZL/ywcJyR9MmJ5BNqZllXNZQqQbnVZOqpPQqE1vHiFgAw4NHbvE0FOduNU8IX9babitBT46571OnPTT0Zcw=="], - "@isaacs/balanced-match": ["@isaacs/balanced-match@4.0.1", "", {}, "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ=="], - - "@isaacs/brace-expansion": ["@isaacs/brace-expansion@5.0.1", "", { "dependencies": { "@isaacs/balanced-match": "^4.0.1" } }, "sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ=="], - "@isaacs/cliui": ["@isaacs/cliui@9.0.0", "", {}, "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg=="], "@isaacs/fs-minipass": ["@isaacs/fs-minipass@4.0.1", "", { "dependencies": { "minipass": "^7.0.4" } }, "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w=="], @@ -1321,16 +922,12 @@ "@jimp/utils": ["@jimp/utils@1.6.0", "", { "dependencies": { "@jimp/types": "1.6.0", "tinycolor2": "^1.6.0" } }, "sha512-gqFTGEosKbOkYF/WFj26jMHOI5OH2jeP1MmC/zbK6BF6VJBf8rIC5898dPfSzZEbSA0wbbV5slbntWVc5PKLFA=="], - "@joshwooding/vite-plugin-react-docgen-typescript": ["@joshwooding/vite-plugin-react-docgen-typescript@0.7.0", "", { "dependencies": { "glob": "^13.0.1", "react-docgen-typescript": "^2.2.2" }, "peerDependencies": { "typescript": ">= 4.3.x", "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["typescript"] }, "sha512-qvsTEwEFefhdirGOPnu9Wp6ChfIwy2dBCRuETU3uE+4cC+PFoxMSiiEhxk4lOluA34eARHA0OxqsEUYDqRMgeQ=="], - "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="], "@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="], "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], - "@jridgewell/source-map": ["@jridgewell/source-map@0.3.11", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25" } }, "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA=="], - "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], @@ -1341,59 +938,15 @@ "@jsdevtools/ono": ["@jsdevtools/ono@7.1.3", "", {}, "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg=="], - "@jsx-email/all": ["@jsx-email/all@2.2.3", "", { "dependencies": { "@jsx-email/body": "1.0.2", "@jsx-email/button": "1.0.4", "@jsx-email/column": "1.0.3", "@jsx-email/container": "1.0.2", "@jsx-email/font": "1.0.3", "@jsx-email/head": "1.0.2", "@jsx-email/heading": "1.0.2", "@jsx-email/hr": "1.0.2", "@jsx-email/html": "1.0.2", "@jsx-email/img": "1.0.2", "@jsx-email/link": "1.0.2", "@jsx-email/markdown": "2.0.4", "@jsx-email/preview": "1.0.2", "@jsx-email/render": "1.1.1", "@jsx-email/row": "1.0.2", "@jsx-email/section": "1.0.2", "@jsx-email/tailwind": "2.4.4", "@jsx-email/text": "1.0.2" }, "peerDependencies": { "react": "^18.2.0" } }, "sha512-OBvLe/hVSQc0LlMSTJnkjFoqs3bmxcC4zpy/5pT5agPCSKMvAKQjzmsc2xJ2wO73jSpRV1K/g38GmvdCfrhSoQ=="], + "@kobalte/core": ["@kobalte/core@0.13.11", "", { "dependencies": { "@floating-ui/dom": "^1.5.1", "@internationalized/date": "^3.4.0", "@internationalized/number": "^3.2.1", "@kobalte/utils": "^0.9.1", "@solid-primitives/props": "^3.1.8", "@solid-primitives/resize-observer": "^2.0.26", "solid-presence": "^0.1.8", "solid-prevent-scroll": "^0.1.4" }, "peerDependencies": { "solid-js": "^1.8.15" } }, "sha512-hK7TYpdib/XDb/r/4XDBFaO9O+3ZHz4ZWryV4/3BfES+tSQVgg2IJupDnztKXB0BqbSRy/aWlHKw1SPtNPYCFQ=="], - "@jsx-email/body": ["@jsx-email/body@1.0.2", "", { "peerDependencies": { "react": "^18.2.0" } }, "sha512-NjR2tgLH4XGfGkm+O8kcVwi9MBqZsXZCLlmk3HlMux3/n/+a5zB+yhJqXWZBJl2i+6cSF+E2O6hK11ekyK9WWQ=="], + "@kobalte/utils": ["@kobalte/utils@0.9.1", "", { "dependencies": { "@solid-primitives/event-listener": "^2.2.14", "@solid-primitives/keyed": "^1.2.0", "@solid-primitives/map": "^0.4.7", "@solid-primitives/media": "^2.2.4", "@solid-primitives/props": "^3.1.8", "@solid-primitives/refs": "^1.0.5", "@solid-primitives/utils": "^6.2.1" }, "peerDependencies": { "solid-js": "^1.8.8" } }, "sha512-eeU60A3kprIiBDAfv9gUJX1tXGLuZiKMajUfSQURAF2pk4ZoMYiqIzmrMBvzcxP39xnYttgTyQEVLwiTZnrV4w=="], - "@jsx-email/button": ["@jsx-email/button@1.0.4", "", { "peerDependencies": { "react": "^18.2.0" } }, "sha512-NbuxtBtTdcFOKpyw166lvgA8sKpgwQzqpRVSTDZdd+2xlh5gzeckXG9VtCbfktIatD26r45ZMmP68QGK3hxIPA=="], + "@leichtgewicht/ip-codec": ["@leichtgewicht/ip-codec@2.0.5", "", {}, "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw=="], - "@jsx-email/cli": ["@jsx-email/cli@1.4.3", "", { "dependencies": { "@dot/log": "^0.1.3", "@fontsource/inter": "^5.0.8", "@jsx-email/doiuse-email": "^1.0.1", "@jsx-email/render": "1.1.1", "@radix-ui/colors": "1.0.1", "@radix-ui/react-collapsible": "1.0.3", "@radix-ui/react-popover": "1.0.6", "@radix-ui/react-slot": "1.0.2", "@radix-ui/react-toggle-group": "1.0.4", "@radix-ui/react-tooltip": "1.0.6", "@vitejs/plugin-react": "^4.1.0", "autoprefixer": "^10.4.16", "chalk": "4.1.2", "cheerio": "1.0.0-rc.12", "classnames": "2.3.2", "debug": "^4.3.4", "esbuild": "^0.19.3", "esbuild-plugin-copy": "^2.1.1", "framer-motion": "8.5.5", "globby": "11.0.4", "html-minifier-terser": "^7.2.0", "import-local": "^3.1.0", "js-beautify": "^1.14.9", "mustache": "^4.2.0", "postcss": "^8.4.30", "react": "18.2.0", "react-dom": "18.2.0", "react-router-dom": "6.16.0", "shikiji": "^0.6.8", "superstruct": "^1.0.3", "tailwindcss": "3.3.3", "titleize": "^4.0.0", "vite": "^4.4.9", "vite-plugin-dynamic-import": "^1.5.0", "yargs-parser": "^21.1.1" }, "bin": { "email": "dist/src/index.js" } }, "sha512-Aid5d5U3RM9sjkjzn/X/a5FFWLJSXlwh8pagBVgnUTiaBM8+nroSPZaC21Xe3rl/uwYpY9lc+2AAH9+7SmroiQ=="], + "@lukeed/ms": ["@lukeed/ms@2.0.2", "", {}, "sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA=="], - "@jsx-email/column": ["@jsx-email/column@1.0.3", "", { "peerDependencies": { "react": "^18.2.0" } }, "sha512-dto5s/INVWy4oMOETX53O53NerpPxezO8CQctriTaHLrqlR22lWoXJZoGTzMvt9uLyoUrYViA6Tj2F9Bio+fOg=="], - - "@jsx-email/container": ["@jsx-email/container@1.0.2", "", { "peerDependencies": { "react": "^18.2.0" } }, "sha512-Muue8X2PgjxCf+YvUJ6zGTqcmo3i4S3EmsLGYpnWl7e/ZKmMLTjN4DdUeSsi27fWEdpUTjQQG4McMGdFYhZTGg=="], - - "@jsx-email/doiuse-email": ["@jsx-email/doiuse-email@1.0.4", "", { "dependencies": { "@adobe/css-tools": "^4.3.1", "css-what": "^6.1.0", "domhandler": "^5.0.3", "dot-prop": "^8.0.2", "htmlparser2": "^9.0.0", "micromatch": "^4.0.5", "style-to-object": "^1.0.4" } }, "sha512-HfLjuQsAAyAkIZWR0wHR6+P6u40RIX0jBZu/1rgsw18+jc36agZD5j84zG4CDzitRxgXJXrAohPfDFPxcrtjAA=="], - - "@jsx-email/font": ["@jsx-email/font@1.0.3", "", { "peerDependencies": { "react": "^18.2.0" } }, "sha512-NRp9NBjrmYVwAFYRwuifzvavtHB8blRLEJ+q9BygY3y58+FhHENweU8FMdC5OSts2C99FbKrHUicTSanEj8+Aw=="], - - "@jsx-email/head": ["@jsx-email/head@1.0.2", "", { "peerDependencies": { "react": "^18.2.0" } }, "sha512-M5Af6Imt7W/Vp09dY76I/v7gRe1aQLmeXjBZZSrSbvpMVQVAd6gwR/druNaAO+zHDoKhXwR50+pxXpnC+TFiIw=="], - - "@jsx-email/heading": ["@jsx-email/heading@1.0.2", "", { "dependencies": { "@radix-ui/react-slot": "1.0.2" }, "peerDependencies": { "react": "^18.2.0" } }, "sha512-yumw176gsAJQnwSx0HCamCj2DozQireayax7s+jvr+TvEvFxNLD4PQvK45c6JdYYD9OPGnjDApks102FJQ7xDQ=="], - - "@jsx-email/hr": ["@jsx-email/hr@1.0.2", "", { "peerDependencies": { "react": "^18.2.0" } }, "sha512-CuJ/ADJoRwuQyUqulOf00BceTdY9kzrLQTMwGPUmFMtlsF+EFSPNULoksFg6nskVjFV7pBUm78FwiEfP2OAHMQ=="], - - "@jsx-email/html": ["@jsx-email/html@1.0.2", "", { "peerDependencies": { "react": "^18.2.0" } }, "sha512-FOiJdZWbCwNwsAqRuXlrXo39UTVWtrezuzA0pXY0UD5nEPzwpk7N46EwW8uxBRoqNRPiuUnwnFWLXuPZNAIGlg=="], - - "@jsx-email/img": ["@jsx-email/img@1.0.2", "", { "peerDependencies": { "react": "^18.2.0" } }, "sha512-aqqnx43Cvq/wVzALhK6n5pSJBqTRwq5wuM66/QAkEJaZgXqrXCNRx1fNeqQt/Zp2j6KmHq3Ax0AHSJX4pjKIDw=="], - - "@jsx-email/link": ["@jsx-email/link@1.0.2", "", { "peerDependencies": { "react": "^18.2.0" } }, "sha512-+mr+WFHZ7fILkFlSdbusSm9ml6jPq7u89LGe2E71AB23JEaaF8qO5u6so6wySAme+gDIGId/+tobPcTHeI+hHQ=="], - - "@jsx-email/markdown": ["@jsx-email/markdown@2.0.4", "", { "dependencies": { "md-to-react-email": "5.0.0" }, "peerDependencies": { "react": "^18.2.0" } }, "sha512-jYf/BVGKjz7TU1FhEX0ELZGKPQj+6o0R4NjZTBJsJ3PUovgXynS4GqU83eARwGbOSUve/9qvRljsCCQHD+t/Gg=="], - - "@jsx-email/preview": ["@jsx-email/preview@1.0.2", "", { "peerDependencies": { "react": "^18.2.0" } }, "sha512-dkc3hG08R0J0TEQ/cDCtdyoLYddb1MIvhh5OyTqfd5pgSxPF6MaSH8LkDqMUYpSYZ3RtUK6g4d8q3mF7tx28sQ=="], - - "@jsx-email/render": ["@jsx-email/render@1.1.1", "", { "dependencies": { "html-to-text": "9.0.5", "pretty": "2.0.0" } }, "sha512-0y45YofM0Ak8Rswss1AWgy7v9mlMoHMrgD0x601gvb2HBddDp2r0etNJhhN9ZwW8QOteuYluHD279e+PCr2WxA=="], - - "@jsx-email/row": ["@jsx-email/row@1.0.2", "", { "peerDependencies": { "react": "^18.2.0" } }, "sha512-6bUr1rqIsUVrhBWcTj0QTZvUQ/deThDKoi10dSfhjmbUqFYr7RdyGwMwsUuFg1YzZCohvy8dVpBIwd+5wmtsIw=="], - - "@jsx-email/section": ["@jsx-email/section@1.0.2", "", { "peerDependencies": { "react": "^18.2.0" } }, "sha512-gGGE9zkljfrgWOz7NlmFsDPVKCQv6omu+VXsce0yh0+yHBehuFYrv4WOqMZFtfQo6Y1IDdQWt+XCi5GlEvd0Lw=="], - - "@jsx-email/tailwind": ["@jsx-email/tailwind@2.4.4", "", { "dependencies": { "@jsx-email/render": "1.1.1", "react": "18.2.0", "react-dom": "18.2.0", "tw-to-css": "0.0.12" } }, "sha512-RqLD0y2le1ruFBt9MCa0PNnTVUgcS8vcOOWMJUkMezBZUAUkP5KSj3DO+6DdgVn67kH9cnnRvknXo8L6qd6BwA=="], - - "@jsx-email/text": ["@jsx-email/text@1.0.2", "", { "peerDependencies": { "react": "^18.2.0" } }, "sha512-0zzwEwrKtY6tfjPJF0r3krKCDpP/ySYDvkn4+MvIFrIH5RZKmn3XDa5o/3hkbxMwpLn4MsXGIXn9XzMTaqTfUA=="], - - "@kobalte/core": ["@kobalte/core@0.13.11", "", { "dependencies": { "@floating-ui/dom": "^1.5.1", "@internationalized/date": "^3.4.0", "@internationalized/number": "^3.2.1", "@kobalte/utils": "^0.9.1", "@solid-primitives/props": "^3.1.8", "@solid-primitives/resize-observer": "^2.0.26", "solid-presence": "^0.1.8", "solid-prevent-scroll": "^0.1.4" }, "peerDependencies": { "solid-js": "^1.8.15" } }, "sha512-hK7TYpdib/XDb/r/4XDBFaO9O+3ZHz4ZWryV4/3BfES+tSQVgg2IJupDnztKXB0BqbSRy/aWlHKw1SPtNPYCFQ=="], - - "@kobalte/utils": ["@kobalte/utils@0.9.1", "", { "dependencies": { "@solid-primitives/event-listener": "^2.2.14", "@solid-primitives/keyed": "^1.2.0", "@solid-primitives/map": "^0.4.7", "@solid-primitives/media": "^2.2.4", "@solid-primitives/props": "^3.1.8", "@solid-primitives/refs": "^1.0.5", "@solid-primitives/utils": "^6.2.1" }, "peerDependencies": { "solid-js": "^1.8.8" } }, "sha512-eeU60A3kprIiBDAfv9gUJX1tXGLuZiKMajUfSQURAF2pk4ZoMYiqIzmrMBvzcxP39xnYttgTyQEVLwiTZnrV4w=="], - - "@kurkle/color": ["@kurkle/color@0.3.4", "", {}, "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w=="], - - "@leichtgewicht/ip-codec": ["@leichtgewicht/ip-codec@2.0.5", "", {}, "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw=="], - - "@lukeed/ms": ["@lukeed/ms@2.0.2", "", {}, "sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA=="], - - "@lydell/node-pty": ["@lydell/node-pty@1.2.0-beta.10", "", { "optionalDependencies": { "@lydell/node-pty-darwin-arm64": "1.2.0-beta.10", "@lydell/node-pty-darwin-x64": "1.2.0-beta.10", "@lydell/node-pty-linux-arm64": "1.2.0-beta.10", "@lydell/node-pty-linux-x64": "1.2.0-beta.10", "@lydell/node-pty-win32-arm64": "1.2.0-beta.10", "@lydell/node-pty-win32-x64": "1.2.0-beta.10" } }, "sha512-Fv+A3+MZVA8qhkBIZsM1E6dCdHNMyXXz22mAYiMWd03LlyK///F3OH6CKPX9mj4id7LUlxpr45yPzyBVy9aDPw=="], + "@lydell/node-pty": ["@lydell/node-pty@1.2.0-beta.10", "", { "optionalDependencies": { "@lydell/node-pty-darwin-arm64": "1.2.0-beta.10", "@lydell/node-pty-darwin-x64": "1.2.0-beta.10", "@lydell/node-pty-linux-arm64": "1.2.0-beta.10", "@lydell/node-pty-linux-x64": "1.2.0-beta.10", "@lydell/node-pty-win32-arm64": "1.2.0-beta.10", "@lydell/node-pty-win32-x64": "1.2.0-beta.10" } }, "sha512-Fv+A3+MZVA8qhkBIZsM1E6dCdHNMyXXz22mAYiMWd03LlyK///F3OH6CKPX9mj4id7LUlxpr45yPzyBVy9aDPw=="], "@lydell/node-pty-darwin-arm64": ["@lydell/node-pty-darwin-arm64@1.2.0-beta.10", "", { "os": "darwin", "cpu": "arm64" }, "sha512-C+eqDyRNHRYvx7RaHj6VVCx6nCpRBPuuxhTcc3JH3GuBMoxTsYeY4GkWH2XOktrgbAq1BG8e/Y8bu/wNQreCEw=="], @@ -1407,29 +960,23 @@ "@lydell/node-pty-win32-x64": ["@lydell/node-pty-win32-x64@1.2.0-beta.10", "", { "os": "win32", "cpu": "x64" }, "sha512-ExFgWrzyldNAMi45U9PLIOu+g/RatP+f0c/dZxaooifME6yLW32BoHveH26/TtoAjZyJrc2iL0u48pgnR1fzmg=="], - "@malept/cross-spawn-promise": ["@malept/cross-spawn-promise@2.0.0", "", { "dependencies": { "cross-spawn": "^7.0.1" } }, "sha512-1DpKU0Z5ThltBwjNySMC14g0CkbyhCaz9FkhxqNsZI6uAPJXFS8cMXlBKo26FJ8ZuW6S9GCMcR9IO5k2X5/9Fg=="], - - "@malept/flatpak-bundler": ["@malept/flatpak-bundler@0.4.0", "", { "dependencies": { "debug": "^4.1.1", "fs-extra": "^9.0.0", "lodash": "^4.17.15", "tmp-promise": "^3.0.2" } }, "sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q=="], - - "@mdx-js/mdx": ["@mdx-js/mdx@3.1.1", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdx": "^2.0.0", "acorn": "^8.0.0", "collapse-white-space": "^2.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "estree-util-scope": "^1.0.0", "estree-walker": "^3.0.0", "hast-util-to-jsx-runtime": "^2.0.0", "markdown-extensions": "^2.0.0", "recma-build-jsx": "^1.0.0", "recma-jsx": "^1.0.0", "recma-stringify": "^1.0.0", "rehype-recma": "^1.0.0", "remark-mdx": "^3.0.0", "remark-parse": "^11.0.0", "remark-rehype": "^11.0.0", "source-map": "^0.7.0", "unified": "^11.0.0", "unist-util-position-from-estree": "^2.0.0", "unist-util-stringify-position": "^4.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" } }, "sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ=="], - - "@mdx-js/react": ["@mdx-js/react@3.1.1", "", { "dependencies": { "@types/mdx": "^2.0.0" }, "peerDependencies": { "@types/react": ">=16", "react": ">=16" } }, "sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw=="], + "@mendcode/core": ["@mendcode/core@workspace:packages/core"], - "@mixmark-io/domino": ["@mixmark-io/domino@2.2.0", "", {}, "sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw=="], + "@mendcode/function": ["@mendcode/function@workspace:packages/function"], - "@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.27.1", "", { "dependencies": { "@hono/node-server": "^1.19.9", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", "express": "^5.2.1", "express-rate-limit": "^8.2.1", "hono": "^4.11.4", "jose": "^6.1.3", "json-schema-typed": "^8.0.2", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.25 || ^4.0", "zod-to-json-schema": "^3.25.1" }, "peerDependencies": { "@cfworker/json-schema": "^4.1.1" }, "optionalPeers": ["@cfworker/json-schema"] }, "sha512-sr6GbP+4edBwFndLbM60gf07z0FQ79gaExpnsjMGePXqFcSSb7t6iscpjk9DhFhwd+mTEQrzNafGP8/iGGFYaA=="], + "@mendcode/plugin": ["@mendcode/plugin@workspace:packages/plugin"], - "@motionone/animation": ["@motionone/animation@10.18.0", "", { "dependencies": { "@motionone/easing": "^10.18.0", "@motionone/types": "^10.17.1", "@motionone/utils": "^10.18.0", "tslib": "^2.3.1" } }, "sha512-9z2p5GFGCm0gBsZbi8rVMOAJCtw1WqBTIPw3ozk06gDvZInBPIsQcHgYogEJ4yuHJ+akuW8g1SEIOpTOvYs8hw=="], + "@mendcode/script": ["@mendcode/script@workspace:packages/script"], - "@motionone/dom": ["@motionone/dom@10.18.0", "", { "dependencies": { "@motionone/animation": "^10.18.0", "@motionone/generators": "^10.18.0", "@motionone/types": "^10.17.1", "@motionone/utils": "^10.18.0", "hey-listen": "^1.0.8", "tslib": "^2.3.1" } }, "sha512-bKLP7E0eyO4B2UaHBBN55tnppwRnaE3KFfh3Ps9HhnAkar3Cb69kUCJY9as8LrccVYKgHA+JY5dOQqJLOPhF5A=="], + "@mendcode/sdk": ["@mendcode/sdk@workspace:packages/sdk/js"], - "@motionone/easing": ["@motionone/easing@10.18.0", "", { "dependencies": { "@motionone/utils": "^10.18.0", "tslib": "^2.3.1" } }, "sha512-VcjByo7XpdLS4o9T8t99JtgxkdMcNWD3yHU/n6CLEz3bkmKDRZyYQ/wmSf6daum8ZXqfUAgFeCZSpJZIMxaCzg=="], + "@mendcode/slack": ["@mendcode/slack@workspace:packages/slack"], - "@motionone/generators": ["@motionone/generators@10.18.0", "", { "dependencies": { "@motionone/types": "^10.17.1", "@motionone/utils": "^10.18.0", "tslib": "^2.3.1" } }, "sha512-+qfkC2DtkDj4tHPu+AFKVfR/C30O1vYdvsGYaR13W/1cczPrrcjdvYCj0VLFuRMN+lP1xvpNZHCRNM4fBzn1jg=="], + "@mendcode/ui": ["@mendcode/ui@workspace:packages/ui"], - "@motionone/types": ["@motionone/types@10.17.1", "", {}, "sha512-KaC4kgiODDz8hswCrS0btrVrzyU2CSQKO7Ps90ibBVSQmjkrt2teqta6/sOG59v7+dPnKMAg13jyqtMKV2yJ7A=="], + "@mixmark-io/domino": ["@mixmark-io/domino@2.2.0", "", {}, "sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw=="], - "@motionone/utils": ["@motionone/utils@10.18.0", "", { "dependencies": { "@motionone/types": "^10.17.1", "hey-listen": "^1.0.8", "tslib": "^2.3.1" } }, "sha512-3XVF7sgyTSI2KWvTf6uLlBJ5iAgRgmvp3bpuOiQJvInd4nZ19ET8lX5unn30SlmRH7hXbBbH+Gxd0m0klJ3Xtw=="], + "@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.27.1", "", { "dependencies": { "@hono/node-server": "^1.19.9", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", "express": "^5.2.1", "express-rate-limit": "^8.2.1", "hono": "^4.11.4", "jose": "^6.1.3", "json-schema-typed": "^8.0.2", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.25 || ^4.0", "zod-to-json-schema": "^3.25.1" }, "peerDependencies": { "@cfworker/json-schema": "^4.1.1" }, "optionalPeers": ["@cfworker/json-schema"] }, "sha512-sr6GbP+4edBwFndLbM60gf07z0FQ79gaExpnsjMGePXqFcSSb7t6iscpjk9DhFhwd+mTEQrzNafGP8/iGGFYaA=="], "@msgpackr-extract/msgpackr-extract-darwin-arm64": ["@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw=="], @@ -1443,13 +990,7 @@ "@msgpackr-extract/msgpackr-extract-win32-x64": ["@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3", "", { "os": "win32", "cpu": "x64" }, "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ=="], - "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.3", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-xK9sGVbJWYb08+mTJt3/YV24WxvxpXcXtP6B172paPZ+Ts69Re9dAr7lKwJoeIx8OoeuimEiRZ7umkiUVClmmQ=="], - - "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="], - - "@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="], - - "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="], + "@nodable/entities": ["@nodable/entities@2.1.1", "", {}, "sha512-Pig3HxDIoMgjdEH8OCf/dkcTmLFjJRjWuq8jSnklu284/TKOPibSRERmOykiwmyXTtv61mP+44f3GMx0tLAyjg=="], "@npm/types": ["@npm/types@1.0.2", "", {}, "sha512-KXZccTDEnWqNrrx6JjpJKU/wJvNeg9BDgjS0XhmlZab7br921HtyVbsYzJr4L+xIvjdJ20Wh9dgxgCI2a5CEQw=="], @@ -1523,69 +1064,33 @@ "@octokit/webhooks-types": ["@octokit/webhooks-types@7.6.1", "", {}, "sha512-S8u2cJzklBC0FgTwWVLaM8tMrDuDMVE4xiTK4EYXM9GntyvrdbSoxqDQa+Fh57CCNApyIpyeqPhhFEmHPfrXgw=="], - "@one-ini/wasm": ["@one-ini/wasm@0.1.1", "", {}, "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw=="], - "@openauthjs/openauth": ["@openauthjs/openauth@0.0.0-20250322224806", "", { "dependencies": { "@standard-schema/spec": "1.0.0-beta.3", "aws4fetch": "1.0.20", "jose": "5.9.6" }, "peerDependencies": { "arctic": "^2.2.2", "hono": "^4.0.0" } }, "sha512-p5IWSRXvABcwocH2dNI0w8c1QJelIOFulwhKk+aLLFfUbs8u1pr7kQbYe8yCSM2+bcLHiwbogpUQc2ovrGwCuw=="], - "@mendcode/app": ["@mendcode/app@workspace:packages/app"], - - "@mendcode/console-app": ["@mendcode/console-app@workspace:packages/console/app"], - - "@mendcode/console-core": ["@mendcode/console-core@workspace:packages/console/core"], - - "@mendcode/console-function": ["@mendcode/console-function@workspace:packages/console/function"], - - "@mendcode/console-mail": ["@mendcode/console-mail@workspace:packages/console/mail"], - - "@mendcode/console-resource": ["@mendcode/console-resource@workspace:packages/console/resource"], - - "@mendcode/core": ["@mendcode/core@workspace:packages/core"], - - "@mendcode/desktop": ["@mendcode/desktop@workspace:packages/desktop"], - - "@mendcode/enterprise": ["@mendcode/enterprise@workspace:packages/enterprise"], - - "@mendcode/function": ["@mendcode/function@workspace:packages/function"], - - "@mendcode/plugin": ["@mendcode/plugin@workspace:packages/plugin"], - - "@mendcode/script": ["@mendcode/script@workspace:packages/script"], - - "@mendcode/sdk": ["@mendcode/sdk@workspace:packages/sdk/js"], - - "@mendcode/slack": ["@mendcode/slack@workspace:packages/slack"], - - "@mendcode/storybook": ["@mendcode/storybook@workspace:packages/storybook"], - - "@mendcode/ui": ["@mendcode/ui@workspace:packages/ui"], - - "@mendcode/web": ["@mendcode/web@workspace:packages/web"], - "@openrouter/ai-sdk-provider": ["@openrouter/ai-sdk-provider@2.8.1", "", { "peerDependencies": { "ai": "^6.0.0", "zod": "^3.25.0 || ^4.0.0" } }, "sha512-Y6j3yivgoEUf/kutD/k5GX/mzZfioRFoSx0gbQ+mIOzMaH/vJv1rCkztiuvlLw5xRYQil7oxHUZvmSfXqOx1NQ=="], "@opentelemetry/api": ["@opentelemetry/api@1.9.0", "", {}, "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg=="], - "@opentelemetry/api-logs": ["@opentelemetry/api-logs@0.214.0", "", { "dependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-40lSJeqYO8Uz2Yj7u94/SJWE/wONa7rmMKjI1ZcIjgf3MHNHv1OZUCrCETGuaRF62d5pQD1wKIW+L4lmSMTzZA=="], + "@opentelemetry/api-logs": ["@opentelemetry/api-logs@0.219.0", "", { "dependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-FFx7YnaYJlIjqWW/AG/yAZ0L/NEY724PipXXXQLdtZPbLwBGbUMTGL1i/esI56TWfTUXxhLfpgrnWJCG8aUJyg=="], - "@opentelemetry/context-async-hooks": ["@opentelemetry/context-async-hooks@2.6.1", "", { "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-XHzhwRNkBpeP8Fs/qjGrAf9r9PRv67wkJQ/7ZPaBQQ68DYlTBBx5MF9LvPx7mhuXcDessKK2b+DcxqwpgkcivQ=="], + "@opentelemetry/context-async-hooks": ["@opentelemetry/context-async-hooks@2.8.0", "", { "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-/3FIraneMcng67SUJCxvyInk/oxzwsxyadufk0wwfOBLf5wqtAGX4MoQASwSbndBPeARzBryUM9Azr5kHIdWLw=="], - "@opentelemetry/core": ["@opentelemetry/core@2.6.1", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-8xHSGWpJP9wBxgBpnqGL0R3PbdWQndL1Qp50qrg71+B28zK5OQmUgcDKLJgzyAAV38t4tOyLMGDD60LneR5W8g=="], + "@opentelemetry/core": ["@opentelemetry/core@2.8.0", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-hd1Lfh8p545nNz+jq1Ejfz+Mn1hyLuxYn1YzTfFNrxr8urEWMNQLPf1Th8kjOH+HxwawCrtgBp8JpBUR4ZSgww=="], - "@opentelemetry/exporter-trace-otlp-http": ["@opentelemetry/exporter-trace-otlp-http@0.214.0", "", { "dependencies": { "@opentelemetry/core": "2.6.1", "@opentelemetry/otlp-exporter-base": "0.214.0", "@opentelemetry/otlp-transformer": "0.214.0", "@opentelemetry/resources": "2.6.1", "@opentelemetry/sdk-trace-base": "2.6.1" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-kIN8nTBMgV2hXzV/a20BCFilPZdAIMYYJGSgfMMRm/Xa+07y5hRDS2Vm12A/z8Cdu3Sq++ZvJfElokX2rkgGgw=="], + "@opentelemetry/exporter-trace-otlp-http": ["@opentelemetry/exporter-trace-otlp-http@0.219.0", "", { "dependencies": { "@opentelemetry/core": "2.8.0", "@opentelemetry/otlp-exporter-base": "0.219.0", "@opentelemetry/otlp-transformer": "0.219.0", "@opentelemetry/resources": "2.8.0", "@opentelemetry/sdk-trace-base": "2.8.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-9t6SvBXXBEjOBcIzgozvBbd3jWrv3Gt3ngGhl1fhdZ/zRc7oZDVOFEqbi2zlBpW9BXhgDMKv422J0DL/3iQWfw=="], - "@opentelemetry/otlp-exporter-base": ["@opentelemetry/otlp-exporter-base@0.214.0", "", { "dependencies": { "@opentelemetry/core": "2.6.1", "@opentelemetry/otlp-transformer": "0.214.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-u1Gdv0/E9wP+apqWf7Wv2npXmgJtxsW2XL0TEv9FZloTZRuMBKmu8cYVXwS4Hm3q/f/3FuCnPTgiwYvIqRSpRg=="], + "@opentelemetry/otlp-exporter-base": ["@opentelemetry/otlp-exporter-base@0.219.0", "", { "dependencies": { "@opentelemetry/core": "2.8.0", "@opentelemetry/otlp-transformer": "0.219.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-zvIxQX/AZUVKDU+hCuYx+7UkiP7GRdnk1ZbFQRYzHvYp47cAWR4j3IhoPhV9KaeXEv2xdGq3IA6PnpzDmLcmSA=="], - "@opentelemetry/otlp-transformer": ["@opentelemetry/otlp-transformer@0.214.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.214.0", "@opentelemetry/core": "2.6.1", "@opentelemetry/resources": "2.6.1", "@opentelemetry/sdk-logs": "0.214.0", "@opentelemetry/sdk-metrics": "2.6.1", "@opentelemetry/sdk-trace-base": "2.6.1", "protobufjs": "^7.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-DSaYcuBRh6uozfsWN3R8HsN0yDhCuWP7tOFdkUOVaWD1KVJg8m4qiLUsg/tNhTLS9HUYUcwNpwL2eroLtsZZ/w=="], + "@opentelemetry/otlp-transformer": ["@opentelemetry/otlp-transformer@0.219.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.219.0", "@opentelemetry/core": "2.8.0", "@opentelemetry/resources": "2.8.0", "@opentelemetry/sdk-logs": "0.219.0", "@opentelemetry/sdk-metrics": "2.8.0", "@opentelemetry/sdk-trace-base": "2.8.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-aaYKAyXhw9VchKZVGOopD3Gw/kPsyrX2c6IQ0AW32mTjqmZOh5Y6Gf5OYqTNqVktAeBjmFinhyFaCwW6GYK9YQ=="], - "@opentelemetry/resources": ["@opentelemetry/resources@2.6.1", "", { "dependencies": { "@opentelemetry/core": "2.6.1", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "sha512-lID/vxSuKWXM55XhAKNoYXu9Cutoq5hFdkbTdI/zDKQktXzcWBVhNsOkiZFTMU9UtEWuGRNe0HUgmsFldIdxVA=="], + "@opentelemetry/resources": ["@opentelemetry/resources@2.8.0", "", { "dependencies": { "@opentelemetry/core": "2.8.0", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "sha512-qmXQ27ilDbUK/vGMqwL8D4/rhn76C+sherM4wTbjlfknR8Nvfc/hCxjRJPhkzZzUsPiNg16SA31NxMabwttRjg=="], - "@opentelemetry/sdk-logs": ["@opentelemetry/sdk-logs@0.214.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.214.0", "@opentelemetry/core": "2.6.1", "@opentelemetry/resources": "2.6.1", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.4.0 <1.10.0" } }, "sha512-zf6acnScjhsaBUU22zXZ/sLWim1dfhUAbGXdMmHmNG3LfBnQ3DKsOCITb2IZwoUsNNMTogqFKBnlIPPftUgGwA=="], + "@opentelemetry/sdk-logs": ["@opentelemetry/sdk-logs@0.219.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.219.0", "@opentelemetry/core": "2.8.0", "@opentelemetry/resources": "2.8.0", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.4.0 <1.10.0" } }, "sha512-s6lTKRakaPClvKoWHRChxnXjDMkM/TQ30ff78jN6EBGf7MI7VzANE5PU3f4z9qDUudWjvZjOLHG0rBnBKYvoXA=="], - "@opentelemetry/sdk-metrics": ["@opentelemetry/sdk-metrics@2.6.1", "", { "dependencies": { "@opentelemetry/core": "2.6.1", "@opentelemetry/resources": "2.6.1" }, "peerDependencies": { "@opentelemetry/api": ">=1.9.0 <1.10.0" } }, "sha512-9t9hJHX15meBy2NmTJxL+NJfXmnausR2xUDvE19XQce0Qi/GBtDGamU8nS1RMbdgDmhgpm3VaOu2+fiS/SfTpQ=="], + "@opentelemetry/sdk-metrics": ["@opentelemetry/sdk-metrics@2.8.0", "", { "dependencies": { "@opentelemetry/core": "2.8.0", "@opentelemetry/resources": "2.8.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.9.0 <1.10.0" } }, "sha512-UDBGaj6W0Rgy5rTTaoxs8gVGF/aGkAKyjurJv7se6wjRxJu7FoquTLT/vt54DZfo4crbprYfhX/SOK9+BPw1qg=="], - "@opentelemetry/sdk-trace-base": ["@opentelemetry/sdk-trace-base@2.6.1", "", { "dependencies": { "@opentelemetry/core": "2.6.1", "@opentelemetry/resources": "2.6.1", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "sha512-r86ut4T1e8vNwB35CqCcKd45yzqH6/6Wzvpk2/cZB8PsPLlZFTvrh8yfOS3CYZYcUmAx4hHTZJ8AO8Dj8nrdhw=="], + "@opentelemetry/sdk-trace-base": ["@opentelemetry/sdk-trace-base@2.8.0", "", { "dependencies": { "@opentelemetry/core": "2.8.0", "@opentelemetry/resources": "2.8.0", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "sha512-mhU4jp+vW0mGbFRd+GeXHvmfA4aDqWjBjLC3pE5XMpLs0IE2ryYb019Ts2AQrOq67gaTF25D91+fgvEHDZEnuQ=="], - "@opentelemetry/sdk-trace-node": ["@opentelemetry/sdk-trace-node@2.6.1", "", { "dependencies": { "@opentelemetry/context-async-hooks": "2.6.1", "@opentelemetry/core": "2.6.1", "@opentelemetry/sdk-trace-base": "2.6.1" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-Hh2i4FwHWRFhnO2Q/p6svMxy8MPsNCG0uuzUY3glqm0rwM0nQvbTO1dXSp9OqQoTKXcQzaz9q1f65fsurmOhNw=="], + "@opentelemetry/sdk-trace-node": ["@opentelemetry/sdk-trace-node@2.8.0", "", { "dependencies": { "@opentelemetry/context-async-hooks": "2.8.0", "@opentelemetry/core": "2.8.0", "@opentelemetry/sdk-trace-base": "2.8.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-nZt9OGufioAc3AfoLTqA9bsAeaMJAictYDdI2VcNQ+PmT+3rfKjAZDZvgPfd8VPX0O5Bw1hdQF6kDK8VSpZiWg=="], "@opentelemetry/semantic-conventions": ["@opentelemetry/semantic-conventions@1.40.0", "", {}, "sha512-cifvXDhcqMwwTlTK04GBNeIe7yyo28Mfby85QXFe1Yk8nmi36Ab/5UQwptOx84SsoGNRg+EVSjwzfSZMy6pmlw=="], @@ -1615,66 +1120,6 @@ "@oslojs/jwt": ["@oslojs/jwt@0.2.0", "", { "dependencies": { "@oslojs/encoding": "0.4.1" } }, "sha512-bLE7BtHrURedCn4Mco3ma9L4Y1GR2SMBuIvjWr7rmQ4/W/4Jy70TIAgZ+0nIlk0xHz1vNP8x8DCns45Sb2XRbg=="], - "@oxc-minify/binding-android-arm64": ["@oxc-minify/binding-android-arm64@0.96.0", "", { "os": "android", "cpu": "arm64" }, "sha512-lzeIEMu/v6Y+La5JSesq4hvyKtKBq84cgQpKYTYM/yGuNk2tfd5Ha31hnC+mTh48lp/5vZH+WBfjVUjjINCfug=="], - - "@oxc-minify/binding-darwin-arm64": ["@oxc-minify/binding-darwin-arm64@0.96.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-i0LkJAUXb4BeBFrJQbMKQPoxf8+cFEffDyLSb7NEzzKuPcH8qrVsnEItoOzeAdYam8Sr6qCHVwmBNEQzl7PWpw=="], - - "@oxc-minify/binding-darwin-x64": ["@oxc-minify/binding-darwin-x64@0.96.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-C5vI0WPR+KPIFAD5LMOJk2J8iiT+Nv65vDXmemzXEXouzfEOLYNqnW+u6NSsccpuZHHWAiLyPFkYvKFduveAUQ=="], - - "@oxc-minify/binding-freebsd-x64": ["@oxc-minify/binding-freebsd-x64@0.96.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-3//5DNx+xUjVBMLLk2sl6hfe4fwfENJtjVQUBXjxzwPuv8xgZUqASG4cRG3WqG5Qe8dV6SbCI4EgKQFjO4KCZA=="], - - "@oxc-minify/binding-linux-arm-gnueabihf": ["@oxc-minify/binding-linux-arm-gnueabihf@0.96.0", "", { "os": "linux", "cpu": "arm" }, "sha512-WXChFKV7VdDk1NePDK1J31cpSvxACAVztJ7f7lJVYBTkH+iz5D0lCqPcE7a9eb7nC3xvz4yk7DM6dA9wlUQkQg=="], - - "@oxc-minify/binding-linux-arm-musleabihf": ["@oxc-minify/binding-linux-arm-musleabihf@0.96.0", "", { "os": "linux", "cpu": "arm" }, "sha512-7B18glYMX4Z/YoqgE3VRLs/2YhVLxlxNKSgrtsRpuR8xv58xca+hEhiFwZN1Rn+NSMZ29Z33LWD7iYWnqYFvRA=="], - - "@oxc-minify/binding-linux-arm64-gnu": ["@oxc-minify/binding-linux-arm64-gnu@0.96.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-Yl+KcTldsEJNcaYxxonwAXZ2q3gxIzn3kXYQWgKWdaGIpNhOCWqF+KE5WLsldoh5Ro5SHtomvb8GM6cXrIBMog=="], - - "@oxc-minify/binding-linux-arm64-musl": ["@oxc-minify/binding-linux-arm64-musl@0.96.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-rNqoFWOWaxwMmUY5fspd/h5HfvgUlA3sv9CUdA2MpnHFiyoJNovR7WU8tGh+Yn0qOAs0SNH0a05gIthHig14IA=="], - - "@oxc-minify/binding-linux-riscv64-gnu": ["@oxc-minify/binding-linux-riscv64-gnu@0.96.0", "", { "os": "linux", "cpu": "none" }, "sha512-3paajIuzGnukHwSI3YBjYVqbd72pZd8NJxaayaNFR0AByIm8rmIT5RqFXbq8j2uhtpmNdZRXiu0em1zOmIScWA=="], - - "@oxc-minify/binding-linux-s390x-gnu": ["@oxc-minify/binding-linux-s390x-gnu@0.96.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-9ESrpkB2XG0lQ89JlsxlZa86iQCOs+jkDZLl6O+u5wb7ynUy21bpJJ1joauCOSYIOUlSy3+LbtJLiqi7oSQt5Q=="], - - "@oxc-minify/binding-linux-x64-gnu": ["@oxc-minify/binding-linux-x64-gnu@0.96.0", "", { "os": "linux", "cpu": "x64" }, "sha512-UMM1jkns+p+WwwmdjC5giI3SfR2BCTga18x3C0cAu6vDVf4W37uTZeTtSIGmwatTBbgiq++Te24/DE0oCdm1iQ=="], - - "@oxc-minify/binding-linux-x64-musl": ["@oxc-minify/binding-linux-x64-musl@0.96.0", "", { "os": "linux", "cpu": "x64" }, "sha512-8b1naiC7MdP7xeMi7cQ5tb9W1rZAP9Qz/jBRqp1Y5EOZ1yhSGnf1QWuZ/0pCc+XiB9vEHXEY3Aki/H+86m2eOg=="], - - "@oxc-minify/binding-wasm32-wasi": ["@oxc-minify/binding-wasm32-wasi@0.96.0", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.0.7" }, "cpu": "none" }, "sha512-bjGDjkGzo3GWU9Vg2qiFUrfoo5QxojPNV/2RHTlbIB5FWkkV4ExVjsfyqihFiAuj0NXIZqd2SAiEq9htVd3RFw=="], - - "@oxc-minify/binding-win32-arm64-msvc": ["@oxc-minify/binding-win32-arm64-msvc@0.96.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-4L4DlHUT47qMWQuTyUghpncR3NZHWtxvd0G1KgSjVgXf+cXzFdWQCWZZtCU0yrmOoVCNUf4S04IFCJyAe+Ie7A=="], - - "@oxc-minify/binding-win32-x64-msvc": ["@oxc-minify/binding-win32-x64-msvc@0.96.0", "", { "os": "win32", "cpu": "x64" }, "sha512-T2ijfqZLpV2bgGGocXV4SXTuMoouqN0asYTIm+7jVOLvT5XgDogf3ZvCmiEnSWmxl21+r5wHcs8voU2iUROXAg=="], - - "@oxc-transform/binding-android-arm64": ["@oxc-transform/binding-android-arm64@0.96.0", "", { "os": "android", "cpu": "arm64" }, "sha512-wOm+ZsqFvyZ7B9RefUMsj0zcXw77Z2pXA51nbSQyPXqr+g0/pDGxriZWP8Sdpz/e4AEaKPA9DvrwyOZxu7GRDQ=="], - - "@oxc-transform/binding-darwin-arm64": ["@oxc-transform/binding-darwin-arm64@0.96.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-td1sbcvzsyuoNRiNdIRodPXRtFFwxzPpC/6/yIUtRRhKn30XQcizxupIvQQVpJWWchxkphbBDh6UN+u+2CJ8Zw=="], - - "@oxc-transform/binding-darwin-x64": ["@oxc-transform/binding-darwin-x64@0.96.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-xgqxnqhPYH2NYkgbqtnCJfhbXvxIf/pnhF/ig5UBK8PYpCEWIP/cfLpQRQ9DcQnRfuxi7RMIF6LdmB1AiS6Fkg=="], - - "@oxc-transform/binding-freebsd-x64": ["@oxc-transform/binding-freebsd-x64@0.96.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-1i67OXdl/rvSkcTXqDlh6qGRXYseEmf0rl/R+/i88scZ/o3A+FzlX56sThuaPzSSv9eVgesnoYUjIBJELFc1oA=="], - - "@oxc-transform/binding-linux-arm-gnueabihf": ["@oxc-transform/binding-linux-arm-gnueabihf@0.96.0", "", { "os": "linux", "cpu": "arm" }, "sha512-9MJBs0SWODsqyzO3eAnacXgJ/sZu1xqinjEwBzkcZ3tQI8nKhMADOzu2NzbVWDWujeoC8DESXaO08tujvUru+Q=="], - - "@oxc-transform/binding-linux-arm-musleabihf": ["@oxc-transform/binding-linux-arm-musleabihf@0.96.0", "", { "os": "linux", "cpu": "arm" }, "sha512-BQom57I2ScccixljNYh2Wy+5oVZtF1LXiiUPxSLtDHbsanpEvV/+kzCagQpTjk1BVzSQzOxfEUWjvL7mY53pRQ=="], - - "@oxc-transform/binding-linux-arm64-gnu": ["@oxc-transform/binding-linux-arm64-gnu@0.96.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-kaqvUzNu8LL4aBSXqcqGVLFG13GmJEplRI2+yqzkgAItxoP/LfFMdEIErlTWLGyBwd0OLiNMHrOvkcCQRWadVg=="], - - "@oxc-transform/binding-linux-arm64-musl": ["@oxc-transform/binding-linux-arm64-musl@0.96.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-EiG/L3wEkPgTm4p906ufptyblBgtiQWTubGg/JEw82f8uLRroayr5zhbUqx40EgH037a3SfJthIyLZi7XPRFJw=="], - - "@oxc-transform/binding-linux-riscv64-gnu": ["@oxc-transform/binding-linux-riscv64-gnu@0.96.0", "", { "os": "linux", "cpu": "none" }, "sha512-r01CY6OxKGtVeYnvH4mGmtkQMlLkXdPWWNXwo5o7fE2s/fgZPMpqh8bAuXEhuMXipZRJrjxTk1+ZQ4KCHpMn3Q=="], - - "@oxc-transform/binding-linux-s390x-gnu": ["@oxc-transform/binding-linux-s390x-gnu@0.96.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-4djg2vYLGbVeS8YiA2K4RPPpZE4fxTGCX5g/bOMbCYyirDbmBAIop4eOAj8vOA9i1CcWbDtmp+PVJ1dSw7f3IQ=="], - - "@oxc-transform/binding-linux-x64-gnu": ["@oxc-transform/binding-linux-x64-gnu@0.96.0", "", { "os": "linux", "cpu": "x64" }, "sha512-f6pcWVz57Y8jXa2OS7cz3aRNuks34Q3j61+3nQ4xTE8H1KbalcEvHNmM92OEddaJ8QLs9YcE0kUC6eDTbY34+A=="], - - "@oxc-transform/binding-linux-x64-musl": ["@oxc-transform/binding-linux-x64-musl@0.96.0", "", { "os": "linux", "cpu": "x64" }, "sha512-NSiRtFvR7Pbhv3mWyPMkTK38czIjcnK0+K5STo3CuzZRVbX1TM17zGdHzKBUHZu7v6IQ6/XsQ3ELa1BlEHPGWQ=="], - - "@oxc-transform/binding-wasm32-wasi": ["@oxc-transform/binding-wasm32-wasi@0.96.0", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.0.7" }, "cpu": "none" }, "sha512-A91ARLiuZHGN4hBds9s7bW3czUuLuHLsV+cz44iF9j8e1zX9m2hNGXf/acQRbg/zcFUXmjz5nmk8EkZyob876w=="], - - "@oxc-transform/binding-win32-arm64-msvc": ["@oxc-transform/binding-win32-arm64-msvc@0.96.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-IedJf40djKgDObomhYjdRAlmSYUEdfqX3A3M9KfUltl9AghTBBLkTzUMA7O09oo71vYf5TEhbFM7+Vn5vqw7AQ=="], - - "@oxc-transform/binding-win32-x64-msvc": ["@oxc-transform/binding-win32-x64-msvc@0.96.0", "", { "os": "win32", "cpu": "x64" }, "sha512-0fI0P0W7bSO/GCP/N5dkmtB9vBqCA4ggo1WmXTnxNJVmFFOtcA1vYm1I9jl8fxo+sucW2WnlpnI4fjKdo3JKxA=="], - "@oxlint-tsgolint/darwin-arm64": ["@oxlint-tsgolint/darwin-arm64@0.21.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-P20j3MLqfwIT+94qGU3htC7dWp4pXGZW1p1p7FRUzu1aopq7c9nPCgf0W/WjktqQ57+iuTq9mbSlwWinl6+H1A=="], "@oxlint-tsgolint/darwin-x64": ["@oxlint-tsgolint/darwin-x64@0.21.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-81TmmuBcPedEA0MwRmObuQuXnCprS1UiHQWGe7pseqNAJzUWXeAPrayqKTACX92VpruJI+yvY0XJrFp11PpcTA=="], @@ -1725,22 +1170,6 @@ "@oxlint/binding-win32-x64-msvc": ["@oxlint/binding-win32-x64-msvc@1.60.0", "", { "os": "win32", "cpu": "x64" }, "sha512-JOro4ZcfBLamJCyfURQmOQByoorgOdx3ZjAkSqnb/CyG/i+lN3KoV5LAgk5ZAW6DPq7/Cx7n23f8DuTWXTWgyQ=="], - "@pagefind/darwin-arm64": ["@pagefind/darwin-arm64@1.5.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-MXpI+7HsAdPkvJ0gk9xj9g541BCqBZOBbdwj9g6lB5LCj6kSV6nqDSjzcAJwvOsfu0fjwvC8hQU+ecfhp+MpiQ=="], - - "@pagefind/darwin-x64": ["@pagefind/darwin-x64@1.5.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-IojxFWMEJe0RQ7PQ3KXQsPIImNsbpPYpoZ+QUDrL8fAl/O27IX+LVLs74/UzEZy5uA2LD8Nz1AiwKr72vrkZQw=="], - - "@pagefind/default-ui": ["@pagefind/default-ui@1.5.2", "", {}, "sha512-pm1LMnQg8N2B3n2TnjKlhaFihpz6zTiA4HiGQ6/slKO/+8K9CAU5kcjdSSPgpuk1PMuuN4hxLipUIifnrkl3Sg=="], - - "@pagefind/freebsd-x64": ["@pagefind/freebsd-x64@1.5.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-7EVzo9+0w+2cbe671BtMj10UlNo83I+HrLVLfRxO731svHRJKUfJ/mo05gU14pe9PCfpKNQT8FS3Xc/oDN6pOA=="], - - "@pagefind/linux-arm64": ["@pagefind/linux-arm64@1.5.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-Ovt9+K35sqzn8H3ZMXGwls4TD/wMJuvRtShHIsmUQREmaxjrDEX7gHckRCrwYJ4XE1H1p6HkLz3wukrAnsfXQw=="], - - "@pagefind/linux-x64": ["@pagefind/linux-x64@1.5.2", "", { "os": "linux", "cpu": "x64" }, "sha512-V+tFqHKXhQKq/WqPBD67AFy7scn1/aZID00ws4fSDd+1daSi5UHR9VVlRrOUYKxn3VuFQYRD7lYXdZK1WED1YA=="], - - "@pagefind/windows-arm64": ["@pagefind/windows-arm64@1.5.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-hN9Nh90fNW61nNRCW9ZyQrAj/mD0eRvmJ8NlTUzkbuW8kIzGJUi3cxjFkEcMZ5h/8FsKWD/VcouZl4yo1F7B6g=="], - - "@pagefind/windows-x64": ["@pagefind/windows-x64@1.5.2", "", { "os": "win32", "cpu": "x64" }, "sha512-Fa2Iyw7kaDRzGMfNYNUXNW2zbL5FQVDgSOcbDHdzBrDEdpqOqg8TcZ68F22ol6NJ9IGzvUdmeyZypLW5dyhqsg=="], - "@parcel/watcher": ["@parcel/watcher@2.5.1", "", { "dependencies": { "detect-libc": "^1.0.3", "is-glob": "^4.0.3", "micromatch": "^4.0.5", "node-addon-api": "^7.0.0" }, "optionalDependencies": { "@parcel/watcher-android-arm64": "2.5.1", "@parcel/watcher-darwin-arm64": "2.5.1", "@parcel/watcher-darwin-x64": "2.5.1", "@parcel/watcher-freebsd-x64": "2.5.1", "@parcel/watcher-linux-arm-glibc": "2.5.1", "@parcel/watcher-linux-arm-musl": "2.5.1", "@parcel/watcher-linux-arm64-glibc": "2.5.1", "@parcel/watcher-linux-arm64-musl": "2.5.1", "@parcel/watcher-linux-x64-glibc": "2.5.1", "@parcel/watcher-linux-x64-musl": "2.5.1", "@parcel/watcher-win32-arm64": "2.5.1", "@parcel/watcher-win32-ia32": "2.5.1", "@parcel/watcher-win32-x64": "2.5.1" } }, "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg=="], "@parcel/watcher-android-arm64": ["@parcel/watcher-android-arm64@2.5.1", "", { "os": "android", "cpu": "arm64" }, "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA=="], @@ -1777,16 +1206,6 @@ "@pkgjs/parseargs": ["@pkgjs/parseargs@0.11.0", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="], - "@planetscale/database": ["@planetscale/database@1.19.0", "", {}, "sha512-Tv4jcFUFAFjOWrGSio49H6R2ijALv0ZzVBfJKIdm+kl9X046Fh4LLawrF9OMsglVbK6ukqMJsUCeucGAFTBcMA=="], - - "@playwright/test": ["@playwright/test@1.59.1", "", { "dependencies": { "playwright": "1.59.1" }, "bin": { "playwright": "cli.js" } }, "sha512-PG6q63nQg5c9rIi4/Z5lR5IVF7yU5MqmKaPOe0HSc0O2cX1fPi96sUQu5j7eo4gKCkB2AnNGoWt7y4/Xx3Kcqg=="], - - "@poppinss/colors": ["@poppinss/colors@4.1.6", "", { "dependencies": { "kleur": "^4.1.5" } }, "sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg=="], - - "@poppinss/dumper": ["@poppinss/dumper@0.6.5", "", { "dependencies": { "@poppinss/colors": "^4.1.5", "@sindresorhus/is": "^7.0.2", "supports-color": "^10.0.0" } }, "sha512-NBdYIb90J7LfOI32dOewKI1r7wnkiH6m920puQ3qHUeZkxNkQiFnXVWoE6YtFSv6QOiPPf7ys6i+HWWecDz7sw=="], - - "@poppinss/exception": ["@poppinss/exception@1.2.3", "", {}, "sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw=="], - "@protobuf-ts/plugin": ["@protobuf-ts/plugin@2.11.1", "", { "dependencies": { "@bufbuild/protobuf": "^2.4.0", "@bufbuild/protoplugin": "^2.4.0", "@protobuf-ts/protoc": "^2.11.1", "@protobuf-ts/runtime": "^2.11.1", "@protobuf-ts/runtime-rpc": "^2.11.1", "typescript": "^3.9" }, "bin": { "protoc-gen-ts": "bin/protoc-gen-ts", "protoc-gen-dump": "bin/protoc-gen-dump" } }, "sha512-HyuprDcw0bEEJqkOWe1rnXUP0gwYLij8YhPuZyZk6cJbIgc/Q0IFgoHQxOXNIXAcXM4Sbehh6kjVnCzasElw1A=="], "@protobuf-ts/protoc": ["@protobuf-ts/protoc@2.11.1", "", { "bin": { "protoc": "protoc.js" } }, "sha512-mUZJaV0daGO6HUX90o/atzQ6A7bbN2RSuHtdwo8SSF2Qoe3zHwa4IHyCN1evftTeHfLmdz+45qo47sL+5P8nyg=="], @@ -1795,94 +1214,6 @@ "@protobuf-ts/runtime-rpc": ["@protobuf-ts/runtime-rpc@2.11.1", "", { "dependencies": { "@protobuf-ts/runtime": "^2.11.1" } }, "sha512-4CqqUmNA+/uMz00+d3CYKgElXO9VrEbucjnBFEjqI4GuDrEQ32MaI3q+9qPBvIGOlL4PmHXrzM32vBPWRhQKWQ=="], - "@protobufjs/aspromise": ["@protobufjs/aspromise@1.1.2", "", {}, "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="], - - "@protobufjs/base64": ["@protobufjs/base64@1.1.2", "", {}, "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="], - - "@protobufjs/codegen": ["@protobufjs/codegen@2.0.4", "", {}, "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="], - - "@protobufjs/eventemitter": ["@protobufjs/eventemitter@1.1.0", "", {}, "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q=="], - - "@protobufjs/fetch": ["@protobufjs/fetch@1.1.0", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.1", "@protobufjs/inquire": "^1.1.0" } }, "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ=="], - - "@protobufjs/float": ["@protobufjs/float@1.0.2", "", {}, "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ=="], - - "@protobufjs/inquire": ["@protobufjs/inquire@1.1.0", "", {}, "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q=="], - - "@protobufjs/path": ["@protobufjs/path@1.1.2", "", {}, "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA=="], - - "@protobufjs/pool": ["@protobufjs/pool@1.1.0", "", {}, "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw=="], - - "@protobufjs/utf8": ["@protobufjs/utf8@1.1.0", "", {}, "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="], - - "@radix-ui/colors": ["@radix-ui/colors@1.0.1", "", {}, "sha512-xySw8f0ZVsAEP+e7iLl3EvcBXX7gsIlC1Zso/sPBW9gIWerBTgz6axrjU+MZ39wD+WFi5h5zdWpsg3+hwt2Qsg=="], - - "@radix-ui/primitive": ["@radix-ui/primitive@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" } }, "sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw=="], - - "@radix-ui/react-arrow": ["@radix-ui/react-arrow@1.0.3", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-primitive": "1.0.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA=="], - - "@radix-ui/react-collapsible": ["@radix-ui/react-collapsible@1.0.3", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/primitive": "1.0.1", "@radix-ui/react-compose-refs": "1.0.1", "@radix-ui/react-context": "1.0.1", "@radix-ui/react-id": "1.0.1", "@radix-ui/react-presence": "1.0.1", "@radix-ui/react-primitive": "1.0.3", "@radix-ui/react-use-controllable-state": "1.0.1", "@radix-ui/react-use-layout-effect": "1.0.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-UBmVDkmR6IvDsloHVN+3rtx4Mi5TFvylYXpluuv0f37dtaz3H99bp8No0LGXRigVpl3UAT4l9j6bIchh42S/Gg=="], - - "@radix-ui/react-collection": ["@radix-ui/react-collection@1.0.3", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-compose-refs": "1.0.1", "@radix-ui/react-context": "1.0.1", "@radix-ui/react-primitive": "1.0.3", "@radix-ui/react-slot": "1.0.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA=="], - - "@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" }, "optionalPeers": ["@types/react"] }, "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw=="], - - "@radix-ui/react-context": ["@radix-ui/react-context@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" }, "optionalPeers": ["@types/react"] }, "sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg=="], - - "@radix-ui/react-direction": ["@radix-ui/react-direction@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" }, "optionalPeers": ["@types/react"] }, "sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA=="], - - "@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.0.4", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/primitive": "1.0.1", "@radix-ui/react-compose-refs": "1.0.1", "@radix-ui/react-primitive": "1.0.3", "@radix-ui/react-use-callback-ref": "1.0.1", "@radix-ui/react-use-escape-keydown": "1.0.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-7UpBa/RKMoHJYjie1gkF1DlK8l1fdU/VKDpoS3rCCo8YBJR294GwcEHyxHw72yvphJ7ld0AXEcSLAzY2F/WyCg=="], - - "@radix-ui/react-focus-guards": ["@radix-ui/react-focus-guards@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" }, "optionalPeers": ["@types/react"] }, "sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA=="], - - "@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.0.3", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-compose-refs": "1.0.1", "@radix-ui/react-primitive": "1.0.3", "@radix-ui/react-use-callback-ref": "1.0.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-upXdPfqI4islj2CslyfUBNlaJCPybbqRHAi1KER7Isel9Q2AtSJ0zRBZv8mWQiFXD2nyAJ4BhC3yXgZ6kMBSrQ=="], - - "@radix-ui/react-id": ["@radix-ui/react-id@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-use-layout-effect": "1.0.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" }, "optionalPeers": ["@types/react"] }, "sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ=="], - - "@radix-ui/react-popover": ["@radix-ui/react-popover@1.0.6", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/primitive": "1.0.1", "@radix-ui/react-compose-refs": "1.0.1", "@radix-ui/react-context": "1.0.1", "@radix-ui/react-dismissable-layer": "1.0.4", "@radix-ui/react-focus-guards": "1.0.1", "@radix-ui/react-focus-scope": "1.0.3", "@radix-ui/react-id": "1.0.1", "@radix-ui/react-popper": "1.1.2", "@radix-ui/react-portal": "1.0.3", "@radix-ui/react-presence": "1.0.1", "@radix-ui/react-primitive": "1.0.3", "@radix-ui/react-slot": "1.0.2", "@radix-ui/react-use-controllable-state": "1.0.1", "aria-hidden": "^1.1.1", "react-remove-scroll": "2.5.5" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-cZ4defGpkZ0qTRtlIBzJLSzL6ht7ofhhW4i1+pkemjV1IKXm0wgCRnee154qlV6r9Ttunmh2TNZhMfV2bavUyA=="], - - "@radix-ui/react-popper": ["@radix-ui/react-popper@1.1.2", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@floating-ui/react-dom": "^2.0.0", "@radix-ui/react-arrow": "1.0.3", "@radix-ui/react-compose-refs": "1.0.1", "@radix-ui/react-context": "1.0.1", "@radix-ui/react-primitive": "1.0.3", "@radix-ui/react-use-callback-ref": "1.0.1", "@radix-ui/react-use-layout-effect": "1.0.1", "@radix-ui/react-use-rect": "1.0.1", "@radix-ui/react-use-size": "1.0.1", "@radix-ui/rect": "1.0.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-1CnGGfFi/bbqtJZZ0P/NQY20xdG3E0LALJaLUEoKwPLwl6PPPfbeiCqMVQnhoFRAxjJj4RpBRJzDmUgsex2tSg=="], - - "@radix-ui/react-portal": ["@radix-ui/react-portal@1.0.3", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-primitive": "1.0.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-xLYZeHrWoPmA5mEKEfZZevoVRK/Q43GfzRXkWV6qawIWWK8t6ifIiLQdd7rmQ4Vk1bmI21XhqF9BN3jWf+phpA=="], - - "@radix-ui/react-presence": ["@radix-ui/react-presence@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-compose-refs": "1.0.1", "@radix-ui/react-use-layout-effect": "1.0.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg=="], - - "@radix-ui/react-primitive": ["@radix-ui/react-primitive@1.0.3", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-slot": "1.0.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g=="], - - "@radix-ui/react-roving-focus": ["@radix-ui/react-roving-focus@1.0.4", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/primitive": "1.0.1", "@radix-ui/react-collection": "1.0.3", "@radix-ui/react-compose-refs": "1.0.1", "@radix-ui/react-context": "1.0.1", "@radix-ui/react-direction": "1.0.1", "@radix-ui/react-id": "1.0.1", "@radix-ui/react-primitive": "1.0.3", "@radix-ui/react-use-callback-ref": "1.0.1", "@radix-ui/react-use-controllable-state": "1.0.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-2mUg5Mgcu001VkGy+FfzZyzbmuUWzgWkj3rvv4yu+mLw03+mTzbxZHvfcGyFp2b8EkQeMkpRQ5FiA2Vr2O6TeQ=="], - - "@radix-ui/react-slot": ["@radix-ui/react-slot@1.0.2", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-compose-refs": "1.0.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" }, "optionalPeers": ["@types/react"] }, "sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg=="], - - "@radix-ui/react-toggle": ["@radix-ui/react-toggle@1.0.3", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/primitive": "1.0.1", "@radix-ui/react-primitive": "1.0.3", "@radix-ui/react-use-controllable-state": "1.0.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Pkqg3+Bc98ftZGsl60CLANXQBBQ4W3mTFS9EJvNxKMZ7magklKV69/id1mlAlOFDDfHvlCms0fx8fA4CMKDJHg=="], - - "@radix-ui/react-toggle-group": ["@radix-ui/react-toggle-group@1.0.4", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/primitive": "1.0.1", "@radix-ui/react-context": "1.0.1", "@radix-ui/react-direction": "1.0.1", "@radix-ui/react-primitive": "1.0.3", "@radix-ui/react-roving-focus": "1.0.4", "@radix-ui/react-toggle": "1.0.3", "@radix-ui/react-use-controllable-state": "1.0.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Uaj/M/cMyiyT9Bx6fOZO0SAG4Cls0GptBWiBmBxofmDbNVnYYoyRWj/2M/6VCi/7qcXFWnHhRUfdfZFvvkuu8A=="], - - "@radix-ui/react-tooltip": ["@radix-ui/react-tooltip@1.0.6", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/primitive": "1.0.1", "@radix-ui/react-compose-refs": "1.0.1", "@radix-ui/react-context": "1.0.1", "@radix-ui/react-dismissable-layer": "1.0.4", "@radix-ui/react-id": "1.0.1", "@radix-ui/react-popper": "1.1.2", "@radix-ui/react-portal": "1.0.3", "@radix-ui/react-presence": "1.0.1", "@radix-ui/react-primitive": "1.0.3", "@radix-ui/react-slot": "1.0.2", "@radix-ui/react-use-controllable-state": "1.0.1", "@radix-ui/react-visually-hidden": "1.0.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-DmNFOiwEc2UDigsYj6clJENma58OelxD24O4IODoZ+3sQc3Zb+L8w1EP+y9laTuKCLAysPw4fD6/v0j4KNV8rg=="], - - "@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" }, "optionalPeers": ["@types/react"] }, "sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ=="], - - "@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-use-callback-ref": "1.0.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" }, "optionalPeers": ["@types/react"] }, "sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA=="], - - "@radix-ui/react-use-escape-keydown": ["@radix-ui/react-use-escape-keydown@1.0.3", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-use-callback-ref": "1.0.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" }, "optionalPeers": ["@types/react"] }, "sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg=="], - - "@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" }, "optionalPeers": ["@types/react"] }, "sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ=="], - - "@radix-ui/react-use-rect": ["@radix-ui/react-use-rect@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/rect": "1.0.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" }, "optionalPeers": ["@types/react"] }, "sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw=="], - - "@radix-ui/react-use-size": ["@radix-ui/react-use-size@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-use-layout-effect": "1.0.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" }, "optionalPeers": ["@types/react"] }, "sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g=="], - - "@radix-ui/react-visually-hidden": ["@radix-ui/react-visually-hidden@1.0.3", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-primitive": "1.0.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA=="], - - "@radix-ui/rect": ["@radix-ui/rect@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" } }, "sha512-fyrgCaedtvMg9NK3en0pnOYJdtfwxUcNolezkNPUsoX57X8oQk+NkqcvzHXD2uKNij6GXmWU9NDru2IWjrO4BQ=="], - - "@remix-run/node-fetch-server": ["@remix-run/node-fetch-server@0.8.1", "", {}, "sha512-J1dev372wtJqmqn9U/qbpbZxbJSQrogNN2+Qv1lKlpATpe/WQ9aCZfl/xSb9d2Rgh1IyLSvNxZAXPZxruO6Xig=="], - - "@remix-run/router": ["@remix-run/router@1.9.0", "", {}, "sha512-bV63itrKBC0zdT27qYm6SDZHlkXwFL1xMBuhkn+X7l0+IIhNaH5wuuvZKp6eKhCD4KFhujhfhCT1YxXW6esUIA=="], - - "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.27", "", {}, "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA=="], - - "@rollup/pluginutils": ["@rollup/pluginutils@5.3.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q=="], - "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.60.1", "", { "os": "android", "cpu": "arm" }, "sha512-d6FinEBLdIiK+1uACUttJKfgZREXrF0Qc2SmLII7W2AD8FfiZ9Wjd+rD/iRuf5s5dWrr1GgwXCvPqOuDquOowA=="], "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.60.1", "", { "os": "android", "cpu": "arm64" }, "sha512-YjG/EwIDvvYI1YvYbHvDz/BYHtkY4ygUIXHnTdLhG+hKIQFBiosfWiACWortsKPKU/+dUwQQCKQM3qrDe8c9BA=="], @@ -1933,46 +1264,6 @@ "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.60.1", "", { "os": "win32", "cpu": "x64" }, "sha512-lWMnixq/QzxyhTV6NjQJ4SFo1J6PvOX8vUx5Wb4bBPsEb+8xZ89Bz6kOXpfXj9ak9AHTQVQzlgzBEc1SyM27xQ=="], - "@selderee/plugin-htmlparser2": ["@selderee/plugin-htmlparser2@0.11.0", "", { "dependencies": { "domhandler": "^5.0.3", "selderee": "^0.11.0" } }, "sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ=="], - - "@sentry-internal/browser-utils": ["@sentry-internal/browser-utils@10.36.0", "", { "dependencies": { "@sentry/core": "10.36.0" } }, "sha512-WILVR8HQBWOxbqLRuTxjzRCMIACGsDTo6jXvzA8rz6ezElElLmIrn3CFAswrESLqEEUa4CQHl5bLgSVJCRNweA=="], - - "@sentry-internal/feedback": ["@sentry-internal/feedback@10.36.0", "", { "dependencies": { "@sentry/core": "10.36.0" } }, "sha512-zPjz7AbcxEyx8AHj8xvp28fYtPTPWU1XcNtymhAHJLS9CXOblqSC7W02Jxz6eo3eR1/pLyOo6kJBUjvLe9EoFA=="], - - "@sentry-internal/replay": ["@sentry-internal/replay@10.36.0", "", { "dependencies": { "@sentry-internal/browser-utils": "10.36.0", "@sentry/core": "10.36.0" } }, "sha512-nLMkJgvHq+uCCrQKV2KgSdVHxTsmDk0r2hsAoTcKCbzUpXyW5UhCziMRS6ULjBlzt5sbxoIIplE25ZpmIEeNgg=="], - - "@sentry-internal/replay-canvas": ["@sentry-internal/replay-canvas@10.36.0", "", { "dependencies": { "@sentry-internal/replay": "10.36.0", "@sentry/core": "10.36.0" } }, "sha512-DLGIwmT2LX+O6TyYPtOQL5GiTm2rN0taJPDJ/Lzg2KEJZrdd5sKkzTckhh2x+vr4JQyeaLmnb8M40Ch1hvG/vQ=="], - - "@sentry/babel-plugin-component-annotate": ["@sentry/babel-plugin-component-annotate@4.6.0", "", {}, "sha512-3soTX50JPQQ51FSbb4qvNBf4z/yP7jTdn43vMTp9E4IxvJ9HKJR7OEuKkCMszrZmWsVABXl02msqO7QisePdiQ=="], - - "@sentry/browser": ["@sentry/browser@10.36.0", "", { "dependencies": { "@sentry-internal/browser-utils": "10.36.0", "@sentry-internal/feedback": "10.36.0", "@sentry-internal/replay": "10.36.0", "@sentry-internal/replay-canvas": "10.36.0", "@sentry/core": "10.36.0" } }, "sha512-yHhXbgdGY1s+m8CdILC9U/II7gb6+s99S2Eh8VneEn/JG9wHc+UOzrQCeFN0phFP51QbLkjkiQbbanjT1HP8UQ=="], - - "@sentry/bundler-plugin-core": ["@sentry/bundler-plugin-core@4.6.0", "", { "dependencies": { "@babel/core": "^7.18.5", "@sentry/babel-plugin-component-annotate": "4.6.0", "@sentry/cli": "^2.57.0", "dotenv": "^16.3.1", "find-up": "^5.0.0", "glob": "^9.3.2", "magic-string": "0.30.8", "unplugin": "1.0.1" } }, "sha512-Fub2XQqrS258jjS8qAxLLU1k1h5UCNJ76i8m4qZJJdogWWaF8t00KnnTyp9TEDJzrVD64tRXS8+HHENxmeUo3g=="], - - "@sentry/cli": ["@sentry/cli@2.58.5", "", { "dependencies": { "https-proxy-agent": "^5.0.0", "node-fetch": "^2.6.7", "progress": "^2.0.3", "proxy-from-env": "^1.1.0", "which": "^2.0.2" }, "optionalDependencies": { "@sentry/cli-darwin": "2.58.5", "@sentry/cli-linux-arm": "2.58.5", "@sentry/cli-linux-arm64": "2.58.5", "@sentry/cli-linux-i686": "2.58.5", "@sentry/cli-linux-x64": "2.58.5", "@sentry/cli-win32-arm64": "2.58.5", "@sentry/cli-win32-i686": "2.58.5", "@sentry/cli-win32-x64": "2.58.5" }, "bin": { "sentry-cli": "bin/sentry-cli" } }, "sha512-tavJ7yGUZV+z3Ct2/ZB6mg339i08sAk6HDkgqmSRuQEu2iLS5sl9HIvuXfM6xjv8fwlgFOSy++WNABNAcGHUbg=="], - - "@sentry/cli-darwin": ["@sentry/cli-darwin@2.58.5", "", { "os": "darwin" }, "sha512-lYrNzenZFJftfwSya7gwrHGxtE+Kob/e1sr9lmHMFOd4utDlmq0XFDllmdZAMf21fxcPRI1GL28ejZ3bId01fQ=="], - - "@sentry/cli-linux-arm": ["@sentry/cli-linux-arm@2.58.5", "", { "os": [ "linux", "android", "freebsd", ], "cpu": "arm" }, "sha512-KtHweSIomYL4WVDrBrYSYJricKAAzxUgX86kc6OnlikbyOhoK6Fy8Vs6vwd52P6dvWPjgrMpUYjW2M5pYXQDUw=="], - - "@sentry/cli-linux-arm64": ["@sentry/cli-linux-arm64@2.58.5", "", { "os": [ "linux", "android", "freebsd", ], "cpu": "arm64" }, "sha512-/4gywFeBqRB6tR/iGMRAJ3HRqY6Z7Yp4l8ZCbl0TDLAfHNxu7schEw4tSnm2/Hh9eNMiOVy4z58uzAWlZXAYBQ=="], - - "@sentry/cli-linux-i686": ["@sentry/cli-linux-i686@2.58.5", "", { "os": [ "linux", "android", "freebsd", ], "cpu": "ia32" }, "sha512-G7261dkmyxqlMdyvyP06b+RTIVzp1gZNgglj5UksxSouSUqRd/46W/2pQeOMPhloDYo9yLtCN2YFb3Mw4aUsWw=="], - - "@sentry/cli-linux-x64": ["@sentry/cli-linux-x64@2.58.5", "", { "os": [ "linux", "android", "freebsd", ], "cpu": "x64" }, "sha512-rP04494RSmt86xChkQ+ecBNRYSPbyXc4u0IA7R7N1pSLCyO74e5w5Al+LnAq35cMfVbZgz5Sm0iGLjyiUu4I1g=="], - - "@sentry/cli-win32-arm64": ["@sentry/cli-win32-arm64@2.58.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-AOJ2nCXlQL1KBaCzv38m3i2VmSHNurUpm7xVKd6yAHX+ZoVBI8VT0EgvwmtJR2TY2N2hNCC7UrgRmdUsQ152bA=="], - - "@sentry/cli-win32-i686": ["@sentry/cli-win32-i686@2.58.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-EsuboLSOnlrN7MMPJ1eFvfMDm+BnzOaSWl8eYhNo8W/BIrmNgpRUdBwnWn9Q2UOjJj5ZopukmsiMYtU/D7ml9g=="], - - "@sentry/cli-win32-x64": ["@sentry/cli-win32-x64@2.58.5", "", { "os": "win32", "cpu": "x64" }, "sha512-IZf+XIMiQwj+5NzqbOQfywlOitmCV424Vtf9c+ep61AaVScUFD1TSrQbOcJJv5xGxhlxNOMNgMeZhdexdzrKZg=="], - - "@sentry/core": ["@sentry/core@10.36.0", "", {}, "sha512-EYJjZvofI+D93eUsPLDIUV0zQocYqiBRyXS6CCV6dHz64P/Hob5NJQOwPa8/v6nD+UvJXvwsFfvXOHhYZhZJOQ=="], - - "@sentry/solid": ["@sentry/solid@10.36.0", "", { "dependencies": { "@sentry/browser": "10.36.0", "@sentry/core": "10.36.0" }, "peerDependencies": { "@solidjs/router": "^0.13.4 || ^0.14.0 || ^0.15.0", "@tanstack/solid-router": "^1.132.27", "solid-js": "^1.8.4" }, "optionalPeers": ["@solidjs/router", "@tanstack/solid-router"] }, "sha512-AaDqz3JGBrQCm2YVqODVyJHwg7LRTNSJig9mjfProFyvkC7eUXQ/HBJrrhAD1Dct9ufmDH3G+f3/Ut9LgpItSg=="], - - "@sentry/vite-plugin": ["@sentry/vite-plugin@4.6.0", "", { "dependencies": { "@sentry/bundler-plugin-core": "4.6.0", "unplugin": "1.0.1" } }, "sha512-fMR2d+EHwbzBa0S1fp45SNUTProxmyFBp+DeBWWQOSP9IU6AH6ea2rqrpMAnp/skkcdW4z4LSRrOEpMZ5rWXLw=="], - "@shikijs/core": ["@shikijs/core@3.9.2", "", { "dependencies": { "@shikijs/types": "3.9.2", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-3q/mzmw09B2B6PgFNeiaN8pkNOixWS726IHmJEpjDAcneDPMQmUg2cweT9cWXY4XcyQS3i6mOOUgQz9RRUP6HA=="], "@shikijs/engine-javascript": ["@shikijs/engine-javascript@3.20.0", "", { "dependencies": { "@shikijs/types": "3.20.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.4" } }, "sha512-OFx8fHAZuk7I42Z9YAdZ95To6jDePQ9Rnfbw9uSRTSbBhYBp1kEOKv/3jOimcj3VRUKusDYM6DswLauwfhboLg=="], @@ -1991,7 +1282,7 @@ "@sigstore/bundle": ["@sigstore/bundle@4.0.0", "", { "dependencies": { "@sigstore/protobuf-specs": "^0.5.0" } }, "sha512-NwCl5Y0V6Di0NexvkTqdoVfmjTaQwoLM236r89KEojGmq/jMls8S+zb7yOwAPdXvbwfKDlP+lmXgAL4vKSQT+A=="], - "@sigstore/core": ["@sigstore/core@3.2.0", "", {}, "sha512-kxHrDQ9YgfrWUSXU0cjsQGv8JykOFZQ9ErNKbFPWzk3Hgpwu8x2hHrQ9IdA8yl+j9RTLTC3sAF3Tdq1IQCP4oA=="], + "@sigstore/core": ["@sigstore/core@3.2.1", "", {}, "sha512-qRsxPnCrbC/puegGxKuynfnxgLiHqWStrSjxkoB4YKqq3Z3s4cyZyj42ZdWFAEblNP65C+rBH8EuREHIXoi83g=="], "@sigstore/protobuf-specs": ["@sigstore/protobuf-specs@0.5.1", "", {}, "sha512-/ScWUhhoFasJsSRGTVBwId1loQjjnjAfE4djL6ZhrXRpNCmPTnUKF5Jokd58ILseOMjzET3UrMOtJPS9sYeI0g=="], @@ -1999,21 +1290,19 @@ "@sigstore/tuf": ["@sigstore/tuf@4.0.2", "", { "dependencies": { "@sigstore/protobuf-specs": "^0.5.0", "tuf-js": "^4.1.0" } }, "sha512-TCAzTy0xzdP79EnxSjq9KQ3eaR7+FmudLC6eRKknVKZbV7ZNlGLClAAQb/HMNJ5n2OBNk2GT1tEmU0xuPr+SLQ=="], - "@sigstore/verify": ["@sigstore/verify@3.1.0", "", { "dependencies": { "@sigstore/bundle": "^4.0.0", "@sigstore/core": "^3.1.0", "@sigstore/protobuf-specs": "^0.5.0" } }, "sha512-mNe0Iigql08YupSOGv197YdHpPPr+EzDZmfCgMc7RPNaZTw5aLN01nBl6CHJOh3BGtnMIj83EeN4butBchc8Ag=="], + "@sigstore/verify": ["@sigstore/verify@3.1.1", "", { "dependencies": { "@sigstore/bundle": "^4.0.0", "@sigstore/core": "^3.2.1", "@sigstore/protobuf-specs": "^0.5.0" } }, "sha512-qv7+G3J2cc6wwFj3yKvXOamzqhMwSk1ogPGmhpS8iXllcPrJaIIBA+4HbttlHVu1pqWTdmaCH/WE7UOC51kdoA=="], - "@sindresorhus/is": ["@sindresorhus/is@4.6.0", "", {}, "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw=="], - - "@slack/bolt": ["@slack/bolt@3.22.0", "", { "dependencies": { "@slack/logger": "^4.0.0", "@slack/oauth": "^2.6.3", "@slack/socket-mode": "^1.3.6", "@slack/types": "^2.13.0", "@slack/web-api": "^6.13.0", "@types/express": "^4.16.1", "@types/promise.allsettled": "^1.0.3", "@types/tsscmp": "^1.0.0", "axios": "^1.7.4", "express": "^4.21.0", "path-to-regexp": "^8.1.0", "promise.allsettled": "^1.0.2", "raw-body": "^2.3.3", "tsscmp": "^1.0.6" } }, "sha512-iKDqGPEJDnrVwxSVlFW6OKTkijd7s4qLBeSufoBsTM0reTyfdp/5izIQVkxNfzjHi3o6qjdYbRXkYad5HBsBog=="], + "@slack/bolt": ["@slack/bolt@4.7.3", "", { "dependencies": { "@slack/logger": "^4.0.1", "@slack/oauth": "^3.0.5", "@slack/socket-mode": "^2.0.7", "@slack/types": "^2.21.1", "@slack/web-api": "^7.16.0", "axios": "^1.12.0", "express": "^5.0.0", "path-to-regexp": "^8.1.0", "raw-body": "^3", "tsscmp": "^1.0.6" }, "peerDependencies": { "@types/express": "^5.0.0" } }, "sha512-bODs8q/yNDWUPoxmQhFrRqLMA5vhB/PDizYWqb6CkQhLWEUo5JFtfJcmeU4ElGl6qSt++OKjSYNa4MPc77CleQ=="], "@slack/logger": ["@slack/logger@4.0.1", "", { "dependencies": { "@types/node": ">=18" } }, "sha512-6cmdPrV/RYfd2U0mDGiMK8S7OJqpCTm7enMLRR3edccsPX8j7zXTLnaEF4fhxxJJTAIOil6+qZrnUPTuaLvwrQ=="], - "@slack/oauth": ["@slack/oauth@2.6.3", "", { "dependencies": { "@slack/logger": "^3.0.0", "@slack/web-api": "^6.12.1", "@types/jsonwebtoken": "^8.3.7", "@types/node": ">=12", "jsonwebtoken": "^9.0.0", "lodash.isstring": "^4.0.1" } }, "sha512-1amXs6xRkJpoH6zSgjVPgGEJXCibKNff9WNDijcejIuVy1HFAl1adh7lehaGNiHhTWfQkfKxBiF+BGn56kvoFw=="], + "@slack/oauth": ["@slack/oauth@3.0.5", "", { "dependencies": { "@slack/logger": "^4.0.1", "@slack/web-api": "^7.15.0", "@types/jsonwebtoken": "^9", "@types/node": ">=18", "jsonwebtoken": "^9" } }, "sha512-exqFQySKhNDptWYSWhvRUJ4/+ndu2gayIy7vg/JfmJq3wGtGdHk531P96fAZyBm5c1Le3yaPYqv92rL4COlU3A=="], - "@slack/socket-mode": ["@slack/socket-mode@1.3.6", "", { "dependencies": { "@slack/logger": "^3.0.0", "@slack/web-api": "^6.12.1", "@types/node": ">=12.0.0", "@types/ws": "^7.4.7", "eventemitter3": "^5", "finity": "^0.5.4", "ws": "^7.5.3" } }, "sha512-G+im7OP7jVqHhiNSdHgv2VVrnN5U7KY845/5EZimZkrD4ZmtV0P3BiWkgeJhPtdLuM7C7i6+M6h6Bh+S4OOalA=="], + "@slack/socket-mode": ["@slack/socket-mode@2.0.7", "", { "dependencies": { "@slack/logger": "^4.0.1", "@slack/web-api": "^7.15.0", "@types/node": ">=18", "@types/ws": "^8", "eventemitter3": "^5", "ws": "^8" } }, "sha512-qYy07je71WnEHgRwmw12DlAnZLi5HXmdlI2WUzUK2LH/rYXQpP6uEg462S5CwfE8FoCKUdIigHtYnOOfzZH1lQ=="], - "@slack/types": ["@slack/types@2.20.1", "", {}, "sha512-eWX2mdt1ktpn8+40iiMc404uGrih+2fxiky3zBcPjtXKj6HLRdYlmhrPkJi7JTJm8dpXR6BWVWEDBXtaWMKD6A=="], + "@slack/types": ["@slack/types@2.21.1", "", {}, "sha512-I8vmSjNYWsaxuWPx6dz4yeh0h7vRBWbgAMK14LEmblbZ404BtrPbXs6jDPx4cYgGf8msDGF4A9opLZBu21FViQ=="], - "@slack/web-api": ["@slack/web-api@6.13.0", "", { "dependencies": { "@slack/logger": "^3.0.0", "@slack/types": "^2.11.0", "@types/is-stream": "^1.1.0", "@types/node": ">=12.0.0", "axios": "^1.7.4", "eventemitter3": "^3.1.0", "form-data": "^2.5.0", "is-electron": "2.2.2", "is-stream": "^1.1.0", "p-queue": "^6.6.1", "p-retry": "^4.0.0" } }, "sha512-dv65crIgdh9ZYHrevLU6XFHTQwTyDmNqEqzuIrV+Vqe/vgiG6w37oex5ePDU1RGm2IJ90H8iOvHFvzdEO/vB+g=="], + "@slack/web-api": ["@slack/web-api@7.17.0", "", { "dependencies": { "@slack/logger": "^4.0.1", "@slack/types": "^2.21.0", "@types/node": ">=18", "@types/retry": "0.12.0", "axios": "^1.16.0", "eventemitter3": "^5.0.1", "form-data": "^4.0.4", "is-electron": "2.2.2", "is-stream": "^2", "p-queue": "^6", "p-retry": "^4", "retry": "^0.13.1" } }, "sha512-jejr34a8B4L5AS713wOAx1LAqNkW16HVMDEa6sYBvFDc/llUBl8hXaiI4BwF+Al+Sug19Vn2O7iokTVIhVvZ1Q=="], "@smithy/chunked-blob-reader": ["@smithy/chunked-blob-reader@5.2.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-St+kVicSyayWQca+I1rGitaOEH6uKgE8IUWoYnnEX26SWdWQcL6LvMSD19Lg+vYHKdT9B2Zuu7rd3i6Wnyb/iw=="], @@ -2025,7 +1314,7 @@ "@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.13", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.13", "@smithy/property-provider": "^4.2.13", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "tslib": "^2.6.2" } }, "sha512-wboCPijzf6RJKLOvnjDAiBxGSmSnGXj35o5ZAWKDaHa/cvQ5U3ZJ13D4tMCE8JG4dxVAZFy/P0x/V9CwwdfULQ=="], - "@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.7", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.11.0", "@smithy/util-hex-encoding": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-DrpkEoM3j9cBBWhufqBwnbbn+3nf1N9FP6xuVJ+e220jbactKuQgaZwjwP5CP1t+O94brm2JgVMD2atMGX3xIQ=="], + "@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.13", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.14.0", "@smithy/util-hex-encoding": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-vYahwBAtRaAcFbOmE9aLr12z7RiHYDSLcnogSdxfm7kKfsNa3wH+NU5r7vTeB5rKvLsWyPjVX8iH94brP7umiQ=="], "@smithy/eventstream-serde-browser": ["@smithy/eventstream-serde-browser@4.2.13", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-wwybfcOX0tLqCcBP378TIU9IqrDuZq/tDV48LlZNydMpCnqnYr+hWBAYbRE+rFFf/p7IkDJySM3bgiMKP2ihPg=="], @@ -2117,18 +1406,12 @@ "@socket.io/component-emitter": ["@socket.io/component-emitter@3.1.2", "", {}, "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA=="], - "@solid-primitives/active-element": ["@solid-primitives/active-element@2.1.3", "", { "dependencies": { "@solid-primitives/event-listener": "^2.4.3", "@solid-primitives/utils": "^6.3.2" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-9t5K4aR2naVDj950XU8OjnLgOg94a8k5wr6JNOPK+N5ESLsJDq42c1ZP8UKpewi1R+wplMMxiM6OPKRzbxJY7A=="], - - "@solid-primitives/audio": ["@solid-primitives/audio@1.4.2", "", { "dependencies": { "@solid-primitives/static-store": "^0.1.2", "@solid-primitives/utils": "^6.3.2" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-UMD3ORQfI5Ky8yuKPxidDiEazsjv/dsoiKK5yZxLnsgaeNR1Aym3/77h/qT1jBYeXUgj4DX6t7NMpFUSVr14OQ=="], - "@solid-primitives/bounds": ["@solid-primitives/bounds@0.1.3", "", { "dependencies": { "@solid-primitives/event-listener": "^2.4.3", "@solid-primitives/resize-observer": "^2.1.3", "@solid-primitives/static-store": "^0.1.2", "@solid-primitives/utils": "^6.3.2" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-UbiyKMdSPmtijcEDnYLQL3zzaejpwWDAJJ4Gt5P0hgVs6A72piov0GyNw7V2SroH7NZFwxlYS22YmOr8A5xc1Q=="], "@solid-primitives/event-bus": ["@solid-primitives/event-bus@1.1.2", "", { "dependencies": { "@solid-primitives/utils": "^6.3.2" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-l+n10/51neGcMaP3ypYt21bXfoeWh8IaC8k7fYuY3ww2a8S1Zv2N2a7FF5Qn+waTu86l0V8/nRHjkyqVIZBYwA=="], "@solid-primitives/event-listener": ["@solid-primitives/event-listener@2.4.5", "", { "dependencies": { "@solid-primitives/utils": "^6.4.0" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-nwRV558mIabl4yVAhZKY8cb6G+O1F0M6Z75ttTu5hk+SxdOnKSGj+eetDIu7Oax1P138ZdUU01qnBPR8rnxaEA=="], - "@solid-primitives/i18n": ["@solid-primitives/i18n@2.2.1", "", { "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-TnTnE2Ku11MGYZ1JzhJ8pYscwg1fr9MteoYxPwsfxWfh9Jp5K7RRJncJn9BhOHvNLwROjqOHZ46PT7sPHqbcXw=="], - "@solid-primitives/keyed": ["@solid-primitives/keyed@1.5.3", "", { "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-zNadtyYBhJSOjXtogkGHmRxjGdz9KHc8sGGVAGlUABkE8BED2tbIZoxkwSqzOwde8OcUEH0bb5DLZUWIMvyBSA=="], "@solid-primitives/map": ["@solid-primitives/map@0.4.13", "", { "dependencies": { "@solid-primitives/trigger": "^1.1.0" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-B1zyFbsiTQvqPr+cuPCXO72sRuczG9Swncqk5P74NCGw1VE8qa/Ry9GlfI1e/VdeQYHjan+XkbE3rO2GW/qKew=="], @@ -2139,34 +1422,22 @@ "@solid-primitives/refs": ["@solid-primitives/refs@1.1.3", "", { "dependencies": { "@solid-primitives/utils": "^6.4.0" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-aam02fjNKpBteewF/UliPSQCVJsIIGOLEWQOh+ll6R/QePzBOOBMcC4G+5jTaO75JuUS1d/14Q1YXT3X0Ow6iA=="], - "@solid-primitives/resize-observer": ["@solid-primitives/resize-observer@2.1.5", "", { "dependencies": { "@solid-primitives/event-listener": "^2.4.5", "@solid-primitives/rootless": "^1.5.3", "@solid-primitives/static-store": "^0.1.3", "@solid-primitives/utils": "^6.4.0" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-AiyTknKcNBaKHbcSMuxtSNM8FjIuiSuFyFghdD0TcCMU9hKi9EmsC5pjfjDwxE+5EueB1a+T/34PLRI5vbBbKw=="], + "@solid-primitives/resize-observer": ["@solid-primitives/resize-observer@2.1.3", "", { "dependencies": { "@solid-primitives/event-listener": "^2.4.3", "@solid-primitives/rootless": "^1.5.2", "@solid-primitives/static-store": "^0.1.2", "@solid-primitives/utils": "^6.3.2" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-zBLje5E06TgOg93S7rGPldmhDnouNGhvfZVKOp+oG2XU8snA+GoCSSCz1M+jpNAg5Ek2EakU5UVQqL152WmdXQ=="], "@solid-primitives/rootless": ["@solid-primitives/rootless@1.5.3", "", { "dependencies": { "@solid-primitives/utils": "^6.4.0" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-N8cIDAHbWcLahNRLr0knAAQvXyEdEMoAZvIMZKmhNb1mlx9e2UOv9BRD5YNwQUJwbNoYVhhLwFOEOcVXFx0HqA=="], "@solid-primitives/scheduled": ["@solid-primitives/scheduled@1.5.2", "", { "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-/j2igE0xyNaHhj6kMfcUQn5rAVSTLbAX+CDEBm25hSNBmNiHLu2lM7Usj2kJJ5j36D67bE8wR1hBNA8hjtvsQA=="], - "@solid-primitives/scroll": ["@solid-primitives/scroll@2.1.3", "", { "dependencies": { "@solid-primitives/event-listener": "^2.4.3", "@solid-primitives/rootless": "^1.5.2", "@solid-primitives/static-store": "^0.1.2" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-Ejq/Z7zKo/6eIEFr1bFLzXFxiGBCMLuqCM8QB8urr3YdPzjSETFLzYRWUyRiDWaBQN0F7k0SY6S7ig5nWOP7vg=="], - "@solid-primitives/static-store": ["@solid-primitives/static-store@0.1.3", "", { "dependencies": { "@solid-primitives/utils": "^6.4.0" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-uxez7SXnr5GiRnzqO2IEDjOJRIXaG+0LZLBizmUA1FwSi+hrpuMzVBwyk70m4prcl8X6FDDXUl9O8hSq8wHbBQ=="], - "@solid-primitives/storage": ["@solid-primitives/storage@4.3.3", "", { "dependencies": { "@solid-primitives/utils": "^6.3.2" }, "peerDependencies": { "@tauri-apps/plugin-store": "*", "solid-js": "^1.6.12" }, "optionalPeers": ["@tauri-apps/plugin-store"] }, "sha512-ACbNwMZ1s8VAvld6EUXkDkX/US3IhtlPLxg6+B2s9MwNUugwdd51I98LPEaHrdLpqPmyzqgoJe0TxEFlf3Dqrw=="], - - "@solid-primitives/timer": ["@solid-primitives/timer@1.4.4", "", { "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-Ayjyb3+v1hyU92vuLUN0tVHq2mmTCPGxSDLGJMsDydRqx9ZfJIc9xj6cxK4XvdY3pif3ps2mIv52pjgToybEpQ=="], - "@solid-primitives/trigger": ["@solid-primitives/trigger@1.2.3", "", { "dependencies": { "@solid-primitives/utils": "^6.4.0" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-Za2JebEiDyfamjmDwRaESYqBBYOlgYGzB8kHYH0QrkXyLf2qNADlKdGN+z3vWSLCTDcKxChS43Kssjuc0OZhng=="], "@solid-primitives/utils": ["@solid-primitives/utils@6.4.0", "", { "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-AeGTBg8Wtkh/0s+evyLtP8piQoS4wyqqQaAFs2HJcFMMjYAtUgo+ZPduRXLjPlqKVc2ejeR544oeqpbn8Egn8A=="], - "@solid-primitives/websocket": ["@solid-primitives/websocket@1.3.1", "", { "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-F06tA2FKa5VsnS4E4WEc3jHpsJfXRlMTGOtolugTzCqV3JmJTyvk9UVg1oz6PgGHKGi1CQ91OP8iW34myyJgaQ=="], - "@solidjs/meta": ["@solidjs/meta@0.29.4", "", { "peerDependencies": { "solid-js": ">=1.8.4" } }, "sha512-zdIWBGpR9zGx1p1bzIPqF5Gs+Ks/BH8R6fWhmUa/dcK1L2rUC8BAcZJzNRYBQv74kScf1TSOs0EY//Vd/I0V8g=="], "@solidjs/router": ["@solidjs/router@0.15.4", "", { "peerDependencies": { "solid-js": "^1.8.6" } }, "sha512-WOpgg9a9T638cR+5FGbFi/IV4l2FpmBs1GpIMSPa0Ce9vyJN7Wts+X2PqMf9IYn0zUj2MlSJtm1gp7/HI/n5TQ=="], - "@solidjs/start": ["@solidjs/start@https://pkg.pr.new/@solidjs/start@dfb2020", { "dependencies": { "@babel/core": "^7.28.3", "@babel/traverse": "^7.28.3", "@babel/types": "^7.28.5", "@solidjs/meta": "^0.29.4", "@tanstack/server-functions-plugin": "1.134.5", "@types/babel__traverse": "^7.28.0", "@types/micromatch": "^4.0.9", "cookie-es": "^2.0.0", "defu": "^6.1.4", "error-stack-parser": "^2.1.4", "es-module-lexer": "^1.7.0", "esbuild": "^0.25.3", "fast-glob": "^3.3.3", "h3": "npm:h3@2.0.1-rc.4", "html-to-image": "^1.11.13", "micromatch": "^4.0.8", "path-to-regexp": "^8.2.0", "pathe": "^2.0.3", "radix3": "^1.1.2", "seroval": "^1.3.2", "seroval-plugins": "^1.2.1", "shiki": "^1.26.1", "solid-js": "^1.9.9", "source-map-js": "^1.2.1", "srvx": "^0.9.1", "terracotta": "^1.0.6", "vite": "7.1.10", "vite-plugin-solid": "^2.11.9", "vitest": "^4.0.10" } }, "sha512-7JjjA49VGNOsMRI8QRUhVudZmv0CnJ18SliSgK1ojszs/c3ijftgVkzvXdkSLN4miDTzbkXewf65D6ZBo6W+GQ=="], - - "@speed-highlight/core": ["@speed-highlight/core@1.2.15", "", {}, "sha512-BMq1K3DsElxDWawkX6eLg9+CKJrTVGCBAWVuHXVUV2u0s2711qiChLSId6ikYPfxhdYocLNt3wWwSvDiTvFabw=="], - "@stablelib/base64": ["@stablelib/base64@1.0.1", "", {}, "sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ=="], "@standard-community/standard-json": ["@standard-community/standard-json@0.3.5", "", { "peerDependencies": { "@standard-schema/spec": "^1.0.0", "@types/json-schema": "^7.0.15", "@valibot/to-json-schema": "^1.3.0", "arktype": "^2.1.20", "effect": "^3.16.8", "quansync": "^0.2.11", "sury": "^10.0.0", "typebox": "^1.0.17", "valibot": "^1.1.0", "zod": "^3.25.0 || ^4.0.0", "zod-to-json-schema": "^3.24.5" }, "optionalPeers": ["@valibot/to-json-schema", "arktype", "effect", "sury", "typebox", "valibot", "zod", "zod-to-json-schema"] }, "sha512-4+ZPorwDRt47i+O7RjyuaxHRK/37QY/LmgxlGrRrSTLYoFatEOzvqIc85GTlM18SFZ5E91C+v0o/M37wZPpUHA=="], @@ -2175,32 +1446,8 @@ "@standard-schema/spec": ["@standard-schema/spec@1.0.0", "", {}, "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA=="], - "@storybook/addon-a11y": ["@storybook/addon-a11y@10.3.5", "", { "dependencies": { "@storybook/global": "^5.0.0", "axe-core": "^4.2.0" }, "peerDependencies": { "storybook": "^10.3.5" } }, "sha512-5k6lpgfIeLxvNhE8v3wEzdiu73ONKjF4gmH1AHvfqYd8kIVzQJai0KCDxgvqNncXHQhIWkaf1fg6+9hKaYJyaw=="], - - "@storybook/addon-docs": ["@storybook/addon-docs@10.3.5", "", { "dependencies": { "@mdx-js/react": "^3.0.0", "@storybook/csf-plugin": "10.3.5", "@storybook/icons": "^2.0.1", "@storybook/react-dom-shim": "10.3.5", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "ts-dedent": "^2.0.0" }, "peerDependencies": { "storybook": "^10.3.5" } }, "sha512-WuHbxia/o5TX4Rg/IFD0641K5qId/Nk0dxhmAUNoFs5L0+yfZUwh65XOBbzXqrkYmYmcVID4v7cgDRmzstQNkA=="], - - "@storybook/addon-links": ["@storybook/addon-links@10.3.5", "", { "dependencies": { "@storybook/global": "^5.0.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "storybook": "^10.3.5" }, "optionalPeers": ["react"] }, "sha512-Xe2wCGZ+hpZ0cDqAIBHk+kPc8nODNbu585ghd5bLrlYJMDVXoNM/fIlkrLgjIDVbfpgeJLUEg7vldJrn+FyOLw=="], - - "@storybook/addon-onboarding": ["@storybook/addon-onboarding@10.3.5", "", { "peerDependencies": { "storybook": "^10.3.5" } }, "sha512-s3/gIy9Tqxji27iclLY+KSk8kGeow1JxXMl1lPLyu8n6XVvv+tFrUPhAvUTs+fVenG6JQEWc0uzpYBdFRWbMtw=="], - - "@storybook/addon-vitest": ["@storybook/addon-vitest@10.3.5", "", { "dependencies": { "@storybook/global": "^5.0.0", "@storybook/icons": "^2.0.1" }, "peerDependencies": { "@vitest/browser": "^3.0.0 || ^4.0.0", "@vitest/browser-playwright": "^4.0.0", "@vitest/runner": "^3.0.0 || ^4.0.0", "storybook": "^10.3.5", "vitest": "^3.0.0 || ^4.0.0" }, "optionalPeers": ["@vitest/browser", "@vitest/browser-playwright", "@vitest/runner", "vitest"] }, "sha512-PQDeeMwoF55kvzlhFqVKOryBJskkVk71AbDh7F0y8PdRRxlGbTvIUkKXktHZWBdESo0dV6BkeVxGQ4ZpiFxirg=="], - - "@storybook/builder-vite": ["@storybook/builder-vite@10.3.5", "", { "dependencies": { "@storybook/csf-plugin": "10.3.5", "ts-dedent": "^2.0.0" }, "peerDependencies": { "storybook": "^10.3.5", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-i4KwCOKbhtlbQIbhm53+Kk7bMnxa0cwTn1pxmtA/x5wm1Qu7FrrBQV0V0DNjkUqzcSKo1CjspASJV/HlY0zYlw=="], - - "@storybook/csf-plugin": ["@storybook/csf-plugin@10.3.5", "", { "dependencies": { "unplugin": "^2.3.5" }, "peerDependencies": { "esbuild": "*", "rollup": "*", "storybook": "^10.3.5", "vite": "*", "webpack": "*" }, "optionalPeers": ["esbuild", "rollup", "vite", "webpack"] }, "sha512-qlEzNKxOjq86pvrbuMwiGD/bylnsXk1dg7ve0j77YFjEEchqtl7qTlrXvFdNaLA89GhW6D/EV6eOCu/eobPDgw=="], - - "@storybook/global": ["@storybook/global@5.0.0", "", {}, "sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ=="], - - "@storybook/icons": ["@storybook/icons@2.0.1", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-/smVjw88yK3CKsiuR71vNgWQ9+NuY2L+e8X7IMrFjexjm6ZR8ULrV2DRkTA61aV6ryefslzHEGDInGpnNeIocg=="], - - "@storybook/react-dom-shim": ["@storybook/react-dom-shim@10.3.5", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "storybook": "^10.3.5" } }, "sha512-Gw8R7XZm0zSUH0XAuxlQJhmizsLzyD6x00KOlP6l7oW9eQHXGfxg3seNDG3WrSAcW07iP1/P422kuiriQlOv7g=="], - - "@stripe/stripe-js": ["@stripe/stripe-js@8.6.1", "", {}, "sha512-UJ05U2062XDgydbUcETH1AoRQLNhigQ2KmDn1BG8sC3xfzu6JKg95Qt6YozdzFpxl1Npii/02m2LEWFt1RYjVA=="], - "@swc/helpers": ["@swc/helpers@0.5.21", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-jI/VAmtdjB/RnI8GTnokyX7Ug8c+g+ffD6QRLa6XQewtnGyukKkKSk3wLTM3b5cjt1jNh9x0jfVlagdN2gDKQg=="], - "@szmarczak/http-timer": ["@szmarczak/http-timer@4.0.6", "", { "dependencies": { "defer-to-connect": "^2.0.0" } }, "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w=="], - "@tailwindcss/node": ["@tailwindcss/node@4.1.11", "", { "dependencies": { "@ampproject/remapping": "^2.3.0", "enhanced-resolve": "^5.18.1", "jiti": "^2.4.2", "lightningcss": "1.30.1", "magic-string": "^0.30.17", "source-map-js": "^1.2.1", "tailwindcss": "4.1.11" } }, "sha512-yzhzuGRmv5QyU9qLNg4GTlYI6STedBWRE7NjxP45CsFYYq9taI0zJXZBMqIC/c8fViNLhmrbpSFS57EoxUmD6Q=="], "@tailwindcss/oxide": ["@tailwindcss/oxide@4.1.11", "", { "dependencies": { "detect-libc": "^2.0.4", "tar": "^7.4.3" }, "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.1.11", "@tailwindcss/oxide-darwin-arm64": "4.1.11", "@tailwindcss/oxide-darwin-x64": "4.1.11", "@tailwindcss/oxide-freebsd-x64": "4.1.11", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.11", "@tailwindcss/oxide-linux-arm64-gnu": "4.1.11", "@tailwindcss/oxide-linux-arm64-musl": "4.1.11", "@tailwindcss/oxide-linux-x64-gnu": "4.1.11", "@tailwindcss/oxide-linux-x64-musl": "4.1.11", "@tailwindcss/oxide-wasm32-wasi": "4.1.11", "@tailwindcss/oxide-win32-arm64-msvc": "4.1.11", "@tailwindcss/oxide-win32-x64-msvc": "4.1.11" } }, "sha512-Q69XzrtAhuyfHo+5/HMgr1lAiPP/G40OMFAnws7xcFEYqcypZmdW8eGXaOUIeOl1dzPJBPENXgbjsOyhg2nkrg=="], @@ -2231,29 +1478,11 @@ "@tailwindcss/vite": ["@tailwindcss/vite@4.1.11", "", { "dependencies": { "@tailwindcss/node": "4.1.11", "@tailwindcss/oxide": "4.1.11", "tailwindcss": "4.1.11" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7" } }, "sha512-RHYhrR3hku0MJFRV+fN2gNbDNEh3dwKvY8XJvTxCSXeMOsCRSr+uKvDWQcbizrHgjML6ZmTE5OwMrl5wKcujCw=="], - "@tanstack/directive-functions-plugin": ["@tanstack/directive-functions-plugin@1.134.5", "", { "dependencies": { "@babel/code-frame": "7.27.1", "@babel/core": "^7.27.7", "@babel/traverse": "^7.27.7", "@babel/types": "^7.27.7", "@tanstack/router-utils": "1.133.19", "babel-dead-code-elimination": "^1.0.10", "pathe": "^2.0.3", "tiny-invariant": "^1.3.3" }, "peerDependencies": { "vite": ">=6.0.0 || >=7.0.0" } }, "sha512-J3oawV8uBRBbPoLgMdyHt+LxzTNuWRKNJJuCLWsm/yq6v0IQSvIVCgfD2+liIiSnDPxGZ8ExduPXy8IzS70eXw=="], - - "@tanstack/query-core": ["@tanstack/query-core@5.91.2", "", {}, "sha512-Uz2pTgPC1mhqrrSGg18RKCWT/pkduAYtxbcyIyKBhw7dTWjXZIzqmpzO2lBkyWr4hlImQgpu1m1pei3UnkFRWw=="], - - "@tanstack/router-utils": ["@tanstack/router-utils@1.133.19", "", { "dependencies": { "@babel/core": "^7.27.4", "@babel/generator": "^7.27.5", "@babel/parser": "^7.27.5", "@babel/preset-typescript": "^7.27.1", "ansis": "^4.1.0", "diff": "^8.0.2", "pathe": "^2.0.3", "tinyglobby": "^0.2.15" } }, "sha512-WEp5D2gPxvlLDRXwD/fV7RXjYtqaqJNXKB/L6OyZEbT+9BG/Ib2d7oG9GSUZNNMGPGYAlhBUOi3xutySsk6rxA=="], - - "@tanstack/server-functions-plugin": ["@tanstack/server-functions-plugin@1.134.5", "", { "dependencies": { "@babel/code-frame": "7.27.1", "@babel/core": "^7.27.7", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1", "@babel/template": "^7.27.2", "@babel/traverse": "^7.27.7", "@babel/types": "^7.27.7", "@tanstack/directive-functions-plugin": "1.134.5", "babel-dead-code-elimination": "^1.0.9", "tiny-invariant": "^1.3.3" } }, "sha512-2sWxq70T+dOEUlE3sHlXjEPhaFZfdPYlWTSkHchWXrFGw2YOAa+hzD6L9wHMjGDQezYd03ue8tQlHG+9Jzbzgw=="], - - "@tanstack/solid-query": ["@tanstack/solid-query@5.91.4", "", { "dependencies": { "@tanstack/query-core": "5.91.2" }, "peerDependencies": { "solid-js": "^1.6.0" } }, "sha512-oCEgn8iT7WnF/7ISd7usBpUK1C9EdvQfg8ZUpKNKZ4edVClICZrCX6f3/Bp8ZlwQnL21KLc2rp+CejEuehlRxg=="], - - "@tauri-apps/api": ["@tauri-apps/api@2.10.1", "", {}, "sha512-hKL/jWf293UDSUN09rR69hrToyIXBb8CjGaWC7gfinvnQrBVvnLr08FeFi38gxtugAVyVcTa5/FD/Xnkb1siBw=="], - - "@tauri-apps/plugin-store": ["@tauri-apps/plugin-store@2.4.2", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-0ClHS50Oq9HEvLPhNzTNFxbWVOqoAp3dRvtewQBeqfIQ0z5m3JRnOISIn2ZVPCrQC0MyGyhTS9DWhHjpigQE7A=="], - "@tediousjs/connection-string": ["@tediousjs/connection-string@0.5.0", "", {}, "sha512-7qSgZbincDDDFyRweCIEvZULFAw5iz/DeunhvuxpL31nfntX3P4Yd4HkHBRg9H8CdqY1e5WFN1PZIz/REL9MVQ=="], - "@testing-library/dom": ["@testing-library/dom@10.4.1", "", { "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", "@types/aria-query": "^5.0.1", "aria-query": "5.3.0", "dom-accessibility-api": "^0.5.9", "lz-string": "^1.5.0", "picocolors": "1.1.1", "pretty-format": "^27.0.2" } }, "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg=="], - "@testing-library/jest-dom": ["@testing-library/jest-dom@6.9.1", "", { "dependencies": { "@adobe/css-tools": "^4.4.0", "aria-query": "^5.0.0", "css.escape": "^1.5.1", "dom-accessibility-api": "^0.6.3", "picocolors": "^1.1.1", "redent": "^3.0.0" } }, "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA=="], - "@testing-library/user-event": ["@testing-library/user-event@14.6.1", "", { "peerDependencies": { "@testing-library/dom": ">=7.21.4" } }, "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw=="], - - "@thisbeyond/solid-dnd": ["@thisbeyond/solid-dnd@0.7.5", "", { "peerDependencies": { "solid-js": "^1.5" } }, "sha512-DfI5ff+yYGpK9M21LhYwIPlbP2msKxN2ARwuu6GF8tT1GgNVDTI8VCQvH4TJFoVApP9d44izmAcTh/iTCH2UUw=="], + "@tokenizer/inflate": ["@tokenizer/inflate@0.4.1", "", { "dependencies": { "debug": "^4.4.3", "token-types": "^6.1.1" } }, "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA=="], "@tokenizer/token": ["@tokenizer/token@0.3.0", "", {}, "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="], @@ -2265,9 +1494,17 @@ "@tufjs/models": ["@tufjs/models@4.1.0", "", { "dependencies": { "@tufjs/canonical-json": "2.0.0", "minimatch": "^10.1.1" } }, "sha512-Y8cK9aggNRsqJVaKUlEYs4s7CvQ1b1ta2DVPyAimb0I2qhzjNk+A+mxvll/klL0RlfuIUei8BF7YWiua4kQqww=="], - "@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="], + "@turbo/darwin-64": ["@turbo/darwin-64@2.9.14", "", { "os": "darwin", "cpu": "x64" }, "sha512-t7QiPflaEyBE4oayeZtSmu4mEfjgIrcNlNNl1z1dmIVPqEdtA7+CfTf8d7KXsOGPh6aNgWjKxyvQg9uGfDQF+A=="], + + "@turbo/darwin-arm64": ["@turbo/darwin-arm64@2.9.14", "", { "os": "darwin", "cpu": "arm64" }, "sha512-d23147mC9BsCPA9mJ0h/ubcpbRgcJBXbcG3+Vq7YLhjz3IXuvQsJ1UXH8f4MD76ZjJ4m/E4aRdJV+MW88CDfbw=="], - "@types/aria-query": ["@types/aria-query@5.0.4", "", {}, "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw=="], + "@turbo/linux-64": ["@turbo/linux-64@2.9.14", "", { "os": "linux", "cpu": "x64" }, "sha512-P3ZKB5tuUDdDQWuAsACGUR1qv9W7BNWxdxqVJ0kZNuNNPRaVYTPPikLcp79+GiEcW3npsR+KyP38lnQiBc5aSA=="], + + "@turbo/linux-arm64": ["@turbo/linux-arm64@2.9.14", "", { "os": "linux", "cpu": "arm64" }, "sha512-ZRTlzcUMrrPv9ZuDzRF9n60Ym13bKeG9jDB8WjxyLhWNzV+AJQN+zdpIk3NJYf2zQsGUm1mNar2P0elRzLw25g=="], + + "@turbo/windows-64": ["@turbo/windows-64@2.9.14", "", { "os": "win32", "cpu": "x64" }, "sha512-exanwN6sIduZwykYeiTQj8kCmOhazP5WOz3bvXMcYtjhL6Z3iRWLewKrXCBq0bqwSP3iBMb/AerRCnHI4lx46A=="], + + "@turbo/windows-arm64": ["@turbo/windows-arm64@2.9.14", "", { "os": "win32", "cpu": "arm64" }, "sha512-fVdCsnmYoKICsycbWuuGp6Jvi51/3G/UluFWuAUCvR8PIW5IJkAk5BM9UF8PSm0Q2IphWHFZjYEgjHsh3B9y/g=="], "@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="], @@ -2279,62 +1516,34 @@ "@types/body-parser": ["@types/body-parser@1.19.6", "", { "dependencies": { "@types/connect": "*", "@types/node": "*" } }, "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g=="], - "@types/braces": ["@types/braces@3.0.5", "", {}, "sha512-SQFof9H+LXeWNz8wDe7oN5zu7ket0qwMu5vZubW4GCJ8Kkeh6nBWUz87+KTz/G3Kqsrp0j/W253XJb3KMEeg3w=="], - "@types/bun": ["@types/bun@1.3.12", "", { "dependencies": { "bun-types": "1.3.12" } }, "sha512-DBv81elK+/VSwXHDlnH3Qduw+KxkTIWi7TXkAeh24zpi5l0B2kUg9Ga3tb4nJaPcOFswflgi/yAvMVBPrxMB+A=="], "@types/cacache": ["@types/cacache@20.0.1", "", { "dependencies": { "@types/node": "*", "minipass": "*" } }, "sha512-QlKW3AFoFr/hvPHwFHMIVUH/ZCYeetBNou3PCmxu5LaNDvrtBlPJtIA6uhmU9JRt9oxj7IYoqoLcpxtzpPiTcw=="], - "@types/cacheable-request": ["@types/cacheable-request@6.0.3", "", { "dependencies": { "@types/http-cache-semantics": "*", "@types/keyv": "^3.1.4", "@types/node": "*", "@types/responselike": "^1.0.0" } }, "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw=="], - - "@types/chai": ["@types/chai@5.2.3", "", { "dependencies": { "@types/deep-eql": "*", "assertion-error": "^2.0.1" } }, "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA=="], - "@types/connect": ["@types/connect@3.4.38", "", { "dependencies": { "@types/node": "*" } }, "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug=="], "@types/cross-spawn": ["@types/cross-spawn@6.0.6", "", { "dependencies": { "@types/node": "*" } }, "sha512-fXRhhUkG4H3TQk5dBhQ7m/JDdSNHKwR2BBia62lhwEIq9xGiQKLxd6LymNhn47SjXhsUEPmxi+PKw2OkW4LLjA=="], - "@types/debug": ["@types/debug@4.1.13", "", { "dependencies": { "@types/ms": "*" } }, "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw=="], - - "@types/deep-eql": ["@types/deep-eql@4.0.2", "", {}, "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw=="], - "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], - "@types/estree-jsx": ["@types/estree-jsx@1.0.5", "", { "dependencies": { "@types/estree": "*" } }, "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg=="], - "@types/express": ["@types/express@4.17.25", "", { "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", "@types/qs": "*", "@types/serve-static": "^1" } }, "sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw=="], "@types/express-serve-static-core": ["@types/express-serve-static-core@4.19.8", "", { "dependencies": { "@types/node": "*", "@types/qs": "*", "@types/range-parser": "*", "@types/send": "*" } }, "sha512-02S5fmqeoKzVZCHPZid4b8JH2eM5HzQLZWN2FohQEy/0eXTq8VXZfSN6Pcr3F6N9R/vNrj7cpgbhjie6m/1tCA=="], - "@types/fontkit": ["@types/fontkit@2.0.9", "", { "dependencies": { "@types/node": "*" } }, "sha512-qNYerFky3muCmZPq+R+B3cUDRA5OONw/oh6aGGFxx2LOBz6yu8eamKusrhkHnC6rc2fm76+G9z9QoWSB2SaQaw=="], - - "@types/fs-extra": ["@types/fs-extra@9.0.13", "", { "dependencies": { "@types/node": "*" } }, "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA=="], - "@types/hast": ["@types/hast@3.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ=="], - "@types/http-cache-semantics": ["@types/http-cache-semantics@4.2.0", "", {}, "sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q=="], - "@types/http-errors": ["@types/http-errors@2.0.5", "", {}, "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg=="], - "@types/is-stream": ["@types/is-stream@1.1.0", "", { "dependencies": { "@types/node": "*" } }, "sha512-jkZatu4QVbR60mpIzjINmtS1ZF4a/FqdTUTBeQDVOQ2PYyidtwFKr0B5G6ERukKwliq+7mIXvxyppwzG5EgRYg=="], - - "@types/js-yaml": ["@types/js-yaml@4.0.9", "", {}, "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg=="], - "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="], - "@types/jsonwebtoken": ["@types/jsonwebtoken@8.5.9", "", { "dependencies": { "@types/node": "*" } }, "sha512-272FMnFGzAVMGtu9tkr29hRL6bZj4Zs1KZNeHLnKqAvp06tAIcarTMwOh8/8bz4FmKRcMxZhZNeUAQsNLoiPhg=="], + "@types/jsonwebtoken": ["@types/jsonwebtoken@9.0.10", "", { "dependencies": { "@types/ms": "*", "@types/node": "*" } }, "sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA=="], "@types/katex": ["@types/katex@0.16.7", "", {}, "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ=="], - "@types/keyv": ["@types/keyv@3.1.4", "", { "dependencies": { "@types/node": "*" } }, "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg=="], - "@types/luxon": ["@types/luxon@3.7.1", "", {}, "sha512-H3iskjFIAn5SlJU7OuxUmTEpebK6TKB8rxZShDslBMZJ5u9S//KM1sbdAisiSrqwLQncVjnpi2OK2J51h+4lsg=="], "@types/mdast": ["@types/mdast@4.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="], - "@types/mdx": ["@types/mdx@2.0.13", "", {}, "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw=="], - - "@types/micromatch": ["@types/micromatch@4.0.10", "", { "dependencies": { "@types/braces": "*" } }, "sha512-5jOhFDElqr4DKTrTEbnW8DZ4Hz5LRUEmyrGpCMrD/NphYv3nUnaF08xmSLx1rGGnyEs/kFnhiw6dCgcDqMr5PQ=="], - "@types/mime": ["@types/mime@1.3.5", "", {}, "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w=="], "@types/mime-types": ["@types/mime-types@3.0.1", "", {}, "sha512-xRMsfuQbnRq1Ef+C+RKaENOxXX87Ygl38W1vDfPHRku02TgQr+Qd8iivLtAMcR0KF5/29xlnFihkTlbqFrGOVQ=="], @@ -2343,8 +1552,6 @@ "@types/mssql": ["@types/mssql@9.1.11", "", { "dependencies": { "@types/node": "*", "tarn": "^3.0.1", "tedious": "*" } }, "sha512-vcujgrDbDezCxNDO4KY6gjwduLYOKfrexpRUwhoysRvcXZ3+IgZ/PMYFDgh8c3cQIxZ6skAwYo+H6ibMrBWPjQ=="], - "@types/nlcst": ["@types/nlcst@2.0.3", "", { "dependencies": { "@types/unist": "*" } }, "sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA=="], - "@types/node": ["@types/node@24.12.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g=="], "@types/node-fetch": ["@types/node-fetch@2.6.13", "", { "dependencies": { "@types/node": "*", "form-data": "^4.0.4" } }, "sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw=="], @@ -2361,28 +1568,14 @@ "@types/pacote": ["@types/pacote@11.1.8", "", { "dependencies": { "@types/node": "*", "@types/npm-registry-fetch": "*", "@types/npmlog": "*", "@types/ssri": "*" } }, "sha512-/XLR0VoTh2JEO0jJg1q/e6Rh9bxjBq9vorJuQmtT7rRrXSiWz7e7NsvXVYJQ0i8JxMlBMPPYDTnrRe7MZRFA8Q=="], - "@types/plist": ["@types/plist@3.0.5", "", { "dependencies": { "@types/node": "*", "xmlbuilder": ">=11.0.1" } }, "sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA=="], - - "@types/promise.allsettled": ["@types/promise.allsettled@1.0.6", "", {}, "sha512-wA0UT0HeT2fGHzIFV9kWpYz5mdoyLxKrTgMdZQM++5h6pYAFH73HXcQhefg24nD1yivUFEn5KU+EF4b+CXJ4Wg=="], - - "@types/prop-types": ["@types/prop-types@15.7.15", "", {}, "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw=="], - "@types/qs": ["@types/qs@6.15.0", "", {}, "sha512-JawvT8iBVWpzTrz3EGw9BTQFg3BQNmwERdKE22vlTxawwtbyUSlMppvZYKLZzB5zgACXdXxbD3m1bXaMqP/9ow=="], "@types/range-parser": ["@types/range-parser@1.2.7", "", {}, "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ=="], - "@types/react": ["@types/react@18.0.25", "", { "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", "csstype": "^3.0.2" } }, "sha512-xD6c0KDT4m7n9uD4ZHi02lzskaiqcBxf4zi+tXZY98a04wvc0hi/TcCPC2FOESZi51Nd7tlUeOJY8RofL799/g=="], - "@types/readable-stream": ["@types/readable-stream@4.0.23", "", { "dependencies": { "@types/node": "*" } }, "sha512-wwXrtQvbMHxCbBgjHaMGEmImFTQxxpfMOR/ZoQnXxB1woqkUbdLGFDgauo00Py9IudiaqSeiBiulSV9i6XIPig=="], - "@types/responselike": ["@types/responselike@1.0.3", "", { "dependencies": { "@types/node": "*" } }, "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw=="], - "@types/retry": ["@types/retry@0.12.0", "", {}, "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA=="], - "@types/sax": ["@types/sax@1.2.7", "", { "dependencies": { "@types/node": "*" } }, "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A=="], - - "@types/scheduler": ["@types/scheduler@0.26.0", "", {}, "sha512-WFHp9YUJQ6CKshqoC37iOlHnQSmxNc795UhB26CyBBttrN9svdIrUjl/NjnNmfcwtncN0h/0PPAFWv9ovP8mLA=="], - "@types/semver": ["@types/semver@7.7.1", "", {}, "sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA=="], "@types/send": ["@types/send@0.17.6", "", { "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og=="], @@ -2393,18 +1586,10 @@ "@types/trusted-types": ["@types/trusted-types@2.0.7", "", {}, "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="], - "@types/tsscmp": ["@types/tsscmp@1.0.2", "", {}, "sha512-cy7BRSU8GYYgxjcx0Py+8lo5MthuDhlyu076KUcYzVNXL23luYgRHkMG2fIFEc6neckeh/ntP82mw+U4QjZq+g=="], - - "@types/tunnel": ["@types/tunnel@0.0.3", "", { "dependencies": { "@types/node": "*" } }, "sha512-sOUTGn6h1SfQ+gbgqC364jLFBw2lnFqkgF3q0WovEHRLMrVD1sd5aufqi/aJObLekJO+Aq5z646U4Oxy6shXMA=="], - "@types/turndown": ["@types/turndown@5.0.5", "", {}, "sha512-TL2IgGgc7B5j78rIccBtlYAnkuv8nUQqhQc+DSYV5j9Be9XOcm/SKOVRuA47xAVI3680Tk9B1d8flK2GWT2+4w=="], "@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], - "@types/verror": ["@types/verror@1.10.11", "", {}, "sha512-RlDm9K7+o5stv0Co8i8ZRGxDbrTxhJtgjqjFyVh/tXQyl/rYtTKlnTvZ88oSTeYREWurwx20Js4kTuKCsFkUtg=="], - - "@types/whatwg-mimetype": ["@types/whatwg-mimetype@3.0.2", "", {}, "sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA=="], - "@types/which": ["@types/which@3.0.4", "", {}, "sha512-liyfuo/106JdlgSchJzXEQCVArk0CvevqPote8F8HgWgJ3dRCcTHgJIsLDuee0kxk/mhbInzIZk3QWSZJ8R+2w=="], "@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="], @@ -2413,8 +1598,6 @@ "@types/yargs-parser": ["@types/yargs-parser@21.0.3", "", {}, "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ=="], - "@types/yauzl": ["@types/yauzl@2.10.3", "", { "dependencies": { "@types/node": "*" } }, "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q=="], - "@typescript/native-preview": ["@typescript/native-preview@7.0.0-dev.20251207.1", "", { "optionalDependencies": { "@typescript/native-preview-darwin-arm64": "7.0.0-dev.20251207.1", "@typescript/native-preview-darwin-x64": "7.0.0-dev.20251207.1", "@typescript/native-preview-linux-arm": "7.0.0-dev.20251207.1", "@typescript/native-preview-linux-arm64": "7.0.0-dev.20251207.1", "@typescript/native-preview-linux-x64": "7.0.0-dev.20251207.1", "@typescript/native-preview-win32-arm64": "7.0.0-dev.20251207.1", "@typescript/native-preview-win32-x64": "7.0.0-dev.20251207.1" }, "bin": { "tsgo": "bin/tsgo.js" } }, "sha512-4QcRnzB0pi9rS0AOvg8kWbmuwHv5X7B2EXHbgcms9+56hsZ8SZrZjNgBJb2rUIodJ4kU5mrkj/xlTTT4r9VcpQ=="], "@typescript/native-preview-darwin-arm64": ["@typescript/native-preview-darwin-arm64@7.0.0-dev.20251207.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-waWJnuuvkXh4WdpbTjYf7pyahJzx0ycesV2BylyHrE9OxU9FSKcD/cRLQYvbq3YcBSdF7sZwRLDBer7qTeLsYA=="], @@ -2441,152 +1624,52 @@ "@vercel/oidc": ["@vercel/oidc@3.2.0", "", {}, "sha512-UycprH3T6n3jH0k44NHMa7pnFHGu/N05MjojYr+Mc6I7obkoLIJujSWwin1pCvdy/eOxrI/l3uDLQsmcrOb4ug=="], - "@vitejs/plugin-react": ["@vitejs/plugin-react@4.7.0", "", { "dependencies": { "@babel/core": "^7.28.0", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-beta.27", "@types/babel__core": "^7.20.5", "react-refresh": "^0.17.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA=="], + "@webgpu/types": ["@webgpu/types@0.1.69", "", {}, "sha512-RPmm6kgRbI8e98zSD3RVACvnuktIja5+yLgDAkTmxLr90BEwdTXRQWNLF3ETTTyH/8mKhznZuN5AveXYFEsMGQ=="], - "@vitest/expect": ["@vitest/expect@3.2.4", "", { "dependencies": { "@types/chai": "^5.2.2", "@vitest/spy": "3.2.4", "@vitest/utils": "3.2.4", "chai": "^5.2.0", "tinyrainbow": "^2.0.0" } }, "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig=="], + "@zip.js/zip.js": ["@zip.js/zip.js@2.7.62", "", {}, "sha512-OaLvZ8j4gCkLn048ypkZu29KX30r8/OfFF2w4Jo5WXFr+J04J+lzJ5TKZBVgFXhlvSkqNFQdfnY1Q8TMTCyBVA=="], - "@vitest/mocker": ["@vitest/mocker@4.1.4", "", { "dependencies": { "@vitest/spy": "4.1.4", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["msw", "vite"] }, "sha512-R9HTZBhW6yCSGbGQnDnH3QHfJxokKN4KB+Yvk9Q1le7eQNYwiCyKxmLmurSpFy6BzJanSLuEUDrD+j97Q+ZLPg=="], + "abbrev": ["abbrev@4.0.0", "", {}, "sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA=="], - "@vitest/pretty-format": ["@vitest/pretty-format@4.1.4", "", { "dependencies": { "tinyrainbow": "^3.1.0" } }, "sha512-ddmDHU0gjEUyEVLxtZa7xamrpIefdEETu3nZjWtHeZX4QxqJ7tRxSteHVXJOcr8jhiLoGAhkK4WJ3WqBpjx42A=="], + "abort-controller": ["abort-controller@3.0.0", "", { "dependencies": { "event-target-shim": "^5.0.0" } }, "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg=="], - "@vitest/runner": ["@vitest/runner@4.1.4", "", { "dependencies": { "@vitest/utils": "4.1.4", "pathe": "^2.0.3" } }, "sha512-xTp7VZ5aXP5ZJrn15UtJUWlx6qXLnGtF6jNxHepdPHpMfz/aVPx+htHtgcAL2mDXJgKhpoo2e9/hVJsIeFbytQ=="], + "abstract-logging": ["abstract-logging@2.0.1", "", {}, "sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA=="], - "@vitest/snapshot": ["@vitest/snapshot@4.1.4", "", { "dependencies": { "@vitest/pretty-format": "4.1.4", "@vitest/utils": "4.1.4", "magic-string": "^0.30.21", "pathe": "^2.0.3" } }, "sha512-MCjCFgaS8aZz+m5nTcEcgk/xhWv0rEH4Yl53PPlMXOZ1/Ka2VcZU6CJ+MgYCZbcJvzGhQRjVrGQNZqkGPttIKw=="], + "accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="], - "@vitest/spy": ["@vitest/spy@3.2.4", "", { "dependencies": { "tinyspy": "^4.0.3" } }, "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw=="], + "agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="], - "@vitest/utils": ["@vitest/utils@4.1.4", "", { "dependencies": { "@vitest/pretty-format": "4.1.4", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" } }, "sha512-13QMT+eysM5uVGa1rG4kegGYNp6cnQcsTc67ELFbhNLQO+vgsygtYJx2khvdt4gVQqSSpC/KT5FZZxUpP3Oatw=="], + "ai": ["ai@6.0.168", "", { "dependencies": { "@ai-sdk/gateway": "3.0.104", "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.23", "@opentelemetry/api": "1.9.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-2HqCJuO+1V2aV7vfYs5LFEUfxbkGX+5oa54q/gCCTL7KLTdbxcCu5D7TdLA5kwsrs3Szgjah9q6D9tpjHM3hUQ=="], - "@volar/kit": ["@volar/kit@2.4.28", "", { "dependencies": { "@volar/language-service": "2.4.28", "@volar/typescript": "2.4.28", "typesafe-path": "^0.2.2", "vscode-languageserver-textdocument": "^1.0.11", "vscode-uri": "^3.0.8" }, "peerDependencies": { "typescript": "*" } }, "sha512-cKX4vK9dtZvDRaAzeoUdaAJEew6IdxHNCRrdp5Kvcl6zZOqb6jTOfk3kXkIkG3T7oTFXguEMt5+9ptyqYR84Pg=="], + "ai-gateway-provider": ["ai-gateway-provider@3.1.2", "", { "optionalDependencies": { "@ai-sdk/amazon-bedrock": "^4.0.62", "@ai-sdk/anthropic": "^3.0.46", "@ai-sdk/azure": "^3.0.31", "@ai-sdk/cerebras": "^2.0.34", "@ai-sdk/cohere": "^3.0.21", "@ai-sdk/deepgram": "^2.0.20", "@ai-sdk/deepseek": "^2.0.20", "@ai-sdk/elevenlabs": "^2.0.20", "@ai-sdk/fireworks": "^2.0.34", "@ai-sdk/google": "^3.0.30", "@ai-sdk/google-vertex": "^4.0.61", "@ai-sdk/groq": "^3.0.24", "@ai-sdk/mistral": "^3.0.20", "@ai-sdk/openai": "^3.0.30", "@ai-sdk/perplexity": "^3.0.19", "@ai-sdk/xai": "^3.0.57", "@openrouter/ai-sdk-provider": "^2.2.3" }, "peerDependencies": { "@ai-sdk/openai-compatible": "^2.0.0", "@ai-sdk/provider": "^3.0.0", "@ai-sdk/provider-utils": "^4.0.0", "ai": "^6.0.0" } }, "sha512-krGNnJSoO/gJ7Hbe5nQDlsBpDUGIBGtMQTRUaW7s1MylsfvLduba0TLWzQaGtOmNRkP0pGhtGlwsnS6FNQMlyw=="], - "@volar/language-core": ["@volar/language-core@2.4.28", "", { "dependencies": { "@volar/source-map": "2.4.28" } }, "sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ=="], + "ajv": ["ajv@8.18.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A=="], - "@volar/language-server": ["@volar/language-server@2.4.28", "", { "dependencies": { "@volar/language-core": "2.4.28", "@volar/language-service": "2.4.28", "@volar/typescript": "2.4.28", "path-browserify": "^1.0.1", "request-light": "^0.7.0", "vscode-languageserver": "^9.0.1", "vscode-languageserver-protocol": "^3.17.5", "vscode-languageserver-textdocument": "^1.0.11", "vscode-uri": "^3.0.8" } }, "sha512-NqcLnE5gERKuS4PUFwlhMxf6vqYo7hXtbMFbViXcbVkbZ905AIVWhnSo0ZNBC2V127H1/2zP7RvVOVnyITFfBw=="], + "ajv-formats": ["ajv-formats@3.0.1", "", { "dependencies": { "ajv": "^8.0.0" } }, "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ=="], - "@volar/language-service": ["@volar/language-service@2.4.28", "", { "dependencies": { "@volar/language-core": "2.4.28", "vscode-languageserver-protocol": "^3.17.5", "vscode-languageserver-textdocument": "^1.0.11", "vscode-uri": "^3.0.8" } }, "sha512-Rh/wYCZJrI5vCwMk9xyw/Z+MsWxlJY1rmMZPsxUoJKfzIRjS/NF1NmnuEcrMbEVGja00aVpCsInJfixQTMdvLw=="], + "ansi-colors": ["ansi-colors@4.1.3", "", {}, "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw=="], - "@volar/source-map": ["@volar/source-map@2.4.28", "", {}, "sha512-yX2BDBqJkRXfKw8my8VarTyjv48QwxdJtvRgUpNE5erCsgEUdI2DsLbpa+rOQVAJYshY99szEcRDmyHbF10ggQ=="], + "ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], - "@volar/typescript": ["@volar/typescript@2.4.28", "", { "dependencies": { "@volar/language-core": "2.4.28", "path-browserify": "^1.0.1", "vscode-uri": "^3.0.8" } }, "sha512-Ja6yvWrbis2QtN4ClAKreeUZPVYMARDYZl9LMEv1iQ1QdepB6wn0jTRxA9MftYmYa4DQ4k/DaSZpFPUfxl8giw=="], + "ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], - "@vscode/emmet-helper": ["@vscode/emmet-helper@2.11.0", "", { "dependencies": { "emmet": "^2.4.3", "jsonc-parser": "^2.3.0", "vscode-languageserver-textdocument": "^1.0.1", "vscode-languageserver-types": "^3.15.1", "vscode-uri": "^3.0.8" } }, "sha512-QLxjQR3imPZPQltfbWRnHU6JecWTF1QSWhx3GAKQpslx7y3Dp6sIIXhKjiUJ/BR9FX8PVthjr9PD6pNwOJfAzw=="], + "any-base": ["any-base@1.1.0", "", {}, "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg=="], - "@vscode/l10n": ["@vscode/l10n@0.0.18", "", {}, "sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ=="], + "archiver": ["archiver@7.0.1", "", { "dependencies": { "archiver-utils": "^5.0.2", "async": "^3.2.4", "buffer-crc32": "^1.0.0", "readable-stream": "^4.0.0", "readdir-glob": "^1.1.2", "tar-stream": "^3.0.0", "zip-stream": "^6.0.1" } }, "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ=="], - "@webcontainer/env": ["@webcontainer/env@1.1.1", "", {}, "sha512-6aN99yL695Hi9SuIk1oC88l9o0gmxL1nGWWQ/kNy81HigJ0FoaoTXpytCj6ItzgyCEwA9kF1wixsTuv5cjsgng=="], + "archiver-utils": ["archiver-utils@5.0.2", "", { "dependencies": { "glob": "^10.0.0", "graceful-fs": "^4.2.0", "is-stream": "^2.0.1", "lazystream": "^1.0.0", "lodash": "^4.17.15", "normalize-path": "^3.0.0", "readable-stream": "^4.0.0" } }, "sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA=="], - "@webgpu/types": ["@webgpu/types@0.1.54", "", {}, "sha512-81oaalC8LFrXjhsczomEQ0u3jG+TqE6V9QHLA8GNZq/Rnot0KDugu3LhSYSlie8tSdooAN1Hov05asrUUp9qgg=="], + "arctic": ["arctic@2.3.4", "", { "dependencies": { "@oslojs/crypto": "1.0.1", "@oslojs/encoding": "1.1.0", "@oslojs/jwt": "0.2.0" } }, "sha512-+p30BOWsctZp+CVYCt7oAean/hWGW42sH5LAcRQX56ttEkFJWbzXBhmSpibbzwSJkRrotmsA+oAoJoVsU0f5xA=="], - "@xmldom/xmldom": ["@xmldom/xmldom@0.8.12", "", {}, "sha512-9k/gHF6n/pAi/9tqr3m3aqkuiNosYTurLLUtc7xQ9sxB/wm7WPygCv8GYa6mS0fLJEHhqMC1ATYhz++U/lRHqg=="], + "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], - "@zip.js/zip.js": ["@zip.js/zip.js@2.7.62", "", {}, "sha512-OaLvZ8j4gCkLn048ypkZu29KX30r8/OfFF2w4Jo5WXFr+J04J+lzJ5TKZBVgFXhlvSkqNFQdfnY1Q8TMTCyBVA=="], - - "abbrev": ["abbrev@4.0.0", "", {}, "sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA=="], - - "abort-controller": ["abort-controller@3.0.0", "", { "dependencies": { "event-target-shim": "^5.0.0" } }, "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg=="], - - "abstract-logging": ["abstract-logging@2.0.1", "", {}, "sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA=="], - - "accepts": ["accepts@1.3.8", "", { "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" } }, "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw=="], - - "acorn": ["acorn@8.16.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw=="], - - "acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="], - - "acorn-walk": ["acorn-walk@8.3.2", "", {}, "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A=="], - - "agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], - - "agentkeepalive": ["agentkeepalive@4.6.0", "", { "dependencies": { "humanize-ms": "^1.2.1" } }, "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ=="], - - "ai": ["ai@6.0.168", "", { "dependencies": { "@ai-sdk/gateway": "3.0.104", "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.23", "@opentelemetry/api": "1.9.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-2HqCJuO+1V2aV7vfYs5LFEUfxbkGX+5oa54q/gCCTL7KLTdbxcCu5D7TdLA5kwsrs3Szgjah9q6D9tpjHM3hUQ=="], - - "ai-gateway-provider": ["ai-gateway-provider@3.1.2", "", { "optionalDependencies": { "@ai-sdk/amazon-bedrock": "^4.0.62", "@ai-sdk/anthropic": "^3.0.46", "@ai-sdk/azure": "^3.0.31", "@ai-sdk/cerebras": "^2.0.34", "@ai-sdk/cohere": "^3.0.21", "@ai-sdk/deepgram": "^2.0.20", "@ai-sdk/deepseek": "^2.0.20", "@ai-sdk/elevenlabs": "^2.0.20", "@ai-sdk/fireworks": "^2.0.34", "@ai-sdk/google": "^3.0.30", "@ai-sdk/google-vertex": "^4.0.61", "@ai-sdk/groq": "^3.0.24", "@ai-sdk/mistral": "^3.0.20", "@ai-sdk/openai": "^3.0.30", "@ai-sdk/perplexity": "^3.0.19", "@ai-sdk/xai": "^3.0.57", "@openrouter/ai-sdk-provider": "^2.2.3" }, "peerDependencies": { "@ai-sdk/openai-compatible": "^2.0.0", "@ai-sdk/provider": "^3.0.0", "@ai-sdk/provider-utils": "^4.0.0", "ai": "^6.0.0" } }, "sha512-krGNnJSoO/gJ7Hbe5nQDlsBpDUGIBGtMQTRUaW7s1MylsfvLduba0TLWzQaGtOmNRkP0pGhtGlwsnS6FNQMlyw=="], - - "ajv": ["ajv@8.18.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A=="], - - "ajv-draft-04": ["ajv-draft-04@1.0.0", "", { "peerDependencies": { "ajv": "^8.5.0" }, "optionalPeers": ["ajv"] }, "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw=="], - - "ajv-formats": ["ajv-formats@3.0.1", "", { "dependencies": { "ajv": "^8.0.0" } }, "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ=="], - - "ajv-keywords": ["ajv-keywords@3.5.2", "", { "peerDependencies": { "ajv": "^6.9.1" } }, "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ=="], - - "ansi-align": ["ansi-align@3.0.1", "", { "dependencies": { "string-width": "^4.1.0" } }, "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w=="], - - "ansi-colors": ["ansi-colors@4.1.3", "", {}, "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw=="], - - "ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], - - "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], - - "ansis": ["ansis@4.2.0", "", {}, "sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig=="], - - "any-base": ["any-base@1.1.0", "", {}, "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg=="], - - "any-promise": ["any-promise@1.3.0", "", {}, "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="], - - "anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="], - - "app-builder-bin": ["app-builder-bin@5.0.0-alpha.12", "", {}, "sha512-j87o0j6LqPL3QRr8yid6c+Tt5gC7xNfYo6uQIQkorAC6MpeayVMZrEDzKmJJ/Hlv7EnOQpaRm53k6ktDYZyB6w=="], - - "app-builder-lib": ["app-builder-lib@26.8.1", "", { "dependencies": { "@develar/schema-utils": "~2.6.5", "@electron/asar": "3.4.1", "@electron/fuses": "^1.8.0", "@electron/get": "^3.0.0", "@electron/notarize": "2.5.0", "@electron/osx-sign": "1.3.3", "@electron/rebuild": "^4.0.3", "@electron/universal": "2.0.3", "@malept/flatpak-bundler": "^0.4.0", "@types/fs-extra": "9.0.13", "async-exit-hook": "^2.0.1", "builder-util": "26.8.1", "builder-util-runtime": "9.5.1", "chromium-pickle-js": "^0.2.0", "ci-info": "4.3.1", "debug": "^4.3.4", "dotenv": "^16.4.5", "dotenv-expand": "^11.0.6", "ejs": "^3.1.8", "electron-publish": "26.8.1", "fs-extra": "^10.1.0", "hosted-git-info": "^4.1.0", "isbinaryfile": "^5.0.0", "jiti": "^2.4.2", "js-yaml": "^4.1.0", "json5": "^2.2.3", "lazy-val": "^1.0.5", "minimatch": "^10.0.3", "plist": "3.1.0", "proper-lockfile": "^4.1.2", "resedit": "^1.7.0", "semver": "~7.7.3", "tar": "^7.5.7", "temp-file": "^3.4.0", "tiny-async-pool": "1.3.0", "which": "^5.0.0" }, "peerDependencies": { "dmg-builder": "26.8.1", "electron-builder-squirrel-windows": "26.8.1" } }, "sha512-p0Im/Dx5C4tmz8QEE1Yn4MkuPC8PrnlRneMhWJj7BBXQfNTJUshM/bp3lusdEsDbvvfJZpXWnYesgSLvwtM2Zw=="], - - "archiver": ["archiver@7.0.1", "", { "dependencies": { "archiver-utils": "^5.0.2", "async": "^3.2.4", "buffer-crc32": "^1.0.0", "readable-stream": "^4.0.0", "readdir-glob": "^1.1.2", "tar-stream": "^3.0.0", "zip-stream": "^6.0.1" } }, "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ=="], - - "archiver-utils": ["archiver-utils@5.0.2", "", { "dependencies": { "glob": "^10.0.0", "graceful-fs": "^4.2.0", "is-stream": "^2.0.1", "lazystream": "^1.0.0", "lodash": "^4.17.15", "normalize-path": "^3.0.0", "readable-stream": "^4.0.0" } }, "sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA=="], - - "arctic": ["arctic@2.3.4", "", { "dependencies": { "@oslojs/crypto": "1.0.1", "@oslojs/encoding": "1.1.0", "@oslojs/jwt": "0.2.0" } }, "sha512-+p30BOWsctZp+CVYCt7oAean/hWGW42sH5LAcRQX56ttEkFJWbzXBhmSpibbzwSJkRrotmsA+oAoJoVsU0f5xA=="], - - "arg": ["arg@5.0.2", "", {}, "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="], - - "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], - - "aria-hidden": ["aria-hidden@1.2.6", "", { "dependencies": { "tslib": "^2.0.0" } }, "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA=="], - - "aria-query": ["aria-query@5.3.2", "", {}, "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="], - - "array-buffer-byte-length": ["array-buffer-byte-length@1.0.2", "", { "dependencies": { "call-bound": "^1.0.3", "is-array-buffer": "^3.0.5" } }, "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw=="], - - "array-flatten": ["array-flatten@1.1.1", "", {}, "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="], - - "array-iterate": ["array-iterate@2.0.1", "", {}, "sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg=="], - - "array-union": ["array-union@2.1.0", "", {}, "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw=="], - - "array.prototype.map": ["array.prototype.map@1.0.8", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-abstract": "^1.23.6", "es-array-method-boxes-properly": "^1.0.0", "es-object-atoms": "^1.0.0", "is-string": "^1.1.1" } }, "sha512-YocPM7bYYu2hXGxWpb5vwZ8cMeudNHYtYBcUDY4Z1GWa53qcnQMWSl25jeBHNzitjl9HW2AWW4ro/S/nftUaOQ=="], - - "arraybuffer.prototype.slice": ["arraybuffer.prototype.slice@1.0.4", "", { "dependencies": { "array-buffer-byte-length": "^1.0.1", "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.5", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "is-array-buffer": "^3.0.4" } }, "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ=="], - - "assert-plus": ["assert-plus@1.0.0", "", {}, "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw=="], - - "assertion-error": ["assertion-error@2.0.1", "", {}, "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA=="], - - "ast-types": ["ast-types@0.16.1", "", { "dependencies": { "tslib": "^2.0.1" } }, "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg=="], - - "astral-regex": ["astral-regex@2.0.0", "", {}, "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ=="], - - "astring": ["astring@1.9.0", "", { "bin": { "astring": "bin/astring" } }, "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg=="], - - "astro": ["astro@5.7.13", "", { "dependencies": { "@astrojs/compiler": "^2.11.0", "@astrojs/internal-helpers": "0.6.1", "@astrojs/markdown-remark": "6.3.1", "@astrojs/telemetry": "3.2.1", "@capsizecss/unpack": "^2.4.0", "@oslojs/encoding": "^1.1.0", "@rollup/pluginutils": "^5.1.4", "acorn": "^8.14.1", "aria-query": "^5.3.2", "axobject-query": "^4.1.0", "boxen": "8.0.1", "ci-info": "^4.2.0", "clsx": "^2.1.1", "common-ancestor-path": "^1.0.1", "cookie": "^1.0.2", "cssesc": "^3.0.0", "debug": "^4.4.0", "deterministic-object-hash": "^2.0.2", "devalue": "^5.1.1", "diff": "^5.2.0", "dlv": "^1.1.3", "dset": "^3.1.4", "es-module-lexer": "^1.6.0", "esbuild": "^0.25.0", "estree-walker": "^3.0.3", "flattie": "^1.1.1", "fontace": "~0.3.0", "github-slugger": "^2.0.0", "html-escaper": "3.0.3", "http-cache-semantics": "^4.1.1", "js-yaml": "^4.1.0", "kleur": "^4.1.5", "magic-string": "^0.30.17", "magicast": "^0.3.5", "mrmime": "^2.0.1", "neotraverse": "^0.6.18", "p-limit": "^6.2.0", "p-queue": "^8.1.0", "package-manager-detector": "^1.1.0", "picomatch": "^4.0.2", "prompts": "^2.4.2", "rehype": "^13.0.2", "semver": "^7.7.1", "shiki": "^3.2.1", "tinyexec": "^0.3.2", "tinyglobby": "^0.2.12", "tsconfck": "^3.1.5", "ultrahtml": "^1.6.0", "unifont": "~0.5.0", "unist-util-visit": "^5.0.0", "unstorage": "^1.15.0", "vfile": "^6.0.3", "vite": "^6.3.4", "vitefu": "^1.0.6", "xxhash-wasm": "^1.1.0", "yargs-parser": "^21.1.1", "yocto-spinner": "^0.2.1", "zod": "^3.24.2", "zod-to-json-schema": "^3.24.5", "zod-to-ts": "^1.2.0" }, "optionalDependencies": { "sharp": "^0.33.3" }, "bin": { "astro": "astro.js" } }, "sha512-cRGq2llKOhV3XMcYwQpfBIUcssN6HEK5CRbcMxAfd9OcFhvWE7KUy50zLioAZVVl3AqgUTJoNTlmZfD2eG0G1w=="], - - "astro-expressive-code": ["astro-expressive-code@0.41.7", "", { "dependencies": { "rehype-expressive-code": "^0.41.7" }, "peerDependencies": { "astro": "^4.0.0-beta || ^5.0.0-beta || ^3.3.0 || ^6.0.0-beta" } }, "sha512-hUpogGc6DdAd+I7pPXsctyYPRBJDK7Q7d06s4cyP0Vz3OcbziP3FNzN0jZci1BpCvLn9675DvS7B9ctKKX64JQ=="], + "aria-query": ["aria-query@5.3.2", "", {}, "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="], "async": ["async@3.2.6", "", {}, "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA=="], - "async-exit-hook": ["async-exit-hook@2.0.1", "", {}, "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw=="], - - "async-function": ["async-function@1.0.0", "", {}, "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA=="], - "asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="], - "at-least-node": ["at-least-node@1.0.0", "", {}, "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg=="], - "atomic-sleep": ["atomic-sleep@1.0.0", "", {}, "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ=="], - "atomically": ["atomically@2.1.1", "", { "dependencies": { "stubborn-fs": "^2.0.0", "when-exit": "^2.1.4" } }, "sha512-P4w9o2dqARji6P7MHprklbfiArZAWvo07yW7qs3pdljb3BWr12FIB7W+p0zJiuiVsUpRO0iZn1kFFcpPegg0tQ=="], - - "autoprefixer": ["autoprefixer@10.5.0", "", { "dependencies": { "browserslist": "^4.28.2", "caniuse-lite": "^1.0.30001787", "fraction.js": "^5.3.4", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.1.0" }, "bin": { "autoprefixer": "bin/autoprefixer" } }, "sha512-FMhOoZV4+qR6aTUALKX2rEqGG+oyATvwBt9IIzVR5rMa2HRWPkxf+P+PAJLD1I/H5/II+HuZcBJYEFBpq39ong=="], - "available-typed-arrays": ["available-typed-arrays@1.0.7", "", { "dependencies": { "possible-typed-array-names": "^1.0.0" } }, "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ=="], "avvio": ["avvio@9.2.0", "", { "dependencies": { "@fastify/error": "^4.0.0", "fastq": "^1.17.1" } }, "sha512-2t/sy01ArdHHE0vRH5Hsay+RtCZt3dLPji7W7/MMOCEgze5b7SNDC4j5H6FnVgPkI1MTNFGzHdHrVXDDl7QSSQ=="], @@ -2595,28 +1678,18 @@ "aws-sdk": ["aws-sdk@2.1692.0", "", { "dependencies": { "buffer": "4.9.2", "events": "1.1.1", "ieee754": "1.1.13", "jmespath": "0.16.0", "querystring": "0.2.0", "sax": "1.2.1", "url": "0.10.3", "util": "^0.12.4", "uuid": "8.0.0", "xml2js": "0.6.2" } }, "sha512-x511uiJ/57FIsbgUe5csJ13k3uzu25uWQE+XqfBis/sB0SFoiElJWXRkgEAUh0U6n40eT3ay5Ue4oPkRMu1LYw=="], - "aws-ssl-profiles": ["aws-ssl-profiles@1.1.2", "", {}, "sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g=="], + "aws4fetch": ["aws4fetch@1.0.18", "", {}, "sha512-3Cf+YaUl07p24MoQ46rFwulAmiyCwH2+1zw1ZyPAX5OtJ34Hh185DwB8y/qRLb6cYYYtSFJ9pthyLc0MD4e8sQ=="], - "aws4fetch": ["aws4fetch@1.0.20", "", {}, "sha512-/djoAN709iY65ETD6LKCtyyEI04XIBP5xVvfmNxsEP0uJB5tyaGBztSryRr4HqMStr9R06PisQE7m9zDTXKu6g=="], - - "axe-core": ["axe-core@4.11.3", "", {}, "sha512-zBQouZixDTbo3jMGqHKyePxYxr1e5W8UdTmBQ7sNtaA9M2bE32daxxPLS/jojhKOHxQ7LWwPjfiwf/fhaJWzlg=="], - - "axios": ["axios@1.15.0", "", { "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", "proxy-from-env": "^2.1.0" } }, "sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q=="], - - "axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="], + "axios": ["axios@1.18.0", "", { "dependencies": { "follow-redirects": "^1.16.0", "form-data": "^4.0.5", "https-proxy-agent": "^5.0.1", "proxy-from-env": "^2.1.0" } }, "sha512-E32NzpYKp++W7XRe52rHiXV2ehxmh3wbdgO7MHeFM+vqxLBYHzt0ElkiImtOBxtOmyp0yoC8C6uESVV84Y2/hw=="], "b4a": ["b4a@1.8.0", "", { "peerDependencies": { "react-native-b4a": "*" }, "optionalPeers": ["react-native-b4a"] }, "sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg=="], - "babel-dead-code-elimination": ["babel-dead-code-elimination@1.0.12", "", { "dependencies": { "@babel/core": "^7.23.7", "@babel/parser": "^7.23.6", "@babel/traverse": "^7.23.7", "@babel/types": "^7.23.6" } }, "sha512-GERT7L2TiYcYDtYk1IpD+ASAYXjKbLTDPhBtYj7X1NuRMDTMtAx9kyBenub1Ev41lo91OHCKdmP+egTDmfQ7Ig=="], - "babel-plugin-jsx-dom-expressions": ["babel-plugin-jsx-dom-expressions@0.40.6", "", { "dependencies": { "@babel/helper-module-imports": "7.18.6", "@babel/plugin-syntax-jsx": "^7.18.6", "@babel/types": "^7.20.7", "html-entities": "2.3.3", "parse5": "^7.1.2" }, "peerDependencies": { "@babel/core": "^7.20.12" } }, "sha512-v3P1MW46Lm7VMpAkq0QfyzLWWkC8fh+0aE5Km4msIgDx5kjenHU0pF2s+4/NH8CQn/kla6+Hvws+2AF7bfV5qQ=="], "babel-plugin-module-resolver": ["babel-plugin-module-resolver@5.0.2", "", { "dependencies": { "find-babel-config": "^2.1.1", "glob": "^9.3.3", "pkg-up": "^3.1.0", "reselect": "^4.1.7", "resolve": "^1.22.8" } }, "sha512-9KtaCazHee2xc0ibfqsDeamwDps6FZNo5S0Q81dUqEuFzVwPhcT4J5jOqIVvgCA3Q/wO9hKYxN/Ds3tIsp5ygg=="], "babel-preset-solid": ["babel-preset-solid@1.9.12", "", { "dependencies": { "babel-plugin-jsx-dom-expressions": "^0.40.6" }, "peerDependencies": { "@babel/core": "^7.0.0", "solid-js": "^1.9.12" }, "optionalPeers": ["solid-js"] }, "sha512-LLqnuKVDlKpyBlMPcH6qEvs/wmS9a+NczppxJ3ryS/c0O5IiSFOIBQi9GzyiGDSbcJpx4Gr87jyFTos1MyEuWg=="], - "bail": ["bail@2.0.2", "", {}, "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw=="], - "balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], "bare-events": ["bare-events@2.8.2", "", { "peerDependencies": { "bare-abort-controller": "*" }, "optionalPeers": ["bare-abort-controller"] }, "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ=="], @@ -2631,15 +1704,9 @@ "bare-url": ["bare-url@2.4.0", "", { "dependencies": { "bare-path": "^3.0.0" } }, "sha512-NSTU5WN+fy/L0DDenfE8SXQna4voXuW0FHM7wH8i3/q9khUSchfPbPezO4zSFMnDGIf9YE+mt/RWhZgNRKRIXA=="], - "base-64": ["base-64@1.0.0", "", {}, "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg=="], - "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="], - "baseline-browser-mapping": ["baseline-browser-mapping@2.10.19", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-qCkNLi2sfBOn8XhZQ0FXsT1Ki/Yo5P90hrkRamVFRS7/KV9hpfA4HkoWNU152+8w0zPjnxo5psx5NL3PSGgv5g=="], - - "bcp-47": ["bcp-47@2.1.0", "", { "dependencies": { "is-alphabetical": "^2.0.0", "is-alphanumerical": "^2.0.0", "is-decimal": "^2.0.0" } }, "sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w=="], - - "bcp-47-match": ["bcp-47-match@2.0.3", "", {}, "sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ=="], + "baseline-browser-mapping": ["baseline-browser-mapping@2.11.19", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-Grytf1xOxOEMTGRwx6rLGKkTabd4vMg3VrKdj/7joCmV0qgh4QwMMO6xh34YEXQqirAuUdgQGa5orJQQ+69RBw=="], "before-after-hook": ["before-after-hook@2.2.3", "", {}, "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ=="], @@ -2649,37 +1716,25 @@ "binary": ["binary@0.3.0", "", { "dependencies": { "buffers": "~0.1.1", "chainsaw": "~0.1.0" } }, "sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg=="], - "binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="], - "bl": ["bl@6.1.6", "", { "dependencies": { "@types/readable-stream": "^4.0.0", "buffer": "^6.0.3", "inherits": "^2.0.4", "readable-stream": "^4.2.0" } }, "sha512-jLsPgN/YSvPUg9UX0Kd73CXpm2Psg9FxMeCSXnk3WBO3CMT10JMwijubhGfHCnFu6TPn1ei3b975dxv7K2pWVg=="], - "blake3-wasm": ["blake3-wasm@2.1.5", "", {}, "sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g=="], - - "blob-to-buffer": ["blob-to-buffer@1.2.9", "", {}, "sha512-BF033y5fN6OCofD3vgHmNtwZWRcq9NLyyxyILx9hfMy1sXYy4ojFl765hJ2lP0YaN2fuxPaLO2Vzzoxy0FLFFA=="], - "bmp-ts": ["bmp-ts@1.0.9", "", {}, "sha512-cTEHk2jLrPyi+12M3dhpEbnnPOsaZuq7C45ylbbQIiWgDFZq4UVYPEY5mlqjvsj/6gJv9qX5sa+ebDzLXT28Vw=="], - "body-parser": ["body-parser@1.20.4", "", { "dependencies": { "bytes": "~3.1.2", "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "~1.2.0", "http-errors": "~2.0.1", "iconv-lite": "~0.4.24", "on-finished": "~2.4.1", "qs": "~6.14.0", "raw-body": "~2.5.3", "type-is": "~1.6.18", "unpipe": "~1.0.0" } }, "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA=="], + "body-parser": ["body-parser@2.3.0", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^2.0.0", "debug": "^4.4.3", "http-errors": "^2.0.1", "iconv-lite": "^0.7.2", "on-finished": "^2.4.1", "qs": "^6.15.2", "raw-body": "^3.0.2", "type-is": "^2.1.0" } }, "sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw=="], "bonjour-service": ["bonjour-service@1.3.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "multicast-dns": "^7.2.5" } }, "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA=="], "boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="], - "boolean": ["boolean@3.2.0", "", {}, "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw=="], - "bottleneck": ["bottleneck@2.19.5", "", {}, "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw=="], "bowser": ["bowser@2.14.1", "", {}, "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg=="], - "boxen": ["boxen@8.0.1", "", { "dependencies": { "ansi-align": "^3.0.1", "camelcase": "^8.0.0", "chalk": "^5.3.0", "cli-boxes": "^3.0.0", "string-width": "^7.2.0", "type-fest": "^4.21.0", "widest-line": "^5.0.0", "wrap-ansi": "^9.0.0" } }, "sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw=="], - - "brace-expansion": ["brace-expansion@5.0.5", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ=="], + "brace-expansion": ["brace-expansion@5.0.9", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg=="], "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], - "brotli": ["brotli@1.3.3", "", { "dependencies": { "base64-js": "^1.1.2" } }, "sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg=="], - - "browserslist": ["browserslist@4.28.2", "", { "dependencies": { "baseline-browser-mapping": "^2.10.12", "caniuse-lite": "^1.0.30001782", "electron-to-chromium": "^1.5.328", "node-releases": "^2.0.36", "update-browserslist-db": "^1.2.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg=="], + "browserslist": ["browserslist@4.28.7", "", { "dependencies": { "baseline-browser-mapping": "^2.10.44", "caniuse-lite": "^1.0.30001806", "electron-to-chromium": "^1.5.393", "node-releases": "^2.0.51", "update-browserslist-db": "^1.2.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-JxV13hNrFxqjOc8alRbq9dK1MM79NEXYpma2B2J4wAtpWS5zIEIKqWPGCl7N4o7Uc7B7itylh7SuDujATRyyTw=="], "buffer": ["buffer@4.9.2", "", { "dependencies": { "base64-js": "^1.0.2", "ieee754": "^1.1.4", "isarray": "^1.0.0" } }, "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg=="], @@ -2687,14 +1742,8 @@ "buffer-equal-constant-time": ["buffer-equal-constant-time@1.0.1", "", {}, "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="], - "buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="], - "buffers": ["buffers@0.1.1", "", {}, "sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ=="], - "builder-util": ["builder-util@26.8.1", "", { "dependencies": { "7zip-bin": "~5.2.0", "@types/debug": "^4.1.6", "app-builder-bin": "5.0.0-alpha.12", "builder-util-runtime": "9.5.1", "chalk": "^4.1.2", "cross-spawn": "^7.0.6", "debug": "^4.3.4", "fs-extra": "^10.1.0", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.0", "js-yaml": "^4.1.0", "sanitize-filename": "^1.6.3", "source-map-support": "^0.5.19", "stat-mode": "^1.0.0", "temp-file": "^3.4.0", "tiny-async-pool": "1.3.0" } }, "sha512-pm1lTYbGyc90DHgCDO7eo8Rl4EqKLciayNbZqGziqnH9jrlKe8ZANGdityLZU+pJh16dfzjAx2xQq9McuIPEtw=="], - - "builder-util-runtime": ["builder-util-runtime@9.5.1", "", { "dependencies": { "debug": "^4.3.4", "sax": "^1.2.4" } }, "sha512-qt41tMfgHTllhResqM5DcnHyDIWNgzHvuY2jDcYP9iaGpkWxTUzV6GQjDeLnlR1/DtdlcsWQbA7sByMpmJFTLQ=="], - "bun-ffi-structs": ["bun-ffi-structs@0.2.2", "", { "peerDependencies": { "typescript": "^5" } }, "sha512-N/ZWtyN0piZlrXQT7TO0V+q952orYqkfhXRXM1Hcbb+R3QSiBH4vLnib187Mrs1H7pWIYECAmPeapGYDOMCl+w=="], "bun-pty": ["bun-pty@0.4.8", "", {}, "sha512-rO70Mrbr13+jxHHHu2YBkk2pNqrJE5cJn29WE++PUr+GFA0hq/VgtQPZANJ8dJo6d7XImvBk37Innt8GM7O28w=="], @@ -2715,166 +1764,88 @@ "bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="], - "c12": ["c12@3.3.3", "", { "dependencies": { "chokidar": "^5.0.0", "confbox": "^0.2.2", "defu": "^6.1.4", "dotenv": "^17.2.3", "exsolve": "^1.0.8", "giget": "^2.0.0", "jiti": "^2.6.1", "ohash": "^2.0.11", "pathe": "^2.0.3", "perfect-debounce": "^2.0.0", "pkg-types": "^2.3.0", "rc9": "^2.1.2" }, "peerDependencies": { "magicast": "*" }, "optionalPeers": ["magicast"] }, "sha512-750hTRvgBy5kcMNPdh95Qo+XUBeGo8C7nsKSmedDmaQI+E0r82DwHeM6vBewDe4rGFbnxoa4V9pw+sPh5+Iz8Q=="], - - "cac": ["cac@6.7.14", "", {}, "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ=="], + "c12": ["c12@3.3.4", "", { "dependencies": { "chokidar": "^5.0.0", "confbox": "^0.2.4", "defu": "^6.1.6", "dotenv": "^17.3.1", "exsolve": "^1.0.8", "giget": "^3.2.0", "jiti": "^2.6.1", "ohash": "^2.0.11", "pathe": "^2.0.3", "perfect-debounce": "^2.1.0", "pkg-types": "^2.3.0", "rc9": "^3.0.1" }, "peerDependencies": { "magicast": "*" }, "optionalPeers": ["magicast"] }, "sha512-cM0ApFQSBXuourJejzwv/AuPRvAxordTyParRVcHjjtXirtkzM0uK2L9TTn9s0cXZbG7E55jCivRQzoxYmRAlA=="], "cacache": ["cacache@20.0.4", "", { "dependencies": { "@npmcli/fs": "^5.0.0", "fs-minipass": "^3.0.0", "glob": "^13.0.0", "lru-cache": "^11.1.0", "minipass": "^7.0.3", "minipass-collect": "^2.0.1", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "p-map": "^7.0.2", "ssri": "^13.0.0" } }, "sha512-M3Lab8NPYlZU2exsL3bMVvMrMqgwCnMWfdZbK28bn3pK6APT/Te/I8hjRPNu1uwORY9a1eEQoifXbKPQMfMTOA=="], - "cacheable-lookup": ["cacheable-lookup@5.0.4", "", {}, "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA=="], - - "cacheable-request": ["cacheable-request@7.0.4", "", { "dependencies": { "clone-response": "^1.0.2", "get-stream": "^5.1.0", "http-cache-semantics": "^4.0.0", "keyv": "^4.0.0", "lowercase-keys": "^2.0.0", "normalize-url": "^6.0.1", "responselike": "^2.0.0" } }, "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg=="], - "call-bind": ["call-bind@1.0.9", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "get-intrinsic": "^1.3.0", "set-function-length": "^1.2.2" } }, "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ=="], "call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="], "call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="], - "camel-case": ["camel-case@4.1.2", "", { "dependencies": { "pascal-case": "^3.1.2", "tslib": "^2.0.3" } }, "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw=="], - - "camelcase": ["camelcase@8.0.0", "", {}, "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA=="], - - "camelcase-css": ["camelcase-css@2.0.1", "", {}, "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA=="], - - "caniuse-lite": ["caniuse-lite@1.0.30001788", "", {}, "sha512-6q8HFp+lOQtcf7wBK+uEenxymVWkGKkjFpCvw5W25cmMwEDU45p1xQFBQv8JDlMMry7eNxyBaR+qxgmTUZkIRQ=="], + "caniuse-lite": ["caniuse-lite@1.0.30001810", "", {}, "sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg=="], "ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="], - "chai": ["chai@5.3.3", "", { "dependencies": { "assertion-error": "^2.0.1", "check-error": "^2.1.1", "deep-eql": "^5.0.1", "loupe": "^3.1.0", "pathval": "^2.0.0" } }, "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw=="], - "chainsaw": ["chainsaw@0.1.0", "", { "dependencies": { "traverse": ">=0.3.0 <0.4" } }, "sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ=="], "chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], - "character-entities": ["character-entities@2.0.2", "", {}, "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ=="], - "character-entities-html4": ["character-entities-html4@2.1.0", "", {}, "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA=="], "character-entities-legacy": ["character-entities-legacy@3.0.0", "", {}, "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ=="], - "character-reference-invalid": ["character-reference-invalid@2.0.1", "", {}, "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw=="], - - "chart.js": ["chart.js@4.5.1", "", { "dependencies": { "@kurkle/color": "^0.3.0" } }, "sha512-GIjfiT9dbmHRiYi6Nl2yFCq7kkwdkp1W/lp2J99rX0yo9tgJGn3lKQATztIjb5tVtevcBtIdICNWqlq5+E8/Pw=="], - - "check-error": ["check-error@2.1.3", "", {}, "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA=="], - - "cheerio": ["cheerio@1.0.0-rc.12", "", { "dependencies": { "cheerio-select": "^2.1.0", "dom-serializer": "^2.0.0", "domhandler": "^5.0.3", "domutils": "^3.0.1", "htmlparser2": "^8.0.1", "parse5": "^7.0.0", "parse5-htmlparser2-tree-adapter": "^7.0.0" } }, "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q=="], - - "cheerio-select": ["cheerio-select@2.1.0", "", { "dependencies": { "boolbase": "^1.0.0", "css-select": "^5.1.0", "css-what": "^6.1.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.0.1" } }, "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g=="], - "chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="], "chownr": ["chownr@3.0.0", "", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="], - "chromium-pickle-js": ["chromium-pickle-js@0.2.0", "", {}, "sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw=="], - "ci-info": ["ci-info@4.4.0", "", {}, "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg=="], - "citty": ["citty@0.1.6", "", { "dependencies": { "consola": "^3.2.3" } }, "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ=="], - - "classnames": ["classnames@2.3.2", "", {}, "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw=="], - - "clean-css": ["clean-css@5.3.3", "", { "dependencies": { "source-map": "~0.6.0" } }, "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg=="], - - "cli-boxes": ["cli-boxes@3.0.0", "", {}, "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g=="], - - "cli-cursor": ["cli-cursor@3.1.0", "", { "dependencies": { "restore-cursor": "^3.1.0" } }, "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw=="], - "cli-sound": ["cli-sound@1.1.3", "", { "dependencies": { "find-exec": "^1.0.3" }, "bin": { "cli-sound": "dist/esm/cli.js" } }, "sha512-dpdF3KS3wjo1fobKG5iU9KyKqzQWAqueymHzZ9epus/dZ40487gAvS6aXFeBul+GiQAQYUTAtUWgQvw6Jftbyg=="], "cli-spinners": ["cli-spinners@3.4.0", "", {}, "sha512-bXfOC4QcT1tKXGorxL3wbJm6XJPDqEnij2gQ2m7ESQuE+/z9YFIWnl/5RpTiKWbMq3EVKR4fRLJGn6DVfu0mpw=="], - "cli-truncate": ["cli-truncate@4.0.0", "", { "dependencies": { "slice-ansi": "^5.0.0", "string-width": "^7.0.0" } }, "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA=="], - "clipboardy": ["clipboardy@4.0.0", "", { "dependencies": { "execa": "^8.0.1", "is-wsl": "^3.1.0", "is64bit": "^2.0.0" } }, "sha512-5mOlNS0mhX0707P2I0aZ2V/cmHUEO/fL7VFLqszkhUsxt7RwnmrInf/eEQKlf5GzvYeHIjT+Ov1HRfNmymlG0w=="], "cliui": ["cliui@9.0.1", "", { "dependencies": { "string-width": "^7.2.0", "strip-ansi": "^7.1.0", "wrap-ansi": "^9.0.0" } }, "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w=="], - "clone": ["clone@2.1.2", "", {}, "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w=="], - - "clone-response": ["clone-response@1.0.3", "", { "dependencies": { "mimic-response": "^1.0.0" } }, "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA=="], - - "cloudflare": ["cloudflare@5.2.0", "", { "dependencies": { "@types/node": "^18.11.18", "@types/node-fetch": "^2.6.4", "abort-controller": "^3.0.0", "agentkeepalive": "^4.2.1", "form-data-encoder": "1.7.2", "formdata-node": "^4.3.2", "node-fetch": "^2.6.7" } }, "sha512-dVzqDpPFYR9ApEC9e+JJshFJZXcw4HzM8W+3DHzO5oy9+8rLC53G7x6fEf9A7/gSuSCxuvndzui5qJKftfIM9A=="], - - "clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="], - "cluster-key-slot": ["cluster-key-slot@1.1.2", "", {}, "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA=="], "cmd-shim": ["cmd-shim@8.0.0", "", {}, "sha512-Jk/BK6NCapZ58BKUxlSI+ouKRbjH1NLZCgJkYoab+vEHUY3f6OzpNBN9u7HFSv9J6TRDGs4PLOHezoKGaFRSCA=="], - "collapse-white-space": ["collapse-white-space@2.1.0", "", {}, "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw=="], - - "color": ["color@4.2.3", "", { "dependencies": { "color-convert": "^2.0.1", "color-string": "^1.9.0" } }, "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A=="], - "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], - "color-string": ["color-string@1.9.1", "", { "dependencies": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" } }, "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg=="], - "color-support": ["color-support@1.1.3", "", { "bin": { "color-support": "bin.js" } }, "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg=="], "combined-stream": ["combined-stream@1.0.8", "", { "dependencies": { "delayed-stream": "~1.0.0" } }, "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg=="], "comma-separated-tokens": ["comma-separated-tokens@2.0.3", "", {}, "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg=="], - "commander": ["commander@14.0.2", "", {}, "sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ=="], + "commander": ["commander@14.0.3", "", {}, "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw=="], "common-ancestor-path": ["common-ancestor-path@2.0.0", "", {}, "sha512-dnN3ibLeoRf2HNC+OlCiNc5d2zxbLJXOtiZUudNFSXZrNSydxcCsSpRzXwfu7BBWCIfHPw+xTayeBvJCP/D8Ng=="], - "compare-version": ["compare-version@0.1.2", "", {}, "sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A=="], - "compress-commons": ["compress-commons@6.0.2", "", { "dependencies": { "crc-32": "^1.2.0", "crc32-stream": "^6.0.0", "is-stream": "^2.0.1", "normalize-path": "^3.0.0", "readable-stream": "^4.0.0" } }, "sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg=="], - "concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="], - - "condense-newlines": ["condense-newlines@0.2.1", "", { "dependencies": { "extend-shallow": "^2.0.1", "is-whitespace": "^0.3.0", "kind-of": "^3.0.2" } }, "sha512-P7X+QL9Hb9B/c8HI5BFFKmjgBu2XpQuF98WZ9XkO+dBGgk5XgwiQz7o1SmpglNWId3581UcS0SFAWfoIhMHPfg=="], - - "conf": ["conf@14.0.0", "", { "dependencies": { "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "atomically": "^2.0.3", "debounce-fn": "^6.0.0", "dot-prop": "^9.0.0", "env-paths": "^3.0.0", "json-schema-typed": "^8.0.1", "semver": "^7.7.2", "uint8array-extras": "^1.4.0" } }, "sha512-L6BuueHTRuJHQvQVc6YXYZRtN5vJUtOdCTLn0tRYYV5azfbAFcPghB5zEE40mVrV6w7slMTqUfkDomutIK14fw=="], - "confbox": ["confbox@0.2.4", "", {}, "sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ=="], - "config-chain": ["config-chain@1.1.13", "", { "dependencies": { "ini": "^1.3.4", "proto-list": "~1.2.1" } }, "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ=="], - - "consola": ["consola@3.4.2", "", {}, "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA=="], - - "content-disposition": ["content-disposition@0.5.4", "", { "dependencies": { "safe-buffer": "5.2.1" } }, "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ=="], + "content-disposition": ["content-disposition@1.1.0", "", {}, "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g=="], "content-type": ["content-type@1.0.5", "", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="], "convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="], - "cookie": ["cookie@1.1.1", "", {}, "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ=="], + "cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="], - "cookie-es": ["cookie-es@2.0.1", "", {}, "sha512-aVf4A4hI2w70LnF7GG+7xDQUkliwiXWXFvTjkip4+b64ygDQ2sJPRSKFDHbxn8o0xu9QzPkMuuiWIXyFSE2slA=="], + "cookie-signature": ["cookie-signature@1.2.2", "", {}, "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg=="], - "cookie-signature": ["cookie-signature@1.0.7", "", {}, "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA=="], - - "core-util-is": ["core-util-is@1.0.2", "", {}, "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ=="], + "core-util-is": ["core-util-is@1.0.3", "", {}, "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="], "cors": ["cors@2.8.6", "", { "dependencies": { "object-assign": "^4", "vary": "^1" } }, "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw=="], - "crc": ["crc@3.8.0", "", { "dependencies": { "buffer": "^5.1.0" } }, "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ=="], - "crc-32": ["crc-32@1.2.2", "", { "bin": { "crc32": "bin/crc32.njs" } }, "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ=="], "crc32-stream": ["crc32-stream@6.0.0", "", { "dependencies": { "crc-32": "^1.2.0", "readable-stream": "^4.0.0" } }, "sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g=="], - "cross-dirname": ["cross-dirname@0.1.0", "", {}, "sha512-+R08/oI0nl3vfPcqftZRpytksBXDzOUveBq/NBVx0sUp1axwzPQrKinNx5yd5sxPu8j1wIy8AfnVQ+5eFdha6Q=="], - "cross-fetch": ["cross-fetch@3.2.0", "", { "dependencies": { "node-fetch": "^2.7.0" } }, "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q=="], "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], - "crossws": ["crossws@0.4.5", "", { "peerDependencies": { "srvx": ">=0.11.5" }, "optionalPeers": ["srvx"] }, "sha512-wUR89x/Rw7/8t+vn0CmGDYM9TD6VtARGb0LD5jq2wjtMy1vCP4M+sm6N6TigWeTYvnA8MoW29NqqXD0ep0rfBA=="], - "css-select": ["css-select@5.2.2", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw=="], - "css-selector-parser": ["css-selector-parser@3.3.0", "", {}, "sha512-Y2asgMGFqJKF4fq4xHDSlFYIkeVfRsm69lQC1q9kbEsH5XtnINTMrweLkjYMeaUgiXBy/uvKeO/a1JHTNnmB2g=="], - - "css-tree": ["css-tree@3.2.1", "", { "dependencies": { "mdn-data": "2.27.1", "source-map-js": "^1.2.1" } }, "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA=="], - "css-what": ["css-what@6.2.2", "", {}, "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA=="], "css.escape": ["css.escape@1.5.1", "", {}, "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg=="], @@ -2885,42 +1856,18 @@ "data-uri-to-buffer": ["data-uri-to-buffer@4.0.1", "", {}, "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A=="], - "data-view-buffer": ["data-view-buffer@1.0.2", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-data-view": "^1.0.2" } }, "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ=="], - - "data-view-byte-length": ["data-view-byte-length@1.0.2", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-data-view": "^1.0.2" } }, "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ=="], - - "data-view-byte-offset": ["data-view-byte-offset@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-data-view": "^1.0.1" } }, "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ=="], - - "db0": ["db0@0.3.4", "", { "peerDependencies": { "@electric-sql/pglite": "*", "@libsql/client": "*", "better-sqlite3": "*", "drizzle-orm": "*", "mysql2": "*", "sqlite3": "*" }, "optionalPeers": ["@electric-sql/pglite", "@libsql/client", "better-sqlite3", "drizzle-orm", "mysql2", "sqlite3"] }, "sha512-RiXXi4WaNzPTHEOu8UPQKMooIbqOEyqA1t7Z6MsdxSCeb8iUC9ko3LcmsLmeUt2SM5bctfArZKkRQggKZz7JNw=="], - - "debounce-fn": ["debounce-fn@6.0.0", "", { "dependencies": { "mimic-function": "^5.0.0" } }, "sha512-rBMW+F2TXryBwB54Q0d8drNEI+TfoS9JpNTAoVpukbWEhjXQq4rySFYLaqXMFXwdv61Zb2OHtj5bviSoimqxRQ=="], - "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], "decimal.js": ["decimal.js@10.5.0", "", {}, "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw=="], - "decode-named-character-reference": ["decode-named-character-reference@1.3.0", "", { "dependencies": { "character-entities": "^2.0.0" } }, "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q=="], - - "decompress-response": ["decompress-response@6.0.0", "", { "dependencies": { "mimic-response": "^3.1.0" } }, "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ=="], - - "deep-eql": ["deep-eql@5.0.2", "", {}, "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q=="], - - "deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="], - "default-browser": ["default-browser@5.5.0", "", { "dependencies": { "bundle-name": "^4.1.0", "default-browser-id": "^5.0.0" } }, "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw=="], "default-browser-id": ["default-browser-id@5.0.1", "", {}, "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q=="], - "defaults": ["defaults@1.0.4", "", { "dependencies": { "clone": "^1.0.2" } }, "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A=="], - - "defer-to-connect": ["defer-to-connect@2.0.1", "", {}, "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg=="], - "define-data-property": ["define-data-property@1.1.4", "", { "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "gopd": "^1.0.1" } }, "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A=="], "define-lazy-prop": ["define-lazy-prop@3.0.0", "", {}, "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg=="], - "define-properties": ["define-properties@1.2.1", "", { "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" } }, "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg=="], - "defu": ["defu@6.1.7", "", {}, "sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ=="], "delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="], @@ -2935,37 +1882,11 @@ "destr": ["destr@2.0.5", "", {}, "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA=="], - "destroy": ["destroy@1.2.0", "", {}, "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="], - "detect-libc": ["detect-libc@1.0.3", "", { "bin": { "detect-libc": "./bin/detect-libc.js" } }, "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg=="], - "detect-node": ["detect-node@2.1.0", "", {}, "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g=="], - - "detect-node-es": ["detect-node-es@1.1.0", "", {}, "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="], - - "deterministic-object-hash": ["deterministic-object-hash@2.0.2", "", { "dependencies": { "base-64": "^1.0.0" } }, "sha512-KxektNH63SrbfUyDiwXqRb1rLwKt33AmMv+5Nhsw1kqZ13SJBRTgZHtGbE+hH3a1mVW1cz+4pqSWVPAtLVXTzQ=="], - - "devalue": ["devalue@5.7.1", "", {}, "sha512-MUbZ586EgQqdRnC4yDrlod3BEdyvE4TapGYHMW2CiaW+KkkFmWEFqBUaLltEZCGi0iFXCEjRF0OjF0DV2QHjOA=="], - "devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="], - "dfa": ["dfa@1.2.0", "", {}, "sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q=="], - - "didyoumean": ["didyoumean@1.2.2", "", {}, "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw=="], - - "diff": ["diff@8.0.2", "", {}, "sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg=="], - - "dir-compare": ["dir-compare@4.2.0", "", { "dependencies": { "minimatch": "^3.0.5", "p-limit": "^3.1.0 " } }, "sha512-2xMCmOoMrdQIPHdsTawECdNPwlVFB9zGcz3kuhmBO6U3oU+UQjsue0i8ayLKpgBcm+hcXPMVSGUN9d+pvJ6+VQ=="], - - "dir-glob": ["dir-glob@3.0.1", "", { "dependencies": { "path-type": "^4.0.0" } }, "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA=="], - - "direction": ["direction@2.0.1", "", { "bin": { "direction": "cli.js" } }, "sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA=="], - - "dlv": ["dlv@1.1.3", "", {}, "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="], - - "dmg-builder": ["dmg-builder@26.8.1", "", { "dependencies": { "app-builder-lib": "26.8.1", "builder-util": "26.8.1", "fs-extra": "^10.1.0", "iconv-lite": "^0.6.2", "js-yaml": "^4.1.0" }, "optionalDependencies": { "dmg-license": "^1.0.11" } }, "sha512-glMJgnTreo8CFINujtAhCgN96QAqApDMZ8Vl1r8f0QT8QprvC1UCltV4CcWj20YoIyLZx6IUskaJZ0NV8fokcg=="], - - "dmg-license": ["dmg-license@1.0.11", "", { "dependencies": { "@types/plist": "^3.0.1", "@types/verror": "^1.10.3", "ajv": "^6.10.0", "crc": "^3.8.0", "iconv-corefoundation": "^1.1.7", "plist": "^3.0.4", "smart-buffer": "^4.0.2", "verror": "^1.10.0" }, "os": "darwin", "bin": { "dmg-license": "bin/dmg-license.js" } }, "sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q=="], + "diff": ["diff@8.0.3", "", {}, "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ=="], "dns-packet": ["dns-packet@5.6.1", "", { "dependencies": { "@leichtgewicht/ip-codec": "^2.0.1" } }, "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw=="], @@ -2977,23 +1898,15 @@ "domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="], - "dompurify": ["dompurify@3.3.1", "", { "optionalDependencies": { "@types/trusted-types": "^2.0.7" } }, "sha512-qkdCKzLNtrgPFP1Vo+98FRzJnBRGe4ffyCea9IwHB1fyxPOeNTHpLKYGd4Uk9xvNoH0ZoOjwZxNptyMwqrId1Q=="], + "dompurify": ["dompurify@3.4.13", "", { "optionalDependencies": { "@types/trusted-types": "^2.0.7" } }, "sha512-2vmYIoqjze2d+kakP8S/nS5shfsl587kzwEjcGlTdiksUVgFHnFCsLYDVj/JNqJVOQZGSYBTmuycv0PodwmnMQ=="], "domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="], - "dot-case": ["dot-case@3.0.4", "", { "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3" } }, "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w=="], - - "dot-prop": ["dot-prop@8.0.2", "", { "dependencies": { "type-fest": "^3.8.0" } }, "sha512-xaBe6ZT4DHPkg0k4Ytbvn5xoxgpG0jOS1dYxSOwAHPuNLjP3/OzN0gH55SrLqpx8cBfSaVt91lXYkApjb+nYdQ=="], - - "dotenv": ["dotenv@16.6.1", "", {}, "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow=="], - - "dotenv-expand": ["dotenv-expand@11.0.7", "", { "dependencies": { "dotenv": "^16.4.5" } }, "sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA=="], + "dotenv": ["dotenv@17.4.2", "", {}, "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw=="], - "drizzle-kit": ["drizzle-kit@1.0.0-beta.19-d95b7a4", "", { "dependencies": { "@drizzle-team/brocli": "^0.11.0", "@js-temporal/polyfill": "^0.5.1", "esbuild": "^0.25.10", "get-tsconfig": "^4.13.6", "jiti": "^2.6.1" }, "bin": { "drizzle-kit": "bin.cjs" } }, "sha512-M0sqc+42TYBod6kEZ3AsW6+JWe3+76gR1aDFbHH5DmuLKEwewmbzlhBG6qnvV6YA1cIIbkuam3dC7r6PREOCXw=="], + "drizzle-kit": ["drizzle-kit@1.0.0-beta.20", "", { "dependencies": { "@drizzle-team/brocli": "^0.11.0", "@js-temporal/polyfill": "^0.5.1", "esbuild": "^0.25.10", "get-tsconfig": "^4.13.6", "jiti": "^2.6.1" }, "bin": { "drizzle-kit": "bin.cjs" } }, "sha512-qMUBnrOQIU+H32aF80BSn7lT1IQuKmofCypmkrKMuOMqvM0bhz5hjCHim1bLcXUzXYRtTSr6U2pe0MSV79WbAg=="], - "drizzle-orm": ["drizzle-orm@1.0.0-beta.19-d95b7a4", "", { "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", "@cloudflare/workers-types": ">=4", "@effect/sql": "^0.48.5", "@effect/sql-pg": "^0.49.7", "@electric-sql/pglite": ">=0.2.0", "@libsql/client": ">=0.10.0", "@libsql/client-wasm": ">=0.10.0", "@neondatabase/serverless": ">=0.10.0", "@op-engineering/op-sqlite": ">=2", "@opentelemetry/api": "^1.4.1", "@planetscale/database": ">=1.13", "@sinclair/typebox": ">=0.34.8", "@sqlitecloud/drivers": ">=1.0.653", "@tidbcloud/serverless": "*", "@tursodatabase/database": ">=0.2.1", "@tursodatabase/database-common": ">=0.2.1", "@tursodatabase/database-wasm": ">=0.2.1", "@types/better-sqlite3": "*", "@types/mssql": "^9.1.4", "@types/pg": "*", "@types/sql.js": "*", "@upstash/redis": ">=1.34.7", "@vercel/postgres": ">=0.8.0", "@xata.io/client": "*", "arktype": ">=2.0.0", "better-sqlite3": ">=9.3.0", "bun-types": "*", "expo-sqlite": ">=14.0.0", "gel": ">=2", "mssql": "^11.0.1", "mysql2": ">=2", "pg": ">=8", "postgres": ">=3", "sql.js": ">=1", "sqlite3": ">=5", "typebox": ">=1.0.0", "valibot": ">=1.0.0-beta.7", "zod": "^3.25.0 || ^4.0.0" }, "optionalPeers": ["@aws-sdk/client-rds-data", "@cloudflare/workers-types", "@effect/sql", "@effect/sql-pg", "@electric-sql/pglite", "@libsql/client", "@libsql/client-wasm", "@neondatabase/serverless", "@op-engineering/op-sqlite", "@opentelemetry/api", "@planetscale/database", "@sinclair/typebox", "@sqlitecloud/drivers", "@tidbcloud/serverless", "@tursodatabase/database", "@tursodatabase/database-common", "@tursodatabase/database-wasm", "@types/better-sqlite3", "@types/pg", "@types/sql.js", "@upstash/redis", "@vercel/postgres", "@xata.io/client", "arktype", "better-sqlite3", "bun-types", "expo-sqlite", "gel", "mysql2", "pg", "postgres", "sql.js", "sqlite3", "typebox", "valibot", "zod"] }, "sha512-bZZKKeoRKrMVU6zKTscjrSH0+WNb1WEi3N0Jl4wEyQ7aQpTgHzdYY6IJQ1P0M74HuSJVeX4UpkFB/S6dtqLEJg=="], - - "dset": ["dset@3.1.4", "", {}, "sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA=="], + "drizzle-orm": ["drizzle-orm@1.0.0-beta.20", "", { "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", "@cloudflare/workers-types": ">=4", "@effect/sql": "^0.48.5", "@effect/sql-pg": "^0.49.7", "@electric-sql/pglite": ">=0.2.0", "@libsql/client": ">=0.10.0", "@libsql/client-wasm": ">=0.10.0", "@neondatabase/serverless": ">=0.10.0", "@op-engineering/op-sqlite": ">=2", "@opentelemetry/api": "^1.4.1", "@planetscale/database": ">=1.13", "@sinclair/typebox": ">=0.34.8", "@sqlitecloud/drivers": ">=1.0.653", "@tidbcloud/serverless": "*", "@tursodatabase/database": ">=0.2.1", "@tursodatabase/database-common": ">=0.2.1", "@tursodatabase/database-wasm": ">=0.2.1", "@types/better-sqlite3": "*", "@types/mssql": "^9.1.4", "@types/pg": "*", "@types/sql.js": "*", "@upstash/redis": ">=1.34.7", "@vercel/postgres": ">=0.8.0", "@xata.io/client": "*", "arktype": ">=2.0.0", "better-sqlite3": ">=9.3.0", "bun-types": "*", "expo-sqlite": ">=14.0.0", "gel": ">=2", "mssql": "^11.0.1", "mysql2": ">=2", "pg": ">=8", "postgres": ">=3", "sql.js": ">=1", "sqlite3": ">=5", "typebox": ">=1.0.0", "valibot": ">=1.0.0-beta.7", "zod": "^3.25.0 || ^4.0.0" }, "optionalPeers": ["@aws-sdk/client-rds-data", "@cloudflare/workers-types", "@effect/sql", "@effect/sql-pg", "@electric-sql/pglite", "@libsql/client", "@libsql/client-wasm", "@neondatabase/serverless", "@op-engineering/op-sqlite", "@opentelemetry/api", "@planetscale/database", "@sinclair/typebox", "@sqlitecloud/drivers", "@tidbcloud/serverless", "@tursodatabase/database", "@tursodatabase/database-common", "@tursodatabase/database-wasm", "@types/better-sqlite3", "@types/pg", "@types/sql.js", "@upstash/redis", "@vercel/postgres", "@xata.io/client", "arktype", "better-sqlite3", "bun-types", "expo-sqlite", "gel", "mysql2", "pg", "postgres", "sql.js", "sqlite3", "typebox", "valibot", "zod"] }, "sha512-7qiuw+Z6yGr+ywt3PS5dP6UCfdymIuFT/ni6GnPGzLhkBIolNBTo4ByMBWTxJ7dW/Ya6d73GtkeuKfcVcriVHA=="], "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], @@ -3001,54 +1914,18 @@ "ecdsa-sig-formatter": ["ecdsa-sig-formatter@1.0.11", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ=="], - "editorconfig": ["editorconfig@1.0.7", "", { "dependencies": { "@one-ini/wasm": "0.1.1", "commander": "^10.0.0", "minimatch": "^9.0.1", "semver": "^7.5.3" }, "bin": { "editorconfig": "bin/editorconfig" } }, "sha512-e0GOtq/aTQhVdNyDU9e02+wz9oDDM+SIOQxWME2QRjzRX5yyLAuHDE+0aE8vHb9XRC8XD37eO2u57+F09JqFhw=="], - "ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="], "effect": ["effect@4.0.0-beta.59", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "fast-check": "^4.6.0", "find-my-way-ts": "^0.1.6", "ini": "^6.0.0", "kubernetes-types": "^1.30.0", "msgpackr": "^1.11.9", "multipasta": "^0.2.7", "toml": "^4.1.1", "uuid": "^13.0.0", "yaml": "^2.8.3" } }, "sha512-xyUDLeHSe8d6lWGOvR6Fgn2HL6gYeTZ/S4Jzk9uc4ZUxMPPsNZlNXrvk0C7/utQFzeX7uAWcVnG2BjbA0SRoAA=="], - "ejs": ["ejs@3.1.10", "", { "dependencies": { "jake": "^10.8.5" }, "bin": { "ejs": "bin/cli.js" } }, "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA=="], - - "electron": ["electron@41.2.1", "", { "dependencies": { "@electron/get": "^2.0.0", "@types/node": "^24.9.0", "extract-zip": "^2.0.1" }, "bin": { "electron": "cli.js" } }, "sha512-teeRThiYGTPKf/2yOW7zZA1bhb91KEQ4yLBPOg7GxpmnkLFLugKgQaAKOrCgdzwsXh/5mFIfmkm+4+wACJKwaA=="], - - "electron-builder": ["electron-builder@26.8.1", "", { "dependencies": { "app-builder-lib": "26.8.1", "builder-util": "26.8.1", "builder-util-runtime": "9.5.1", "chalk": "^4.1.2", "ci-info": "^4.2.0", "dmg-builder": "26.8.1", "fs-extra": "^10.1.0", "lazy-val": "^1.0.5", "simple-update-notifier": "2.0.0", "yargs": "^17.6.2" }, "bin": { "electron-builder": "cli.js", "install-app-deps": "install-app-deps.js" } }, "sha512-uWhx1r74NGpCagG0ULs/P9Nqv2nsoo+7eo4fLUOB8L8MdWltq9odW/uuLXMFCDGnPafknYLZgjNX0ZIFRzOQAw=="], - - "electron-builder-squirrel-windows": ["electron-builder-squirrel-windows@26.8.1", "", { "dependencies": { "app-builder-lib": "26.8.1", "builder-util": "26.8.1", "electron-winstaller": "5.4.0" } }, "sha512-o288fIdgPLHA76eDrFADHPoo7VyGkDCYbLV1GzndaMSAVBoZrGvM9m2IehdcVMzdAZJ2eV9bgyissQXHv5tGzA=="], - - "electron-context-menu": ["electron-context-menu@4.1.2", "", { "dependencies": { "cli-truncate": "^4.0.0", "electron-dl": "^4.0.0", "electron-is-dev": "^3.0.1" } }, "sha512-9xYTUV0oRqKL50N9W71IrXNdVRB0LuBp3R1zkUdUc2wfIa2/QZwYYj5RLuO7Tn7ZSLVIaO3X6u+EIBK+cBvzrQ=="], - - "electron-dl": ["electron-dl@4.0.0", "", { "dependencies": { "ext-name": "^5.0.0", "pupa": "^3.1.0", "unused-filename": "^4.0.1" } }, "sha512-USiB9816d2JzKv0LiSbreRfTg5lDk3lWh0vlx/gugCO92ZIJkHVH0UM18EHvKeadErP6Xn4yiTphWzYfbA2Ong=="], - - "electron-is-dev": ["electron-is-dev@3.0.1", "", {}, "sha512-8TjjAh8Ec51hUi3o4TaU0mD3GMTOESi866oRNavj9A3IQJ7pmv+MJVmdZBFGw4GFT36X7bkqnuDNYvkQgvyI8Q=="], - - "electron-log": ["electron-log@5.4.3", "", {}, "sha512-sOUsM3LjZdugatazSQ/XTyNcw8dfvH1SYhXWiJyfYodAAKOZdHs0txPiLDXFzOZbhXgAgshQkshH2ccq0feyLQ=="], - - "electron-publish": ["electron-publish@26.8.1", "", { "dependencies": { "@types/fs-extra": "^9.0.11", "builder-util": "26.8.1", "builder-util-runtime": "9.5.1", "chalk": "^4.1.2", "form-data": "^4.0.5", "fs-extra": "^10.1.0", "lazy-val": "^1.0.5", "mime": "^2.5.2" } }, "sha512-q+jrSTIh/Cv4eGZa7oVR+grEJo/FoLMYBAnSL5GCtqwUpr1T+VgKB/dn1pnzxIxqD8S/jP1yilT9VrwCqINR4w=="], - - "electron-store": ["electron-store@10.1.0", "", { "dependencies": { "conf": "^14.0.0", "type-fest": "^4.41.0" } }, "sha512-oL8bRy7pVCLpwhmXy05Rh/L6O93+k9t6dqSw0+MckIc3OmCTZm6Mp04Q4f/J0rtu84Ky6ywkR8ivtGOmrq+16w=="], - - "electron-to-chromium": ["electron-to-chromium@1.5.336", "", {}, "sha512-AbH9q9J455r/nLmdNZes0G0ZKcRX73FicwowalLs6ijwOmCJSRRrLX63lcAlzy9ux3dWK1w1+1nsBJEWN11hcQ=="], - - "electron-updater": ["electron-updater@6.8.3", "", { "dependencies": { "builder-util-runtime": "9.5.1", "fs-extra": "^10.1.0", "js-yaml": "^4.1.0", "lazy-val": "^1.0.5", "lodash.escaperegexp": "^4.1.2", "lodash.isequal": "^4.5.0", "semver": "~7.7.3", "tiny-typed-emitter": "^2.1.0" } }, "sha512-Z6sgw3jgbikWKXei1ENdqFOxBP0WlXg3TtKfz0rgw2vIZFJUyI4pD7ZN7jrkm7EoMK+tcm/qTnPUdqfZukBlBQ=="], - - "electron-vite": ["electron-vite@5.0.0", "", { "dependencies": { "@babel/core": "^7.28.4", "@babel/plugin-transform-arrow-functions": "^7.27.1", "cac": "^6.7.14", "esbuild": "^0.25.11", "magic-string": "^0.30.19", "picocolors": "^1.1.1" }, "peerDependencies": { "@swc/core": "^1.0.0", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0" }, "optionalPeers": ["@swc/core"], "bin": { "electron-vite": "bin/electron-vite.js" } }, "sha512-OHp/vjdlubNlhNkPkL/+3JD34ii5ov7M0GpuXEVdQeqdQ3ulvVR7Dg/rNBLfS5XPIFwgoBLDf9sjjrL+CuDyRQ=="], - - "electron-window-state": ["electron-window-state@5.0.3", "", { "dependencies": { "jsonfile": "^4.0.0", "mkdirp": "^0.5.1" } }, "sha512-1mNTwCfkolXl3kMf50yW3vE2lZj0y92P/HYWFBrb+v2S/pCka5mdwN3cagKm458A7NjndSwijynXgcLWRodsVg=="], - - "electron-winstaller": ["electron-winstaller@5.4.0", "", { "dependencies": { "@electron/asar": "^3.2.1", "debug": "^4.1.1", "fs-extra": "^7.0.1", "lodash": "^4.17.21", "temp": "^0.9.0" }, "optionalDependencies": { "@electron/windows-sign": "^1.1.2" } }, "sha512-bO3y10YikuUwUuDUQRM4KfwNkKhnpVO7IPdbsrejwN9/AABJzzTQ4GeHwyzNSrVO+tEH3/Np255a3sVZpZDjvg=="], - - "emmet": ["emmet@2.4.11", "", { "dependencies": { "@emmetio/abbreviation": "^2.3.3", "@emmetio/css-abbreviation": "^2.1.8" } }, "sha512-23QPJB3moh/U9sT4rQzGgeyyGIrcM+GH5uVYg2C6wZIxAIJq7Ng3QLT79tl8FUwDXhyq9SusfknOrofAKqvgyQ=="], + "electron-to-chromium": ["electron-to-chromium@1.5.415", "", {}, "sha512-958V+Kbhtgz+SxXeEVKBjrlKRBIDAYvUJfwhjxMZ5S6ut9jAl7l9ZKBkBrvjyjZE36PabLUo2L8kEeV5O4vgJg=="], "emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="], - "emoji-regex-xs": ["emoji-regex-xs@1.0.0", "", {}, "sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg=="], - "encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="], "encoding": ["encoding@0.1.13", "", { "dependencies": { "iconv-lite": "^0.6.2" } }, "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A=="], - "end-of-stream": ["end-of-stream@1.4.5", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg=="], - "engine.io-client": ["engine.io-client@6.6.4", "", { "dependencies": { "@socket.io/component-emitter": "~3.1.0", "debug": "~4.4.1", "engine.io-parser": "~5.2.1", "ws": "~8.18.3", "xmlhttprequest-ssl": "~2.1.1" } }, "sha512-+kjUJnZGwzewFDw951CDWcwj35vMNf2fcj7xQWOctq1F2i1jkDdVvdFG9kM/BEChymCH36KgjnW0NsL58JYRxw=="], "engine.io-parser": ["engine.io-parser@5.2.3", "", {}, "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q=="], @@ -3059,64 +1936,20 @@ "env-paths": ["env-paths@2.2.1", "", {}, "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="], - "err-code": ["err-code@2.0.3", "", {}, "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA=="], - - "error-stack-parser": ["error-stack-parser@2.1.4", "", { "dependencies": { "stackframe": "^1.3.4" } }, "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ=="], - - "error-stack-parser-es": ["error-stack-parser-es@1.0.5", "", {}, "sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA=="], - - "es-abstract": ["es-abstract@1.24.2", "", { "dependencies": { "array-buffer-byte-length": "^1.0.2", "arraybuffer.prototype.slice": "^1.0.4", "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.4", "data-view-buffer": "^1.0.2", "data-view-byte-length": "^1.0.2", "data-view-byte-offset": "^1.0.1", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "es-set-tostringtag": "^2.1.0", "es-to-primitive": "^1.3.0", "function.prototype.name": "^1.1.8", "get-intrinsic": "^1.3.0", "get-proto": "^1.0.1", "get-symbol-description": "^1.1.0", "globalthis": "^1.0.4", "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", "has-proto": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "internal-slot": "^1.1.0", "is-array-buffer": "^3.0.5", "is-callable": "^1.2.7", "is-data-view": "^1.0.2", "is-negative-zero": "^2.0.3", "is-regex": "^1.2.1", "is-set": "^2.0.3", "is-shared-array-buffer": "^1.0.4", "is-string": "^1.1.1", "is-typed-array": "^1.1.15", "is-weakref": "^1.1.1", "math-intrinsics": "^1.1.0", "object-inspect": "^1.13.4", "object-keys": "^1.1.1", "object.assign": "^4.1.7", "own-keys": "^1.0.1", "regexp.prototype.flags": "^1.5.4", "safe-array-concat": "^1.1.3", "safe-push-apply": "^1.0.0", "safe-regex-test": "^1.1.0", "set-proto": "^1.0.0", "stop-iteration-iterator": "^1.1.0", "string.prototype.trim": "^1.2.10", "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", "typed-array-buffer": "^1.0.3", "typed-array-byte-length": "^1.0.3", "typed-array-byte-offset": "^1.0.4", "typed-array-length": "^1.0.7", "unbox-primitive": "^1.1.0", "which-typed-array": "^1.1.19" } }, "sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg=="], - - "es-array-method-boxes-properly": ["es-array-method-boxes-properly@1.0.0", "", {}, "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA=="], - "es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="], "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="], - "es-get-iterator": ["es-get-iterator@1.1.3", "", { "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.3", "has-symbols": "^1.0.3", "is-arguments": "^1.1.1", "is-map": "^2.0.2", "is-set": "^2.0.2", "is-string": "^1.0.7", "isarray": "^2.0.5", "stop-iteration-iterator": "^1.0.0" } }, "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw=="], - - "es-module-lexer": ["es-module-lexer@1.7.0", "", {}, "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA=="], - "es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="], "es-set-tostringtag": ["es-set-tostringtag@2.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="], - "es-to-primitive": ["es-to-primitive@1.3.0", "", { "dependencies": { "is-callable": "^1.2.7", "is-date-object": "^1.0.5", "is-symbol": "^1.0.4" } }, "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g=="], - - "es6-error": ["es6-error@4.1.1", "", {}, "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg=="], - - "esast-util-from-estree": ["esast-util-from-estree@2.0.0", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "devlop": "^1.0.0", "estree-util-visit": "^2.0.0", "unist-util-position-from-estree": "^2.0.0" } }, "sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ=="], - - "esast-util-from-js": ["esast-util-from-js@2.0.1", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "acorn": "^8.0.0", "esast-util-from-estree": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw=="], - - "esbuild": ["esbuild@0.25.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="], - - "esbuild-plugin-copy": ["esbuild-plugin-copy@2.1.1", "", { "dependencies": { "chalk": "^4.1.2", "chokidar": "^3.5.3", "fs-extra": "^10.0.1", "globby": "^11.0.3" }, "peerDependencies": { "esbuild": ">= 0.14.0" } }, "sha512-Bk66jpevTcV8KMFzZI1P7MZKZ+uDcrZm2G2egZ2jNIvVnivDpodZI+/KnpL3Jnap0PBdIHU7HwFGB8r+vV5CVw=="], + "esbuild": ["esbuild@0.28.1", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.28.1", "@esbuild/android-arm": "0.28.1", "@esbuild/android-arm64": "0.28.1", "@esbuild/android-x64": "0.28.1", "@esbuild/darwin-arm64": "0.28.1", "@esbuild/darwin-x64": "0.28.1", "@esbuild/freebsd-arm64": "0.28.1", "@esbuild/freebsd-x64": "0.28.1", "@esbuild/linux-arm": "0.28.1", "@esbuild/linux-arm64": "0.28.1", "@esbuild/linux-ia32": "0.28.1", "@esbuild/linux-loong64": "0.28.1", "@esbuild/linux-mips64el": "0.28.1", "@esbuild/linux-ppc64": "0.28.1", "@esbuild/linux-riscv64": "0.28.1", "@esbuild/linux-s390x": "0.28.1", "@esbuild/linux-x64": "0.28.1", "@esbuild/netbsd-arm64": "0.28.1", "@esbuild/netbsd-x64": "0.28.1", "@esbuild/openbsd-arm64": "0.28.1", "@esbuild/openbsd-x64": "0.28.1", "@esbuild/openharmony-arm64": "0.28.1", "@esbuild/sunos-x64": "0.28.1", "@esbuild/win32-arm64": "0.28.1", "@esbuild/win32-ia32": "0.28.1", "@esbuild/win32-x64": "0.28.1" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw=="], "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], - "escape-goat": ["escape-goat@4.0.0", "", {}, "sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg=="], - "escape-html": ["escape-html@1.0.3", "", {}, "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="], - "escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="], - - "esprima": ["esprima@4.0.1", "", { "bin": { "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="], - - "estree-util-attach-comments": ["estree-util-attach-comments@3.0.0", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw=="], - - "estree-util-build-jsx": ["estree-util-build-jsx@3.0.1", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "estree-walker": "^3.0.0" } }, "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ=="], - - "estree-util-is-identifier-name": ["estree-util-is-identifier-name@3.0.0", "", {}, "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg=="], - - "estree-util-scope": ["estree-util-scope@1.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "devlop": "^1.0.0" } }, "sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ=="], - - "estree-util-to-js": ["estree-util-to-js@2.0.0", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "astring": "^1.8.0", "source-map": "^0.7.0" } }, "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg=="], - - "estree-util-visit": ["estree-util-visit@2.0.0", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/unist": "^3.0.0" } }, "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww=="], - - "estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="], - "etag": ["etag@1.8.1", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="], "event-target-shim": ["event-target-shim@5.0.1", "", {}, "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="], @@ -3129,38 +1962,24 @@ "eventsource": ["eventsource@3.0.7", "", { "dependencies": { "eventsource-parser": "^3.0.1" } }, "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA=="], - "eventsource-parser": ["eventsource-parser@3.0.6", "", {}, "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg=="], + "eventsource-parser": ["eventsource-parser@3.1.1", "", {}, "sha512-EKN1vKAMcZ8MlYMpaNuxN6R9yakzH6uajHcHVTqWJzvu5pWw9DyhbP35HH8MVBQ+dZjAfDxk+A8NiR9KWaXiyQ=="], "execa": ["execa@8.0.1", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^8.0.1", "human-signals": "^5.0.0", "is-stream": "^3.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^5.1.0", "onetime": "^6.0.0", "signal-exit": "^4.1.0", "strip-final-newline": "^3.0.0" } }, "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg=="], "exif-parser": ["exif-parser@0.1.12", "", {}, "sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw=="], - "exit-hook": ["exit-hook@2.2.1", "", {}, "sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw=="], - - "expect-type": ["expect-type@1.3.0", "", {}, "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA=="], - "exponential-backoff": ["exponential-backoff@3.1.3", "", {}, "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA=="], - "express": ["express@4.22.1", "", { "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", "body-parser": "~1.20.3", "content-disposition": "~0.5.4", "content-type": "~1.0.4", "cookie": "~0.7.1", "cookie-signature": "~1.0.6", "debug": "2.6.9", "depd": "2.0.0", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", "finalhandler": "~1.3.1", "fresh": "~0.5.2", "http-errors": "~2.0.0", "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "~2.4.1", "parseurl": "~1.3.3", "path-to-regexp": "~0.1.12", "proxy-addr": "~2.0.7", "qs": "~6.14.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "~0.19.0", "serve-static": "~1.16.2", "setprototypeof": "1.2.0", "statuses": "~2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" } }, "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g=="], + "express": ["express@5.2.1", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "depd": "^2.0.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" } }, "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw=="], "express-rate-limit": ["express-rate-limit@8.3.2", "", { "dependencies": { "ip-address": "10.1.0" }, "peerDependencies": { "express": ">= 4.11" } }, "sha512-77VmFeJkO0/rvimEDuUC5H30oqUC4EyOhyGccfqoLebB0oiEYfM7nwPrsDsBL1gsTpwfzX8SFy2MT3TDyRq+bg=="], - "expressive-code": ["expressive-code@0.41.7", "", { "dependencies": { "@expressive-code/core": "^0.41.7", "@expressive-code/plugin-frames": "^0.41.7", "@expressive-code/plugin-shiki": "^0.41.7", "@expressive-code/plugin-text-markers": "^0.41.7" } }, "sha512-2wZjC8OQ3TaVEMcBtYY4Va3lo6J+Ai9jf3d4dbhURMJcU4Pbqe6EcHe424MIZI0VHUA1bR6xdpoHYi3yxokWqA=="], - "exsolve": ["exsolve@1.0.8", "", {}, "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA=="], - "ext-list": ["ext-list@2.2.2", "", { "dependencies": { "mime-db": "^1.28.0" } }, "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA=="], - - "ext-name": ["ext-name@5.0.0", "", { "dependencies": { "ext-list": "^2.0.0", "sort-keys-length": "^1.0.0" } }, "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ=="], - "extend": ["extend@3.0.2", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="], "extend-shallow": ["extend-shallow@2.0.1", "", { "dependencies": { "is-extendable": "^0.1.0" } }, "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug=="], - "extract-zip": ["extract-zip@2.0.1", "", { "dependencies": { "debug": "^4.1.1", "get-stream": "^5.1.0", "yauzl": "^2.10.0" }, "optionalDependencies": { "@types/yauzl": "^2.9.1" }, "bin": { "extract-zip": "cli.js" } }, "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg=="], - - "extsprintf": ["extsprintf@1.4.1", "", {}, "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA=="], - "fast-check": ["fast-check@4.6.0", "", { "dependencies": { "pure-rand": "^8.0.0" } }, "sha512-h7H6Dm0Fy+H4ciQYFxFjXnXkzR2kr9Fb22c0UBpHnm59K2zpr2t13aPTHlltFiNT6zuxp6HMPAVVvgur4BLdpA=="], "fast-content-type-parse": ["fast-content-type-parse@3.0.0", "", {}, "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg=="], @@ -3171,83 +1990,59 @@ "fast-fifo": ["fast-fifo@1.3.2", "", {}, "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ=="], - "fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="], - - "fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="], - "fast-json-stringify": ["fast-json-stringify@6.3.0", "", { "dependencies": { "@fastify/merge-json-schemas": "^0.2.0", "ajv": "^8.12.0", "ajv-formats": "^3.0.1", "fast-uri": "^3.0.0", "json-schema-ref-resolver": "^3.0.0", "rfdc": "^1.2.0" } }, "sha512-oRCntNDY/329HJPlmdNLIdogNtt6Vyjb1WuT01Soss3slIdyUp8kAcDU3saQTOquEK8KFVfwIIF7FebxUAu+yA=="], "fast-querystring": ["fast-querystring@1.1.2", "", { "dependencies": { "fast-decode-uri-component": "^1.0.1" } }, "sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg=="], "fast-sha256": ["fast-sha256@1.3.0", "", {}, "sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ=="], - "fast-uri": ["fast-uri@3.1.0", "", {}, "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA=="], + "fast-uri": ["fast-uri@3.1.6", "", {}, "sha512-7Ical1vFEMr0onbVzEDIreM22I4khW+fzyQPwvAFWBp1iwdshSZRsL4jjRvPG9JP1uiqMHRto+YU6R2/CzDz5Q=="], - "fast-xml-builder": ["fast-xml-builder@1.1.4", "", { "dependencies": { "path-expression-matcher": "^1.1.3" } }, "sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg=="], + "fast-xml-builder": ["fast-xml-builder@1.1.7", "", { "dependencies": { "path-expression-matcher": "^1.1.3" } }, "sha512-Yh7/7rQuMXICNr0oMYDR2yHP6oUvmQsTToFeOWj/kIDhAwQ+c4Ol/lbcwOmEM5OHYQmh6S6EQSQ1sljCKP36bQ=="], - "fast-xml-parser": ["fast-xml-parser@4.4.1", "", { "dependencies": { "strnum": "^1.0.5" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw=="], + "fast-xml-parser": ["fast-xml-parser@5.7.0", "", { "dependencies": { "@nodable/entities": "^2.1.0", "fast-xml-builder": "^1.1.5", "path-expression-matcher": "^1.5.0", "strnum": "^2.2.3" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-MTcrUoRQ1GSQ9iG3QJzBGquYYYeA7piZaJoIWbPFGbRn6Jj6z7xgoAyi4DrZX4y2ZIQQBF59gc/zmvvejjgoFQ=="], - "fastify": ["fastify@5.8.5", "", { "dependencies": { "@fastify/ajv-compiler": "^4.0.5", "@fastify/error": "^4.0.0", "@fastify/fast-json-stringify-compiler": "^5.0.0", "@fastify/proxy-addr": "^5.0.0", "abstract-logging": "^2.0.1", "avvio": "^9.0.0", "fast-json-stringify": "^6.0.0", "find-my-way": "^9.0.0", "light-my-request": "^6.0.0", "pino": "^9.14.0 || ^10.1.0", "process-warning": "^5.0.0", "rfdc": "^1.3.1", "secure-json-parse": "^4.0.0", "semver": "^7.6.0", "toad-cache": "^3.7.0" } }, "sha512-Yqptv59pQzPgQUSIm87hMqHJmdkb1+GPxdE6vW6FRyVE9G86mt7rOghitiU4JHRaTyDUk9pfeKmDeu70lAwM4Q=="], + "fastify": ["fastify@5.12.1", "", { "dependencies": { "@fastify/ajv-compiler": "^4.0.5", "@fastify/error": "^4.0.0", "@fastify/fast-json-stringify-compiler": "^5.0.0", "@fastify/proxy-addr": "^5.0.0", "abstract-logging": "^2.0.1", "avvio": "^9.0.0", "fast-json-stringify": "^7.0.0", "find-my-way": "^9.6.0", "light-my-request": "^6.0.0", "pino": "^9.14.0 || ^10.1.0", "process-warning": "^5.1.0", "rfdc": "^1.3.1", "secure-json-parse": "^4.0.0", "semver": "^7.6.0", "toad-cache": "^3.7.0" } }, "sha512-FWi+tQvwxR/PeRX7Z2mhfEF5ozJ3jn9asiiclzKXNSzJRHAYcU924aIOKAdHFJ+YIKieh3cqr1IwCOvTr41B3Q=="], "fastify-plugin": ["fastify-plugin@5.1.0", "", {}, "sha512-FAIDA8eovSt5qcDgcBvDuX/v0Cjz0ohGhENZ/wpc3y+oZCY2afZ9Baqql3g/lC+OHRnciQol4ww7tuthOb9idw=="], "fastq": ["fastq@1.20.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw=="], - "fd-slicer": ["fd-slicer@1.1.0", "", { "dependencies": { "pend": "~1.2.0" } }, "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g=="], - "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], "fetch-blob": ["fetch-blob@3.2.0", "", { "dependencies": { "node-domexception": "^1.0.0", "web-streams-polyfill": "^3.0.3" } }, "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ=="], - "file-type": ["file-type@16.5.4", "", { "dependencies": { "readable-web-to-node-stream": "^3.0.0", "strtok3": "^6.2.4", "token-types": "^4.1.1" } }, "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw=="], - - "filelist": ["filelist@1.0.6", "", { "dependencies": { "minimatch": "^5.0.1" } }, "sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA=="], + "file-type": ["file-type@21.3.2", "", { "dependencies": { "@tokenizer/inflate": "^0.4.1", "strtok3": "^10.3.4", "token-types": "^6.1.1", "uint8array-extras": "^1.4.0" } }, "sha512-DLkUvGwep3poOV2wpzbHCOnSKGk1LzyXTv+aHFgN2VFl96wnp8YA9YjO2qPzg5PuL8q/SW9Pdi6WTkYOIh995w=="], "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], - "finalhandler": ["finalhandler@1.3.2", "", { "dependencies": { "debug": "2.6.9", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "on-finished": "~2.4.1", "parseurl": "~1.3.3", "statuses": "~2.0.2", "unpipe": "~1.0.0" } }, "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg=="], + "finalhandler": ["finalhandler@2.1.1", "", { "dependencies": { "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "on-finished": "^2.4.1", "parseurl": "^1.3.3", "statuses": "^2.0.1" } }, "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA=="], "find-babel-config": ["find-babel-config@2.1.2", "", { "dependencies": { "json5": "^2.2.3" } }, "sha512-ZfZp1rQyp4gyuxqt1ZqjFGVeVBvmpURMqdIWXbPRfB97Bf6BzdK/xSIbylEINzQ0kB5tlDQfn9HkNXXWsqTqLg=="], "find-exec": ["find-exec@1.0.3", "", { "dependencies": { "shell-quote": "^1.8.1" } }, "sha512-gnG38zW90mS8hm5smNcrBnakPEt+cGJoiMkJwCU0IYnEb0H2NQk0NIljhNW+48oniCriFek/PH6QXbwsJo/qug=="], - "find-my-way": ["find-my-way@9.5.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-querystring": "^1.0.0", "safe-regex2": "^5.0.0" } }, "sha512-VW2RfnmscZO5KgBY5XVyKREMW5nMZcxDy+buTOsL+zIPnBlbKm+00sgzoQzq1EVh4aALZLfKdwv6atBGcjvjrQ=="], + "find-my-way": ["find-my-way@9.7.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-querystring": "^1.0.0", "safe-regex2": "^5.0.0" } }, "sha512-f2JHn75x2JlwUwLenZypgczR7YWMb/uO9BvUXtus+JMgkbIkLADd38cI4EiV+OQqrGo1Zlq6V8wnqMJ8e62wUQ=="], "find-my-way-ts": ["find-my-way-ts@0.1.6", "", {}, "sha512-a85L9ZoXtNAey3Y6Z+eBWW658kO/MwR7zIafkIUPUMf3isZG0NCs2pjW2wtjxAKuJPxMAsHUIP4ZPGv0o5gyTA=="], - "find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="], - - "finity": ["finity@0.5.4", "", {}, "sha512-3l+5/1tuw616Lgb0QBimxfdd2TqaDGpfCBpfX6EqtFmqUV3FtQnVEX4Aa62DagYEqnsTIjZcTfbq9msDbXYgyA=="], - - "flattie": ["flattie@1.1.1", "", {}, "sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ=="], + "find-up": ["find-up@3.0.0", "", { "dependencies": { "locate-path": "^3.0.0" } }, "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg=="], "follow-redirects": ["follow-redirects@1.16.0", "", {}, "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw=="], - "fontace": ["fontace@0.3.1", "", { "dependencies": { "@types/fontkit": "^2.0.8", "fontkit": "^2.0.4" } }, "sha512-9f5g4feWT1jWT8+SbL85aLIRLIXUaDygaM2xPXRmzPYxrOMNok79Lr3FGJoKVNKibE0WCunNiEVG2mwuE+2qEg=="], - - "fontkit": ["fontkit@2.0.4", "", { "dependencies": { "@swc/helpers": "^0.5.12", "brotli": "^1.3.2", "clone": "^2.1.2", "dfa": "^1.2.0", "fast-deep-equal": "^3.1.3", "restructure": "^3.0.0", "tiny-inflate": "^1.0.3", "unicode-properties": "^1.4.0", "unicode-trie": "^2.0.0" } }, "sha512-syetQadaUEDNdxdugga9CpEYVaQIxOwk7GlwZWWZ19//qW4zE5bknOKeMBDYAASwnpaSHKJITRLMF9m1fp3s6g=="], - "for-each": ["for-each@0.3.5", "", { "dependencies": { "is-callable": "^1.2.7" } }, "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg=="], "foreground-child": ["foreground-child@3.3.1", "", { "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" } }, "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw=="], - "form-data": ["form-data@4.0.5", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" } }, "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w=="], - - "form-data-encoder": ["form-data-encoder@1.7.2", "", {}, "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A=="], - - "formdata-node": ["formdata-node@4.4.1", "", { "dependencies": { "node-domexception": "1.0.0", "web-streams-polyfill": "4.0.0-beta.3" } }, "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ=="], + "form-data": ["form-data@4.0.6", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.4", "mime-types": "^2.1.35" } }, "sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ=="], "formdata-polyfill": ["formdata-polyfill@4.0.10", "", { "dependencies": { "fetch-blob": "^3.1.2" } }, "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g=="], "forwarded": ["forwarded@0.2.0", "", {}, "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="], - "fraction.js": ["fraction.js@5.3.4", "", {}, "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ=="], - - "framer-motion": ["framer-motion@8.5.5", "", { "dependencies": { "@motionone/dom": "^10.15.3", "hey-listen": "^1.0.8", "tslib": "^2.4.0" }, "optionalDependencies": { "@emotion/is-prop-valid": "^0.8.2" }, "peerDependencies": { "react": "^18.0.0", "react-dom": "^18.0.0" } }, "sha512-5IDx5bxkjWHWUF3CVJoSyUVOtrbAxtzYBBowRE2uYI/6VYhkEBD+rbTHEGuUmbGHRj6YqqSfoG7Aa1cLyWCrBA=="], - - "fresh": ["fresh@0.5.2", "", {}, "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="], + "framer-motion": ["framer-motion@12.38.0", "", { "dependencies": { "motion-dom": "^12.38.0", "motion-utils": "^12.36.0", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-rFYkY/pigbcswl1XQSb7q424kSTQ8q6eAC+YUsSKooHQYuLdzdHjrt6uxUC+PRAO++q5IS7+TamgIw1AphxR+g=="], - "fs-extra": ["fs-extra@10.1.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ=="], + "fresh": ["fresh@2.0.0", "", {}, "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A=="], "fs-minipass": ["fs-minipass@3.0.3", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw=="], @@ -3257,18 +2052,12 @@ "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], - "function.prototype.name": ["function.prototype.name@1.1.8", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "functions-have-names": "^1.2.3", "hasown": "^2.0.2", "is-callable": "^1.2.7" } }, "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q=="], - - "functions-have-names": ["functions-have-names@1.2.3", "", {}, "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ=="], - "fuzzysort": ["fuzzysort@3.1.0", "", {}, "sha512-sR9BNCjBg6LNgwvxlBd0sBABvQitkLzoVY9MYYROQVX/FvfJ4Mai9LsGhDgd8qYdds0bY77VzYd5iuB+v5rwQQ=="], "gaxios": ["gaxios@7.1.4", "", { "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", "node-fetch": "^3.3.2" } }, "sha512-bTIgTsM2bWn3XklZISBTQX7ZSddGW+IO3bMdGaemHZ3tbqExMENHLx6kKZ/KlejgrMtj8q7wBItt51yegqalrA=="], "gcp-metadata": ["gcp-metadata@8.1.2", "", { "dependencies": { "gaxios": "^7.0.0", "google-logging-utils": "^1.0.0", "json-bigint": "^1.0.0" } }, "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg=="], - "generate-function": ["generate-function@2.3.1", "", { "dependencies": { "is-property": "^1.0.2" } }, "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ=="], - "generator-function": ["generator-function@2.0.1", "", {}, "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g=="], "gensync": ["gensync@1.0.0-beta.2", "", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="], @@ -3279,48 +2068,26 @@ "get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="], - "get-nonce": ["get-nonce@1.0.1", "", {}, "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q=="], - - "get-port": ["get-port@7.2.0", "", {}, "sha512-afP4W205ONCuMoPBqcR6PSXnzX35KTcJygfJfcp+QY+uwm3p20p1YczWXhlICIzGMCxYBQcySEcOgsJcrkyobg=="], - "get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="], - "get-stream": ["get-stream@5.2.0", "", { "dependencies": { "pump": "^3.0.0" } }, "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA=="], - - "get-symbol-description": ["get-symbol-description@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6" } }, "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg=="], + "get-stream": ["get-stream@8.0.1", "", {}, "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA=="], - "get-tsconfig": ["get-tsconfig@4.13.8", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-J87BxkLXykmisLQ+KA4x2+O6rVf+PJrtFUO8lGyiRg4lyxJLJ8/v0sRAKdVZQOy6tR6lMRAF1NqzCf9BQijm0w=="], - - "ghostty-web": ["ghostty-web@github:anomalyco/ghostty-web#20bd361", {}, "anomalyco-ghostty-web-20bd361", "sha512-dW0nwaiBBcun9y5WJSvm3HxDLe5o9V0xLCndQvWonRVubU8CS1PHxZpLffyPt1YujPWC13ez03aWxcuKBPYYGQ=="], + "get-tsconfig": ["get-tsconfig@4.14.0", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA=="], "gifwrap": ["gifwrap@0.10.1", "", { "dependencies": { "image-q": "^4.0.0", "omggif": "^1.0.10" } }, "sha512-2760b1vpJHNmLzZ/ubTtNnEx5WApN/PYWJvXvgS+tL1egTTthayFYIQQNi136FLEDcN/IyEY2EcGpIITD6eYUw=="], - "giget": ["giget@2.0.0", "", { "dependencies": { "citty": "^0.1.6", "consola": "^3.4.0", "defu": "^6.1.4", "node-fetch-native": "^1.6.6", "nypm": "^0.6.0", "pathe": "^2.0.3" }, "bin": { "giget": "dist/cli.mjs" } }, "sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA=="], - - "github-slugger": ["github-slugger@2.0.0", "", {}, "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw=="], + "giget": ["giget@3.3.1", "", { "bin": { "giget": "dist/cli.mjs" } }, "sha512-r+mvuDjrjMpsdw46Kmeydb8bdHm7wOKw8wNBtTndkjbPjgAp5oUJUxRE76wZFknxIPokfWvep2qSXK37aXE6zg=="], "gitlab-ai-provider": ["gitlab-ai-provider@6.6.0", "", { "dependencies": { "@anthropic-ai/sdk": "^0.71.0", "@anycable/core": "^0.9.2", "graphql-request": "^6.1.0", "isomorphic-ws": "^5.0.0", "openai": "^6.16.0", "socket.io-client": "^4.8.1", "vscode-jsonrpc": "^8.2.1", "zod": "^3.25.76" }, "peerDependencies": { "@ai-sdk/provider": ">=3.0.0", "@ai-sdk/provider-utils": ">=4.0.0" } }, "sha512-jUxYnKA4XQaPc3wxACDZ8bPDXO0Mzx7cZaBDxbT2uGgLqtGZmSi+9tVNIg7louSS+s/ioVra3SoUz3iOFVhKPA=="], "glob": ["glob@13.0.5", "", { "dependencies": { "minimatch": "^10.2.1", "minipass": "^7.1.2", "path-scurry": "^2.0.0" } }, "sha512-BzXxZg24Ibra1pbQ/zE7Kys4Ua1ks7Bn6pKLkVPZ9FZe4JQS6/Q7ef3LG1H+k7lUf5l4T3PLSyYyYJVYUvfgTw=="], - "glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], - - "glob-to-regexp": ["glob-to-regexp@0.4.1", "", {}, "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw=="], - - "global-agent": ["global-agent@3.0.0", "", { "dependencies": { "boolean": "^3.0.1", "es6-error": "^4.1.1", "matcher": "^3.0.0", "roarr": "^2.15.3", "semver": "^7.3.2", "serialize-error": "^7.0.1" } }, "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q=="], - - "globalthis": ["globalthis@1.0.4", "", { "dependencies": { "define-properties": "^1.2.1", "gopd": "^1.0.1" } }, "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ=="], - - "globby": ["globby@11.0.4", "", { "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", "fast-glob": "^3.1.1", "ignore": "^5.1.4", "merge2": "^1.3.0", "slash": "^3.0.0" } }, "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg=="], - "google-auth-library": ["google-auth-library@10.5.0", "", { "dependencies": { "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", "gaxios": "^7.0.0", "gcp-metadata": "^8.0.0", "google-logging-utils": "^1.0.0", "gtoken": "^8.0.0", "jws": "^4.0.0" } }, "sha512-7ABviyMOlX5hIVD60YOfHw4/CxOfBhyduaYB+wbFWCWoni4N7SLcV46hrVRktuBbZjFC9ONyqamZITN7q3n32w=="], "google-logging-utils": ["google-logging-utils@1.1.3", "", {}, "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA=="], "gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="], - "got": ["got@11.8.6", "", { "dependencies": { "@sindresorhus/is": "^4.0.0", "@szmarczak/http-timer": "^4.0.5", "@types/cacheable-request": "^6.0.1", "@types/responselike": "^1.0.0", "cacheable-lookup": "^5.0.3", "cacheable-request": "^7.0.2", "decompress-response": "^6.0.0", "http2-wrapper": "^1.0.0-beta.5.2", "lowercase-keys": "^2.0.0", "p-cancelable": "^2.0.0", "responselike": "^2.0.0" } }, "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g=="], - "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], "graphql": ["graphql@16.13.2", "", {}, "sha512-5bJ+nf/UCpAjHM8i06fl7eLyVC9iuNAjm9qzkiu2ZGhM0VscSvS6WDPfAwkdkBuoXGM9FJSbKl6wylMwP9Ktig=="], @@ -3331,73 +2098,23 @@ "gtoken": ["gtoken@8.0.0", "", { "dependencies": { "gaxios": "^7.0.0", "jws": "^4.0.0" } }, "sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw=="], - "h3": ["h3@2.0.1-rc.4", "", { "dependencies": { "rou3": "^0.7.8", "srvx": "^0.9.1" }, "peerDependencies": { "crossws": "^0.4.1" }, "optionalPeers": ["crossws"] }, "sha512-vZq8pEUp6THsXKXrUXX44eOqfChic2wVQ1GlSzQCBr7DeFBkfIZAo2WyNND4GSv54TAa0E4LYIK73WSPdgKUgw=="], - - "happy-dom": ["happy-dom@20.9.0", "", { "dependencies": { "@types/node": ">=20.0.0", "@types/whatwg-mimetype": "^3.0.2", "@types/ws": "^8.18.1", "entities": "^7.0.1", "whatwg-mimetype": "^3.0.0", "ws": "^8.18.3" } }, "sha512-GZZ9mKe8r646NUAf/zemnGbjYh4Bt8/MqASJY+pSm5ZDtc3YQox+4gsLI7yi1hba6o+eCsGxpHn5+iEVn31/FQ=="], - - "has-bigints": ["has-bigints@1.1.0", "", {}, "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg=="], - - "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], - "has-property-descriptors": ["has-property-descriptors@1.0.2", "", { "dependencies": { "es-define-property": "^1.0.0" } }, "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg=="], - "has-proto": ["has-proto@1.2.0", "", { "dependencies": { "dunder-proto": "^1.0.0" } }, "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ=="], - "has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="], "has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="], - "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="], - - "hast-util-embedded": ["hast-util-embedded@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-is-element": "^3.0.0" } }, "sha512-naH8sld4Pe2ep03qqULEtvYr7EjrLK2QHY8KJR6RJkTUjPGObe1vnx585uzem2hGra+s1q08DZZpfgDVYRbaXA=="], - - "hast-util-format": ["hast-util-format@1.1.0", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-embedded": "^3.0.0", "hast-util-minify-whitespace": "^1.0.0", "hast-util-phrasing": "^3.0.0", "hast-util-whitespace": "^3.0.0", "html-whitespace-sensitive-tag-names": "^3.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-yY1UDz6bC9rDvCWHpx12aIBGRG7krurX0p0Fm6pT547LwDIZZiNr8a+IHDogorAdreULSEzP82Nlv5SZkHZcjA=="], - - "hast-util-from-html": ["hast-util-from-html@2.0.3", "", { "dependencies": { "@types/hast": "^3.0.0", "devlop": "^1.1.0", "hast-util-from-parse5": "^8.0.0", "parse5": "^7.0.0", "vfile": "^6.0.0", "vfile-message": "^4.0.0" } }, "sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw=="], - - "hast-util-from-parse5": ["hast-util-from-parse5@8.0.3", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "devlop": "^1.0.0", "hastscript": "^9.0.0", "property-information": "^7.0.0", "vfile": "^6.0.0", "vfile-location": "^5.0.0", "web-namespaces": "^2.0.0" } }, "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg=="], - - "hast-util-has-property": ["hast-util-has-property@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA=="], - - "hast-util-heading-rank": ["hast-util-heading-rank@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA=="], - - "hast-util-is-body-ok-link": ["hast-util-is-body-ok-link@3.0.1", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-0qpnzOBLztXHbHQenVB8uNuxTnm/QBFUOmdOSsEn7GnBtyY07+ENTWVFBAnXd/zEgd9/SUG3lRY7hSIBWRgGpQ=="], - - "hast-util-is-element": ["hast-util-is-element@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g=="], - - "hast-util-minify-whitespace": ["hast-util-minify-whitespace@1.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-embedded": "^3.0.0", "hast-util-is-element": "^3.0.0", "hast-util-whitespace": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-L96fPOVpnclQE0xzdWb/D12VT5FabA7SnZOUMtL1DbXmYiHJMXZvFkIZfiMmTCNJHUeO2K9UYNXoVyfz+QHuOw=="], - - "hast-util-parse-selector": ["hast-util-parse-selector@4.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A=="], - - "hast-util-phrasing": ["hast-util-phrasing@3.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-embedded": "^3.0.0", "hast-util-has-property": "^3.0.0", "hast-util-is-body-ok-link": "^3.0.0", "hast-util-is-element": "^3.0.0" } }, "sha512-6h60VfI3uBQUxHqTyMymMZnEbNl1XmEGtOxxKYL7stY2o601COo62AWAYBQR9lZbYXYSBoxag8UpPRXK+9fqSQ=="], - - "hast-util-raw": ["hast-util-raw@9.1.0", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "@ungap/structured-clone": "^1.0.0", "hast-util-from-parse5": "^8.0.0", "hast-util-to-parse5": "^8.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "parse5": "^7.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0", "web-namespaces": "^2.0.0", "zwitch": "^2.0.0" } }, "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw=="], - - "hast-util-select": ["hast-util-select@6.0.4", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "bcp-47-match": "^2.0.0", "comma-separated-tokens": "^2.0.0", "css-selector-parser": "^3.0.0", "devlop": "^1.0.0", "direction": "^2.0.0", "hast-util-has-property": "^3.0.0", "hast-util-to-string": "^3.0.0", "hast-util-whitespace": "^3.0.0", "nth-check": "^2.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "unist-util-visit": "^5.0.0", "zwitch": "^2.0.0" } }, "sha512-RqGS1ZgI0MwxLaKLDxjprynNzINEkRHY2i8ln4DDjgv9ZhcYVIHN9rlpiYsqtFwrgpYU361SyWDQcGNIBVu3lw=="], - - "hast-util-to-estree": ["hast-util-to-estree@3.1.3", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "comma-separated-tokens": "^2.0.0", "devlop": "^1.0.0", "estree-util-attach-comments": "^3.0.0", "estree-util-is-identifier-name": "^3.0.0", "hast-util-whitespace": "^3.0.0", "mdast-util-mdx-expression": "^2.0.0", "mdast-util-mdx-jsx": "^3.0.0", "mdast-util-mdxjs-esm": "^2.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "style-to-js": "^1.0.0", "unist-util-position": "^5.0.0", "zwitch": "^2.0.0" } }, "sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w=="], + "hasown": ["hasown@2.0.4", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A=="], "hast-util-to-html": ["hast-util-to-html@9.0.5", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-whitespace": "^3.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "stringify-entities": "^4.0.0", "zwitch": "^2.0.4" } }, "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw=="], - "hast-util-to-jsx-runtime": ["hast-util-to-jsx-runtime@2.3.6", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "comma-separated-tokens": "^2.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "hast-util-whitespace": "^3.0.0", "mdast-util-mdx-expression": "^2.0.0", "mdast-util-mdx-jsx": "^3.0.0", "mdast-util-mdxjs-esm": "^2.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "style-to-js": "^1.0.0", "unist-util-position": "^5.0.0", "vfile-message": "^4.0.0" } }, "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg=="], - - "hast-util-to-parse5": ["hast-util-to-parse5@8.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "comma-separated-tokens": "^2.0.0", "devlop": "^1.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "web-namespaces": "^2.0.0", "zwitch": "^2.0.0" } }, "sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA=="], - - "hast-util-to-string": ["hast-util-to-string@3.0.1", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A=="], - - "hast-util-to-text": ["hast-util-to-text@4.0.2", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "hast-util-is-element": "^3.0.0", "unist-util-find-after": "^5.0.0" } }, "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A=="], - "hast-util-whitespace": ["hast-util-whitespace@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw=="], - "hastscript": ["hastscript@9.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-parse-selector": "^4.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0" } }, "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w=="], - "he": ["he@1.2.0", "", { "bin": { "he": "bin/he" } }, "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="], "heap-snapshot-toolkit": ["heap-snapshot-toolkit@1.1.3", "", {}, "sha512-joThu2rEsDu8/l4arupRDI1qP4CZXNG+J6Wr348vnbLGSiBkwRdqZ6aOHl5BzEiC+Dc8OTbMlmWjD0lbXD5K2Q=="], - "hey-listen": ["hey-listen@1.0.8", "", {}, "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q=="], - - "hono": ["hono@4.10.7", "", {}, "sha512-icXIITfw/07Q88nLSkB9aiUrd8rYzSweK681Kjo/TSggaGbOX4RRyxxm71v+3PC8C/j+4rlxGeoTRxQDkaJkUw=="], + "hono": ["hono@4.13.5", "", {}, "sha512-O6+/eCYRkzzzy0rPWwKLiGBR1nFuUPZynnwjxN1MBA62NNqbT0wQEzQyK2gSO5yDIDB336sXQleAhOHrzlYyKw=="], "hono-openapi": ["hono-openapi@1.1.2", "", { "peerDependencies": { "@hono/standard-validator": "^0.2.0", "@standard-community/standard-json": "^0.3.5", "@standard-community/standard-openapi": "^0.2.9", "@types/json-schema": "^7.0.15", "hono": "^4.8.3", "openapi-types": "^12.1.3" }, "optionalPeers": ["@hono/standard-validator", "hono"] }, "sha512-toUcO60MftRBxqcVyxsHNYs2m4vf4xkQaiARAucQx3TiBPDtMNNkoh+C4I1vAretQZiGyaLOZNWn1YxfSyUA5g=="], @@ -3405,42 +2122,21 @@ "html-entities": ["html-entities@2.3.3", "", {}, "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA=="], - "html-escaper": ["html-escaper@3.0.3", "", {}, "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ=="], - - "html-minifier-terser": ["html-minifier-terser@7.2.0", "", { "dependencies": { "camel-case": "^4.1.2", "clean-css": "~5.3.2", "commander": "^10.0.0", "entities": "^4.4.0", "param-case": "^3.0.4", "relateurl": "^0.2.7", "terser": "^5.15.1" }, "bin": { "html-minifier-terser": "cli.js" } }, "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA=="], - - "html-to-image": ["html-to-image@1.11.13", "", {}, "sha512-cuOPoI7WApyhBElTTb9oqsawRvZ0rHhaHwghRLlTuffoD1B2aDemlCruLeZrUIIdvG7gs9xeELEPm6PhuASqrg=="], - - "html-to-text": ["html-to-text@9.0.5", "", { "dependencies": { "@selderee/plugin-htmlparser2": "^0.11.0", "deepmerge": "^4.3.1", "dom-serializer": "^2.0.0", "htmlparser2": "^8.0.2", "selderee": "^0.11.0" } }, "sha512-qY60FjREgVZL03vJU6IfMV4GDjGBIoOyvuFdpBDIX9yTlDw0TjxVBQp+P8NvpdIXNJvfWBTNul7fsAQJq2FNpg=="], - "html-void-elements": ["html-void-elements@3.0.0", "", {}, "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg=="], - "html-whitespace-sensitive-tag-names": ["html-whitespace-sensitive-tag-names@3.0.1", "", {}, "sha512-q+310vW8zmymYHALr1da4HyXUQ0zgiIwIicEfotYPWGN0OJVEN/58IJ3A4GBYcEq3LGAZqKb+ugvP0GNB9CEAA=="], - - "htmlparser2": ["htmlparser2@8.0.2", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.0.1", "entities": "^4.4.0" } }, "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA=="], - "http-cache-semantics": ["http-cache-semantics@4.2.0", "", {}, "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ=="], "http-errors": ["http-errors@2.0.1", "", { "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" } }, "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ=="], "http-proxy-agent": ["http-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" } }, "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig=="], - "http2-wrapper": ["http2-wrapper@1.0.3", "", { "dependencies": { "quick-lru": "^5.1.1", "resolve-alpn": "^1.0.0" } }, "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg=="], - - "https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], + "https-proxy-agent": ["https-proxy-agent@5.0.1", "", { "dependencies": { "agent-base": "6", "debug": "4" } }, "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA=="], "human-signals": ["human-signals@5.0.0", "", {}, "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ=="], - "humanize-ms": ["humanize-ms@1.2.1", "", { "dependencies": { "ms": "^2.0.0" } }, "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ=="], + "iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="], - - "i18next": ["i18next@23.16.8", "", { "dependencies": { "@babel/runtime": "^7.23.2" } }, "sha512-06r/TitrM88Mg5FdUXAKL96dJMzgqLE5dv3ryBAra4KCwD9mJ4ndOTS95ZuymIGoE+2hzfdaMak2X11/es7ZWg=="], - - "iconv-corefoundation": ["iconv-corefoundation@1.1.7", "", { "dependencies": { "cli-truncate": "^2.1.0", "node-addon-api": "^1.6.3" }, "os": "darwin" }, "sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ=="], - - "iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="], - - "ieee754": ["ieee754@1.1.13", "", {}, "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="], + "ieee754": ["ieee754@1.1.13", "", {}, "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="], "ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], @@ -3450,62 +2146,24 @@ "immer": ["immer@11.1.4", "", {}, "sha512-XREFCPo6ksxVzP4E0ekD5aMdf8WMwmdNaz6vuvxgI40UaEiu6q3p8X52aU6GdyvLY3XXX/8R7JOTXStz/nBbRw=="], - "import-local": ["import-local@3.2.0", "", { "dependencies": { "pkg-dir": "^4.2.0", "resolve-cwd": "^3.0.0" }, "bin": { "import-local-fixture": "fixtures/cli.js" } }, "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA=="], - - "import-meta-resolve": ["import-meta-resolve@4.2.0", "", {}, "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg=="], - - "imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="], - "indent-string": ["indent-string@4.0.0", "", {}, "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg=="], - "inflight": ["inflight@1.0.6", "", { "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA=="], - "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], "ini": ["ini@6.0.0", "", {}, "sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ=="], - "inline-style-parser": ["inline-style-parser@0.2.7", "", {}, "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA=="], - - "internal-slot": ["internal-slot@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "hasown": "^2.0.2", "side-channel": "^1.1.0" } }, "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw=="], - "ioredis": ["ioredis@5.10.1", "", { "dependencies": { "@ioredis/commands": "1.5.1", "cluster-key-slot": "^1.1.0", "debug": "^4.3.4", "denque": "^2.1.0", "lodash.defaults": "^4.2.0", "lodash.isarguments": "^3.1.0", "redis-errors": "^1.2.0", "redis-parser": "^3.0.0", "standard-as-callback": "^2.1.0" } }, "sha512-HuEDBTI70aYdx1v6U97SbNx9F1+svQKBDo30o0b9fw055LMepzpOOd0Ccg9Q6tbqmBSJaMuY0fB7yw9/vjBYCA=="], - "ip-address": ["ip-address@10.1.0", "", {}, "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q=="], + "ip-address": ["ip-address@10.3.1", "", {}, "sha512-1e9d3kb97NHJTIJDZW9rKqW2h6+dFa50Dy0fpPSMQp2ADje5gvKsXmdiK6dwY5t76TaTt5+P5N1Y/LoToIxP6g=="], "ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="], - "iron-webcrypto": ["iron-webcrypto@1.2.1", "", {}, "sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg=="], - - "is-alphabetical": ["is-alphabetical@2.0.1", "", {}, "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ=="], - - "is-alphanumerical": ["is-alphanumerical@2.0.1", "", { "dependencies": { "is-alphabetical": "^2.0.0", "is-decimal": "^2.0.0" } }, "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw=="], - "is-arguments": ["is-arguments@1.2.0", "", { "dependencies": { "call-bound": "^1.0.2", "has-tostringtag": "^1.0.2" } }, "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA=="], - "is-array-buffer": ["is-array-buffer@3.0.5", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "get-intrinsic": "^1.2.6" } }, "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A=="], - - "is-arrayish": ["is-arrayish@0.3.4", "", {}, "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA=="], - - "is-async-function": ["is-async-function@2.1.1", "", { "dependencies": { "async-function": "^1.0.0", "call-bound": "^1.0.3", "get-proto": "^1.0.1", "has-tostringtag": "^1.0.2", "safe-regex-test": "^1.1.0" } }, "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ=="], - - "is-bigint": ["is-bigint@1.1.0", "", { "dependencies": { "has-bigints": "^1.0.2" } }, "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ=="], - - "is-binary-path": ["is-binary-path@2.1.0", "", { "dependencies": { "binary-extensions": "^2.0.0" } }, "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw=="], - - "is-boolean-object": ["is-boolean-object@1.2.2", "", { "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" } }, "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A=="], - - "is-buffer": ["is-buffer@1.1.6", "", {}, "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="], - "is-callable": ["is-callable@1.2.7", "", {}, "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA=="], "is-core-module": ["is-core-module@2.16.1", "", { "dependencies": { "hasown": "^2.0.2" } }, "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w=="], - "is-data-view": ["is-data-view@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "get-intrinsic": "^1.2.6", "is-typed-array": "^1.1.13" } }, "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw=="], - - "is-date-object": ["is-date-object@1.1.0", "", { "dependencies": { "call-bound": "^1.0.2", "has-tostringtag": "^1.0.2" } }, "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg=="], - - "is-decimal": ["is-decimal@2.0.1", "", {}, "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A=="], - "is-docker": ["is-docker@3.0.0", "", { "bin": { "is-docker": "cli.js" } }, "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ=="], "is-electron": ["is-electron@2.2.2", "", {}, "sha512-FO/Rhvz5tuw4MCWkpMzHFKWD2LsfHzIb7i6MdPYZ/KW7AlxawyLkqdy+jPZP1WubqEADE3O4FUENlJHDfQASRg=="], @@ -3514,82 +2172,40 @@ "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="], - "is-finalizationregistry": ["is-finalizationregistry@1.1.1", "", { "dependencies": { "call-bound": "^1.0.3" } }, "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg=="], - "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="], "is-generator-function": ["is-generator-function@1.1.2", "", { "dependencies": { "call-bound": "^1.0.4", "generator-function": "^2.0.0", "get-proto": "^1.0.1", "has-tostringtag": "^1.0.2", "safe-regex-test": "^1.1.0" } }, "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA=="], "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="], - "is-hexadecimal": ["is-hexadecimal@2.0.1", "", {}, "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg=="], - "is-in-ssh": ["is-in-ssh@1.0.0", "", {}, "sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw=="], "is-inside-container": ["is-inside-container@1.0.0", "", { "dependencies": { "is-docker": "^3.0.0" }, "bin": { "is-inside-container": "cli.js" } }, "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA=="], - "is-interactive": ["is-interactive@1.0.0", "", {}, "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w=="], - - "is-map": ["is-map@2.0.3", "", {}, "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw=="], - - "is-negative-zero": ["is-negative-zero@2.0.3", "", {}, "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw=="], - "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="], - "is-number-object": ["is-number-object@1.1.1", "", { "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" } }, "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw=="], - - "is-plain-obj": ["is-plain-obj@4.1.0", "", {}, "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg=="], - "is-promise": ["is-promise@4.0.0", "", {}, "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="], - "is-property": ["is-property@1.0.2", "", {}, "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g=="], - "is-regex": ["is-regex@1.2.1", "", { "dependencies": { "call-bound": "^1.0.2", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g=="], - "is-set": ["is-set@2.0.3", "", {}, "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg=="], - - "is-shared-array-buffer": ["is-shared-array-buffer@1.0.4", "", { "dependencies": { "call-bound": "^1.0.3" } }, "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A=="], - - "is-stream": ["is-stream@1.1.0", "", {}, "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ=="], - - "is-string": ["is-string@1.1.1", "", { "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" } }, "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA=="], - - "is-symbol": ["is-symbol@1.1.1", "", { "dependencies": { "call-bound": "^1.0.2", "has-symbols": "^1.1.0", "safe-regex-test": "^1.1.0" } }, "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w=="], + "is-stream": ["is-stream@2.0.1", "", {}, "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="], "is-typed-array": ["is-typed-array@1.1.15", "", { "dependencies": { "which-typed-array": "^1.1.16" } }, "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ=="], - "is-unicode-supported": ["is-unicode-supported@0.1.0", "", {}, "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw=="], - - "is-weakmap": ["is-weakmap@2.0.2", "", {}, "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w=="], - - "is-weakref": ["is-weakref@1.1.1", "", { "dependencies": { "call-bound": "^1.0.3" } }, "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew=="], - - "is-weakset": ["is-weakset@2.0.4", "", { "dependencies": { "call-bound": "^1.0.3", "get-intrinsic": "^1.2.6" } }, "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ=="], - "is-what": ["is-what@4.1.16", "", {}, "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A=="], - "is-whitespace": ["is-whitespace@0.3.0", "", {}, "sha512-RydPhl4S6JwAyj0JJjshWJEFG6hNye3pZFBRZaTUfZFwGHxzppNaNOVgQuS/E/SlhrApuMXrpnK1EEIXfdo3Dg=="], - "is-wsl": ["is-wsl@3.1.1", "", { "dependencies": { "is-inside-container": "^1.0.0" } }, "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw=="], "is64bit": ["is64bit@2.0.0", "", { "dependencies": { "system-architecture": "^0.1.0" } }, "sha512-jv+8jaWCl0g2lSBkNSVXdzfBA0npK1HGC2KtWM9FumFRoGS94g3NbCCLVnCYHLjp4GrW2KZeeSTMo5ddtznmGw=="], "isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="], - "isbinaryfile": ["isbinaryfile@5.0.7", "", {}, "sha512-gnWD14Jh3FzS3CPhF0AxNOJ8CxqeblPTADzI38r0wt8ZyQl5edpy75myt08EG2oKvpyiqSqsx+Wkz9vtkbTqYQ=="], - "isexe": ["isexe@4.0.0", "", {}, "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw=="], "isomorphic-ws": ["isomorphic-ws@5.0.0", "", { "peerDependencies": { "ws": "*" } }, "sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw=="], - "iterate-iterator": ["iterate-iterator@1.0.2", "", {}, "sha512-t91HubM4ZDQ70M9wqp+pcNpu8OyJ9UAtXntT/Bcsvp5tZMnz9vRa+IunKXeI8AnfZMTv0jNuVEmGeLSMjVvfPw=="], - - "iterate-value": ["iterate-value@1.0.2", "", { "dependencies": { "es-get-iterator": "^1.0.2", "iterate-iterator": "^1.0.1" } }, "sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ=="], - "jackspeak": ["jackspeak@4.2.3", "", { "dependencies": { "@isaacs/cliui": "^9.0.0" } }, "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg=="], - "jake": ["jake@10.9.4", "", { "dependencies": { "async": "^3.2.6", "filelist": "^1.0.4", "picocolors": "^1.1.1" }, "bin": { "jake": "bin/cli.js" } }, "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA=="], - "jimp": ["jimp@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/diff": "1.6.0", "@jimp/js-bmp": "1.6.0", "@jimp/js-gif": "1.6.0", "@jimp/js-jpeg": "1.6.0", "@jimp/js-png": "1.6.0", "@jimp/js-tiff": "1.6.0", "@jimp/plugin-blit": "1.6.0", "@jimp/plugin-blur": "1.6.0", "@jimp/plugin-circle": "1.6.0", "@jimp/plugin-color": "1.6.0", "@jimp/plugin-contain": "1.6.0", "@jimp/plugin-cover": "1.6.0", "@jimp/plugin-crop": "1.6.0", "@jimp/plugin-displace": "1.6.0", "@jimp/plugin-dither": "1.6.0", "@jimp/plugin-fisheye": "1.6.0", "@jimp/plugin-flip": "1.6.0", "@jimp/plugin-hash": "1.6.0", "@jimp/plugin-mask": "1.6.0", "@jimp/plugin-print": "1.6.0", "@jimp/plugin-quantize": "1.6.0", "@jimp/plugin-resize": "1.6.0", "@jimp/plugin-rotate": "1.6.0", "@jimp/plugin-threshold": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0" } }, "sha512-YcwCHw1kiqEeI5xRpDlPPBGL2EOpBKLwO4yIBJcXWHPj5PnA5urGq0jbyhM5KoNpypQ6VboSoxc9D8HyfvngSg=="], "jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="], @@ -3600,17 +2216,11 @@ "jpeg-js": ["jpeg-js@0.4.4", "", {}, "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg=="], - "js-base64": ["js-base64@3.7.7", "", {}, "sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw=="], - - "js-beautify": ["js-beautify@1.15.4", "", { "dependencies": { "config-chain": "^1.1.13", "editorconfig": "^1.0.4", "glob": "^10.4.2", "js-cookie": "^3.0.5", "nopt": "^7.2.1" }, "bin": { "css-beautify": "js/bin/css-beautify.js", "html-beautify": "js/bin/html-beautify.js", "js-beautify": "js/bin/js-beautify.js" } }, "sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA=="], - - "js-cookie": ["js-cookie@3.0.5", "", {}, "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw=="], - "js-md4": ["js-md4@0.3.2", "", {}, "sha512-/GDnfQYsltsjRswQhN9fhv3EMw2sCpUdrdxyWDOUK7eyD++r3gRhzgiQgc/x4MAv2i1iuQ4lxO5mvqM3vj4bwA=="], "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], - "js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="], + "js-yaml": ["js-yaml@4.3.2", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA=="], "jsbi": ["jsbi@4.3.2", "", {}, "sha512-9fqMSQbhJykSeii05nxKl4m6Eqn2P6rOlYiS+C5Dr/HPIU/7yZxu5qzbs40tgaFORiw2Amd0mirjxatXYMkIew=="], @@ -3618,8 +2228,6 @@ "json-bigint": ["json-bigint@1.0.0", "", { "dependencies": { "bignumber.js": "^9.0.0" } }, "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ=="], - "json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="], - "json-parse-even-better-errors": ["json-parse-even-better-errors@5.0.0", "", {}, "sha512-ZF1nxZ28VhQouRWhUcVlUIN3qwSgPuswK05s/HIaoetAoE/9tngVmCHjSxmSQPav1nd+lPtTL0YZ/2AFdR/iYQ=="], "json-schema": ["json-schema@0.4.0", "", {}, "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="], @@ -3634,16 +2242,12 @@ "json-stringify-nice": ["json-stringify-nice@1.1.4", "", {}, "sha512-5Z5RFW63yxReJ7vANgW6eZFGWaQvnPE3WNmZoOJrSkGju2etKA2L5rrOa1sm877TVTFt57A80BH1bArcmlLfPw=="], - "json-stringify-safe": ["json-stringify-safe@5.0.1", "", {}, "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA=="], - "json-with-bigint": ["json-with-bigint@3.5.8", "", {}, "sha512-eq/4KP6K34kwa7TcFdtvnftvHCD9KvHOGGICWwMFc4dOOKF5t4iYqnfLK8otCRCRv06FXOzGGyqE8h8ElMvvdw=="], "json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="], "jsonc-parser": ["jsonc-parser@3.3.1", "", {}, "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ=="], - "jsonfile": ["jsonfile@4.0.0", "", { "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg=="], - "jsonparse": ["jsonparse@1.3.1", "", {}, "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg=="], "jsonwebtoken": ["jsonwebtoken@9.0.3", "", { "dependencies": { "jws": "^4.0.1", "lodash.includes": "^4.3.0", "lodash.isboolean": "^3.0.3", "lodash.isinteger": "^4.0.4", "lodash.isnumber": "^3.0.3", "lodash.isplainobject": "^4.0.6", "lodash.isstring": "^4.0.1", "lodash.once": "^4.0.0", "ms": "^2.1.1", "semver": "^7.5.4" } }, "sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g=="], @@ -3660,26 +2264,12 @@ "katex": ["katex@0.16.27", "", { "dependencies": { "commander": "^8.3.0" }, "bin": { "katex": "cli.js" } }, "sha512-aeQoDkuRWSqQN6nSvVCEFvfXdqo1OQiCmmW1kc9xSdjutPv7BGO7pqY9sQRJpMOGrEdfDgF2TfRXe5eUAD2Waw=="], - "keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="], - "kind-of": ["kind-of@6.0.3", "", {}, "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="], - "kleur": ["kleur@4.1.5", "", {}, "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="], - - "klona": ["klona@2.0.6", "", {}, "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA=="], - "kubernetes-types": ["kubernetes-types@1.30.0", "", {}, "sha512-Dew1okvhM/SQcIa2rcgujNndZwU8VnSapDgdxlYoB84ZlpAD43U6KLAFqYo17ykSFGHNPrg0qry0bP+GJd9v7Q=="], - "lang-map": ["lang-map@0.4.0", "", { "dependencies": { "language-map": "^1.1.0" } }, "sha512-oiSqZIEUnWdFeDNsp4HId4tAxdFbx5iMBOwA3666Fn2L8Khj8NiD9xRvMsGmKXopPVkaDFtSv3CJOmXFUB0Hcg=="], - - "language-map": ["language-map@1.5.0", "", {}, "sha512-n7gFZpe+DwEAX9cXVTw43i3wiudWDDtSn28RmdnS/HCPr284dQI/SztsamWanRr75oSlKSaGbV2nmWCTzGCoVg=="], - - "lazy-val": ["lazy-val@1.0.5", "", {}, "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q=="], - "lazystream": ["lazystream@1.0.1", "", { "dependencies": { "readable-stream": "^2.0.5" } }, "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw=="], - "leac": ["leac@0.6.0", "", {}, "sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg=="], - "light-my-request": ["light-my-request@6.6.0", "", { "dependencies": { "cookie": "^1.0.1", "process-warning": "^4.0.0", "set-cookie-parser": "^2.6.0" } }, "sha512-CHYbu8RtboSIoVsHZ6Ye4cj4Aw/yg2oAFimlF7mNvfDV192LR7nDiKtSIfCuLT7KokPSTn/9kfVLm5OGN0A28A=="], "lightningcss": ["lightningcss@1.30.1", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-darwin-arm64": "1.30.1", "lightningcss-darwin-x64": "1.30.1", "lightningcss-freebsd-x64": "1.30.1", "lightningcss-linux-arm-gnueabihf": "1.30.1", "lightningcss-linux-arm64-gnu": "1.30.1", "lightningcss-linux-arm64-musl": "1.30.1", "lightningcss-linux-x64-gnu": "1.30.1", "lightningcss-linux-x64-musl": "1.30.1", "lightningcss-win32-arm64-msvc": "1.30.1", "lightningcss-win32-x64-msvc": "1.30.1" } }, "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg=="], @@ -3704,26 +2294,18 @@ "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.30.1", "", { "os": "win32", "cpu": "x64" }, "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg=="], - "lilconfig": ["lilconfig@2.1.0", "", {}, "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ=="], - - "lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="], - - "locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="], + "locate-path": ["locate-path@3.0.0", "", { "dependencies": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" } }, "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A=="], "lodash": ["lodash@4.18.1", "", {}, "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q=="], "lodash.defaults": ["lodash.defaults@4.2.0", "", {}, "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ=="], - "lodash.escaperegexp": ["lodash.escaperegexp@4.1.2", "", {}, "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw=="], - "lodash.includes": ["lodash.includes@4.3.0", "", {}, "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w=="], "lodash.isarguments": ["lodash.isarguments@3.1.0", "", {}, "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg=="], "lodash.isboolean": ["lodash.isboolean@3.0.3", "", {}, "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg=="], - "lodash.isequal": ["lodash.isequal@4.5.0", "", {}, "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ=="], - "lodash.isinteger": ["lodash.isinteger@4.0.4", "", {}, "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA=="], "lodash.isnumber": ["lodash.isnumber@3.0.3", "", {}, "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw=="], @@ -3734,174 +2316,44 @@ "lodash.once": ["lodash.once@4.1.1", "", {}, "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="], - "log-symbols": ["log-symbols@4.1.0", "", { "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" } }, "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg=="], - - "loglevelnext": ["loglevelnext@6.0.0", "", {}, "sha512-FDl1AI2sJGjHHG3XKJd6sG3/6ncgiGCQ0YkW46nxe7SfqQq6hujd9CvFXIXtkGBUN83KPZ2KSOJK8q5P0bSSRQ=="], - - "long": ["long@5.3.2", "", {}, "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA=="], - - "longest-streak": ["longest-streak@3.1.0", "", {}, "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g=="], - "loose-envify": ["loose-envify@1.4.0", "", { "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": { "loose-envify": "cli.js" } }, "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="], - "loupe": ["loupe@3.2.1", "", {}, "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ=="], - - "lower-case": ["lower-case@2.0.2", "", { "dependencies": { "tslib": "^2.0.3" } }, "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg=="], - - "lowercase-keys": ["lowercase-keys@2.0.0", "", {}, "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA=="], - "lru-cache": ["lru-cache@11.3.5", "", {}, "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw=="], - "lru.min": ["lru.min@1.1.4", "", {}, "sha512-DqC6n3QQ77zdFpCMASA1a3Jlb64Hv2N2DciFGkO/4L9+q/IpIAuRlKOvCXabtRW6cQf8usbmM6BE/TOPysCdIA=="], - "lru_map": ["lru_map@0.4.1", "", {}, "sha512-I+lBvqMMFfqaV8CJCISjI3wbjmwVu/VyOoU7+qtu9d7ioW5klMgsTTiUOUp+DJvfTTzKXoPbyC6YfgkNcyPSOg=="], "luxon": ["luxon@3.6.1", "", {}, "sha512-tJLxrKJhO2ukZ5z0gyjY1zPh3Rh88Ej9P7jNrZiHMUXHae1yvI2imgOZtL1TO8TW6biMMKfTtAOoEJANgtWBMQ=="], - "lz-string": ["lz-string@1.5.0", "", { "bin": { "lz-string": "bin/bin.js" } }, "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ=="], - "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], - "magicast": ["magicast@0.3.5", "", { "dependencies": { "@babel/parser": "^7.25.4", "@babel/types": "^7.25.4", "source-map-js": "^1.2.0" } }, "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ=="], - "make-fetch-happen": ["make-fetch-happen@15.0.5", "", { "dependencies": { "@gar/promise-retry": "^1.0.0", "@npmcli/agent": "^4.0.0", "@npmcli/redact": "^4.0.0", "cacache": "^20.0.1", "http-cache-semantics": "^4.1.1", "minipass": "^7.0.2", "minipass-fetch": "^5.0.0", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "negotiator": "^1.0.0", "proc-log": "^6.0.0", "ssri": "^13.0.0" } }, "sha512-uCbIa8jWWmQZt4dSnEStkVC6gdakiinAm4PiGsywIkguF0eWMdcjDz0ECYhUolFU3pFLOev9VNPCEygydXnddg=="], - "markdown-extensions": ["markdown-extensions@2.0.0", "", {}, "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q=="], - - "markdown-table": ["markdown-table@3.0.4", "", {}, "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw=="], - "marked": ["marked@17.0.1", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-boeBdiS0ghpWcSwoNm/jJBwdpFaMnZWRzjA6SkUMYb40SVaN1x7mmfGKp0jvexGcx+7y2La5zRZsYFZI6Qpypg=="], "marked-katex-extension": ["marked-katex-extension@5.1.6", "", { "peerDependencies": { "katex": ">=0.16 <0.17", "marked": ">=4 <18" } }, "sha512-vYpLXwmlIDKILIhJtiRTgdyZRn5sEYdFBuTmbpjD7lbCIzg0/DWyK3HXIntN3Tp8zV6hvOUgpZNLWRCgWVc24A=="], "marked-shiki": ["marked-shiki@1.2.1", "", { "peerDependencies": { "marked": ">=7.0.0", "shiki": ">=1.0.0" } }, "sha512-yHxYQhPY5oYaIRnROn98foKhuClark7M373/VpLxiy5TrDu9Jd/LsMwo8w+U91Up4oDb9IXFrP0N1MFRz8W/DQ=="], - "matcher": ["matcher@3.0.0", "", { "dependencies": { "escape-string-regexp": "^4.0.0" } }, "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng=="], - "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="], - "md-to-react-email": ["md-to-react-email@5.0.0", "", { "dependencies": { "marked": "7.0.4" }, "peerDependencies": { "react": "18.x" } }, "sha512-GdBrBUbAAJHypnuyofYGfVos8oUslxHx69hs3CW9P0L8mS1sT6GnJuMBTlz/Fw+2widiwdavcu9UwyLF/BzZ4w=="], - - "mdast-util-definitions": ["mdast-util-definitions@6.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "unist-util-visit": "^5.0.0" } }, "sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ=="], - - "mdast-util-directive": ["mdast-util-directive@3.1.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "devlop": "^1.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0", "parse-entities": "^4.0.0", "stringify-entities": "^4.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q=="], - - "mdast-util-find-and-replace": ["mdast-util-find-and-replace@3.0.2", "", { "dependencies": { "@types/mdast": "^4.0.0", "escape-string-regexp": "^5.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg=="], - - "mdast-util-from-markdown": ["mdast-util-from-markdown@2.0.3", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "mdast-util-to-string": "^4.0.0", "micromark": "^4.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q=="], - - "mdast-util-gfm": ["mdast-util-gfm@3.1.0", "", { "dependencies": { "mdast-util-from-markdown": "^2.0.0", "mdast-util-gfm-autolink-literal": "^2.0.0", "mdast-util-gfm-footnote": "^2.0.0", "mdast-util-gfm-strikethrough": "^2.0.0", "mdast-util-gfm-table": "^2.0.0", "mdast-util-gfm-task-list-item": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ=="], - - "mdast-util-gfm-autolink-literal": ["mdast-util-gfm-autolink-literal@2.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "ccount": "^2.0.0", "devlop": "^1.0.0", "mdast-util-find-and-replace": "^3.0.0", "micromark-util-character": "^2.0.0" } }, "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ=="], - - "mdast-util-gfm-footnote": ["mdast-util-gfm-footnote@2.1.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.1.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0" } }, "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ=="], - - "mdast-util-gfm-strikethrough": ["mdast-util-gfm-strikethrough@2.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg=="], - - "mdast-util-gfm-table": ["mdast-util-gfm-table@2.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "markdown-table": "^3.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg=="], - - "mdast-util-gfm-task-list-item": ["mdast-util-gfm-task-list-item@2.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ=="], - - "mdast-util-mdx": ["mdast-util-mdx@3.0.0", "", { "dependencies": { "mdast-util-from-markdown": "^2.0.0", "mdast-util-mdx-expression": "^2.0.0", "mdast-util-mdx-jsx": "^3.0.0", "mdast-util-mdxjs-esm": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w=="], - - "mdast-util-mdx-expression": ["mdast-util-mdx-expression@2.0.1", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ=="], - - "mdast-util-mdx-jsx": ["mdast-util-mdx-jsx@3.2.0", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "devlop": "^1.1.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0", "parse-entities": "^4.0.0", "stringify-entities": "^4.0.0", "unist-util-stringify-position": "^4.0.0", "vfile-message": "^4.0.0" } }, "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q=="], - - "mdast-util-mdxjs-esm": ["mdast-util-mdxjs-esm@2.0.1", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg=="], - - "mdast-util-phrasing": ["mdast-util-phrasing@4.1.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "unist-util-is": "^6.0.0" } }, "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w=="], - "mdast-util-to-hast": ["mdast-util-to-hast@13.2.1", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "@ungap/structured-clone": "^1.0.0", "devlop": "^1.0.0", "micromark-util-sanitize-uri": "^2.0.0", "trim-lines": "^3.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" } }, "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA=="], - "mdast-util-to-markdown": ["mdast-util-to-markdown@2.1.2", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "longest-streak": "^3.0.0", "mdast-util-phrasing": "^4.0.0", "mdast-util-to-string": "^4.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "unist-util-visit": "^5.0.0", "zwitch": "^2.0.0" } }, "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA=="], + "media-typer": ["media-typer@1.1.0", "", {}, "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw=="], - "mdast-util-to-string": ["mdast-util-to-string@4.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0" } }, "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg=="], - - "mdn-data": ["mdn-data@2.27.1", "", {}, "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ=="], - - "media-typer": ["media-typer@0.3.0", "", {}, "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ=="], - - "mendcode": ["mendcode-runtime-cli@workspace:packages/opencode"], + "mendcode": ["mendcode@workspace:packages/opencode"], "merge-anything": ["merge-anything@5.1.7", "", { "dependencies": { "is-what": "^4.1.8" } }, "sha512-eRtbOb1N5iyH0tkQDAoQ4Ipsp/5qSR79Dzrz8hEPxRX10RWWR/iQXdoKmBSRCThY1Fh5EhISDtpSc93fpxUniQ=="], - "merge-descriptors": ["merge-descriptors@1.0.3", "", {}, "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ=="], + "merge-descriptors": ["merge-descriptors@2.0.0", "", {}, "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g=="], "merge-stream": ["merge-stream@2.0.0", "", {}, "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="], - "merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="], - - "methods": ["methods@1.1.2", "", {}, "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w=="], - - "micromark": ["micromark@4.0.2", "", { "dependencies": { "@types/debug": "^4.0.0", "debug": "^4.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "micromark-core-commonmark": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-combine-extensions": "^2.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA=="], - - "micromark-core-commonmark": ["micromark-core-commonmark@2.0.3", "", { "dependencies": { "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "micromark-factory-destination": "^2.0.0", "micromark-factory-label": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-factory-title": "^2.0.0", "micromark-factory-whitespace": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-html-tag-name": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg=="], - - "micromark-extension-directive": ["micromark-extension-directive@3.0.2", "", { "dependencies": { "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", "micromark-factory-whitespace": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "parse-entities": "^4.0.0" } }, "sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA=="], - - "micromark-extension-gfm": ["micromark-extension-gfm@3.0.0", "", { "dependencies": { "micromark-extension-gfm-autolink-literal": "^2.0.0", "micromark-extension-gfm-footnote": "^2.0.0", "micromark-extension-gfm-strikethrough": "^2.0.0", "micromark-extension-gfm-table": "^2.0.0", "micromark-extension-gfm-tagfilter": "^2.0.0", "micromark-extension-gfm-task-list-item": "^2.0.0", "micromark-util-combine-extensions": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w=="], - - "micromark-extension-gfm-autolink-literal": ["micromark-extension-gfm-autolink-literal@2.1.0", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw=="], - - "micromark-extension-gfm-footnote": ["micromark-extension-gfm-footnote@2.1.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-core-commonmark": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw=="], - - "micromark-extension-gfm-strikethrough": ["micromark-extension-gfm-strikethrough@2.1.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw=="], - - "micromark-extension-gfm-table": ["micromark-extension-gfm-table@2.1.1", "", { "dependencies": { "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg=="], - - "micromark-extension-gfm-tagfilter": ["micromark-extension-gfm-tagfilter@2.0.0", "", { "dependencies": { "micromark-util-types": "^2.0.0" } }, "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg=="], - - "micromark-extension-gfm-task-list-item": ["micromark-extension-gfm-task-list-item@2.1.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw=="], - - "micromark-extension-mdx-expression": ["micromark-extension-mdx-expression@3.0.1", "", { "dependencies": { "@types/estree": "^1.0.0", "devlop": "^1.0.0", "micromark-factory-mdx-expression": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-events-to-acorn": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q=="], - - "micromark-extension-mdx-jsx": ["micromark-extension-mdx-jsx@3.0.2", "", { "dependencies": { "@types/estree": "^1.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "micromark-factory-mdx-expression": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-events-to-acorn": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ=="], - - "micromark-extension-mdx-md": ["micromark-extension-mdx-md@2.0.0", "", { "dependencies": { "micromark-util-types": "^2.0.0" } }, "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ=="], - - "micromark-extension-mdxjs": ["micromark-extension-mdxjs@3.0.0", "", { "dependencies": { "acorn": "^8.0.0", "acorn-jsx": "^5.0.0", "micromark-extension-mdx-expression": "^3.0.0", "micromark-extension-mdx-jsx": "^3.0.0", "micromark-extension-mdx-md": "^2.0.0", "micromark-extension-mdxjs-esm": "^3.0.0", "micromark-util-combine-extensions": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ=="], - - "micromark-extension-mdxjs-esm": ["micromark-extension-mdxjs-esm@3.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "devlop": "^1.0.0", "micromark-core-commonmark": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-events-to-acorn": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "unist-util-position-from-estree": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A=="], - - "micromark-factory-destination": ["micromark-factory-destination@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA=="], - - "micromark-factory-label": ["micromark-factory-label@2.0.1", "", { "dependencies": { "devlop": "^1.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg=="], - - "micromark-factory-mdx-expression": ["micromark-factory-mdx-expression@2.0.3", "", { "dependencies": { "@types/estree": "^1.0.0", "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-events-to-acorn": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "unist-util-position-from-estree": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ=="], - - "micromark-factory-space": ["micromark-factory-space@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg=="], - - "micromark-factory-title": ["micromark-factory-title@2.0.1", "", { "dependencies": { "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw=="], - - "micromark-factory-whitespace": ["micromark-factory-whitespace@2.0.1", "", { "dependencies": { "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ=="], - "micromark-util-character": ["micromark-util-character@2.1.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q=="], - "micromark-util-chunked": ["micromark-util-chunked@2.0.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA=="], - - "micromark-util-classify-character": ["micromark-util-classify-character@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q=="], - - "micromark-util-combine-extensions": ["micromark-util-combine-extensions@2.0.1", "", { "dependencies": { "micromark-util-chunked": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg=="], - - "micromark-util-decode-numeric-character-reference": ["micromark-util-decode-numeric-character-reference@2.0.2", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw=="], - - "micromark-util-decode-string": ["micromark-util-decode-string@2.0.1", "", { "dependencies": { "decode-named-character-reference": "^1.0.0", "micromark-util-character": "^2.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-symbol": "^2.0.0" } }, "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ=="], - "micromark-util-encode": ["micromark-util-encode@2.0.1", "", {}, "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw=="], - "micromark-util-events-to-acorn": ["micromark-util-events-to-acorn@2.0.3", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/unist": "^3.0.0", "devlop": "^1.0.0", "estree-util-visit": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg=="], - - "micromark-util-html-tag-name": ["micromark-util-html-tag-name@2.0.1", "", {}, "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA=="], - - "micromark-util-normalize-identifier": ["micromark-util-normalize-identifier@2.0.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q=="], - - "micromark-util-resolve-all": ["micromark-util-resolve-all@2.0.1", "", { "dependencies": { "micromark-util-types": "^2.0.0" } }, "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg=="], - "micromark-util-sanitize-uri": ["micromark-util-sanitize-uri@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-symbol": "^2.0.0" } }, "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ=="], - "micromark-util-subtokenize": ["micromark-util-subtokenize@2.1.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA=="], - "micromark-util-symbol": ["micromark-util-symbol@2.0.1", "", {}, "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q=="], "micromark-util-types": ["micromark-util-types@2.0.2", "", {}, "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA=="], @@ -3916,14 +2368,8 @@ "mimic-fn": ["mimic-fn@4.0.0", "", {}, "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw=="], - "mimic-function": ["mimic-function@5.0.1", "", {}, "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA=="], - - "mimic-response": ["mimic-response@3.1.0", "", {}, "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="], - "min-indent": ["min-indent@1.0.1", "", {}, "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg=="], - "miniflare": ["miniflare@4.20251118.1", "", { "dependencies": { "@cspotcode/source-map-support": "0.8.1", "acorn": "8.14.0", "acorn-walk": "8.3.2", "exit-hook": "2.2.1", "glob-to-regexp": "0.4.1", "sharp": "^0.33.5", "stoppable": "1.1.0", "undici": "7.14.0", "workerd": "1.20251118.0", "ws": "8.18.0", "youch": "4.1.0-beta.10", "zod": "3.22.3" }, "bin": { "miniflare": "bootstrap.js" } }, "sha512-uLSAE/DvOm392fiaig4LOaatxLjM7xzIniFRG5Y3yF9IduOYLLK/pkCPQNCgKQH3ou0YJRHnTN+09LPfqYNTQQ=="], - "minimatch": ["minimatch@10.2.5", "", { "dependencies": { "brace-expansion": "^5.0.5" } }, "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg=="], "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="], @@ -3952,8 +2398,6 @@ "motion-utils": ["motion-utils@12.29.2", "", {}, "sha512-G3kc34H2cX2gI63RqU+cZq+zWRRPSsNIOjpdl9TN4AQwC4sgwYPl/Q/Obf/d53nOm569T0fYK+tcoSV50BWx8A=="], - "mrmime": ["mrmime@2.0.1", "", {}, "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ=="], - "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], "msgpackr": ["msgpackr@1.11.9", "", { "optionalDependencies": { "msgpackr-extract": "^3.0.2" } }, "sha512-FkoAAyyA6HM8wL882EcEyFZ9s7hVADSwG9xrVx3dxxNQAtgADTrJoEWivID82Iv1zWDsv/OtbrrcZAzGzOMdNw=="], @@ -3962,49 +2406,23 @@ "mssql": ["mssql@11.0.1", "", { "dependencies": { "@tediousjs/connection-string": "^0.5.0", "commander": "^11.0.0", "debug": "^4.3.3", "rfdc": "^1.3.0", "tarn": "^3.0.2", "tedious": "^18.2.1" }, "bin": { "mssql": "bin/mssql" } }, "sha512-KlGNsugoT90enKlR8/G36H0kTxPthDhmtNUCwEHvgRza5Cjpjoj+P2X6eMpFUDN7pFrJZsKadL4x990G8RBE1w=="], - "muggle-string": ["muggle-string@0.4.1", "", {}, "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ=="], - "multicast-dns": ["multicast-dns@7.2.5", "", { "dependencies": { "dns-packet": "^5.2.2", "thunky": "^1.0.2" }, "bin": { "multicast-dns": "cli.js" } }, "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg=="], "multipasta": ["multipasta@0.2.7", "", {}, "sha512-KPA58d68KgGil15oDqXjkUBEBYc00XvbPj5/X+dyzeo/lWm9Nc25pQRlf1D+gv4OpK7NM0J1odrbu9JNNGvynA=="], - "mustache": ["mustache@4.2.0", "", { "bin": { "mustache": "bin/mustache" } }, "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ=="], - - "mysql2": ["mysql2@3.14.4", "", { "dependencies": { "aws-ssl-profiles": "^1.1.1", "denque": "^2.1.0", "generate-function": "^2.3.1", "iconv-lite": "^0.7.0", "long": "^5.2.1", "lru.min": "^1.0.0", "named-placeholders": "^1.1.3", "seq-queue": "^0.0.5", "sqlstring": "^2.3.2" } }, "sha512-Cs/jx3WZPNrYHVz+Iunp9ziahaG5uFMvD2R8Zlmc194AqXNxt9HBNu7ZsPYrUtmJsF0egETCWIdMIYAwOGjL1w=="], - - "mz": ["mz@2.7.0", "", { "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", "thenify-all": "^1.0.0" } }, "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q=="], - - "named-placeholders": ["named-placeholders@1.1.6", "", { "dependencies": { "lru.min": "^1.1.0" } }, "sha512-Tz09sEL2EEuv5fFowm419c1+a/jSMiBjI9gHxVLrVdbUkkNUUfjsVYs9pVZu5oCon/kmRh9TfLEObFtkVxmY0w=="], - "nanoevents": ["nanoevents@7.0.1", "", {}, "sha512-o6lpKiCxLeijK4hgsqfR6CNToPyRU3keKyyI6uwuHRvpRTbZ0wXw51WRgyldVugZqoJfkGFrjrIenYH3bfEO3Q=="], - "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], + "nanoid": ["nanoid@3.3.18", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w=="], "native-duplexpair": ["native-duplexpair@1.0.0", "", {}, "sha512-E7QQoM+3jvNtlmyfqRZ0/U75VFgCls+fSkbml2MpgWkWyz3ox8Y58gNhfuziuQYGNNQAbFZJQck55LHCnCK6CA=="], "negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="], - "neotraverse": ["neotraverse@0.6.18", "", {}, "sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA=="], - - "nf3": ["nf3@0.1.12", "", {}, "sha512-qbMXT7RTGh74MYWPeqTIED8nDW70NXOULVHpdWcdZ7IVHVnAsMV9fNugSNnvooipDc1FMOzpis7T9nXJEbJhvQ=="], - - "nitro": ["nitro@3.0.1-alpha.1", "", { "dependencies": { "consola": "^3.4.2", "crossws": "^0.4.1", "db0": "^0.3.4", "h3": "2.0.1-rc.5", "jiti": "^2.6.1", "nf3": "^0.1.10", "ofetch": "^2.0.0-alpha.3", "ohash": "^2.0.11", "oxc-minify": "^0.96.0", "oxc-transform": "^0.96.0", "srvx": "^0.9.5", "undici": "^7.16.0", "unenv": "^2.0.0-rc.24", "unstorage": "^2.0.0-alpha.4" }, "peerDependencies": { "rolldown": "*", "rollup": "^4", "vite": "^7", "xml2js": "^0.6.2" }, "optionalPeers": ["rolldown", "rollup", "vite", "xml2js"], "bin": { "nitro": "dist/cli/index.mjs" } }, "sha512-U4AxIsXxdkxzkFrK0XAw0e5Qbojk8jQ50MjjRBtBakC4HurTtQoiZvF+lSe382jhuQZCfAyywGWOFa9QzXLFaw=="], - - "nlcst-to-string": ["nlcst-to-string@4.0.0", "", { "dependencies": { "@types/nlcst": "^2.0.0" } }, "sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA=="], - - "no-case": ["no-case@3.0.4", "", { "dependencies": { "lower-case": "^2.0.2", "tslib": "^2.0.3" } }, "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg=="], - - "node-abi": ["node-abi@4.28.0", "", { "dependencies": { "semver": "^7.6.3" } }, "sha512-Qfp5XZL1cJDOabOT8H5gnqMTmM4NjvYzHp4I/Kt/Sl76OVkOBBHRFlPspGV0hYvMoqQsypFjT/Yp7Km0beXW9g=="], - "node-addon-api": ["node-addon-api@7.1.1", "", {}, "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="], - "node-api-version": ["node-api-version@0.2.1", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-2xP/IGGMmmSQpI1+O/k72jF/ykvZ89JeuKX3TLJAYPDVLUalrshrLHkeVcCCZqG/eEa635cr8IBYzgnDvM2O8Q=="], - "node-domexception": ["node-domexception@1.0.0", "", {}, "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ=="], - "node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], - - "node-fetch-native": ["node-fetch-native@1.6.7", "", {}, "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q=="], + "node-fetch": ["node-fetch@3.3.2", "", { "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", "formdata-polyfill": "^4.0.10" } }, "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA=="], "node-gyp": ["node-gyp@12.2.0", "", { "dependencies": { "env-paths": "^2.2.0", "exponential-backoff": "^3.1.1", "graceful-fs": "^4.2.6", "make-fetch-happen": "^15.0.0", "nopt": "^9.0.0", "proc-log": "^6.0.0", "semver": "^7.3.5", "tar": "^7.5.4", "tinyglobby": "^0.2.12", "which": "^6.0.0" }, "bin": { "node-gyp": "bin/node-gyp.js" } }, "sha512-q23WdzrQv48KozXlr0U1v9dwO/k59NHeSzn6loGcasyf0UnSrtzs8kRxM+mfwJSf0DkX0s43hcqgnSO4/VNthQ=="], @@ -4014,16 +2432,12 @@ "node-html-parser": ["node-html-parser@7.1.0", "", { "dependencies": { "css-select": "^5.1.0", "he": "1.2.0" } }, "sha512-iJo8b2uYGT40Y8BTyy5ufL6IVbN8rbm/1QK2xffXU/1a/v3AAa0d1YAoqBNYqaS4R/HajkWIpIfdE6KcyFh1AQ=="], - "node-mock-http": ["node-mock-http@1.0.4", "", {}, "sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ=="], - - "node-releases": ["node-releases@2.0.37", "", {}, "sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg=="], + "node-releases": ["node-releases@2.0.53", "", {}, "sha512-D9UOmYG3UH1V+ENW56t5QXBwJw1YEY18ruVeus89Rw+SyIgjPkCO84bRzO3uNIYosJbNwiabWVn48o3uJLjxFQ=="], "nopt": ["nopt@9.0.0", "", { "dependencies": { "abbrev": "^4.0.0" }, "bin": { "nopt": "bin/nopt.js" } }, "sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw=="], "normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="], - "normalize-url": ["normalize-url@6.1.0", "", {}, "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A=="], - "npm-bundled": ["npm-bundled@5.0.0", "", { "dependencies": { "npm-normalize-package-bin": "^5.0.0" } }, "sha512-JLSpbzh6UUXIEoqPsYBvVNVmyrjVZ1fzEFbqxKkTJQkWBO3xFzFT+KDnSKQWwOQNbuWRwt5LSD6HOTLGIWzfrw=="], "npm-install-checks": ["npm-install-checks@8.0.0", "", { "dependencies": { "semver": "^7.1.1" } }, "sha512-ScAUdMpyzkbpxoNekQ3tNRdFI8SJ86wgKZSQZdUxT+bj0wVFpsEMWnkXP0twVe1gJyNF5apBWDJhhIbgrIViRA=="], @@ -4042,22 +2456,12 @@ "nth-check": ["nth-check@2.1.1", "", { "dependencies": { "boolbase": "^1.0.0" } }, "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="], - "nypm": ["nypm@0.6.5", "", { "dependencies": { "citty": "^0.2.0", "pathe": "^2.0.3", "tinyexec": "^1.0.2" }, "bin": { "nypm": "dist/cli.mjs" } }, "sha512-K6AJy1GMVyfyMXRVB88700BJqNUkByijGJM8kEHpLdcAt+vSQAVfkWWHYzuRXHSY6xA2sNc5RjTj0p9rE2izVQ=="], - "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], "object-hash": ["object-hash@2.2.0", "", {}, "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw=="], "object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="], - "object-keys": ["object-keys@1.1.1", "", {}, "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="], - - "object.assign": ["object.assign@4.1.7", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0", "has-symbols": "^1.1.0", "object-keys": "^1.1.1" } }, "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw=="], - - "obug": ["obug@2.1.1", "", {}, "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ=="], - - "ofetch": ["ofetch@2.0.0-alpha.3", "", {}, "sha512-zpYTCs2byOuft65vI3z43Dd6iSdFbOZZLb9/d21aCpx2rGastVU9dOCv0lu4ykc1Ur1anAYjDi3SUvR0vq50JA=="], - "ohash": ["ohash@2.0.11", "", {}, "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ=="], "oidc-token-hash": ["oidc-token-hash@5.2.0", "", {}, "sha512-6gj2m8cJZ+iSW8bm0FXdGF0YhIQbKrfP4yWTNzxc31U6MOjfEmB1rHvlYvxI1B7t7BCi1F2vYTT6YhtQRG4hxw=="], @@ -4078,12 +2482,10 @@ "open": ["open@10.1.2", "", { "dependencies": { "default-browser": "^5.2.1", "define-lazy-prop": "^3.0.0", "is-inside-container": "^1.0.0", "is-wsl": "^3.1.0" } }, "sha512-cxN6aIDPz6rm8hbebcP7vrQNhvRcveZoJU72Y7vskh4oIm+BZwBECnx5nTmrlres1Qapvx27Qo1Auukpf8PKXw=="], - "openai": ["openai@5.11.0", "", { "peerDependencies": { "ws": "^8.18.0", "zod": "^3.23.8" }, "optionalPeers": ["ws", "zod"], "bin": { "openai": "bin/cli" } }, "sha512-+AuTc5pVjlnTuA9zvn8rA/k+1RluPIx9AD4eDcnutv6JNwHHZxIhkFy+tmMKCvmMFDQzfA/r1ujvPWB19DQkYg=="], + "openai": ["openai@6.34.0", "", { "peerDependencies": { "ws": "^8.18.0", "zod": "^3.25 || ^4.0" }, "optionalPeers": ["ws", "zod"], "bin": { "openai": "bin/cli" } }, "sha512-yEr2jdGf4tVFYG6ohmr3pF6VJuveP0EA/sS8TBx+4Eq5NT10alu5zg2dmxMXMgqpihRDQlFGpRt2XwsGj+Fyxw=="], "openapi-types": ["openapi-types@12.1.3", "", {}, "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw=="], - "opencode": ["mendcode-runtime-cli@workspace:packages/opencode"], - "opencode-gitlab-auth": ["opencode-gitlab-auth@2.0.1", "", { "dependencies": { "@fastify/rate-limit": "^10.2.0", "@mendcode/plugin": "*", "fastify": "^5.2.0", "open": "^10.0.0" } }, "sha512-1EMZHdbADLMVaTVLQ6C/V8uVMDr6MP++osj2lmOecowtn46AafP/w6ADkV4AN/ddjA1rob5cWpMuf/iME6DI6A=="], "opencode-poe-auth": ["opencode-poe-auth@0.0.1", "", { "dependencies": { "open": "^10.0.0", "poe-oauth": "*" }, "peerDependencies": { "@mendcode/plugin": "*" } }, "sha512-cXqTlS6AXHzo1oBdosnxbT47ZJEZ9WXn050X8Re6wZ1vaNnTpB/l2fMQt90evT7RBK0fB8UjXQUDMKyd7bbiqg=="], @@ -4094,49 +2496,31 @@ "opentui-spinner": ["opentui-spinner@0.0.6", "", { "dependencies": { "cli-spinners": "^3.3.0" }, "peerDependencies": { "@opentui/core": "^0.1.49", "@opentui/react": "^0.1.49", "@opentui/solid": "^0.1.49", "typescript": "^5" }, "optionalPeers": ["@opentui/react", "@opentui/solid"] }, "sha512-xupLOeVQEAXEvVJCvHkfX6fChDWmJIPHe5jyUrVb8+n4XVTX8mBNhitFfB9v2ZbkC1H2UwPab/ElePHoW37NcA=="], - "ora": ["ora@5.4.1", "", { "dependencies": { "bl": "^4.1.0", "chalk": "^4.1.0", "cli-cursor": "^3.1.0", "cli-spinners": "^2.5.0", "is-interactive": "^1.0.0", "is-unicode-supported": "^0.1.0", "log-symbols": "^4.1.0", "strip-ansi": "^6.0.0", "wcwidth": "^1.0.1" } }, "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ=="], - - "own-keys": ["own-keys@1.0.1", "", { "dependencies": { "get-intrinsic": "^1.2.6", "object-keys": "^1.1.1", "safe-push-apply": "^1.0.0" } }, "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg=="], - - "oxc-minify": ["oxc-minify@0.96.0", "", { "optionalDependencies": { "@oxc-minify/binding-android-arm64": "0.96.0", "@oxc-minify/binding-darwin-arm64": "0.96.0", "@oxc-minify/binding-darwin-x64": "0.96.0", "@oxc-minify/binding-freebsd-x64": "0.96.0", "@oxc-minify/binding-linux-arm-gnueabihf": "0.96.0", "@oxc-minify/binding-linux-arm-musleabihf": "0.96.0", "@oxc-minify/binding-linux-arm64-gnu": "0.96.0", "@oxc-minify/binding-linux-arm64-musl": "0.96.0", "@oxc-minify/binding-linux-riscv64-gnu": "0.96.0", "@oxc-minify/binding-linux-s390x-gnu": "0.96.0", "@oxc-minify/binding-linux-x64-gnu": "0.96.0", "@oxc-minify/binding-linux-x64-musl": "0.96.0", "@oxc-minify/binding-wasm32-wasi": "0.96.0", "@oxc-minify/binding-win32-arm64-msvc": "0.96.0", "@oxc-minify/binding-win32-x64-msvc": "0.96.0" } }, "sha512-dXeeGrfPJJ4rMdw+NrqiCRtbzVX2ogq//R0Xns08zql2HjV3Zi2SBJ65saqfDaJzd2bcHqvGWH+M44EQCHPAcA=="], - - "oxc-transform": ["oxc-transform@0.96.0", "", { "optionalDependencies": { "@oxc-transform/binding-android-arm64": "0.96.0", "@oxc-transform/binding-darwin-arm64": "0.96.0", "@oxc-transform/binding-darwin-x64": "0.96.0", "@oxc-transform/binding-freebsd-x64": "0.96.0", "@oxc-transform/binding-linux-arm-gnueabihf": "0.96.0", "@oxc-transform/binding-linux-arm-musleabihf": "0.96.0", "@oxc-transform/binding-linux-arm64-gnu": "0.96.0", "@oxc-transform/binding-linux-arm64-musl": "0.96.0", "@oxc-transform/binding-linux-riscv64-gnu": "0.96.0", "@oxc-transform/binding-linux-s390x-gnu": "0.96.0", "@oxc-transform/binding-linux-x64-gnu": "0.96.0", "@oxc-transform/binding-linux-x64-musl": "0.96.0", "@oxc-transform/binding-wasm32-wasi": "0.96.0", "@oxc-transform/binding-win32-arm64-msvc": "0.96.0", "@oxc-transform/binding-win32-x64-msvc": "0.96.0" } }, "sha512-dQPNIF+gHpSkmC0+Vg9IktNyhcn28Y8R3eTLyzn52UNymkasLicl3sFAtz7oEVuFmCpgGjaUTKkwk+jW2cHpDQ=="], - "oxlint": ["oxlint@1.60.0", "", { "optionalDependencies": { "@oxlint/binding-android-arm-eabi": "1.60.0", "@oxlint/binding-android-arm64": "1.60.0", "@oxlint/binding-darwin-arm64": "1.60.0", "@oxlint/binding-darwin-x64": "1.60.0", "@oxlint/binding-freebsd-x64": "1.60.0", "@oxlint/binding-linux-arm-gnueabihf": "1.60.0", "@oxlint/binding-linux-arm-musleabihf": "1.60.0", "@oxlint/binding-linux-arm64-gnu": "1.60.0", "@oxlint/binding-linux-arm64-musl": "1.60.0", "@oxlint/binding-linux-ppc64-gnu": "1.60.0", "@oxlint/binding-linux-riscv64-gnu": "1.60.0", "@oxlint/binding-linux-riscv64-musl": "1.60.0", "@oxlint/binding-linux-s390x-gnu": "1.60.0", "@oxlint/binding-linux-x64-gnu": "1.60.0", "@oxlint/binding-linux-x64-musl": "1.60.0", "@oxlint/binding-openharmony-arm64": "1.60.0", "@oxlint/binding-win32-arm64-msvc": "1.60.0", "@oxlint/binding-win32-ia32-msvc": "1.60.0", "@oxlint/binding-win32-x64-msvc": "1.60.0" }, "peerDependencies": { "oxlint-tsgolint": ">=0.18.0" }, "optionalPeers": ["oxlint-tsgolint"], "bin": { "oxlint": "bin/oxlint" } }, "sha512-tnRzTWiWJ9pg3ftRWnD0+Oqh78L6ZSwcEudvCZaER0PIqiAnNyXj5N1dPwjmNpDalkKS9m/WMLN1CTPUBPmsgw=="], "oxlint-tsgolint": ["oxlint-tsgolint@0.21.0", "", { "optionalDependencies": { "@oxlint-tsgolint/darwin-arm64": "0.21.0", "@oxlint-tsgolint/darwin-x64": "0.21.0", "@oxlint-tsgolint/linux-arm64": "0.21.0", "@oxlint-tsgolint/linux-x64": "0.21.0", "@oxlint-tsgolint/win32-arm64": "0.21.0", "@oxlint-tsgolint/win32-x64": "0.21.0" }, "bin": { "tsgolint": "bin/tsgolint.js" } }, "sha512-HiWPhANwRnN1pZJQ2SgNB3WRR+1etLJHmRzQ/MJhyINsEIaOUCjxhlXJKbEaVUwdnyXwRWqo/P9Fx21lz0/mSg=="], - "p-cancelable": ["p-cancelable@2.1.1", "", {}, "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg=="], - - "p-defer": ["p-defer@3.0.0", "", {}, "sha512-ugZxsxmtTln604yeYd29EGrNhazN2lywetzpKhfmQjW/VJmhpDmWbiX+h0zL8V91R0UXkhb3KtPmyq9PZw3aYw=="], - "p-finally": ["p-finally@1.0.0", "", {}, "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow=="], - "p-limit": ["p-limit@6.2.0", "", { "dependencies": { "yocto-queue": "^1.1.1" } }, "sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA=="], + "p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="], - "p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="], + "p-locate": ["p-locate@3.0.0", "", { "dependencies": { "p-limit": "^2.0.0" } }, "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ=="], "p-map": ["p-map@7.0.4", "", {}, "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ=="], - "p-queue": ["p-queue@8.1.1", "", { "dependencies": { "eventemitter3": "^5.0.1", "p-timeout": "^6.1.2" } }, "sha512-aNZ+VfjobsWryoiPnEApGGmf5WmNsCo9xu8dfaYamG5qaLP7ClhLN6NgsFe6SwJ2UbLEBK5dv9x8Mn5+RVhMWQ=="], + "p-queue": ["p-queue@6.6.2", "", { "dependencies": { "eventemitter3": "^4.0.4", "p-timeout": "^3.2.0" } }, "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ=="], "p-retry": ["p-retry@4.6.2", "", { "dependencies": { "@types/retry": "0.12.0", "retry": "^0.13.1" } }, "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ=="], - "p-timeout": ["p-timeout@6.1.4", "", {}, "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg=="], + "p-timeout": ["p-timeout@3.2.0", "", { "dependencies": { "p-finally": "^1.0.0" } }, "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg=="], "p-try": ["p-try@2.2.0", "", {}, "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="], "package-json-from-dist": ["package-json-from-dist@1.0.1", "", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="], - "package-manager-detector": ["package-manager-detector@1.6.0", "", {}, "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA=="], - - "pacote": ["pacote@21.5.0", "", { "dependencies": { "@gar/promise-retry": "^1.0.0", "@npmcli/git": "^7.0.0", "@npmcli/installed-package-contents": "^4.0.0", "@npmcli/package-json": "^7.0.0", "@npmcli/promise-spawn": "^9.0.0", "@npmcli/run-script": "^10.0.0", "cacache": "^20.0.0", "fs-minipass": "^3.0.0", "minipass": "^7.0.2", "npm-package-arg": "^13.0.0", "npm-packlist": "^10.0.1", "npm-pick-manifest": "^11.0.1", "npm-registry-fetch": "^19.0.0", "proc-log": "^6.0.0", "sigstore": "^4.0.0", "ssri": "^13.0.0", "tar": "^7.4.3" }, "bin": { "pacote": "bin/index.js" } }, "sha512-VtZ0SB8mb5Tzw3dXDfVAIjhyVKUHZkS/ZH9/5mpKenwC9sFOXNI0JI7kEF7IMkwOnsWMFrvAZHzx1T5fmrp9FQ=="], + "pacote": ["pacote@21.5.1", "", { "dependencies": { "@gar/promise-retry": "^1.0.0", "@npmcli/git": "^7.0.0", "@npmcli/installed-package-contents": "^4.0.0", "@npmcli/package-json": "^7.0.0", "@npmcli/promise-spawn": "^9.0.0", "@npmcli/run-script": "^10.0.0", "cacache": "^20.0.0", "fs-minipass": "^3.0.0", "minipass": "^7.0.2", "npm-package-arg": "^13.0.0", "npm-packlist": "^10.0.1", "npm-pick-manifest": "^11.0.1", "npm-registry-fetch": "^19.0.0", "proc-log": "^6.0.0", "sigstore": "^4.0.0", "ssri": "^13.0.0", "tar": "^7.4.3" }, "bin": { "pacote": "bin/index.js" } }, "sha512-KvcJ9iy3crysCsgqc4+PknH/w6jkrp8JN36mpZBPwNaDRwTfMZD37YzRazNstiZUOhuF5pno9f78n9mEJBavwg=="], - "pagefind": ["pagefind@1.5.2", "", { "optionalDependencies": { "@pagefind/darwin-arm64": "1.5.2", "@pagefind/darwin-x64": "1.5.2", "@pagefind/freebsd-x64": "1.5.2", "@pagefind/linux-arm64": "1.5.2", "@pagefind/linux-x64": "1.5.2", "@pagefind/windows-arm64": "1.5.2", "@pagefind/windows-x64": "1.5.2" }, "bin": { "pagefind": "lib/runner/bin.cjs" } }, "sha512-XTUaK0hXMCu2jszWE584JGQT7y284TmMV9l/HX3rnG5uo3rHI/uHU56XTyyyPFjeWEBxECbAi0CaFDJOONtG0Q=="], - - "pako": ["pako@0.2.9", "", {}, "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA=="], - - "param-case": ["param-case@3.0.4", "", { "dependencies": { "dot-case": "^3.0.4", "tslib": "^2.0.3" } }, "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A=="], + "pako": ["pako@1.0.11", "", {}, "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="], "parse-bmfont-ascii": ["parse-bmfont-ascii@1.0.6", "", {}, "sha512-U4RrVsUFCleIOBsIGYOMKjn9PavsGOXxbvYGtMOEfnId0SVNsgehXh1DxUdVPLoxd5mvcEtvmKs2Mmf0Mpa1ZA=="], @@ -4146,407 +2530,197 @@ "parse-conflict-json": ["parse-conflict-json@5.0.1", "", { "dependencies": { "json-parse-even-better-errors": "^5.0.0", "just-diff": "^6.0.0", "just-diff-apply": "^5.2.0" } }, "sha512-ZHEmNKMq1wyJXNwLxyHnluPfRAFSIliBvbK/UiOceROt4Xh9Pz0fq49NytIaeaCUf5VR86hwQ/34FCcNU5/LKQ=="], - "parse-entities": ["parse-entities@4.0.2", "", { "dependencies": { "@types/unist": "^2.0.0", "character-entities-legacy": "^3.0.0", "character-reference-invalid": "^2.0.0", "decode-named-character-reference": "^1.0.0", "is-alphanumerical": "^2.0.0", "is-decimal": "^2.0.0", "is-hexadecimal": "^2.0.0" } }, "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw=="], - - "parse-latin": ["parse-latin@7.0.0", "", { "dependencies": { "@types/nlcst": "^2.0.0", "@types/unist": "^3.0.0", "nlcst-to-string": "^4.0.0", "unist-util-modify-children": "^4.0.0", "unist-util-visit-children": "^3.0.0", "vfile": "^6.0.0" } }, "sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ=="], - "parse5": ["parse5@7.3.0", "", { "dependencies": { "entities": "^6.0.0" } }, "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw=="], - "parse5-htmlparser2-tree-adapter": ["parse5-htmlparser2-tree-adapter@7.1.0", "", { "dependencies": { "domhandler": "^5.0.3", "parse5": "^7.0.0" } }, "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g=="], - - "parseley": ["parseley@0.12.1", "", { "dependencies": { "leac": "^0.6.0", "peberminta": "^0.9.0" } }, "sha512-e6qHKe3a9HWr0oMRVDTRhKce+bRO8VGQR3NyVwcjwrbhMmFCX9KszEV35+rn4AdilFAq9VPxP/Fe1wC9Qjd2lw=="], - "parseurl": ["parseurl@1.3.3", "", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="], "partial-json": ["partial-json@0.1.7", "", {}, "sha512-Njv/59hHaokb/hRUjce3Hdv12wd60MtM9Z5Olmn+nehe0QDAsRtRbJPvJ0Z91TusF0SuZRIvnM+S4l6EIP8leA=="], - "pascal-case": ["pascal-case@3.1.2", "", { "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3" } }, "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g=="], - - "path-browserify": ["path-browserify@1.0.1", "", {}, "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g=="], - - "path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="], + "path-exists": ["path-exists@3.0.0", "", {}, "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ=="], "path-expression-matcher": ["path-expression-matcher@1.5.0", "", {}, "sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ=="], - "path-is-absolute": ["path-is-absolute@1.0.1", "", {}, "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="], - "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], "path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="], "path-scurry": ["path-scurry@2.0.2", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg=="], - "path-to-regexp": ["path-to-regexp@6.3.0", "", {}, "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ=="], - - "path-type": ["path-type@4.0.0", "", {}, "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="], + "path-to-regexp": ["path-to-regexp@8.4.2", "", {}, "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA=="], "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], - "pathval": ["pathval@2.0.1", "", {}, "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ=="], - - "pe-library": ["pe-library@0.4.1", "", {}, "sha512-eRWB5LBz7PpDu4PUlwT0PhnQfTQJlDDdPa35urV4Osrm0t0AqQFGn+UIkU3klZvwJ8KPO3VbBFsXquA6p6kqZw=="], - - "peberminta": ["peberminta@0.9.0", "", {}, "sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ=="], - - "peek-readable": ["peek-readable@4.1.0", "", {}, "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg=="], - - "pend": ["pend@1.2.0", "", {}, "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="], - "perfect-debounce": ["perfect-debounce@2.1.0", "", {}, "sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g=="], - "piccolore": ["piccolore@0.1.3", "", {}, "sha512-o8bTeDWjE086iwKrROaDf31K0qC/BENdm15/uH9usSC/uZjJOKb2YGiVHfLY4GhwsERiPI1jmwI2XrA7ACOxVw=="], - "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], "picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="], - "pify": ["pify@2.3.0", "", {}, "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog=="], - "pino": ["pino@10.3.1", "", { "dependencies": { "@pinojs/redact": "^0.4.0", "atomic-sleep": "^1.0.0", "on-exit-leak-free": "^2.1.0", "pino-abstract-transport": "^3.0.0", "pino-std-serializers": "^7.0.0", "process-warning": "^5.0.0", "quick-format-unescaped": "^4.0.3", "real-require": "^0.2.0", "safe-stable-stringify": "^2.3.1", "sonic-boom": "^4.0.1", "thread-stream": "^4.0.0" }, "bin": { "pino": "bin.js" } }, "sha512-r34yH/GlQpKZbU1BvFFqOjhISRo1MNx1tWYsYvmj6KIRHSPMT2+yHOEb1SG6NMvRoHRF0a07kCOox/9yakl1vg=="], "pino-abstract-transport": ["pino-abstract-transport@3.0.0", "", { "dependencies": { "split2": "^4.0.0" } }, "sha512-wlfUczU+n7Hy/Ha5j9a/gZNy7We5+cXp8YL+X+PG8S0KXxw7n/JXA3c46Y0zQznIJ83URJiwy7Lh56WLokNuxg=="], "pino-std-serializers": ["pino-std-serializers@7.1.0", "", {}, "sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw=="], - "pirates": ["pirates@4.0.7", "", {}, "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA=="], - "pixelmatch": ["pixelmatch@5.3.0", "", { "dependencies": { "pngjs": "^6.0.0" }, "bin": { "pixelmatch": "bin/pixelmatch" } }, "sha512-o8mkY4E/+LNUf6LzX96ht6k6CEDi65k9G2rjMtBe9Oo+VPKSvl+0GKHuH/AlG+GA5LPG/i5hrekkxUc3s2HU+Q=="], "pkce-challenge": ["pkce-challenge@5.0.1", "", {}, "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ=="], - "pkg-dir": ["pkg-dir@4.2.0", "", { "dependencies": { "find-up": "^4.0.0" } }, "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ=="], - "pkg-types": ["pkg-types@2.3.0", "", { "dependencies": { "confbox": "^0.2.2", "exsolve": "^1.0.7", "pathe": "^2.0.3" } }, "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig=="], "pkg-up": ["pkg-up@3.1.0", "", { "dependencies": { "find-up": "^3.0.0" } }, "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA=="], "planck": ["planck@1.5.0", "", { "peerDependencies": { "stage-js": "^1.0.0-alpha.12" } }, "sha512-dlvqJE+FscZgrGUXJ5ybd0o5bvZ5XXyZNbm08xGsXp9WjXeAyWSFT6n9s/1PQcUBo4546fDXA5RMA4wbDyZw6g=="], - "playwright": ["playwright@1.59.1", "", { "dependencies": { "playwright-core": "1.59.1" }, "optionalDependencies": { "fsevents": "2.3.2" }, "bin": { "playwright": "cli.js" } }, "sha512-C8oWjPR3F81yljW9o5OxcWzfh6avkVwDD2VYdwIGqTkl+OGFISgypqzfu7dOe4QNLL2aqcWBmI3PMtLIK233lw=="], - - "playwright-core": ["playwright-core@1.59.1", "", { "bin": { "playwright-core": "cli.js" } }, "sha512-HBV/RJg81z5BiiZ9yPzIiClYV/QMsDCKUyogwH9p3MCP6IYjUFu/MActgYAvK0oWyV9NlwM3GLBjADyWgydVyg=="], - - "plist": ["plist@3.1.0", "", { "dependencies": { "@xmldom/xmldom": "^0.8.8", "base64-js": "^1.5.1", "xmlbuilder": "^15.1.1" } }, "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ=="], - "pngjs": ["pngjs@7.0.0", "", {}, "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow=="], "poe-oauth": ["poe-oauth@0.0.6", "", {}, "sha512-dI8xrVl7RSFh0B+cb4GGuCjIfGtDT9VpbpVkP0UKcunpXF0eFw+6GencoJ7k+E02ZYqopBQApMVWGq70/GP69w=="], "possible-typed-array-names": ["possible-typed-array-names@1.1.0", "", {}, "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg=="], - "postcss": ["postcss@8.5.9", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw=="], - - "postcss-css-variables": ["postcss-css-variables@0.18.0", "", { "dependencies": { "balanced-match": "^1.0.0", "escape-string-regexp": "^1.0.3", "extend": "^3.0.1" }, "peerDependencies": { "postcss": "^8.2.6" } }, "sha512-lYS802gHbzn1GI+lXvy9MYIYDuGnl1WB4FTKoqMQqJ3Mab09A7a/1wZvGTkCEZJTM8mSbIyb1mJYn8f0aPye0Q=="], - - "postcss-import": ["postcss-import@15.1.0", "", { "dependencies": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", "resolve": "^1.1.7" }, "peerDependencies": { "postcss": "^8.0.0" } }, "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew=="], + "postcss": ["postcss@8.5.23", "", { "dependencies": { "nanoid": "^3.3.16", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg=="], - "postcss-js": ["postcss-js@4.1.0", "", { "dependencies": { "camelcase-css": "^2.0.1" }, "peerDependencies": { "postcss": "^8.4.21" } }, "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw=="], - - "postcss-load-config": ["postcss-load-config@4.0.2", "", { "dependencies": { "lilconfig": "^3.0.0", "yaml": "^2.3.4" }, "peerDependencies": { "postcss": ">=8.0.9", "ts-node": ">=9.0.0" }, "optionalPeers": ["postcss", "ts-node"] }, "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ=="], - - "postcss-nested": ["postcss-nested@6.2.0", "", { "dependencies": { "postcss-selector-parser": "^6.1.1" }, "peerDependencies": { "postcss": "^8.2.14" } }, "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ=="], - - "postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="], - - "postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="], - - "postgres": ["postgres@3.4.7", "", {}, "sha512-Jtc2612XINuBjIl/QTWsV5UvE8UHuNblcO3vVADSrKsrc6RqGX6lOW1cEo3CM2v0XG4Nat8nI+YM7/f26VxXLw=="], - - "postject": ["postject@1.0.0-alpha.6", "", { "dependencies": { "commander": "^9.4.0" }, "bin": { "postject": "dist/cli.js" } }, "sha512-b9Eb8h2eVqNE8edvKdwqkrY6O7kAwmI8kcnBv1NScolYJbo59XUF0noFq+lxbC1yN20bmC0WBEbDC5H/7ASb0A=="], + "postcss-selector-parser": ["postcss-selector-parser@7.1.3", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-ajnd7iZnqjJDkyHNfznl/ZVO0lWqvBmQXfKKENx9/p/bEiF/L3eHwdydNUg9RXZx6xfZWOCmXmBa5oeB+YrAPQ=="], "powershell-utils": ["powershell-utils@0.1.0", "", {}, "sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A=="], "prettier": ["prettier@3.6.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ=="], - "pretty": ["pretty@2.0.0", "", { "dependencies": { "condense-newlines": "^0.2.1", "extend-shallow": "^2.0.1", "js-beautify": "^1.6.12" } }, "sha512-G9xUchgTEiNpormdYBl+Pha50gOUovT18IvAe7EYMZ1/f9W/WWMPRn+xI68yXNMUk3QXHDwo/1wV/4NejVNe1w=="], - - "pretty-format": ["pretty-format@27.5.1", "", { "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^17.0.1" } }, "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ=="], - - "prismjs": ["prismjs@1.30.0", "", {}, "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw=="], - "proc-log": ["proc-log@6.1.0", "", {}, "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ=="], "process": ["process@0.11.10", "", {}, "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A=="], "process-nextick-args": ["process-nextick-args@2.0.1", "", {}, "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="], - "process-warning": ["process-warning@5.0.0", "", {}, "sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA=="], + "process-warning": ["process-warning@5.1.0", "", {}, "sha512-jQSaVHsPgtyw60e1rQ/A+/ArPEj/S8pS/vFnyGa/gYFXrKk/6RuDkoqVDQ5NI5MmS01698ltlAk0NoDBNLujRw=="], "proggy": ["proggy@4.0.0", "", {}, "sha512-MbA4R+WQT76ZBm/5JUpV9yqcJt92175+Y0Bodg3HgiXzrmKu7Ggq+bpn6y6wHH+gN9NcyKn3yg1+d47VaKwNAQ=="], - "progress": ["progress@2.0.3", "", {}, "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="], - "promise-all-reject-late": ["promise-all-reject-late@1.0.1", "", {}, "sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw=="], "promise-call-limit": ["promise-call-limit@3.0.2", "", {}, "sha512-mRPQO2T1QQVw11E7+UdCJu7S61eJVWknzml9sC1heAdj1jxl0fWMBypIt9ZOcLFf8FkG995ZD7RnVk7HH72fZw=="], - "promise-retry": ["promise-retry@2.0.1", "", { "dependencies": { "err-code": "^2.0.2", "retry": "^0.12.0" } }, "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g=="], - - "promise.allsettled": ["promise.allsettled@1.0.7", "", { "dependencies": { "array.prototype.map": "^1.0.5", "call-bind": "^1.0.2", "define-properties": "^1.2.0", "es-abstract": "^1.22.1", "get-intrinsic": "^1.2.1", "iterate-value": "^1.0.2" } }, "sha512-hezvKvQQmsFkOdrZfYxUxkyxl8mgFQeT259Ajj9PXdbg9VzBCWrItOev72JyWxkCD5VSSqAeHmlN3tWx4DlmsA=="], - - "prompts": ["prompts@2.4.2", "", { "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" } }, "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q=="], - - "proper-lockfile": ["proper-lockfile@4.1.2", "", { "dependencies": { "graceful-fs": "^4.2.4", "retry": "^0.12.0", "signal-exit": "^3.0.2" } }, "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA=="], - "property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="], - "proto-list": ["proto-list@1.2.4", "", {}, "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA=="], - - "protobufjs": ["protobufjs@7.5.4", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg=="], - "proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="], "proxy-from-env": ["proxy-from-env@2.1.0", "", {}, "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA=="], - "pump": ["pump@3.0.4", "", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA=="], - "punycode": ["punycode@1.3.2", "", {}, "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw=="], - "pupa": ["pupa@3.3.0", "", { "dependencies": { "escape-goat": "^4.0.0" } }, "sha512-LjgDO2zPtoXP2wJpDjZrGdojii1uqO0cnwKoIoUzkfS98HDmbeiGmYiXo3lXeFlq2xvne1QFQhwYXSUCLKtEuA=="], - "pure-rand": ["pure-rand@8.4.0", "", {}, "sha512-IoM8YF/jY0hiugFo/wOWqfmarlE6J0wc6fDK1PhftMk7MGhVZl88sZimmqBBFomLOCSmcCCpsfj7wXASCpvK9A=="], - "qs": ["qs@6.15.1", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg=="], + "qs": ["qs@6.16.0", "", { "dependencies": { "es-define-property": "^1.0.1", "side-channel": "^1.1.1" } }, "sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA=="], "quansync": ["quansync@0.2.11", "", {}, "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA=="], "querystring": ["querystring@0.2.0", "", {}, "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g=="], - "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="], - "quick-format-unescaped": ["quick-format-unescaped@4.0.4", "", {}, "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg=="], - "quick-lru": ["quick-lru@5.1.1", "", {}, "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA=="], - - "radix3": ["radix3@1.1.2", "", {}, "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA=="], - "range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="], - "raw-body": ["raw-body@2.5.3", "", { "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", "iconv-lite": "~0.4.24", "unpipe": "~1.0.0" } }, "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA=="], + "raw-body": ["raw-body@3.0.2", "", { "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", "iconv-lite": "~0.7.0", "unpipe": "~1.0.0" } }, "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA=="], - "rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="], + "rc9": ["rc9@3.0.1", "", { "dependencies": { "defu": "^6.1.6", "destr": "^2.0.5" } }, "sha512-gMDyleLWVE+i6Sgtc0QbbY6pEKqYs97NGi6isHQPqYlLemPoO8dxQ3uGi0f4NiP98c+jMW6cG1Kx9dDwfvqARQ=="], "react": ["react@18.2.0", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ=="], - "react-docgen-typescript": ["react-docgen-typescript@2.4.0", "", { "peerDependencies": { "typescript": ">= 4.3.x" } }, "sha512-ZtAp5XTO5HRzQctjPU0ybY0RRCQO19X/8fxn3w7y2VVTUbGHDKULPTL4ky3vB05euSgG5NpALhEhDPvQ56wvXg=="], - "react-dom": ["react-dom@18.2.0", "", { "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.0" }, "peerDependencies": { "react": "^18.2.0" } }, "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g=="], - "react-is": ["react-is@17.0.2", "", {}, "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="], - - "react-refresh": ["react-refresh@0.17.0", "", {}, "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ=="], - - "react-remove-scroll": ["react-remove-scroll@2.5.5", "", { "dependencies": { "react-remove-scroll-bar": "^2.3.3", "react-style-singleton": "^2.2.1", "tslib": "^2.1.0", "use-callback-ref": "^1.3.0", "use-sidecar": "^1.1.2" }, "peerDependencies": { "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0" }, "optionalPeers": ["@types/react"] }, "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw=="], - - "react-remove-scroll-bar": ["react-remove-scroll-bar@2.3.8", "", { "dependencies": { "react-style-singleton": "^2.2.2", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["@types/react"] }, "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q=="], - - "react-router": ["react-router@6.16.0", "", { "dependencies": { "@remix-run/router": "1.9.0" }, "peerDependencies": { "react": ">=16.8" } }, "sha512-VT4Mmc4jj5YyjpOi5jOf0I+TYzGpvzERy4ckNSvSh2RArv8LLoCxlsZ2D+tc7zgjxcY34oTz2hZaeX5RVprKqA=="], - - "react-router-dom": ["react-router-dom@6.16.0", "", { "dependencies": { "@remix-run/router": "1.9.0", "react-router": "6.16.0" }, "peerDependencies": { "react": ">=16.8", "react-dom": ">=16.8" } }, "sha512-aTfBLv3mk/gaKLxgRDUPbPw+s4Y/O+ma3rEN1u8EgEpLpPe6gNjIsWt9rxushMHHMb7mSwxRGdGlGdvmFsyPIg=="], - - "react-style-singleton": ["react-style-singleton@2.2.3", "", { "dependencies": { "get-nonce": "^1.0.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ=="], - - "read-binary-file-arch": ["read-binary-file-arch@1.0.6", "", { "dependencies": { "debug": "^4.3.4" }, "bin": { "read-binary-file-arch": "cli.js" } }, "sha512-BNg9EN3DD3GsDXX7Aa8O4p92sryjkmzYYgmgTAc6CA4uGLEDzFfxOxugu21akOxpcXHiEgsYkC6nPsQvLLLmEg=="], - - "read-cache": ["read-cache@1.0.0", "", { "dependencies": { "pify": "^2.3.0" } }, "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA=="], - "read-cmd-shim": ["read-cmd-shim@6.0.0", "", {}, "sha512-1zM5HuOfagXCBWMN83fuFI/x+T/UhZ7k+KIzhrHXcQoeX5+7gmaDYjELQHmmzIodumBHeByBJT4QYS7ufAgs7A=="], "readable-stream": ["readable-stream@4.7.0", "", { "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", "process": "^0.11.10", "string_decoder": "^1.3.0" } }, "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg=="], - "readable-web-to-node-stream": ["readable-web-to-node-stream@3.0.4", "", { "dependencies": { "readable-stream": "^4.7.0" } }, "sha512-9nX56alTf5bwXQ3ZDipHJhusu9NTQJ/CVPtb/XHAJCXihZeitfJvIRS4GqQ/mfIoOE3IelHMrpayVrosdHBuLw=="], - "readdir-glob": ["readdir-glob@1.1.3", "", { "dependencies": { "minimatch": "^5.1.0" } }, "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA=="], "readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="], "real-require": ["real-require@0.2.0", "", {}, "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg=="], - "recast": ["recast@0.23.11", "", { "dependencies": { "ast-types": "^0.16.1", "esprima": "~4.0.0", "source-map": "~0.6.1", "tiny-invariant": "^1.3.3", "tslib": "^2.0.1" } }, "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA=="], - - "recma-build-jsx": ["recma-build-jsx@1.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-util-build-jsx": "^3.0.0", "vfile": "^6.0.0" } }, "sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew=="], - - "recma-jsx": ["recma-jsx@1.0.1", "", { "dependencies": { "acorn-jsx": "^5.0.0", "estree-util-to-js": "^2.0.0", "recma-parse": "^1.0.0", "recma-stringify": "^1.0.0", "unified": "^11.0.0" }, "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w=="], - - "recma-parse": ["recma-parse@1.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "esast-util-from-js": "^2.0.0", "unified": "^11.0.0", "vfile": "^6.0.0" } }, "sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ=="], - - "recma-stringify": ["recma-stringify@1.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-util-to-js": "^2.0.0", "unified": "^11.0.0", "vfile": "^6.0.0" } }, "sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g=="], - "redent": ["redent@3.0.0", "", { "dependencies": { "indent-string": "^4.0.0", "strip-indent": "^3.0.0" } }, "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg=="], "redis-errors": ["redis-errors@1.2.0", "", {}, "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w=="], "redis-parser": ["redis-parser@3.0.0", "", { "dependencies": { "redis-errors": "^1.0.0" } }, "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A=="], - "reflect.getprototypeof": ["reflect.getprototypeof@1.0.10", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.9", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "get-intrinsic": "^1.2.7", "get-proto": "^1.0.1", "which-builtin-type": "^1.2.1" } }, "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw=="], - "regex": ["regex@6.1.0", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg=="], "regex-recursion": ["regex-recursion@6.0.2", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg=="], "regex-utilities": ["regex-utilities@2.3.0", "", {}, "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng=="], - "regexp.prototype.flags": ["regexp.prototype.flags@1.5.4", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-errors": "^1.3.0", "get-proto": "^1.0.1", "gopd": "^1.2.0", "set-function-name": "^2.0.2" } }, "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA=="], + "remeda": ["remeda@2.26.0", "", { "dependencies": { "type-fest": "^4.41.0" } }, "sha512-lmNNwtaC6Co4m0WTTNoZ/JlpjEqAjPZO0+czC9YVRQUpkbS4x8Hmh+Mn9HPfJfiXqUQ5IXXgSXSOB2pBKAytdA=="], - "rehype": ["rehype@13.0.2", "", { "dependencies": { "@types/hast": "^3.0.0", "rehype-parse": "^9.0.0", "rehype-stringify": "^10.0.0", "unified": "^11.0.0" } }, "sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A=="], + "remend": ["remend@1.3.0", "", {}, "sha512-iIhggPkhW3hFImKtB10w0dz4EZbs28mV/dmbcYVonWEJ6UGHHpP+bFZnTh6GNWJONg5m+U56JrL+8IxZRdgWjw=="], - "rehype-autolink-headings": ["rehype-autolink-headings@7.1.0", "", { "dependencies": { "@types/hast": "^3.0.0", "@ungap/structured-clone": "^1.0.0", "hast-util-heading-rank": "^3.0.0", "hast-util-is-element": "^3.0.0", "unified": "^11.0.0", "unist-util-visit": "^5.0.0" } }, "sha512-rItO/pSdvnvsP4QRB1pmPiNHUskikqtPojZKJPPPAVx9Hj8i8TwMBhofrrAYRhYOOBZH9tgmG5lPqDLuIWPWmw=="], + "require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="], - "rehype-expressive-code": ["rehype-expressive-code@0.41.7", "", { "dependencies": { "expressive-code": "^0.41.7" } }, "sha512-25f8ZMSF1d9CMscX7Cft0TSQIqdwjce2gDOvQ+d/w0FovsMwrSt3ODP4P3Z7wO1jsIJ4eYyaDRnIR/27bd/EMQ=="], + "reselect": ["reselect@4.1.8", "", {}, "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ=="], - "rehype-format": ["rehype-format@5.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-format": "^1.0.0" } }, "sha512-zvmVru9uB0josBVpr946OR8ui7nJEdzZobwLOOqHb/OOD88W0Vk2SqLwoVOj0fM6IPCCO6TaV9CvQvJMWwukFQ=="], + "resolve": ["resolve@1.22.12", "", { "dependencies": { "es-errors": "^1.3.0", "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA=="], - "rehype-parse": ["rehype-parse@9.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-from-html": "^2.0.0", "unified": "^11.0.0" } }, "sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag=="], + "resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="], - "rehype-raw": ["rehype-raw@7.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-raw": "^9.0.0", "vfile": "^6.0.0" } }, "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww=="], + "ret": ["ret@0.5.0", "", {}, "sha512-I1XxrZSQ+oErkRR4jYbAyEEu2I0avBvvMM5JN+6EBprOGRCs63ENqZ3vjavq8fBw2+62G5LF5XelKwuJpcvcxw=="], - "rehype-recma": ["rehype-recma@1.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/hast": "^3.0.0", "hast-util-to-estree": "^3.0.0" } }, "sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw=="], + "retry": ["retry@0.13.1", "", {}, "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg=="], - "rehype-stringify": ["rehype-stringify@10.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-to-html": "^9.0.0", "unified": "^11.0.0" } }, "sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA=="], + "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="], - "relateurl": ["relateurl@0.2.7", "", {}, "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog=="], + "rfdc": ["rfdc@1.4.1", "", {}, "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="], - "remark-directive": ["remark-directive@3.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-directive": "^3.0.0", "micromark-extension-directive": "^3.0.0", "unified": "^11.0.0" } }, "sha512-gwglrEQEZcZYgVyG1tQuA+h58EZfq5CSULw7J90AFuCTyib1thgHPoqQ+h9iFvU6R+vnZ5oNFQR5QKgGpk741A=="], + "rollup": ["rollup@4.60.1", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.60.1", "@rollup/rollup-android-arm64": "4.60.1", "@rollup/rollup-darwin-arm64": "4.60.1", "@rollup/rollup-darwin-x64": "4.60.1", "@rollup/rollup-freebsd-arm64": "4.60.1", "@rollup/rollup-freebsd-x64": "4.60.1", "@rollup/rollup-linux-arm-gnueabihf": "4.60.1", "@rollup/rollup-linux-arm-musleabihf": "4.60.1", "@rollup/rollup-linux-arm64-gnu": "4.60.1", "@rollup/rollup-linux-arm64-musl": "4.60.1", "@rollup/rollup-linux-loong64-gnu": "4.60.1", "@rollup/rollup-linux-loong64-musl": "4.60.1", "@rollup/rollup-linux-ppc64-gnu": "4.60.1", "@rollup/rollup-linux-ppc64-musl": "4.60.1", "@rollup/rollup-linux-riscv64-gnu": "4.60.1", "@rollup/rollup-linux-riscv64-musl": "4.60.1", "@rollup/rollup-linux-s390x-gnu": "4.60.1", "@rollup/rollup-linux-x64-gnu": "4.60.1", "@rollup/rollup-linux-x64-musl": "4.60.1", "@rollup/rollup-openbsd-x64": "4.60.1", "@rollup/rollup-openharmony-arm64": "4.60.1", "@rollup/rollup-win32-arm64-msvc": "4.60.1", "@rollup/rollup-win32-ia32-msvc": "4.60.1", "@rollup/rollup-win32-x64-gnu": "4.60.1", "@rollup/rollup-win32-x64-msvc": "4.60.1", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-VmtB2rFU/GroZ4oL8+ZqXgSA38O6GR8KSIvWmEFv63pQ0G6KaBH9s07PO8XTXP4vI+3UJUEypOfjkGfmSBBR0w=="], - "remark-gfm": ["remark-gfm@4.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-gfm": "^3.0.0", "micromark-extension-gfm": "^3.0.0", "remark-parse": "^11.0.0", "remark-stringify": "^11.0.0", "unified": "^11.0.0" } }, "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg=="], + "router": ["router@2.2.0", "", { "dependencies": { "debug": "^4.4.0", "depd": "^2.0.0", "is-promise": "^4.0.0", "parseurl": "^1.3.3", "path-to-regexp": "^8.0.0" } }, "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ=="], - "remark-mdx": ["remark-mdx@3.1.1", "", { "dependencies": { "mdast-util-mdx": "^3.0.0", "micromark-extension-mdxjs": "^3.0.0" } }, "sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg=="], + "run-applescript": ["run-applescript@7.1.0", "", {}, "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q=="], - "remark-parse": ["remark-parse@11.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-from-markdown": "^2.0.0", "micromark-util-types": "^2.0.0", "unified": "^11.0.0" } }, "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA=="], + "s-js": ["s-js@0.4.9", "", {}, "sha512-RtpOm+cM6O0sHg6IA70wH+UC3FZcND+rccBZpBAHzlUgNO2Bm5BN+FnM8+OBxzXdwpKWFwX11JGF0MFRkhSoIQ=="], - "remark-rehype": ["remark-rehype@11.1.2", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "mdast-util-to-hast": "^13.0.0", "unified": "^11.0.0", "vfile": "^6.0.0" } }, "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw=="], + "safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="], - "remark-smartypants": ["remark-smartypants@3.0.2", "", { "dependencies": { "retext": "^9.0.0", "retext-smartypants": "^6.0.0", "unified": "^11.0.4", "unist-util-visit": "^5.0.0" } }, "sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA=="], + "safe-regex-test": ["safe-regex-test@1.1.0", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-regex": "^1.2.1" } }, "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw=="], - "remark-stringify": ["remark-stringify@11.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-to-markdown": "^2.0.0", "unified": "^11.0.0" } }, "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw=="], + "safe-regex2": ["safe-regex2@5.1.0", "", { "dependencies": { "ret": "~0.5.0" }, "bin": { "safe-regex2": "bin/safe-regex2.js" } }, "sha512-pNHAuBW7TrcleFHsxBr5QMi/Iyp0ENjUKz7GCcX1UO7cMh+NmVK6HxQckNL1tJp1XAJVjG6B8OKIPqodqj9rtw=="], - "remeda": ["remeda@2.26.0", "", { "dependencies": { "type-fest": "^4.41.0" } }, "sha512-lmNNwtaC6Co4m0WTTNoZ/JlpjEqAjPZO0+czC9YVRQUpkbS4x8Hmh+Mn9HPfJfiXqUQ5IXXgSXSOB2pBKAytdA=="], + "safe-stable-stringify": ["safe-stable-stringify@2.5.0", "", {}, "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA=="], - "remend": ["remend@1.3.0", "", {}, "sha512-iIhggPkhW3hFImKtB10w0dz4EZbs28mV/dmbcYVonWEJ6UGHHpP+bFZnTh6GNWJONg5m+U56JrL+8IxZRdgWjw=="], + "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], - "request-light": ["request-light@0.7.0", "", {}, "sha512-lMbBMrDoxgsyO+yB3sDcrDuX85yYt7sS8BfQd11jtbW/z5ZWgLZRcEGLsLoYw7I0WSUGQBs8CC8ScIxkTX1+6Q=="], + "sax": ["sax@1.2.1", "", {}, "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA=="], - "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="], + "scheduler": ["scheduler@0.23.2", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ=="], - "require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="], + "section-matter": ["section-matter@1.0.0", "", { "dependencies": { "extend-shallow": "^2.0.1", "kind-of": "^6.0.0" } }, "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA=="], - "resedit": ["resedit@1.7.2", "", { "dependencies": { "pe-library": "^0.4.1" } }, "sha512-vHjcY2MlAITJhC0eRD/Vv8Vlgmu9Sd3LX9zZvtGzU5ZImdTN3+d6e/4mnTyV8vEbyf1sgNIrWxhWlrys52OkEA=="], + "secure-json-parse": ["secure-json-parse@4.1.0", "", {}, "sha512-l4KnYfEyqYJxDwlNVyRfO2E4NTHfMKAWdUuA8J0yve2Dz/E/PdBepY03RvyJpssIpRFwJoCD55wA+mEDs6ByWA=="], - "reselect": ["reselect@4.1.8", "", {}, "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ=="], + "semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], - "resolve": ["resolve@1.22.12", "", { "dependencies": { "es-errors": "^1.3.0", "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA=="], + "send": ["send@1.2.1", "", { "dependencies": { "debug": "^4.4.3", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.1", "mime-types": "^3.0.2", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.2" } }, "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ=="], - "resolve-alpn": ["resolve-alpn@1.2.1", "", {}, "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g=="], + "seroval": ["seroval@1.5.3", "", {}, "sha512-BXe0x4buEeYiIKaRUnth1WqCILQ3k4O67KP/B4pC3pVz0Mv2c96ngA9QDREUYxWY1sb2RZVRqwI9RcpVMyHCVw=="], - "resolve-cwd": ["resolve-cwd@3.0.0", "", { "dependencies": { "resolve-from": "^5.0.0" } }, "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg=="], + "seroval-plugins": ["seroval-plugins@1.3.3", "", { "peerDependencies": { "seroval": "^1.0" } }, "sha512-16OL3NnUBw8JG1jBLUoZJsLnQq0n5Ua6aHalhJK4fMQkz1lqR7Osz1sA30trBtd9VUDc2NgkuRCn8+/pBwqZ+w=="], - "resolve-from": ["resolve-from@5.0.0", "", {}, "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="], + "serve-static": ["serve-static@2.2.1", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw=="], - "resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="], + "set-cookie-parser": ["set-cookie-parser@2.7.2", "", {}, "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw=="], - "responselike": ["responselike@2.0.1", "", { "dependencies": { "lowercase-keys": "^2.0.0" } }, "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw=="], + "set-function-length": ["set-function-length@1.2.2", "", { "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2" } }, "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg=="], - "restore-cursor": ["restore-cursor@3.1.0", "", { "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" } }, "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA=="], + "setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="], - "restructure": ["restructure@3.0.2", "", {}, "sha512-gSfoiOEA0VPE6Tukkrr7I0RBdE0s7H1eFCDBk05l1KIQT1UIKNc5JZy6jdyW6eYH3aR3g5b3PuL77rq0hvwtAw=="], - - "ret": ["ret@0.5.0", "", {}, "sha512-I1XxrZSQ+oErkRR4jYbAyEEu2I0avBvvMM5JN+6EBprOGRCs63ENqZ3vjavq8fBw2+62G5LF5XelKwuJpcvcxw=="], - - "retext": ["retext@9.0.0", "", { "dependencies": { "@types/nlcst": "^2.0.0", "retext-latin": "^4.0.0", "retext-stringify": "^4.0.0", "unified": "^11.0.0" } }, "sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA=="], - - "retext-latin": ["retext-latin@4.0.0", "", { "dependencies": { "@types/nlcst": "^2.0.0", "parse-latin": "^7.0.0", "unified": "^11.0.0" } }, "sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA=="], - - "retext-smartypants": ["retext-smartypants@6.2.0", "", { "dependencies": { "@types/nlcst": "^2.0.0", "nlcst-to-string": "^4.0.0", "unist-util-visit": "^5.0.0" } }, "sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ=="], - - "retext-stringify": ["retext-stringify@4.0.0", "", { "dependencies": { "@types/nlcst": "^2.0.0", "nlcst-to-string": "^4.0.0", "unified": "^11.0.0" } }, "sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA=="], - - "retry": ["retry@0.12.0", "", {}, "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow=="], - - "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="], - - "rfdc": ["rfdc@1.4.1", "", {}, "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="], - - "rimraf": ["rimraf@2.6.3", "", { "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "./bin.js" } }, "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA=="], - - "roarr": ["roarr@2.15.4", "", { "dependencies": { "boolean": "^3.0.1", "detect-node": "^2.0.4", "globalthis": "^1.0.1", "json-stringify-safe": "^5.0.1", "semver-compare": "^1.0.0", "sprintf-js": "^1.1.2" } }, "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A=="], - - "rollup": ["rollup@4.60.1", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.60.1", "@rollup/rollup-android-arm64": "4.60.1", "@rollup/rollup-darwin-arm64": "4.60.1", "@rollup/rollup-darwin-x64": "4.60.1", "@rollup/rollup-freebsd-arm64": "4.60.1", "@rollup/rollup-freebsd-x64": "4.60.1", "@rollup/rollup-linux-arm-gnueabihf": "4.60.1", "@rollup/rollup-linux-arm-musleabihf": "4.60.1", "@rollup/rollup-linux-arm64-gnu": "4.60.1", "@rollup/rollup-linux-arm64-musl": "4.60.1", "@rollup/rollup-linux-loong64-gnu": "4.60.1", "@rollup/rollup-linux-loong64-musl": "4.60.1", "@rollup/rollup-linux-ppc64-gnu": "4.60.1", "@rollup/rollup-linux-ppc64-musl": "4.60.1", "@rollup/rollup-linux-riscv64-gnu": "4.60.1", "@rollup/rollup-linux-riscv64-musl": "4.60.1", "@rollup/rollup-linux-s390x-gnu": "4.60.1", "@rollup/rollup-linux-x64-gnu": "4.60.1", "@rollup/rollup-linux-x64-musl": "4.60.1", "@rollup/rollup-openbsd-x64": "4.60.1", "@rollup/rollup-openharmony-arm64": "4.60.1", "@rollup/rollup-win32-arm64-msvc": "4.60.1", "@rollup/rollup-win32-ia32-msvc": "4.60.1", "@rollup/rollup-win32-x64-gnu": "4.60.1", "@rollup/rollup-win32-x64-msvc": "4.60.1", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-VmtB2rFU/GroZ4oL8+ZqXgSA38O6GR8KSIvWmEFv63pQ0G6KaBH9s07PO8XTXP4vI+3UJUEypOfjkGfmSBBR0w=="], - - "rou3": ["rou3@0.7.12", "", {}, "sha512-iFE4hLDuloSWcD7mjdCDhx2bKcIsYbtOTpfH5MHHLSKMOUyjqQXTeZVa289uuwEGEKFoE/BAPbhaU4B774nceg=="], - - "router": ["router@2.2.0", "", { "dependencies": { "debug": "^4.4.0", "depd": "^2.0.0", "is-promise": "^4.0.0", "parseurl": "^1.3.3", "path-to-regexp": "^8.0.0" } }, "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ=="], - - "run-applescript": ["run-applescript@7.1.0", "", {}, "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q=="], - - "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="], - - "s-js": ["s-js@0.4.9", "", {}, "sha512-RtpOm+cM6O0sHg6IA70wH+UC3FZcND+rccBZpBAHzlUgNO2Bm5BN+FnM8+OBxzXdwpKWFwX11JGF0MFRkhSoIQ=="], - - "safe-array-concat": ["safe-array-concat@1.1.3", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", "get-intrinsic": "^1.2.6", "has-symbols": "^1.1.0", "isarray": "^2.0.5" } }, "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q=="], - - "safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="], - - "safe-push-apply": ["safe-push-apply@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "isarray": "^2.0.5" } }, "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA=="], - - "safe-regex-test": ["safe-regex-test@1.1.0", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-regex": "^1.2.1" } }, "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw=="], - - "safe-regex2": ["safe-regex2@5.1.0", "", { "dependencies": { "ret": "~0.5.0" }, "bin": { "safe-regex2": "bin/safe-regex2.js" } }, "sha512-pNHAuBW7TrcleFHsxBr5QMi/Iyp0ENjUKz7GCcX1UO7cMh+NmVK6HxQckNL1tJp1XAJVjG6B8OKIPqodqj9rtw=="], - - "safe-stable-stringify": ["safe-stable-stringify@2.5.0", "", {}, "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA=="], - - "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], - - "sanitize-filename": ["sanitize-filename@1.6.4", "", { "dependencies": { "truncate-utf8-bytes": "^1.0.0" } }, "sha512-9ZyI08PsvdQl2r/bBIGubpVdR3RR9sY6RDiWFPreA21C/EFlQhmgo20UZlNjZMMZNubusLhAQozkA0Od5J21Eg=="], - - "sax": ["sax@1.2.1", "", {}, "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA=="], - - "scheduler": ["scheduler@0.23.2", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ=="], - - "section-matter": ["section-matter@1.0.0", "", { "dependencies": { "extend-shallow": "^2.0.1", "kind-of": "^6.0.0" } }, "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA=="], - - "secure-json-parse": ["secure-json-parse@4.1.0", "", {}, "sha512-l4KnYfEyqYJxDwlNVyRfO2E4NTHfMKAWdUuA8J0yve2Dz/E/PdBepY03RvyJpssIpRFwJoCD55wA+mEDs6ByWA=="], - - "selderee": ["selderee@0.11.0", "", { "dependencies": { "parseley": "^0.12.0" } }, "sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA=="], - - "semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], - - "semver-compare": ["semver-compare@1.0.0", "", {}, "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow=="], - - "send": ["send@0.19.2", "", { "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "~0.5.2", "http-errors": "~2.0.1", "mime": "1.6.0", "ms": "2.1.3", "on-finished": "~2.4.1", "range-parser": "~1.2.1", "statuses": "~2.0.2" } }, "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg=="], - - "seq-queue": ["seq-queue@0.0.5", "", {}, "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q=="], - - "serialize-error": ["serialize-error@7.0.1", "", { "dependencies": { "type-fest": "^0.13.1" } }, "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw=="], - - "seroval": ["seroval@1.3.2", "", {}, "sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ=="], - - "seroval-plugins": ["seroval-plugins@1.3.3", "", { "peerDependencies": { "seroval": "^1.0" } }, "sha512-16OL3NnUBw8JG1jBLUoZJsLnQq0n5Ua6aHalhJK4fMQkz1lqR7Osz1sA30trBtd9VUDc2NgkuRCn8+/pBwqZ+w=="], - - "serve-static": ["serve-static@1.16.3", "", { "dependencies": { "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", "send": "~0.19.1" } }, "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA=="], - - "set-cookie-parser": ["set-cookie-parser@2.7.2", "", {}, "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw=="], - - "set-function-length": ["set-function-length@1.2.2", "", { "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2" } }, "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg=="], - - "set-function-name": ["set-function-name@2.0.2", "", { "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "functions-have-names": "^1.2.3", "has-property-descriptors": "^1.0.2" } }, "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ=="], - - "set-proto": ["set-proto@1.0.0", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0" } }, "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw=="], - - "setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="], - - "sharp": ["sharp@0.33.5", "", { "dependencies": { "color": "^4.2.3", "detect-libc": "^2.0.3", "semver": "^7.6.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.33.5", "@img/sharp-darwin-x64": "0.33.5", "@img/sharp-libvips-darwin-arm64": "1.0.4", "@img/sharp-libvips-darwin-x64": "1.0.4", "@img/sharp-libvips-linux-arm": "1.0.5", "@img/sharp-libvips-linux-arm64": "1.0.4", "@img/sharp-libvips-linux-s390x": "1.0.4", "@img/sharp-libvips-linux-x64": "1.0.4", "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", "@img/sharp-libvips-linuxmusl-x64": "1.0.4", "@img/sharp-linux-arm": "0.33.5", "@img/sharp-linux-arm64": "0.33.5", "@img/sharp-linux-s390x": "0.33.5", "@img/sharp-linux-x64": "0.33.5", "@img/sharp-linuxmusl-arm64": "0.33.5", "@img/sharp-linuxmusl-x64": "0.33.5", "@img/sharp-wasm32": "0.33.5", "@img/sharp-win32-ia32": "0.33.5", "@img/sharp-win32-x64": "0.33.5" } }, "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw=="], - - "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], + "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], - "shell-quote": ["shell-quote@1.8.3", "", {}, "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw=="], + "shell-quote": ["shell-quote@1.9.0", "", {}, "sha512-Iov+JwFv/2HcTpcwNMKd8+IWNb8tboQJNQTkAY/LLVK7gGH9jy+LGkVqPxfekHl+yMmiqXszdGWXgkfml7hjqA=="], "shiki": ["shiki@3.20.0", "", { "dependencies": { "@shikijs/core": "3.20.0", "@shikijs/engine-javascript": "3.20.0", "@shikijs/engine-oniguruma": "3.20.0", "@shikijs/langs": "3.20.0", "@shikijs/themes": "3.20.0", "@shikijs/types": "3.20.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-kgCOlsnyWb+p0WU+01RjkCH+eBVsjL1jOwUYWv0YDWkM2/A46+LDKVs5yZCUXjJG6bj4ndFoAg5iLIIue6dulg=="], - "shikiji": ["shikiji@0.6.13", "", { "dependencies": { "hast-util-to-html": "^9.0.0" } }, "sha512-4T7X39csvhT0p7GDnq9vysWddf2b6BeioiN3Ymhnt3xcy9tXmDcnsEFVxX18Z4YcQgEE/w48dLJ4pPPUcG9KkA=="], - - "side-channel": ["side-channel@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="], + "side-channel": ["side-channel@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.4", "side-channel-list": "^1.0.1", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ=="], "side-channel-list": ["side-channel-list@1.0.1", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.4" } }, "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w=="], @@ -4554,33 +2728,19 @@ "side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="], - "siginfo": ["siginfo@2.0.0", "", {}, "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g=="], - "signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], - "sigstore": ["sigstore@4.1.0", "", { "dependencies": { "@sigstore/bundle": "^4.0.0", "@sigstore/core": "^3.1.0", "@sigstore/protobuf-specs": "^0.5.0", "@sigstore/sign": "^4.1.0", "@sigstore/tuf": "^4.0.1", "@sigstore/verify": "^3.1.0" } }, "sha512-/fUgUhYghuLzVT/gaJoeVehLCgZiUxPCPMcyVNY0lIf/cTCz58K/WTI7PefDarXxp9nUKpEwg1yyz3eSBMTtgA=="], - - "simple-swizzle": ["simple-swizzle@0.2.4", "", { "dependencies": { "is-arrayish": "^0.3.1" } }, "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw=="], - - "simple-update-notifier": ["simple-update-notifier@2.0.0", "", { "dependencies": { "semver": "^7.5.3" } }, "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w=="], + "sigstore": ["sigstore@4.1.1", "", { "dependencies": { "@sigstore/bundle": "^4.0.0", "@sigstore/core": "^3.2.1", "@sigstore/protobuf-specs": "^0.5.0", "@sigstore/sign": "^4.1.1", "@sigstore/tuf": "^4.0.2", "@sigstore/verify": "^3.1.1" } }, "sha512-endqECJkfhozrXMK5ngu/UAA0xVcVEFdnHJCElGaExypjW+HK5i6zu3NteLoaX/iFbRUbC3+DjttQs0GARr+5w=="], "simple-xml-to-json": ["simple-xml-to-json@1.2.7", "", {}, "sha512-mz9VXphOxQWX3eQ/uXCtm6upltoN0DLx8Zb5T4TFC4FHB7S9FDPGre8CfLWqPWQQH/GrQYd2AXhhVM5LDpYx6Q=="], "sisteransi": ["sisteransi@1.0.5", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="], - "sitemap": ["sitemap@9.0.1", "", { "dependencies": { "@types/node": "^24.9.2", "@types/sax": "^1.2.1", "arg": "^5.0.0", "sax": "^1.4.1" }, "bin": { "sitemap": "dist/esm/cli.js" } }, "sha512-S6hzjGJSG3d6if0YoF5kTyeRJvia6FSTBroE5fQ0bu1QNxyJqhhinfUsXi9fH3MgtXODWvwo2BDyQSnhPQ88uQ=="], - - "slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="], - - "slice-ansi": ["slice-ansi@5.0.0", "", { "dependencies": { "ansi-styles": "^6.0.0", "is-fullwidth-code-point": "^4.0.0" } }, "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ=="], - "smart-buffer": ["smart-buffer@4.2.0", "", {}, "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg=="], - "smol-toml": ["smol-toml@1.6.1", "", {}, "sha512-dWUG8F5sIIARXih1DTaQAX4SsiTXhInKf1buxdY9DIg4ZYPZK5nGM1VRIYmEbDbsHt7USo99xSLFu5Q1IqTmsg=="], - "socket.io-client": ["socket.io-client@4.8.3", "", { "dependencies": { "@socket.io/component-emitter": "~3.1.0", "debug": "~4.4.1", "engine.io-client": "~6.6.1", "socket.io-parser": "~4.2.4" } }, "sha512-uP0bpjWrjQmUt5DTHq9RuoCBdFJF10cdX9X+a368j/Ft0wmaVgxlrjvK3kjvgCODOMMOz9lcaRzxmso0bTWZ/g=="], - "socket.io-parser": ["socket.io-parser@4.2.6", "", { "dependencies": { "@socket.io/component-emitter": "~3.1.0", "debug": "~4.4.1" } }, "sha512-asJqbVBDsBCJx0pTqw3WfesSY0iRX+2xzWEWzrpcH7L6fLzrhyF8WPI8UaeM4YCuDfpwA/cgsdugMsmtz8EJeg=="], + "socket.io-parser": ["socket.io-parser@4.2.7", "", { "dependencies": { "@socket.io/component-emitter": "~3.1.0", "debug": "~4.4.1" } }, "sha512-IH/iSeO9T6gz1KkFleGDWkG9N3dl4jXVYUtMhIqH10Md0ttMer8nUNWiP1DKuNrybD2xBrixLJdCC9J6ECoYkg=="], "socks": ["socks@2.8.7", "", { "dependencies": { "ip-address": "^10.0.1", "smart-buffer": "^4.2.0" } }, "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A=="], @@ -4596,22 +2756,10 @@ "solid-refresh": ["solid-refresh@0.6.3", "", { "dependencies": { "@babel/generator": "^7.23.6", "@babel/helper-module-imports": "^7.22.15", "@babel/types": "^7.23.6" }, "peerDependencies": { "solid-js": "^1.3" } }, "sha512-F3aPsX6hVw9ttm5LYlth8Q15x6MlI/J3Dn+o3EQyRTtTxidepSTwAYdozt01/YA+7ObcciagGEyXIopGZzQtbA=="], - "solid-stripe": ["solid-stripe@0.8.1", "", { "peerDependencies": { "@stripe/stripe-js": ">=1.44.1 <8.0.0", "solid-js": "^1.6.0" } }, "sha512-l2SkWoe51rsvk9u1ILBRWyCHODZebChSGMR6zHYJTivTRC0XWrRnNNKs5x1PYXsaIU71KYI6ov5CZB5cOtGLWw=="], - - "solid-use": ["solid-use@0.9.1", "", { "peerDependencies": { "solid-js": "^1.7" } }, "sha512-UwvXDVPlrrbj/9ewG9ys5uL2IO4jSiwys2KPzK4zsnAcmEl7iDafZWW1Mo4BSEWOmQCGK6IvpmGHo1aou8iOFw=="], - "sonic-boom": ["sonic-boom@4.2.1", "", { "dependencies": { "atomic-sleep": "^1.0.0" } }, "sha512-w6AxtubXa2wTXAUsZMMWERrsIRAdrK0Sc+FUytWvYAhBJLyuI4llrMIC1DtlNSdI99EI86KZum2MMq3EAZlF9Q=="], - "sort-keys": ["sort-keys@1.1.2", "", { "dependencies": { "is-plain-obj": "^1.0.0" } }, "sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg=="], - - "sort-keys-length": ["sort-keys-length@1.0.1", "", { "dependencies": { "sort-keys": "^1.0.0" } }, "sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw=="], - - "source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], - "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], - "source-map-support": ["source-map-support@0.5.21", "", { "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w=="], - "space-separated-tokens": ["space-separated-tokens@2.0.2", "", {}, "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q=="], "spdx-exceptions": ["spdx-exceptions@2.5.0", "", {}, "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w=="], @@ -4624,10 +2772,6 @@ "sprintf-js": ["sprintf-js@1.1.3", "", {}, "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA=="], - "sqlstring": ["sqlstring@2.3.3", "", {}, "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg=="], - - "srvx": ["srvx@0.9.8", "", { "bin": { "srvx": "bin/srvx.mjs" } }, "sha512-RZaxTKJEE/14HYn8COLuUOJAt0U55N9l1Xf6jj+T0GoA01EUH1Xz5JtSUOI+EHn+AEgPCVn7gk6jHJffrr06fQ=="], - "ssri": ["ssri@13.0.1", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-QUiRf1+u9wPTL/76GTYlKttDEBWV1ga9ZXW8BG6kfdeyyM8LGPix9gROyg9V2+P0xNyF3X2Go526xKFdMZrHSQ=="], "sst": ["sst@3.18.10", "", { "dependencies": { "aws-sdk": "2.1692.0", "aws4fetch": "1.0.18", "jose": "5.2.3", "opencontrol": "0.0.6", "openid-client": "5.6.4" }, "optionalDependencies": { "sst-darwin-arm64": "3.18.10", "sst-darwin-x64": "3.18.10", "sst-linux-arm64": "3.18.10", "sst-linux-x64": "3.18.10", "sst-linux-x86": "3.18.10", "sst-win32-arm64": "3.18.10", "sst-win32-x64": "3.18.10", "sst-win32-x86": "3.18.10" }, "bin": { "sst": "bin/sst.mjs" } }, "sha512-SY+ldeJ9K5E9q+DhjXA3e2W3BEOzBwkE3IyLSD71uA3/5nRhUAST31iOWEpW36LbIvSQ9uOVDFcebztoLJ8s7w=="], @@ -4648,44 +2792,20 @@ "sst-win32-x86": ["sst-win32-x86@3.18.10", "", { "os": "win32", "cpu": "none" }, "sha512-pq8SmV0pIjBFMY6DraUZ4akyTxHnfjIKCRbBLdMxFUZK8TzA1NK2YdjRt1AwrgXRYGRyctrz/mt4WyO0SMOVQQ=="], - "stackback": ["stackback@0.0.2", "", {}, "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw=="], - - "stackframe": ["stackframe@1.3.4", "", {}, "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw=="], - "stage-js": ["stage-js@1.0.2", "", {}, "sha512-EWTRBYlg7Qv9wGUao99/PfRe3KaiQqWmgSvTOXvaWnu1Jk/q/vV8yJVu6bi/3EqDZeMVnCPAjheba6OFc5k1GQ=="], "standard-as-callback": ["standard-as-callback@2.1.0", "", {}, "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A=="], "standardwebhooks": ["standardwebhooks@1.0.0", "", { "dependencies": { "@stablelib/base64": "^1.0.0", "fast-sha256": "^1.3.0" } }, "sha512-BbHGOQK9olHPMvQNHWul6MYlrRTAOKn03rOe4A8O3CLWhNf4YHBqq2HJKKC+sfqpxiBY52pNeesD6jIiLDz8jg=="], - "stat-mode": ["stat-mode@1.0.0", "", {}, "sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg=="], - "statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="], - "std-env": ["std-env@4.0.0", "", {}, "sha512-zUMPtQ/HBY3/50VbpkupYHbRroTRZJPRLvreamgErJVys0ceuzMkD44J/QjqhHjOzK42GQ3QZIeFG1OYfOtKqQ=="], - - "stop-iteration-iterator": ["stop-iteration-iterator@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "internal-slot": "^1.1.0" } }, "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ=="], - - "stoppable": ["stoppable@1.1.0", "", {}, "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw=="], - - "storybook": ["storybook@10.3.5", "", { "dependencies": { "@storybook/global": "^5.0.0", "@storybook/icons": "^2.0.1", "@testing-library/jest-dom": "^6.9.1", "@testing-library/user-event": "^14.6.1", "@vitest/expect": "3.2.4", "@vitest/spy": "3.2.4", "@webcontainer/env": "^1.1.1", "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0 || ^0.26.0 || ^0.27.0", "open": "^10.2.0", "recast": "^0.23.5", "semver": "^7.7.3", "use-sync-external-store": "^1.5.0", "ws": "^8.18.0" }, "peerDependencies": { "prettier": "^2 || ^3" }, "optionalPeers": ["prettier"], "bin": "./dist/bin/dispatcher.js" }, "sha512-uBSZu/GZa9aEIW3QMGvdQPMZWhGxSe4dyRWU8B3/Vd47Gy/XLC7tsBxRr13txmmPOEDHZR94uLuq0H50fvuqBw=="], - - "storybook-solidjs-vite": ["storybook-solidjs-vite@10.0.12", "", { "dependencies": { "@joshwooding/vite-plugin-react-docgen-typescript": "^0.7.0", "@storybook/builder-vite": "^10.3.1", "@storybook/global": "^5.0.0", "vite-plugin-solid": "^2.11.11" }, "peerDependencies": { "solid-js": "^1.9.0", "storybook": "^0.0.0-0 || ^10.0.0", "typescript": "^4.0.0 || ^5.0.0 || ^6.0.0", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["typescript"] }, "sha512-KfKhJRdxbhFLHkBzLKSEk5sO2M/+KV9cdpki5Xdl5pwNP8kcoQnZ3b/okZk8dMRV6x19j86bKc7zDfc5bPSMwA=="], - - "stream-replace-string": ["stream-replace-string@2.0.0", "", {}, "sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w=="], - "streamx": ["streamx@2.25.0", "", { "dependencies": { "events-universal": "^1.0.0", "fast-fifo": "^1.3.2", "text-decoder": "^1.1.0" } }, "sha512-0nQuG6jf1w+wddNEEXCF4nTg3LtufWINB5eFEN+5TNZW7KWJp6x87+JFL43vaAUPyCfH1wID+mNVyW6OHtFamg=="], "string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], "string-width-cjs": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], - "string.prototype.trim": ["string.prototype.trim@1.2.10", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", "define-data-property": "^1.1.4", "define-properties": "^1.2.1", "es-abstract": "^1.23.5", "es-object-atoms": "^1.0.0", "has-property-descriptors": "^1.0.2" } }, "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA=="], - - "string.prototype.trimend": ["string.prototype.trimend@1.0.9", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" } }, "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ=="], - - "string.prototype.trimstart": ["string.prototype.trimstart@1.0.8", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" } }, "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg=="], - "string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="], "stringify-entities": ["stringify-entities@4.0.4", "", { "dependencies": { "character-entities-html4": "^2.0.0", "character-entities-legacy": "^3.0.0" } }, "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg=="], @@ -4700,41 +2820,21 @@ "strip-indent": ["strip-indent@3.0.0", "", { "dependencies": { "min-indent": "^1.0.0" } }, "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ=="], - "stripe": ["stripe@18.0.0", "", { "dependencies": { "@types/node": ">=8.1.0", "qs": "^6.11.0" } }, "sha512-3Fs33IzKUby//9kCkCa1uRpinAoTvj6rJgQ2jrBEysoxEvfsclvXdna1amyEYbA2EKkjynuB4+L/kleCCaWTpA=="], - - "strnum": ["strnum@1.1.2", "", {}, "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA=="], - - "strtok3": ["strtok3@6.3.0", "", { "dependencies": { "@tokenizer/token": "^0.3.0", "peek-readable": "^4.1.0" } }, "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw=="], + "strnum": ["strnum@2.2.3", "", {}, "sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg=="], - "stubborn-fs": ["stubborn-fs@2.0.0", "", { "dependencies": { "stubborn-utils": "^1.0.1" } }, "sha512-Y0AvSwDw8y+nlSNFXMm2g6L51rBGdAQT20J3YSOqxC53Lo3bjWRtr2BKcfYoAf352WYpsZSTURrA0tqhfgudPA=="], - - "stubborn-utils": ["stubborn-utils@1.0.2", "", {}, "sha512-zOh9jPYI+xrNOyisSelgym4tolKTJCQd5GBhK0+0xJvcYDcwlOoxF/rnFKQ2KRZknXSG9jWAp66fwP6AxN9STg=="], - - "style-to-js": ["style-to-js@1.1.21", "", { "dependencies": { "style-to-object": "1.0.14" } }, "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ=="], - - "style-to-object": ["style-to-object@1.0.14", "", { "dependencies": { "inline-style-parser": "0.2.7" } }, "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw=="], - - "sucrase": ["sucrase@3.35.1", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", "lines-and-columns": "^1.1.6", "mz": "^2.7.0", "pirates": "^4.0.1", "tinyglobby": "^0.2.11", "ts-interface-checker": "^0.1.9" }, "bin": { "sucrase": "bin/sucrase", "sucrase-node": "bin/sucrase-node" } }, "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw=="], - - "sumchecker": ["sumchecker@3.0.1", "", { "dependencies": { "debug": "^4.1.0" } }, "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg=="], - - "superstruct": ["superstruct@1.0.4", "", {}, "sha512-7JpaAoX2NGyoFlI9NBh66BQXGONc+uE+MRS5i2iOBKuS4e+ccgMDjATgZldkah+33DakBxDHiss9kvUcGAO8UQ=="], - - "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], + "strtok3": ["strtok3@10.3.5", "", { "dependencies": { "@tokenizer/token": "^0.3.0" } }, "sha512-ki4hZQfh5rX0QDLLkOCj+h+CVNkqmp/CMf8v8kZpkNVK6jGQooMytqzLZYUVYIZcFZ6yDB70EfD8POcFXiF5oA=="], "supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="], "sury": ["sury@11.0.0-alpha.4", "", { "peerDependencies": { "rescript": "12.x" }, "optionalPeers": ["rescript"] }, "sha512-oeG/GJWZvQCKtGPpLbu0yCZudfr5LxycDo5kh7SJmKHDPCsEPJssIZL2Eb4Tl7g9aPEvIDuRrkS+L0pybsMEMA=="], - "svix": ["svix@1.92.2", "", { "dependencies": { "standardwebhooks": "1.0.0" } }, "sha512-ZmuA3UVvlnF9EgxlzmPtF7CKjQb64Z6OFlyfdDfU0sdcC7dJa+3aOYX5B9mA+RS6ch1AxBa4UP/l6KmqfGtWBQ=="], - "system-architecture": ["system-architecture@0.1.0", "", {}, "sha512-ulAk51I9UVUyJgxlv9M6lFot2WP3e7t8Kz9+IS6D4rVba1tR9kON+Ey69f+1R4Q8cd45Lod6a4IcJIxnzGc/zA=="], "tailwindcss": ["tailwindcss@4.1.11", "", {}, "sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA=="], "tapable": ["tapable@2.3.2", "", {}, "sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA=="], - "tar": ["tar@7.5.13", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.1.0", "yallist": "^5.0.0" } }, "sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng=="], + "tar": ["tar@7.5.21", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.1.0", "yallist": "^5.0.0" } }, "sha512-XdhtCvlMywwxpCW8YEq3lOXBJpUPTR2OHHcwLPO3HwsJqOHa2Ok/oJ7ruGzp+JrKoRPVCzJwAdEjqLW/vNRPHA=="], "tar-stream": ["tar-stream@3.1.8", "", { "dependencies": { "b4a": "^1.6.4", "bare-fs": "^4.5.5", "fast-fifo": "^1.2.0", "streamx": "^2.15.0" } }, "sha512-U6QpVRyCGHva435KoNWy9PRoi2IFYCgtEhq9nmrPPpbRacPs9IH4aJ3gbrFC8dPcXvdSZ4XXfXT5Fshbp2MtlQ=="], @@ -4744,63 +2844,29 @@ "teex": ["teex@1.0.1", "", { "dependencies": { "streamx": "^2.12.5" } }, "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg=="], - "temp": ["temp@0.9.4", "", { "dependencies": { "mkdirp": "^0.5.1", "rimraf": "~2.6.2" } }, "sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA=="], - - "temp-file": ["temp-file@3.4.0", "", { "dependencies": { "async-exit-hook": "^2.0.1", "fs-extra": "^10.0.0" } }, "sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg=="], - - "terracotta": ["terracotta@1.1.0", "", { "dependencies": { "solid-use": "^0.9.1" }, "peerDependencies": { "solid-js": "^1.8" } }, "sha512-kfQciWUBUBgYkXu7gh3CK3FAJng/iqZslAaY08C+k1Hdx17aVEpcFFb/WPaysxAfcupNH3y53s/pc53xxZauww=="], - - "terser": ["terser@5.46.1", "", { "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.15.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, "bin": { "terser": "bin/terser" } }, "sha512-vzCjQO/rgUuK9sf8VJZvjqiqiHFaZLnOiimmUuOKODxWL8mm/xua7viT7aqX7dgPY60otQjUotzFMmCB4VdmqQ=="], - "text-decoder": ["text-decoder@1.2.7", "", { "dependencies": { "b4a": "^1.6.4" } }, "sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ=="], - "thenify": ["thenify@3.3.1", "", { "dependencies": { "any-promise": "^1.0.0" } }, "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw=="], - - "thenify-all": ["thenify-all@1.6.0", "", { "dependencies": { "thenify": ">= 3.1.0 < 4" } }, "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA=="], - "thread-stream": ["thread-stream@4.0.0", "", { "dependencies": { "real-require": "^0.2.0" } }, "sha512-4iMVL6HAINXWf1ZKZjIPcz5wYaOdPhtO8ATvZ+Xqp3BTdaqtAwQkNmKORqcIo5YkQqGXq5cwfswDwMqqQNrpJA=="], "three": ["three@0.177.0", "", {}, "sha512-EiXv5/qWAaGI+Vz2A+JfavwYCMdGjxVsrn3oBwllUoqYeaBO75J63ZfyaQKoiLrqNHoTlUc6PFgMXnS0kI45zg=="], "thunky": ["thunky@1.1.0", "", {}, "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA=="], - "tiny-async-pool": ["tiny-async-pool@1.3.0", "", { "dependencies": { "semver": "^5.5.0" } }, "sha512-01EAw5EDrcVrdgyCLgoSPvqznC0sVxDSVeiOz09FUpjh71G79VCqneOr+xvt7T1r76CF6ZZfPjHorN2+d+3mqA=="], - - "tiny-inflate": ["tiny-inflate@1.0.3", "", {}, "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw=="], - - "tiny-invariant": ["tiny-invariant@1.3.3", "", {}, "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="], - - "tiny-typed-emitter": ["tiny-typed-emitter@2.1.0", "", {}, "sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA=="], - - "tinybench": ["tinybench@2.9.0", "", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="], - "tinycolor2": ["tinycolor2@1.6.0", "", {}, "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw=="], "tinyexec": ["tinyexec@0.3.2", "", {}, "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA=="], "tinyglobby": ["tinyglobby@0.2.16", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg=="], - "tinyrainbow": ["tinyrainbow@3.1.0", "", {}, "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw=="], - - "tinyspy": ["tinyspy@4.0.4", "", {}, "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q=="], - - "titleize": ["titleize@4.0.0", "", {}, "sha512-ZgUJ1K83rhdu7uh7EHAC2BgY5DzoX8V5rTvoWI4vFysggi6YjLe5gUXABPWAU7VkvGP7P/0YiWq+dcPeYDsf1g=="], - - "tmp": ["tmp@0.2.5", "", {}, "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow=="], - - "tmp-promise": ["tmp-promise@3.0.3", "", { "dependencies": { "tmp": "^0.2.0" } }, "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ=="], - "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], "toad-cache": ["toad-cache@3.7.0", "", {}, "sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw=="], "toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="], - "token-types": ["token-types@4.2.1", "", { "dependencies": { "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" } }, "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ=="], + "token-types": ["token-types@6.1.2", "", { "dependencies": { "@borewit/text-codec": "^0.2.1", "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" } }, "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww=="], - "toml": ["toml@4.1.1", "", {}, "sha512-EBJnVBr3dTXdA89WVFoAIPUqkBjxPMwRqsfuo1r240tKFHXv3zgca4+NJib/h6TyvGF7vOawz0jGuryJCdNHrw=="], - - "toolbeam-docs-theme": ["toolbeam-docs-theme@0.4.8", "", { "peerDependencies": { "@astrojs/starlight": "^0.34.3", "astro": "^5.7.13" } }, "sha512-b+5ynEFp4Woe5a22hzNQm42lD23t13ZMihVxHbzjA50zdcM9aOSJTIjdJ0PDSd4/50HbBXcpHiQsz6rM4N88ww=="], + "toml": ["toml@4.2.0", "", {}, "sha512-TvAJjbHZlYmI323+srtqHQFyJsoWy6mI09ppkuj9+iRsqsVKG9fvTcOP7FHF2UCb0QSYtjEavffrKzdd0XgClg=="], "tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="], @@ -4814,18 +2880,8 @@ "trim-lines": ["trim-lines@3.0.1", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="], - "trough": ["trough@2.2.0", "", {}, "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw=="], - - "truncate-utf8-bytes": ["truncate-utf8-bytes@1.0.2", "", { "dependencies": { "utf8-byte-length": "^1.0.1" } }, "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ=="], - "ts-algebra": ["ts-algebra@2.0.0", "", {}, "sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw=="], - "ts-dedent": ["ts-dedent@2.2.0", "", {}, "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ=="], - - "ts-interface-checker": ["ts-interface-checker@0.1.13", "", {}, "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="], - - "tsconfck": ["tsconfck@3.1.6", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"], "bin": { "tsconfck": "bin/tsconfck.js" } }, "sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w=="], - "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], "tsscmp": ["tsscmp@1.0.6", "", {}, "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA=="], @@ -4834,133 +2890,55 @@ "tunnel": ["tunnel@0.0.6", "", {}, "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="], - "turbo": ["turbo@2.8.13", "", { "optionalDependencies": { "turbo-darwin-64": "2.8.13", "turbo-darwin-arm64": "2.8.13", "turbo-linux-64": "2.8.13", "turbo-linux-arm64": "2.8.13", "turbo-windows-64": "2.8.13", "turbo-windows-arm64": "2.8.13" }, "bin": { "turbo": "bin/turbo" } }, "sha512-nyM99hwFB9/DHaFyKEqatdayGjsMNYsQ/XBNO6MITc7roncZetKb97MpHxWf3uiU+LB9c9HUlU3Jp2Ixei2k1A=="], - - "turbo-darwin-64": ["turbo-darwin-64@2.8.13", "", { "os": "darwin", "cpu": "x64" }, "sha512-PmOvodQNiOj77+Zwoqku70vwVjKzL34RTNxxoARjp5RU5FOj/CGiC6vcDQhNtFPUOWSAaogHF5qIka9TBhX4XA=="], - - "turbo-darwin-arm64": ["turbo-darwin-arm64@2.8.13", "", { "os": "darwin", "cpu": "arm64" }, "sha512-kI+anKcLIM4L8h+NsM7mtAUpElkCOxv5LgiQVQR8BASyDFfc8Efj5kCk3cqxuxOvIqx0sLfCX7atrHQ2kwuNJQ=="], - - "turbo-linux-64": ["turbo-linux-64@2.8.13", "", { "os": "linux", "cpu": "x64" }, "sha512-j29KnQhHyzdzgCykBFeBqUPS4Wj7lWMnZ8CHqytlYDap4Jy70l4RNG46pOL9+lGu6DepK2s1rE86zQfo0IOdPw=="], - - "turbo-linux-arm64": ["turbo-linux-arm64@2.8.13", "", { "os": "linux", "cpu": "arm64" }, "sha512-OEl1YocXGZDRDh28doOUn49QwNe82kXljO1HXApjU0LapkDiGpfl3jkAlPKxEkGDSYWc8MH5Ll8S16Rf5tEBYg=="], - - "turbo-windows-64": ["turbo-windows-64@2.8.13", "", { "os": "win32", "cpu": "x64" }, "sha512-717bVk1+Pn2Jody7OmWludhEirEe0okoj1NpRbSm5kVZz/yNN/jfjbxWC6ilimXMz7xoMT3IDfQFJsFR3PMANA=="], - - "turbo-windows-arm64": ["turbo-windows-arm64@2.8.13", "", { "os": "win32", "cpu": "arm64" }, "sha512-R819HShLIT0Wj6zWVnIsYvSNtRNj1q9VIyaUz0P24SMcLCbQZIm1sV09F4SDbg+KCCumqD2lcaR2UViQ8SnUJA=="], + "turbo": ["turbo@2.9.14", "", { "optionalDependencies": { "@turbo/darwin-64": "2.9.14", "@turbo/darwin-arm64": "2.9.14", "@turbo/linux-64": "2.9.14", "@turbo/linux-arm64": "2.9.14", "@turbo/windows-64": "2.9.14", "@turbo/windows-arm64": "2.9.14" }, "bin": { "turbo": "bin/turbo" } }, "sha512-BQqXRr4UoWI3UPFrtznCLykYHxwxWh53iCB57x092jPMjIlW1wnm3N895g5irpiXmnxUhREBB0n6+y8BHhs4nw=="], "turndown": ["turndown@7.2.0", "", { "dependencies": { "@mixmark-io/domino": "^2.2.0" } }, "sha512-eCZGBN4nNNqM9Owkv9HAtWRYfLA4h909E/WGAWWBpmB275ehNhZyk87/Tpvjbp0jjNl9XwCsbe6bm6CqFsgD+A=="], - "tw-to-css": ["tw-to-css@0.0.12", "", { "dependencies": { "postcss": "8.4.31", "postcss-css-variables": "0.18.0", "tailwindcss": "3.3.2" } }, "sha512-rQAsQvOtV1lBkyCw+iypMygNHrShYAItES5r8fMsrhhaj5qrV2LkZyXc8ccEH+u5bFjHjQ9iuxe90I7Kykf6pw=="], - "type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="], - "type-is": ["type-is@1.6.18", "", { "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" } }, "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g=="], - - "typed-array-buffer": ["typed-array-buffer@1.0.3", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-typed-array": "^1.1.14" } }, "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw=="], - - "typed-array-byte-length": ["typed-array-byte-length@1.0.3", "", { "dependencies": { "call-bind": "^1.0.8", "for-each": "^0.3.3", "gopd": "^1.2.0", "has-proto": "^1.2.0", "is-typed-array": "^1.1.14" } }, "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg=="], - - "typed-array-byte-offset": ["typed-array-byte-offset@1.0.4", "", { "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "for-each": "^0.3.3", "gopd": "^1.2.0", "has-proto": "^1.2.0", "is-typed-array": "^1.1.15", "reflect.getprototypeof": "^1.0.9" } }, "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ=="], - - "typed-array-length": ["typed-array-length@1.0.7", "", { "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", "is-typed-array": "^1.1.13", "possible-typed-array-names": "^1.0.0", "reflect.getprototypeof": "^1.0.6" } }, "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg=="], - - "typesafe-path": ["typesafe-path@0.2.2", "", {}, "sha512-OJabfkAg1WLZSqJAJ0Z6Sdt3utnbzr/jh+NAHoyWHJe8CMSy79Gm085094M9nvTPy22KzTVn5Zq5mbapCI/hPA=="], + "type-is": ["type-is@2.0.1", "", { "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw=="], "typescript": ["typescript@5.8.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ=="], - "typescript-auto-import-cache": ["typescript-auto-import-cache@0.3.6", "", { "dependencies": { "semver": "^7.3.8" } }, "sha512-RpuHXrknHdVdK7wv/8ug3Fr0WNsNi5l5aB8MYYuXhq2UH5lnEB1htJ1smhtD5VeCsGr2p8mUDtd83LCQDFVgjQ=="], - - "ufo": ["ufo@1.6.3", "", {}, "sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q=="], - "uint8array-extras": ["uint8array-extras@1.5.0", "", {}, "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A=="], "ulid": ["ulid@3.0.1", "", { "bin": { "ulid": "dist/cli.js" } }, "sha512-dPJyqPzx8preQhqq24bBG1YNkvigm87K8kVEHCD+ruZg24t6IFEFv00xMWfxcC4djmFtiTLdFuADn4+DOz6R7Q=="], - "ultrahtml": ["ultrahtml@1.6.0", "", {}, "sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw=="], - - "unbox-primitive": ["unbox-primitive@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "has-bigints": "^1.0.2", "has-symbols": "^1.1.0", "which-boxed-primitive": "^1.1.1" } }, "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw=="], - - "uncrypto": ["uncrypto@0.1.3", "", {}, "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q=="], - - "undici": ["undici@7.25.0", "", {}, "sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ=="], + "undici": ["undici@8.9.0", "", {}, "sha512-aWZpUj7XoGonMClx4gdDRfgBjqeA+F473aDmROQQbM9n6PRfK/u1q/a0X4wMTgcHfT8H6fpbt98PFuDUwFg2YA=="], "undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], - "unenv": ["unenv@2.0.0-rc.24", "", { "dependencies": { "pathe": "^2.0.3" } }, "sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw=="], - - "unicode-properties": ["unicode-properties@1.4.1", "", { "dependencies": { "base64-js": "^1.3.0", "unicode-trie": "^2.0.0" } }, "sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg=="], - - "unicode-trie": ["unicode-trie@2.0.0", "", { "dependencies": { "pako": "^0.2.5", "tiny-inflate": "^1.0.0" } }, "sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ=="], - - "unified": ["unified@11.0.5", "", { "dependencies": { "@types/unist": "^3.0.0", "bail": "^2.0.0", "devlop": "^1.0.0", "extend": "^3.0.0", "is-plain-obj": "^4.0.0", "trough": "^2.0.0", "vfile": "^6.0.0" } }, "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA=="], - - "unifont": ["unifont@0.5.2", "", { "dependencies": { "css-tree": "^3.0.0", "ofetch": "^1.4.1", "ohash": "^2.0.0" } }, "sha512-LzR4WUqzH9ILFvjLAUU7dK3Lnou/qd5kD+IakBtBK4S15/+x2y9VX+DcWQv6s551R6W+vzwgVS6tFg3XggGBgg=="], - - "unique-filename": ["unique-filename@4.0.0", "", { "dependencies": { "unique-slug": "^5.0.0" } }, "sha512-XSnEewXmQ+veP7xX2dS5Q4yZAvO40cBN2MWkJ7D/6sW4Dg6wYBNwM1Vrnz1FhH5AdeLIlUXRI9e28z1YZi71NQ=="], - - "unique-slug": ["unique-slug@5.0.0", "", { "dependencies": { "imurmurhash": "^0.1.4" } }, "sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg=="], - - "unist-util-find-after": ["unist-util-find-after@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ=="], - "unist-util-is": ["unist-util-is@6.0.1", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g=="], - "unist-util-modify-children": ["unist-util-modify-children@4.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "array-iterate": "^2.0.0" } }, "sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw=="], - "unist-util-position": ["unist-util-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA=="], - "unist-util-position-from-estree": ["unist-util-position-from-estree@2.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ=="], - - "unist-util-remove-position": ["unist-util-remove-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-visit": "^5.0.0" } }, "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q=="], - "unist-util-stringify-position": ["unist-util-stringify-position@4.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ=="], "unist-util-visit": ["unist-util-visit@5.1.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg=="], - "unist-util-visit-children": ["unist-util-visit-children@3.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA=="], - "unist-util-visit-parents": ["unist-util-visit-parents@6.0.2", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ=="], "universal-github-app-jwt": ["universal-github-app-jwt@2.2.2", "", {}, "sha512-dcmbeSrOdTnsjGjUfAlqNDJrhxXizjAz94ija9Qw8YkZ1uu0d+GoZzyH+Jb9tIIqvGsadUfwg+22k5aDqqwzbw=="], "universal-user-agent": ["universal-user-agent@7.0.3", "", {}, "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A=="], - "universalify": ["universalify@2.0.1", "", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="], - "unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="], - "unplugin": ["unplugin@1.0.1", "", { "dependencies": { "acorn": "^8.8.1", "chokidar": "^3.5.3", "webpack-sources": "^3.2.3", "webpack-virtual-modules": "^0.5.0" } }, "sha512-aqrHaVBWW1JVKBHmGo33T5TxeL0qWzfvjWokObHA9bYmN7eNDkwOxmLjhioHl9878qDFMAaT51XNroRyuz7WxA=="], - - "unstorage": ["unstorage@2.0.0-alpha.7", "", { "peerDependencies": { "@azure/app-configuration": "^1.11.0", "@azure/cosmos": "^4.9.1", "@azure/data-tables": "^13.3.2", "@azure/identity": "^4.13.0", "@azure/keyvault-secrets": "^4.10.0", "@azure/storage-blob": "^12.31.0", "@capacitor/preferences": "^6 || ^7 || ^8", "@deno/kv": ">=0.13.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.36.2", "@vercel/blob": ">=0.27.3", "@vercel/functions": "^2.2.12 || ^3.0.0", "@vercel/kv": "^1.0.1", "aws4fetch": "^1.0.20", "chokidar": "^4 || ^5", "db0": ">=0.3.4", "idb-keyval": "^6.2.2", "ioredis": "^5.9.3", "lru-cache": "^11.2.6", "mongodb": "^6 || ^7", "ofetch": "*", "uploadthing": "^7.7.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/functions", "@vercel/kv", "aws4fetch", "chokidar", "db0", "idb-keyval", "ioredis", "lru-cache", "mongodb", "ofetch", "uploadthing"] }, "sha512-ELPztchk2zgFJnakyodVY3vJWGW9jy//keJ32IOJVGUMyaPydwcA1FtVvWqT0TNRch9H+cMNEGllfVFfScImog=="], - - "unused-filename": ["unused-filename@4.0.1", "", { "dependencies": { "escape-string-regexp": "^5.0.0", "path-exists": "^5.0.0" } }, "sha512-ZX6U1J04K1FoSUeoX1OicAhw4d0aro2qo+L8RhJkiGTNtBNkd/Fi1Wxoc9HzcVu6HfOzm0si/N15JjxFmD1z6A=="], - "unzip-stream": ["unzip-stream@0.3.4", "", { "dependencies": { "binary": "^0.3.0", "mkdirp": "^0.5.1" } }, "sha512-PyofABPVv+d7fL7GOpusx7eRT9YETY2X04PhwbSipdj6bMxVCFJrr+nm0Mxqbf9hUiTin/UsnuFWBXlDZFy0Cw=="], "update-browserslist-db": ["update-browserslist-db@1.2.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w=="], - "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="], - "url": ["url@0.10.3", "", { "dependencies": { "punycode": "1.3.2", "querystring": "0.2.0" } }, "sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ=="], - "use-callback-ref": ["use-callback-ref@1.3.3", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg=="], - - "use-sidecar": ["use-sidecar@1.1.3", "", { "dependencies": { "detect-node-es": "^1.1.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ=="], - - "use-sync-external-store": ["use-sync-external-store@1.6.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w=="], - - "utf8-byte-length": ["utf8-byte-length@1.0.5", "", {}, "sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA=="], - "utif2": ["utif2@4.1.0", "", { "dependencies": { "pako": "^1.0.11" } }, "sha512-+oknB9FHrJ7oW7A2WZYajOcv4FcDR4CfoGB0dPNfxbi4GO05RRnFmt5oa23+9w32EanrYcSJWspUiJkLMs+37w=="], "util": ["util@0.12.5", "", { "dependencies": { "inherits": "^2.0.3", "is-arguments": "^1.0.4", "is-generator-function": "^1.0.7", "is-typed-array": "^1.1.3", "which-typed-array": "^1.1.2" } }, "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA=="], "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], - "utils-merge": ["utils-merge@1.0.1", "", {}, "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA=="], + "uuid": ["uuid@13.0.1", "", { "bin": { "uuid": "dist-node/bin/uuid" } }, "sha512-9ezox2roIft6ExBVTVqibSd5dc5/47Sw/uY6b4SjQUT2TzQ0tltNquWA46y4xPQmdZYqvnio22SgWd41M86+jw=="], - "uuid": ["uuid@13.0.0", "", { "bin": { "uuid": "dist-node/bin/uuid" } }, "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w=="], - - "valibot": ["valibot@1.3.1", "", { "peerDependencies": { "typescript": ">=5" }, "optionalPeers": ["typescript"] }, "sha512-sfdRir/QFM0JaF22hqTroPc5xy4DimuGQVKFrzF1YfGwaS1nJot3Y8VqMdLO2Lg27fMzat2yD3pY5PbAYO39Gg=="], + "valibot": ["valibot@1.4.2", "", { "peerDependencies": { "typescript": ">=5" }, "optionalPeers": ["typescript"] }, "sha512-gjdCvJ6d3RyHAneqxMYMW9QMCwYMb3jpOO0IyHZV1bnRHFBHrX3VkIILt5XYR0WhwHiH7Mty8ovuPZ/O3gamrg=="], "validate-npm-package-name": ["validate-npm-package-name@7.0.2", "", {}, "sha512-hVDIBwsRruT73PbK7uP5ebUt+ezEtCmzZz3F59BSr2F6OVFnJ/6h8liuvdLrQ88Xmnk6/+xGGuq+pG9WwTuy3A=="], @@ -4968,19 +2946,13 @@ "venice-ai-sdk-provider": ["venice-ai-sdk-provider@2.0.1", "", { "dependencies": { "@ai-sdk/openai-compatible": "^2.0.37", "@ai-sdk/provider": "^3.0.8", "@ai-sdk/provider-utils": "^4.0.21" }, "peerDependencies": { "ai": "^6.0.90" } }, "sha512-6SxA8a4MoA6Q/c+D3q7My0Hfog76enN3n0MXhwosM+tso66rXBEGeBRD/0lravRDVzL2Q1w5QJPc86rAVJtfXg=="], - "verror": ["verror@1.10.1", "", { "dependencies": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", "extsprintf": "^1.2.0" } }, "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg=="], - "vfile": ["vfile@6.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile-message": "^4.0.0" } }, "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q=="], - "vfile-location": ["vfile-location@5.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile": "^6.0.0" } }, "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg=="], - "vfile-message": ["vfile-message@4.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw=="], "virtua": ["virtua@0.42.3", "", { "peerDependencies": { "react": ">=16.14.0", "react-dom": ">=16.14.0", "solid-js": ">=1.0", "svelte": ">=5.0", "vue": ">=3.2" }, "optionalPeers": ["react", "react-dom", "solid-js", "svelte", "vue"] }, "sha512-5FoAKcEvh05qsUF97Yz42SWJ7bwnPExjUYHGuoxz1EUtfWtaOgXaRwnylJbDpA0QcH1rKvJ2qsGRi9MK1fpQbg=="], - "vite": ["vite@7.1.4", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.14" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-X5QFK4SGynAeeIt+A7ZWnApdUyHYm+pzv/8/A57LqSGcI88U6R6ipOs3uCesdc6yl7nl+zNO0t8LmqAdXcQihw=="], - - "vite-plugin-dynamic-import": ["vite-plugin-dynamic-import@1.6.0", "", { "dependencies": { "acorn": "^8.12.1", "es-module-lexer": "^1.5.4", "fast-glob": "^3.3.2", "magic-string": "^0.30.11" } }, "sha512-TM0sz70wfzTIo9YCxVFwS8OA9lNREsh+0vMHGSkWDTZ7bgd1Yjs5RV8EgB634l/91IsXJReg0xtmuQqP0mf+rg=="], + "vite": ["vite@7.3.5", "", { "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-KuOaNhcnGFN2zIPGA7wRmzF+lJA1sea7rHq17aiJ++9lzY1WWG6Jpwqwe1KNbRVPIqHmr8GLYx7jbrQcN/7/ww=="], "vite-plugin-icons-spritesheet": ["vite-plugin-icons-spritesheet@3.0.1", "", { "dependencies": { "chalk": "^5.4.1", "glob": "^11.0.1", "node-html-parser": "^7.0.1", "tinyexec": "^0.3.2" }, "peerDependencies": { "vite": ">=5.2.0" } }, "sha512-Cr0+Z6wRMwSwKisWW9PHeTjqmQFv0jwRQQMc3YgAhAgZEe03j21el0P/CA31KN/L5eiL1LhR14VTXl96LetonA=="], @@ -4988,84 +2960,26 @@ "vitefu": ["vitefu@1.1.3", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["vite"] }, "sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg=="], - "vitest": ["vitest@4.1.4", "", { "dependencies": { "@vitest/expect": "4.1.4", "@vitest/mocker": "4.1.4", "@vitest/pretty-format": "4.1.4", "@vitest/runner": "4.1.4", "@vitest/snapshot": "4.1.4", "@vitest/spy": "4.1.4", "@vitest/utils": "4.1.4", "es-module-lexer": "^2.0.0", "expect-type": "^1.3.0", "magic-string": "^0.30.21", "obug": "^2.1.1", "pathe": "^2.0.3", "picomatch": "^4.0.3", "std-env": "^4.0.0-rc.1", "tinybench": "^2.9.0", "tinyexec": "^1.0.2", "tinyglobby": "^0.2.15", "tinyrainbow": "^3.1.0", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", "why-is-node-running": "^2.3.0" }, "peerDependencies": { "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", "@vitest/browser-playwright": "4.1.4", "@vitest/browser-preview": "4.1.4", "@vitest/browser-webdriverio": "4.1.4", "@vitest/coverage-istanbul": "4.1.4", "@vitest/coverage-v8": "4.1.4", "@vitest/ui": "4.1.4", "happy-dom": "*", "jsdom": "*" }, "optionalPeers": ["@edge-runtime/vm", "@opentelemetry/api", "@types/node", "@vitest/browser-playwright", "@vitest/browser-preview", "@vitest/browser-webdriverio", "@vitest/coverage-istanbul", "@vitest/coverage-v8", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "vitest.mjs" } }, "sha512-tFuJqTxKb8AvfyqMfnavXdzfy3h3sWZRWwfluGbkeR7n0HUev+FmNgZ8SDrRBTVrVCjgH5cA21qGbCffMNtWvg=="], - - "volar-service-css": ["volar-service-css@0.0.70", "", { "dependencies": { "vscode-css-languageservice": "^6.3.0", "vscode-languageserver-textdocument": "^1.0.11", "vscode-uri": "^3.0.8" }, "peerDependencies": { "@volar/language-service": "~2.4.0" }, "optionalPeers": ["@volar/language-service"] }, "sha512-K1qyOvBpE3rzdAv3e4/6Rv5yizrYPy5R/ne3IWCAzLBuMO4qBMV3kSqWzj6KUVe6S0AnN6wxF7cRkiaKfYMYJw=="], - - "volar-service-emmet": ["volar-service-emmet@0.0.70", "", { "dependencies": { "@emmetio/css-parser": "^0.4.1", "@emmetio/html-matcher": "^1.3.0", "@vscode/emmet-helper": "^2.9.3", "vscode-uri": "^3.0.8" }, "peerDependencies": { "@volar/language-service": "~2.4.0" }, "optionalPeers": ["@volar/language-service"] }, "sha512-xi5bC4m/VyE3zy/n2CXspKeDZs3qA41tHLTw275/7dNWM/RqE2z3BnDICQybHIVp/6G1iOQj5c1qXMgQC08TNg=="], - - "volar-service-html": ["volar-service-html@0.0.70", "", { "dependencies": { "vscode-html-languageservice": "^5.3.0", "vscode-languageserver-textdocument": "^1.0.11", "vscode-uri": "^3.0.8" }, "peerDependencies": { "@volar/language-service": "~2.4.0" }, "optionalPeers": ["@volar/language-service"] }, "sha512-eR6vCgMdmYAo4n+gcT7DSyBQbwB8S3HZZvSagTf0sxNaD4WppMCFfpqWnkrlGStPKMZvMiejRRVmqsX9dYcTvQ=="], - - "volar-service-prettier": ["volar-service-prettier@0.0.70", "", { "dependencies": { "vscode-uri": "^3.0.8" }, "peerDependencies": { "@volar/language-service": "~2.4.0", "prettier": "^2.2 || ^3.0" }, "optionalPeers": ["@volar/language-service", "prettier"] }, "sha512-Z6BCFSpGVCd8BPAsZ785Kce1BGlWd5ODqmqZGVuB14MJvrR4+CYz6cDy4F+igmE1gMifqfvMhdgT8Aud4M5ngg=="], - - "volar-service-typescript": ["volar-service-typescript@0.0.70", "", { "dependencies": { "path-browserify": "^1.0.1", "semver": "^7.6.2", "typescript-auto-import-cache": "^0.3.5", "vscode-languageserver-textdocument": "^1.0.11", "vscode-nls": "^5.2.0", "vscode-uri": "^3.0.8" }, "peerDependencies": { "@volar/language-service": "~2.4.0" }, "optionalPeers": ["@volar/language-service"] }, "sha512-l46Bx4cokkUedTd74ojO5H/zqHZJ8SUuyZ0IB8JN4jfRqUM3bQFBHoOwlZCyZmOeO0A3RQNkMnFclxO4c++gsg=="], - - "volar-service-typescript-twoslash-queries": ["volar-service-typescript-twoslash-queries@0.0.70", "", { "dependencies": { "vscode-uri": "^3.0.8" }, "peerDependencies": { "@volar/language-service": "~2.4.0" }, "optionalPeers": ["@volar/language-service"] }, "sha512-IdD13Z9N2Bu8EM6CM0fDV1E69olEYGHDU25X51YXmq8Y0CmJ2LNj6gOiBJgpS5JGUqFzECVhMNBW7R0sPdRTMQ=="], - - "volar-service-yaml": ["volar-service-yaml@0.0.70", "", { "dependencies": { "vscode-uri": "^3.0.8", "yaml-language-server": "~1.20.0" }, "peerDependencies": { "@volar/language-service": "~2.4.0" }, "optionalPeers": ["@volar/language-service"] }, "sha512-0c8bXDBeoATF9F6iPIlOuYTuZAC4c+yi0siQo920u7eiBJk8oQmUmg9cDUbR4+Gl++bvGP4plj3fErbJuPqdcQ=="], - - "vscode-css-languageservice": ["vscode-css-languageservice@6.3.10", "", { "dependencies": { "@vscode/l10n": "^0.0.18", "vscode-languageserver-textdocument": "^1.0.12", "vscode-languageserver-types": "3.17.5", "vscode-uri": "^3.1.0" } }, "sha512-eq5N9Er3fC4vA9zd9EFhyBG90wtCCuXgRSpAndaOgXMh1Wgep5lBgRIeDgjZBW9pa+332yC9+49cZMW8jcL3MA=="], - - "vscode-html-languageservice": ["vscode-html-languageservice@5.6.2", "", { "dependencies": { "@vscode/l10n": "^0.0.18", "vscode-languageserver-textdocument": "^1.0.12", "vscode-languageserver-types": "^3.17.5", "vscode-uri": "^3.1.0" } }, "sha512-ulCrSnFnfQ16YzvwnYUgEbUEl/ZG7u2eV27YhvLObSHKkb8fw1Z9cgsnUwjTEeDIdJDoTDTDpxuhQwoenoLNMg=="], - - "vscode-json-languageservice": ["vscode-json-languageservice@4.1.8", "", { "dependencies": { "jsonc-parser": "^3.0.0", "vscode-languageserver-textdocument": "^1.0.1", "vscode-languageserver-types": "^3.16.0", "vscode-nls": "^5.0.0", "vscode-uri": "^3.0.2" } }, "sha512-0vSpg6Xd9hfV+eZAaYN63xVVMOTmJ4GgHxXnkLCh+9RsQBkWKIghzLhW2B9ebfG+LQQg8uLtsQ2aUKjTgE+QOg=="], - "vscode-jsonrpc": ["vscode-jsonrpc@8.2.1", "", {}, "sha512-kdjOSJ2lLIn7r1rtrMbbNCHjyMPfRnowdKjBQ+mGq6NAW5QY2bEZC/khaC5OR8svbbjvLEaIXkOq45e2X9BIbQ=="], - "vscode-languageserver": ["vscode-languageserver@9.0.1", "", { "dependencies": { "vscode-languageserver-protocol": "3.17.5" }, "bin": { "installServerIntoExtension": "bin/installServerIntoExtension" } }, "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g=="], - - "vscode-languageserver-protocol": ["vscode-languageserver-protocol@3.17.5", "", { "dependencies": { "vscode-jsonrpc": "8.2.0", "vscode-languageserver-types": "3.17.5" } }, "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg=="], - - "vscode-languageserver-textdocument": ["vscode-languageserver-textdocument@1.0.12", "", {}, "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA=="], - "vscode-languageserver-types": ["vscode-languageserver-types@3.17.5", "", {}, "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg=="], - "vscode-nls": ["vscode-nls@5.2.0", "", {}, "sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng=="], - - "vscode-uri": ["vscode-uri@3.1.0", "", {}, "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ=="], - "walk-up-path": ["walk-up-path@4.0.0", "", {}, "sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A=="], - "wcwidth": ["wcwidth@1.0.1", "", { "dependencies": { "defaults": "^1.0.3" } }, "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg=="], - - "web-namespaces": ["web-namespaces@2.0.1", "", {}, "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ=="], - - "web-streams-polyfill": ["web-streams-polyfill@4.0.0-beta.3", "", {}, "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug=="], + "web-streams-polyfill": ["web-streams-polyfill@3.3.3", "", {}, "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw=="], "web-tree-sitter": ["web-tree-sitter@0.25.10", "", { "peerDependencies": { "@types/emscripten": "^1.40.0" }, "optionalPeers": ["@types/emscripten"] }, "sha512-Y09sF44/13XvgVKgO2cNDw5rGk6s26MgoZPXLESvMXeefBf7i6/73eFurre0IsTW6E14Y0ArIzhUMmjoc7xyzA=="], "webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="], - "webpack-sources": ["webpack-sources@3.4.0", "", {}, "sha512-gHwIe1cgBvvfLeu1Yz/dcFpmHfKDVxxyqI+kzqmuxZED81z2ChxpyqPaWcNqigPywhaEke7AjSGga+kxY55gjQ=="], - - "webpack-virtual-modules": ["webpack-virtual-modules@0.5.0", "", {}, "sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw=="], - - "whatwg-mimetype": ["whatwg-mimetype@3.0.0", "", {}, "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q=="], - "whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="], - "when-exit": ["when-exit@2.1.5", "", {}, "sha512-VGkKJ564kzt6Ms1dbgPP/yuIoQCrsFAnRbptpC5wOEsDaNsbCB2bnfnaA8i/vRs5tjUSEOtIuvl9/MyVsvQZCg=="], - "which": ["which@6.0.1", "", { "dependencies": { "isexe": "^4.0.0" }, "bin": { "node-which": "bin/which.js" } }, "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg=="], - "which-boxed-primitive": ["which-boxed-primitive@1.1.1", "", { "dependencies": { "is-bigint": "^1.1.0", "is-boolean-object": "^1.2.1", "is-number-object": "^1.1.1", "is-string": "^1.1.1", "is-symbol": "^1.1.1" } }, "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA=="], - - "which-builtin-type": ["which-builtin-type@1.2.1", "", { "dependencies": { "call-bound": "^1.0.2", "function.prototype.name": "^1.1.6", "has-tostringtag": "^1.0.2", "is-async-function": "^2.0.0", "is-date-object": "^1.1.0", "is-finalizationregistry": "^1.1.0", "is-generator-function": "^1.0.10", "is-regex": "^1.2.1", "is-weakref": "^1.0.2", "isarray": "^2.0.5", "which-boxed-primitive": "^1.1.0", "which-collection": "^1.0.2", "which-typed-array": "^1.1.16" } }, "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q=="], - - "which-collection": ["which-collection@1.0.2", "", { "dependencies": { "is-map": "^2.0.3", "is-set": "^2.0.3", "is-weakmap": "^2.0.2", "is-weakset": "^2.0.3" } }, "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw=="], - - "which-pm-runs": ["which-pm-runs@1.1.0", "", {}, "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA=="], - "which-typed-array": ["which-typed-array@1.1.20", "", { "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.4", "for-each": "^0.3.5", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" } }, "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg=="], "why-is-node-running": ["why-is-node-running@3.2.2", "", { "bin": { "why-is-node-running": "cli.js" } }, "sha512-NKUzAelcoCXhXL4dJzKIwXeR8iEVqsA0Lq6Vnd0UXvgaKbzVo4ZTHROF2Jidrv+SgxOQ03fMinnNhzZATxOD3A=="], - "widest-line": ["widest-line@5.0.0", "", { "dependencies": { "string-width": "^7.0.0" } }, "sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA=="], - - "workerd": ["workerd@1.20251118.0", "", { "optionalDependencies": { "@cloudflare/workerd-darwin-64": "1.20251118.0", "@cloudflare/workerd-darwin-arm64": "1.20251118.0", "@cloudflare/workerd-linux-64": "1.20251118.0", "@cloudflare/workerd-linux-arm64": "1.20251118.0", "@cloudflare/workerd-windows-64": "1.20251118.0" }, "bin": { "workerd": "bin/workerd" } }, "sha512-Om5ns0Lyx/LKtYI04IV0bjIrkBgoFNg0p6urzr2asekJlfP18RqFzyqMFZKf0i9Gnjtz/JfAS/Ol6tjCe5JJsQ=="], - - "wrangler": ["wrangler@4.50.0", "", { "dependencies": { "@cloudflare/kv-asset-handler": "0.4.0", "@cloudflare/unenv-preset": "2.7.11", "blake3-wasm": "2.1.5", "esbuild": "0.25.4", "miniflare": "4.20251118.1", "path-to-regexp": "6.3.0", "unenv": "2.0.0-rc.24", "workerd": "1.20251118.0" }, "optionalDependencies": { "fsevents": "~2.3.2" }, "peerDependencies": { "@cloudflare/workers-types": "^4.20251118.0" }, "optionalPeers": ["@cloudflare/workers-types"], "bin": { "wrangler": "bin/wrangler.js", "wrangler2": "bin/wrangler.js" } }, "sha512-+nuZuHZxDdKmAyXOSrHlciGshCoAPiy5dM+t6mEohWm7HpXvTHmWQGUf/na9jjWlWJHCJYOWzkA1P5HBJqrIEA=="], - "wrap-ansi": ["wrap-ansi@9.0.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww=="], "wrap-ansi-cjs": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], @@ -5074,9 +2988,9 @@ "write-file-atomic": ["write-file-atomic@7.0.1", "", { "dependencies": { "signal-exit": "^4.0.1" } }, "sha512-OTIk8iR8/aCRWBqvxrzxR0hgxWpnYBblY1S5hDWBQfk/VFmJwzmJgQFN3WsoUKHISv2eAwe+PpbUzyL1CKTLXg=="], - "ws": ["ws@8.18.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw=="], + "ws": ["ws@8.21.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g=="], - "wsl-utils": ["wsl-utils@0.3.1", "", { "dependencies": { "is-wsl": "^3.1.0", "powershell-utils": "^0.1.0" } }, "sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg=="], + "wsl-utils": ["wsl-utils@0.1.0", "", { "dependencies": { "is-wsl": "^3.1.0" } }, "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw=="], "xdg-basedir": ["xdg-basedir@5.1.0", "", {}, "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ=="], @@ -5088,34 +3002,18 @@ "xmlhttprequest-ssl": ["xmlhttprequest-ssl@2.1.2", "", {}, "sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ=="], - "xxhash-wasm": ["xxhash-wasm@1.1.0", "", {}, "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA=="], - "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], "yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], "yaml": ["yaml@2.8.3", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg=="], - "yaml-language-server": ["yaml-language-server@1.20.0", "", { "dependencies": { "@vscode/l10n": "^0.0.18", "ajv": "^8.17.1", "ajv-draft-04": "^1.0.0", "prettier": "^3.5.0", "request-light": "^0.5.7", "vscode-json-languageservice": "4.1.8", "vscode-languageserver": "^9.0.0", "vscode-languageserver-textdocument": "^1.0.1", "vscode-languageserver-types": "^3.16.0", "vscode-uri": "^3.0.2", "yaml": "2.7.1" }, "bin": { "yaml-language-server": "bin/yaml-language-server" } }, "sha512-qhjK/bzSRZ6HtTvgeFvjNPJGWdZ0+x5NREV/9XZWFjIGezew2b4r5JPy66IfOhd5OA7KeFwk1JfmEbnTvev0cA=="], - "yargs": ["yargs@18.0.0", "", { "dependencies": { "cliui": "^9.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "string-width": "^7.2.0", "y18n": "^5.0.5", "yargs-parser": "^22.0.0" } }, "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg=="], - "yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="], - - "yauzl": ["yauzl@2.10.0", "", { "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" } }, "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g=="], - - "yocto-queue": ["yocto-queue@1.2.2", "", {}, "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ=="], - - "yocto-spinner": ["yocto-spinner@0.2.3", "", { "dependencies": { "yoctocolors": "^2.1.1" } }, "sha512-sqBChb33loEnkoXte1bLg45bEBsOP9N1kzQh5JZNKj/0rik4zAPTNSAVPj3uQAdc6slYJ0Ksc403G2XgxsJQFQ=="], - - "yoctocolors": ["yoctocolors@2.1.2", "", {}, "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug=="], + "yargs-parser": ["yargs-parser@22.0.0", "", {}, "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw=="], "yoga-layout": ["yoga-layout@3.2.1", "", {}, "sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ=="], - "youch": ["youch@4.1.0-beta.10", "", { "dependencies": { "@poppinss/colors": "^4.1.5", "@poppinss/dumper": "^0.6.4", "@speed-highlight/core": "^1.2.7", "cookie": "^1.0.2", "youch-core": "^0.3.3" } }, "sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ=="], - - "youch-core": ["youch-core@0.3.3", "", { "dependencies": { "@poppinss/exception": "^1.2.2", "error-stack-parser-es": "^1.0.5" } }, "sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA=="], - "zip-stream": ["zip-stream@6.0.1", "", { "dependencies": { "archiver-utils": "^5.0.0", "compress-commons": "^6.0.2", "readable-stream": "^4.0.0" } }, "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA=="], "zod": ["zod@4.1.8", "", {}, "sha512-5R1P+WwQqmmMIEACyzSvo4JXHY5WiAFHRMg+zBZKgKS+Q1viRa0C1hmUKtHltoIFKtIdki3pRxkmpP74jnNYHQ=="], @@ -5124,8 +3022,6 @@ "zod-to-json-schema": ["zod-to-json-schema@3.24.5", "", { "peerDependencies": { "zod": "^3.24.1" } }, "sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g=="], - "zod-to-ts": ["zod-to-ts@1.2.0", "", { "peerDependencies": { "typescript": "^4.9.4 || ^5.0.2", "zod": "^3" } }, "sha512-x30XE43V+InwGpvTySRNz9kB7qFU8DlyEy7BsSTCHPH1R0QasMmHWZDCzYm6bVXtj/9NNJAZF3jW8rzFvH5OFA=="], - "zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], "@actions/artifact/@actions/core": ["@actions/core@2.0.3", "", { "dependencies": { "@actions/exec": "^2.0.0", "@actions/http-client": "^3.0.2" } }, "sha512-Od9Thc3T1mQJYddvVPM4QGiLUewdh+3txmDYHHxoNdkqysR1MbCT+rFOtNUxYAz+7+6RIsqipVahY2GJqGPyxA=="], @@ -5138,69 +3034,23 @@ "@actions/github/@octokit/plugin-rest-endpoint-methods": ["@octokit/plugin-rest-endpoint-methods@10.4.1", "", { "dependencies": { "@octokit/types": "^12.6.0" }, "peerDependencies": { "@octokit/core": "5" } }, "sha512-xV1b+ceKV9KytQe3zCVqjg+8GTGfDYwaT1ATU5isiUyVtlVAO3HNdzpS4sr4GBx4hxQ46s7ITtZrAsxG22+rVg=="], - "@actions/github/undici": ["undici@5.29.0", "", { "dependencies": { "@fastify/busboy": "^2.0.0" } }, "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg=="], - - "@actions/http-client/undici": ["undici@6.25.0", "", {}, "sha512-ZgpWDC5gmNiuY9CnLVXEH8rl50xhRCuLNA97fAUnKi8RRuV4E6KG31pDTsLVUKnohJE0I3XDrTeEydAXRw47xg=="], - - "@ai-sdk/alibaba/@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@2.0.41", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.23" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-kNAGINk71AlOXx10Dq/PXw4t/9XjdK8uxfpVElRwtSFMdeSiLVt58p9TPx4/FJD+hxZuVhvxYj9r42osxWq79g=="], - - "@ai-sdk/amazon-bedrock/@ai-sdk/anthropic": ["@ai-sdk/anthropic@3.0.71", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.23" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-bUWOzrzR0gJKJO/PLGMR4uH2dqEgqGhrsCV+sSpk4KtOEnUQlfjZI/F7BFlqSvVpFbjdgYRRLysAeEZpJ6S1lg=="], - - "@ai-sdk/amazon-bedrock/@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.13", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.14.0", "@smithy/util-hex-encoding": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-vYahwBAtRaAcFbOmE9aLr12z7RiHYDSLcnogSdxfm7kKfsNa3wH+NU5r7vTeB5rKvLsWyPjVX8iH94brP7umiQ=="], - "@ai-sdk/amazon-bedrock/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - "@ai-sdk/anthropic/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@4.0.21", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-MtFUYI1/8mgDvRmaBDjbLJPFFrMG777AvSgyIFQtZHIMzm88R/12vYBBpnk7pfiWLFE1DSZzY4WDYzGbKAcmiw=="], - - "@ai-sdk/azure/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@4.0.21", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-MtFUYI1/8mgDvRmaBDjbLJPFFrMG777AvSgyIFQtZHIMzm88R/12vYBBpnk7pfiWLFE1DSZzY4WDYzGbKAcmiw=="], + "@ai-sdk/amazon-bedrock/aws4fetch": ["aws4fetch@1.0.20", "", {}, "sha512-/djoAN709iY65ETD6LKCtyyEI04XIBP5xVvfmNxsEP0uJB5tyaGBztSryRr4HqMStr9R06PisQE7m9zDTXKu6g=="], - "@ai-sdk/cerebras/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@4.0.21", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-MtFUYI1/8mgDvRmaBDjbLJPFFrMG777AvSgyIFQtZHIMzm88R/12vYBBpnk7pfiWLFE1DSZzY4WDYzGbKAcmiw=="], + "@ai-sdk/azure/@ai-sdk/openai": ["@ai-sdk/openai@3.0.48", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.21" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-ALmj/53EXpcRqMbGpPJPP4UOSWw0q4VGpnDo7YctvsynjkrKDmoneDG/1a7VQnSPYHnJp6tTRMf5ZdxZ5whulg=="], - "@ai-sdk/cohere/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@4.0.21", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-MtFUYI1/8mgDvRmaBDjbLJPFFrMG777AvSgyIFQtZHIMzm88R/12vYBBpnk7pfiWLFE1DSZzY4WDYzGbKAcmiw=="], + "@ai-sdk/cerebras/@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@2.0.37", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.21" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-+POSFVcgiu47BK64dhsI6OpcDC0/VAE2ZSaXdXGNNhpC/ava++uSRJYks0k2bpfY0wwCTgpAWZsXn/dG2Yppiw=="], - "@ai-sdk/deepinfra/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@4.0.21", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-MtFUYI1/8mgDvRmaBDjbLJPFFrMG777AvSgyIFQtZHIMzm88R/12vYBBpnk7pfiWLFE1DSZzY4WDYzGbKAcmiw=="], - - "@ai-sdk/fireworks/@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@2.0.41", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.23" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-kNAGINk71AlOXx10Dq/PXw4t/9XjdK8uxfpVElRwtSFMdeSiLVt58p9TPx4/FJD+hxZuVhvxYj9r42osxWq79g=="], - - "@ai-sdk/google-vertex/@ai-sdk/anthropic": ["@ai-sdk/anthropic@3.0.71", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.23" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-bUWOzrzR0gJKJO/PLGMR4uH2dqEgqGhrsCV+sSpk4KtOEnUQlfjZI/F7BFlqSvVpFbjdgYRRLysAeEZpJ6S1lg=="], + "@ai-sdk/deepinfra/@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@2.0.37", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.21" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-+POSFVcgiu47BK64dhsI6OpcDC0/VAE2ZSaXdXGNNhpC/ava++uSRJYks0k2bpfY0wwCTgpAWZsXn/dG2Yppiw=="], "@ai-sdk/google-vertex/@ai-sdk/google": ["@ai-sdk/google@3.0.64", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.23" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-CbR82EgGPNrj/6q0HtclwuCqe0/pDShyv3nWDP/A9DroujzWXnLMlUJVrgPOsg4b40zQCwwVs2XSKCxvt/4QaA=="], - "@ai-sdk/google-vertex/@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@2.0.41", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.23" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-kNAGINk71AlOXx10Dq/PXw4t/9XjdK8uxfpVElRwtSFMdeSiLVt58p9TPx4/FJD+hxZuVhvxYj9r42osxWq79g=="], - - "@ai-sdk/groq/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@4.0.21", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-MtFUYI1/8mgDvRmaBDjbLJPFFrMG777AvSgyIFQtZHIMzm88R/12vYBBpnk7pfiWLFE1DSZzY4WDYzGbKAcmiw=="], - - "@ai-sdk/mistral/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@4.0.21", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-MtFUYI1/8mgDvRmaBDjbLJPFFrMG777AvSgyIFQtZHIMzm88R/12vYBBpnk7pfiWLFE1DSZzY4WDYzGbKAcmiw=="], - - "@ai-sdk/openai/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@4.0.21", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-MtFUYI1/8mgDvRmaBDjbLJPFFrMG777AvSgyIFQtZHIMzm88R/12vYBBpnk7pfiWLFE1DSZzY4WDYzGbKAcmiw=="], - - "@ai-sdk/openai-compatible/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@4.0.21", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-MtFUYI1/8mgDvRmaBDjbLJPFFrMG777AvSgyIFQtZHIMzm88R/12vYBBpnk7pfiWLFE1DSZzY4WDYzGbKAcmiw=="], - - "@ai-sdk/perplexity/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@4.0.21", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-MtFUYI1/8mgDvRmaBDjbLJPFFrMG777AvSgyIFQtZHIMzm88R/12vYBBpnk7pfiWLFE1DSZzY4WDYzGbKAcmiw=="], - "@ai-sdk/provider-utils/@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], - "@ai-sdk/togetherai/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@4.0.21", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-MtFUYI1/8mgDvRmaBDjbLJPFFrMG777AvSgyIFQtZHIMzm88R/12vYBBpnk7pfiWLFE1DSZzY4WDYzGbKAcmiw=="], - - "@ai-sdk/vercel/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@4.0.21", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-MtFUYI1/8mgDvRmaBDjbLJPFFrMG777AvSgyIFQtZHIMzm88R/12vYBBpnk7pfiWLFE1DSZzY4WDYzGbKAcmiw=="], - - "@ai-sdk/xai/@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@2.0.41", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.23" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-kNAGINk71AlOXx10Dq/PXw4t/9XjdK8uxfpVElRwtSFMdeSiLVt58p9TPx4/FJD+hxZuVhvxYj9r42osxWq79g=="], - - "@astrojs/check/yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="], - - "@astrojs/cloudflare/vite": ["vite@6.4.2", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-2N/55r4JDJ4gdrCvGgINMy+HH3iRpNIz8K6SFwVsA+JbQScLiC+clmAxBgwiSPgcG9U15QmvqCGWzMbqda5zGQ=="], + "@ai-sdk/togetherai/@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@2.0.37", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.21" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-+POSFVcgiu47BK64dhsI6OpcDC0/VAE2ZSaXdXGNNhpC/ava++uSRJYks0k2bpfY0wwCTgpAWZsXn/dG2Yppiw=="], - "@astrojs/markdown-remark/@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.6.1", "", {}, "sha512-l5Pqf6uZu31aG+3Lv8nl/3s4DbUzdlxTWDof4pEpto6GUJNhhCbelVi9dEyurOVyqaelwmS9oSyOWOENSfgo9A=="], - - "@astrojs/mdx/@astrojs/markdown-remark": ["@astrojs/markdown-remark@6.3.11", "", { "dependencies": { "@astrojs/internal-helpers": "0.7.6", "@astrojs/prism": "3.3.0", "github-slugger": "^2.0.0", "hast-util-from-html": "^2.0.3", "hast-util-to-text": "^4.0.2", "import-meta-resolve": "^4.2.0", "js-yaml": "^4.1.1", "mdast-util-definitions": "^6.0.0", "rehype-raw": "^7.0.0", "rehype-stringify": "^10.0.1", "remark-gfm": "^4.0.1", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.2", "remark-smartypants": "^3.0.2", "shiki": "^3.21.0", "smol-toml": "^1.6.0", "unified": "^11.0.5", "unist-util-remove-position": "^5.0.0", "unist-util-visit": "^5.0.0", "unist-util-visit-parents": "^6.0.2", "vfile": "^6.0.3" } }, "sha512-hcaxX/5aC6lQgHeGh1i+aauvSwIT6cfyFjKWvExYSxUhZZBBdvCliOtu06gbQyhbe0pGJNoNmqNlQZ5zYUuIyQ=="], - - "@astrojs/mdx/source-map": ["source-map@0.7.6", "", {}, "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ=="], - - "@astrojs/sitemap/zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="], - - "@astrojs/solid-js/vite": ["vite@6.4.2", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-2N/55r4JDJ4gdrCvGgINMy+HH3iRpNIz8K6SFwVsA+JbQScLiC+clmAxBgwiSPgcG9U15QmvqCGWzMbqda5zGQ=="], - - "@astrojs/solid-js/vite-plugin-solid": ["vite-plugin-solid@2.11.12", "", { "dependencies": { "@babel/core": "^7.23.3", "@types/babel__core": "^7.20.4", "babel-preset-solid": "^1.8.4", "merge-anything": "^5.1.7", "solid-refresh": "^0.6.3", "vitefu": "^1.0.4" }, "peerDependencies": { "@testing-library/jest-dom": "^5.16.6 || ^5.17.0 || ^6.*", "solid-js": "^1.7.2", "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["@testing-library/jest-dom"] }, "sha512-FgjPcx2OwX9h6f28jli7A4bG7PP3te8uyakE5iqsmpq3Jqi1TWLgSroC9N6cMfGRU2zXsl4Q6ISvTr2VL0QHpA=="], + "@ai-sdk/vercel/@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@2.0.37", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.21" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-+POSFVcgiu47BK64dhsI6OpcDC0/VAE2ZSaXdXGNNhpC/ava++uSRJYks0k2bpfY0wwCTgpAWZsXn/dG2Yppiw=="], "@aws-crypto/crc32/@aws-sdk/types": ["@aws-sdk/types@3.973.7", "", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-reXRwoJ6CfChoqAsBszUYajAF8Z2LRE+CRcKocvFSMpIiLOtYU3aJ9trmn6VVPAzbbY5LXF+FfmUslbXk1SYFg=="], @@ -5246,28 +3096,6 @@ "@aws-sdk/client-sso/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - "@aws-sdk/client-sts/@aws-sdk/core": ["@aws-sdk/core@3.775.0", "", { "dependencies": { "@aws-sdk/types": "3.775.0", "@smithy/core": "^3.2.0", "@smithy/node-config-provider": "^4.0.2", "@smithy/property-provider": "^4.0.2", "@smithy/protocol-http": "^5.1.0", "@smithy/signature-v4": "^5.0.2", "@smithy/smithy-client": "^4.2.0", "@smithy/types": "^4.2.0", "@smithy/util-middleware": "^4.0.2", "fast-xml-parser": "4.4.1", "tslib": "^2.6.2" } }, "sha512-8vpW4WihVfz0DX+7WnnLGm3GuQER++b0IwQG35JlQMlgqnc44M//KbJPsIHA0aJUJVwJAEShgfr5dUbY8WUzaA=="], - - "@aws-sdk/client-sts/@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.782.0", "", { "dependencies": { "@aws-sdk/credential-provider-env": "3.775.0", "@aws-sdk/credential-provider-http": "3.775.0", "@aws-sdk/credential-provider-ini": "3.782.0", "@aws-sdk/credential-provider-process": "3.775.0", "@aws-sdk/credential-provider-sso": "3.782.0", "@aws-sdk/credential-provider-web-identity": "3.782.0", "@aws-sdk/types": "3.775.0", "@smithy/credential-provider-imds": "^4.0.2", "@smithy/property-provider": "^4.0.2", "@smithy/shared-ini-file-loader": "^4.0.2", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-HZiAF+TCEyKjju9dgysjiPIWgt/+VerGaeEp18mvKLNfgKz1d+/82A2USEpNKTze7v3cMFASx3CvL8yYyF7mJw=="], - - "@aws-sdk/client-sts/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.775.0", "", { "dependencies": { "@aws-sdk/types": "3.775.0", "@smithy/protocol-http": "^5.1.0", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-tkSegM0Z6WMXpLB8oPys/d+umYIocvO298mGvcMCncpRl77L9XkvSLJIFzaHes+o7djAgIduYw8wKIMStFss2w=="], - - "@aws-sdk/client-sts/@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.775.0", "", { "dependencies": { "@aws-sdk/types": "3.775.0", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-FaxO1xom4MAoUJsldmR92nT1G6uZxTdNYOFYtdHfd6N2wcNaTuxgjIvqzg5y7QIH9kn58XX/dzf1iTjgqUStZw=="], - - "@aws-sdk/client-sts/@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.775.0", "", { "dependencies": { "@aws-sdk/types": "3.775.0", "@smithy/protocol-http": "^5.1.0", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GLCzC8D0A0YDG5u3F5U03Vb9j5tcOEFhr8oc6PDk0k0vm5VwtZOE6LvK7hcCSoAB4HXyOUM0sQuXrbaAh9OwXA=="], - - "@aws-sdk/client-sts/@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.782.0", "", { "dependencies": { "@aws-sdk/core": "3.775.0", "@aws-sdk/types": "3.775.0", "@aws-sdk/util-endpoints": "3.782.0", "@smithy/core": "^3.2.0", "@smithy/protocol-http": "^5.1.0", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-i32H2R6IItX+bQ2p4+v2gGO2jA80jQoJO2m1xjU9rYWQW3+ErWy4I5YIuQHTBfb6hSdAHbaRfqPDgbv9J2rjEg=="], - - "@aws-sdk/client-sts/@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.775.0", "", { "dependencies": { "@aws-sdk/types": "3.775.0", "@smithy/node-config-provider": "^4.0.2", "@smithy/types": "^4.2.0", "@smithy/util-config-provider": "^4.0.0", "@smithy/util-middleware": "^4.0.2", "tslib": "^2.6.2" } }, "sha512-40iH3LJjrQS3LKUJAl7Wj0bln7RFPEvUYKFxtP8a+oKFDO0F65F52xZxIJbPn6sHkxWDAnZlGgdjZXM3p2g5wQ=="], - - "@aws-sdk/client-sts/@aws-sdk/types": ["@aws-sdk/types@3.775.0", "", { "dependencies": { "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-ZoGKwa4C9fC9Av6bdfqcW6Ix5ot05F/S4VxWR2nHuMv7hzfmAjTOcUiWT7UR4hM/U0whf84VhDtXN/DWAk52KA=="], - - "@aws-sdk/client-sts/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.782.0", "", { "dependencies": { "@aws-sdk/types": "3.775.0", "@smithy/types": "^4.2.0", "@smithy/util-endpoints": "^3.0.2", "tslib": "^2.6.2" } }, "sha512-/RJOAO7o7HI6lEa4ASbFFLHGU9iPK876BhsVfnl54MvApPVYWQ9sHO0anOUim2S5lQTwd/6ghuH3rFYSq/+rdw=="], - - "@aws-sdk/client-sts/@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.775.0", "", { "dependencies": { "@aws-sdk/types": "3.775.0", "@smithy/types": "^4.2.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-txw2wkiJmZKVdDbscK7VBK+u+TJnRtlUjRTLei+elZg2ADhpQxfVAQl436FUeIv6AhB/oRHW6/K/EAGXUSWi0A=="], - - "@aws-sdk/client-sts/@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.782.0", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "3.782.0", "@aws-sdk/types": "3.775.0", "@smithy/node-config-provider": "^4.0.2", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-dMFkUBgh2Bxuw8fYZQoH/u3H4afQ12VSkzEi//qFiDTwbKYq+u+RYjc8GLDM6JSK1BShMu5AVR7HD4ap1TYUnA=="], - "@aws-sdk/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.996.19", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.27", "@aws-sdk/middleware-host-header": "^3.972.9", "@aws-sdk/middleware-logger": "^3.972.9", "@aws-sdk/middleware-recursion-detection": "^3.972.10", "@aws-sdk/middleware-user-agent": "^3.972.29", "@aws-sdk/region-config-resolver": "^3.972.11", "@aws-sdk/types": "^3.973.7", "@aws-sdk/util-endpoints": "^3.996.6", "@aws-sdk/util-user-agent-browser": "^3.972.9", "@aws-sdk/util-user-agent-node": "^3.973.15", "@smithy/config-resolver": "^4.4.14", "@smithy/core": "^3.23.14", "@smithy/fetch-http-handler": "^5.3.16", "@smithy/hash-node": "^4.2.13", "@smithy/invalid-dependency": "^4.2.13", "@smithy/middleware-content-length": "^4.2.13", "@smithy/middleware-endpoint": "^4.4.29", "@smithy/middleware-retry": "^4.5.0", "@smithy/middleware-serde": "^4.2.17", "@smithy/middleware-stack": "^4.2.13", "@smithy/node-config-provider": "^4.3.13", "@smithy/node-http-handler": "^4.5.2", "@smithy/protocol-http": "^5.3.13", "@smithy/smithy-client": "^4.12.9", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.45", "@smithy/util-defaults-mode-node": "^4.2.49", "@smithy/util-endpoints": "^3.3.4", "@smithy/util-middleware": "^4.2.13", "@smithy/util-retry": "^4.3.0", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-uFkmCDXvmQYLanlYdOFS0+MQWkrj9wPMt/ZCc/0J0fjPim6F5jBVBmEomvGY/j77ILW6GTPwN22Jc174Mhkw6Q=="], @@ -5360,93 +3188,41 @@ "@aws-sdk/token-providers/@aws-sdk/types": ["@aws-sdk/types@3.973.7", "", { "dependencies": { "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-reXRwoJ6CfChoqAsBszUYajAF8Z2LRE+CRcKocvFSMpIiLOtYU3aJ9trmn6VVPAzbbY5LXF+FfmUslbXk1SYFg=="], - "@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="], - - "@azure/core-http/@azure/abort-controller": ["@azure/abort-controller@1.1.0", "", { "dependencies": { "tslib": "^2.2.0" } }, "sha512-TrRLIoSQVzfAJX9H1JeFjzAoDGcoK1IYX1UImfceTZpsyYfWr09Ss1aHW1y5TrrR3iq6RZLBwJ3E24uwPhwahw=="], - - "@azure/core-http/@azure/core-tracing": ["@azure/core-tracing@1.0.0-preview.13", "", { "dependencies": { "@opentelemetry/api": "^1.0.1", "tslib": "^2.2.0" } }, "sha512-KxDlhXyMlh2Jhj2ykX6vNEU0Vou4nHr025KoSEiz7cS3BNiHNaZcdECk/DmLkEB0as5T7b/TpRcehJ5yV6NeXQ=="], - - "@azure/core-http/uuid": ["uuid@8.3.2", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="], - - "@azure/core-http/xml2js": ["xml2js@0.5.0", "", { "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" } }, "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA=="], - - "@azure/core-xml/fast-xml-parser": ["fast-xml-parser@5.5.12", "", { "dependencies": { "fast-xml-builder": "^1.1.4", "path-expression-matcher": "^1.5.0", "strnum": "^2.2.3" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-nUR0q8PPfoA/svPM43Gup7vLOZWppaNrYgGmrVqrAVJa7cOH4hMG6FX9M4mQ8dZA1/ObGZHzES7Ed88hxEBSJg=="], - "@azure/identity/open": ["open@10.2.0", "", { "dependencies": { "default-browser": "^5.2.1", "define-lazy-prop": "^3.0.0", "is-inside-container": "^1.0.0", "wsl-utils": "^0.1.0" } }, "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA=="], - "@azure/msal-node/uuid": ["uuid@8.3.2", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="], - "@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + "@babel/generator/@babel/types": ["@babel/types@7.29.7", "", { "dependencies": { "@babel/helper-string-parser": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7" } }, "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA=="], + "@babel/helper-compilation-targets/lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="], "@babel/helper-compilation-targets/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], "@babel/helper-create-class-features-plugin/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], - "@bufbuild/protoplugin/typescript": ["typescript@5.4.5", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ=="], + "@babel/parser/@babel/types": ["@babel/types@7.29.7", "", { "dependencies": { "@babel/helper-string-parser": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7" } }, "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA=="], - "@cloudflare/kv-asset-handler/mime": ["mime@3.0.0", "", { "bin": { "mime": "cli.js" } }, "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A=="], + "@babel/template/@babel/parser": ["@babel/parser@7.29.2", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": "./bin/babel-parser.js" }, "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA=="], - "@cspotcode/source-map-support/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.9", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" } }, "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ=="], + "@babel/traverse/@babel/generator": ["@babel/generator@7.29.1", "", { "dependencies": { "@babel/parser": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw=="], - "@develar/schema-utils/ajv": ["ajv@6.14.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw=="], + "@babel/traverse/@babel/parser": ["@babel/parser@7.29.2", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": "./bin/babel-parser.js" }, "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA=="], - "@dot/log/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], + "@bufbuild/protoplugin/typescript": ["typescript@5.4.5", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ=="], - "@effect/platform-node/undici": ["undici@8.1.0", "", {}, "sha512-E9MkTS4xXLnRPYqxH2e6Hr2/49e7WFDKczKcCaFH4VaZs2iNvHMqeIkyUAD9vM8kujy9TjVrRlQ5KkdEJxB2pw=="], + "@fastify/proxy-addr/ipaddr.js": ["ipaddr.js@2.3.0", "", {}, "sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg=="], - "@effect/platform-node-shared/ws": ["ws@8.20.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA=="], + "@gitlab/opencode-gitlab-auth/open": ["open@10.2.0", "", { "dependencies": { "default-browser": "^5.2.1", "define-lazy-prop": "^3.0.0", "is-inside-container": "^1.0.0", "wsl-utils": "^0.1.0" } }, "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA=="], - "@electron/asar/commander": ["commander@5.1.0", "", {}, "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg=="], + "@hey-api/shared/open": ["open@11.0.0", "", { "dependencies": { "default-browser": "^5.4.0", "define-lazy-prop": "^3.0.0", "is-in-ssh": "^1.0.0", "is-inside-container": "^1.0.0", "powershell-utils": "^0.1.0", "wsl-utils": "^0.3.0" } }, "sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw=="], - "@electron/asar/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="], + "@hono/zod-validator/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - "@electron/asar/minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="], + "@jimp/core/mime": ["mime@3.0.0", "", { "bin": { "mime": "cli.js" } }, "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A=="], - "@electron/fuses/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], + "@jimp/plugin-blit/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - "@electron/fuses/fs-extra": ["fs-extra@9.1.0", "", { "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ=="], - - "@electron/get/fs-extra": ["fs-extra@8.1.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g=="], - - "@electron/get/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], - - "@electron/notarize/fs-extra": ["fs-extra@9.1.0", "", { "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ=="], - - "@electron/osx-sign/isbinaryfile": ["isbinaryfile@4.0.10", "", {}, "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw=="], - - "@electron/rebuild/detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], - - "@electron/rebuild/node-gyp": ["node-gyp@11.5.0", "", { "dependencies": { "env-paths": "^2.2.0", "exponential-backoff": "^3.1.1", "graceful-fs": "^4.2.6", "make-fetch-happen": "^14.0.3", "nopt": "^8.0.0", "proc-log": "^5.0.0", "semver": "^7.3.5", "tar": "^7.4.3", "tinyglobby": "^0.2.12", "which": "^5.0.0" }, "bin": { "node-gyp": "bin/node-gyp.js" } }, "sha512-ra7Kvlhxn5V9Slyus0ygMa2h+UqExPqUIkfk7Pc8QTLT956JLSy51uWFwHtIYy0vI8cB4BDhc/S03+880My/LQ=="], - - "@electron/rebuild/yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="], - - "@electron/universal/fs-extra": ["fs-extra@11.3.4", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA=="], - - "@electron/universal/minimatch": ["minimatch@9.0.9", "", { "dependencies": { "brace-expansion": "^2.0.2" } }, "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg=="], - - "@electron/windows-sign/fs-extra": ["fs-extra@11.3.4", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA=="], - - "@expressive-code/plugin-shiki/shiki": ["shiki@3.23.0", "", { "dependencies": { "@shikijs/core": "3.23.0", "@shikijs/engine-javascript": "3.23.0", "@shikijs/engine-oniguruma": "3.23.0", "@shikijs/langs": "3.23.0", "@shikijs/themes": "3.23.0", "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-55Dj73uq9ZXL5zyeRPzHQsK7Nbyt6Y10k5s7OjuFZGMhpp4r/rsLBH0o/0fstIzX1Lep9VxefWljK/SKCzygIA=="], - - "@fastify/proxy-addr/ipaddr.js": ["ipaddr.js@2.3.0", "", {}, "sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg=="], - - "@gitlab/opencode-gitlab-auth/open": ["open@10.2.0", "", { "dependencies": { "default-browser": "^5.2.1", "define-lazy-prop": "^3.0.0", "is-inside-container": "^1.0.0", "wsl-utils": "^0.1.0" } }, "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA=="], - - "@happy-dom/global-registrator/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], - - "@hey-api/openapi-ts/open": ["open@11.0.0", "", { "dependencies": { "default-browser": "^5.4.0", "define-lazy-prop": "^3.0.0", "is-in-ssh": "^1.0.0", "is-inside-container": "^1.0.0", "powershell-utils": "^0.1.0", "wsl-utils": "^0.3.0" } }, "sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw=="], - - "@hey-api/openapi-ts/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], - - "@hono/zod-validator/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - - "@jimp/core/mime": ["mime@3.0.0", "", { "bin": { "mime": "cli.js" } }, "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A=="], - - "@jimp/plugin-blit/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - - "@jimp/plugin-circle/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], + "@jimp/plugin-circle/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], "@jimp/plugin-color/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], @@ -5476,31 +3252,17 @@ "@jimp/types/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - "@jsx-email/cli/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], - - "@jsx-email/cli/esbuild": ["esbuild@0.19.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.19.12", "@esbuild/android-arm": "0.19.12", "@esbuild/android-arm64": "0.19.12", "@esbuild/android-x64": "0.19.12", "@esbuild/darwin-arm64": "0.19.12", "@esbuild/darwin-x64": "0.19.12", "@esbuild/freebsd-arm64": "0.19.12", "@esbuild/freebsd-x64": "0.19.12", "@esbuild/linux-arm": "0.19.12", "@esbuild/linux-arm64": "0.19.12", "@esbuild/linux-ia32": "0.19.12", "@esbuild/linux-loong64": "0.19.12", "@esbuild/linux-mips64el": "0.19.12", "@esbuild/linux-ppc64": "0.19.12", "@esbuild/linux-riscv64": "0.19.12", "@esbuild/linux-s390x": "0.19.12", "@esbuild/linux-x64": "0.19.12", "@esbuild/netbsd-x64": "0.19.12", "@esbuild/openbsd-x64": "0.19.12", "@esbuild/sunos-x64": "0.19.12", "@esbuild/win32-arm64": "0.19.12", "@esbuild/win32-ia32": "0.19.12", "@esbuild/win32-x64": "0.19.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg=="], - - "@jsx-email/cli/tailwindcss": ["tailwindcss@3.3.3", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", "chokidar": "^3.5.3", "didyoumean": "^1.2.2", "dlv": "^1.1.3", "fast-glob": "^3.2.12", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", "jiti": "^1.18.2", "lilconfig": "^2.1.0", "micromatch": "^4.0.5", "normalize-path": "^3.0.0", "object-hash": "^3.0.0", "picocolors": "^1.0.0", "postcss": "^8.4.23", "postcss-import": "^15.1.0", "postcss-js": "^4.0.1", "postcss-load-config": "^4.0.1", "postcss-nested": "^6.0.1", "postcss-selector-parser": "^6.0.11", "resolve": "^1.22.2", "sucrase": "^3.32.0" }, "bin": { "tailwind": "lib/cli.js", "tailwindcss": "lib/cli.js" } }, "sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w=="], - - "@jsx-email/cli/vite": ["vite@4.5.14", "", { "dependencies": { "esbuild": "^0.18.10", "postcss": "^8.4.27", "rollup": "^3.27.1" }, "optionalDependencies": { "fsevents": "~2.3.2" }, "peerDependencies": { "@types/node": ">= 14", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" }, "optionalPeers": ["@types/node", "less", "lightningcss", "sass", "stylus", "sugarss", "terser"], "bin": { "vite": "bin/vite.js" } }, "sha512-+v57oAaoYNnO3hIu5Z/tJRZjq5aHM2zDve9YZ8HngVHbhk66RStobhb1sqPMIPEleV6cNKYK4eGrAbE9Ulbl2g=="], - - "@jsx-email/doiuse-email/htmlparser2": ["htmlparser2@9.1.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.1.0", "entities": "^4.5.0" } }, "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ=="], - - "@malept/flatpak-bundler/fs-extra": ["fs-extra@9.1.0", "", { "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ=="], - - "@mdx-js/mdx/source-map": ["source-map@0.7.6", "", {}, "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ=="], + "@kobalte/core/@solid-primitives/resize-observer": ["@solid-primitives/resize-observer@2.1.5", "", { "dependencies": { "@solid-primitives/event-listener": "^2.4.5", "@solid-primitives/rootless": "^1.5.3", "@solid-primitives/static-store": "^0.1.3", "@solid-primitives/utils": "^6.4.0" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-AiyTknKcNBaKHbcSMuxtSNM8FjIuiSuFyFghdD0TcCMU9hKi9EmsC5pjfjDwxE+5EueB1a+T/34PLRI5vbBbKw=="], - "@modelcontextprotocol/sdk/express": ["express@5.2.1", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "depd": "^2.0.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" } }, "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw=="], - - "@modelcontextprotocol/sdk/hono": ["hono@4.12.12", "", {}, "sha512-p1JfQMKaceuCbpJKAPKVqyqviZdS0eUxH9v82oWo1kb9xjQ5wA6iP3FNVAPDFlz5/p7d45lO+BpSk1tuSZMF4Q=="], + "@modelcontextprotocol/sdk/eventsource-parser": ["eventsource-parser@3.0.6", "", {}, "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg=="], "@modelcontextprotocol/sdk/jose": ["jose@6.2.2", "", {}, "sha512-d7kPDd34KO/YnzaDOlikGpOurfF0ByC2sEV4cANCtdqLlTfBlw2p14O/5d/zv40gJPbIQxfES3nSx1/oYNyuZQ=="], - "@modelcontextprotocol/sdk/raw-body": ["raw-body@3.0.2", "", { "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", "iconv-lite": "~0.7.0", "unpipe": "~1.0.0" } }, "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA=="], - "@modelcontextprotocol/sdk/zod-to-json-schema": ["zod-to-json-schema@3.25.2", "", { "peerDependencies": { "zod": "^3.25.28 || ^4" } }, "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA=="], - "@npmcli/query/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="], + "@npmcli/agent/agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], + + "@npmcli/agent/https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], "@octokit/auth-app/@octokit/request": ["@octokit/request@10.0.8", "", { "dependencies": { "@octokit/endpoint": "^11.0.3", "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0", "fast-content-type-parse": "^3.0.0", "json-with-bigint": "^3.5.3", "universal-user-agent": "^7.0.2" } }, "sha512-SJZNwY9pur9Agf7l87ywFi14W+Hd9Jg6Ifivsd33+/bGUQIjNujdFiXII2/qSlN2ybqUHfp5xpekMEjIBTjlSw=="], @@ -5560,46 +3322,16 @@ "@openauthjs/openauth/@standard-schema/spec": ["@standard-schema/spec@1.0.0-beta.3", "", {}, "sha512-0ifF3BjA1E8SY9C+nUew8RefNOIq0cDlYALPty4rhUm8Rrl6tCM8hBT4bhGhx7I7iXD0uAgt50lgo8dD73ACMw=="], - "@openauthjs/openauth/jose": ["jose@5.9.6", "", {}, "sha512-AMlnetc9+CV9asI19zHmrgS/WYsWUwCn2R7RzlbJWD7F9eWYUTGyBmU9o6PxngtLGOiDGPRu+Uc4fhKzbpteZQ=="], - - "@mendcode/desktop/@actions/artifact": ["@actions/artifact@4.0.0", "", { "dependencies": { "@actions/core": "^1.10.0", "@actions/github": "^6.0.1", "@actions/http-client": "^2.1.0", "@azure/core-http": "^3.0.5", "@azure/storage-blob": "^12.15.0", "@octokit/core": "^5.2.1", "@octokit/plugin-request-log": "^1.0.4", "@octokit/plugin-retry": "^3.0.9", "@octokit/request": "^8.4.1", "@octokit/request-error": "^5.1.1", "@protobuf-ts/plugin": "^2.2.3-alpha.1", "archiver": "^7.0.1", "jwt-decode": "^3.1.2", "unzip-stream": "^0.3.1" } }, "sha512-HCc2jMJRAfviGFAh0FsOR/jNfWhirxl7W6z8zDtttt0GltwxBLdEIjLiweOPFl9WbyJRW1VWnPUSAixJqcWUMQ=="], - - "@mendcode/desktop/marked": ["marked@15.0.12", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA=="], - - "@mendcode/desktop/typescript": ["typescript@5.6.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw=="], - - "@mendcode/ui/@solid-primitives/resize-observer": ["@solid-primitives/resize-observer@2.1.3", "", { "dependencies": { "@solid-primitives/event-listener": "^2.4.3", "@solid-primitives/rootless": "^1.5.2", "@solid-primitives/static-store": "^0.1.2", "@solid-primitives/utils": "^6.3.2" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-zBLje5E06TgOg93S7rGPldmhDnouNGhvfZVKOp+oG2XU8snA+GoCSSCz1M+jpNAg5Ek2EakU5UVQqL152WmdXQ=="], + "@openauthjs/openauth/aws4fetch": ["aws4fetch@1.0.20", "", {}, "sha512-/djoAN709iY65ETD6LKCtyyEI04XIBP5xVvfmNxsEP0uJB5tyaGBztSryRr4HqMStr9R06PisQE7m9zDTXKu6g=="], - "@mendcode/web/@shikijs/transformers": ["@shikijs/transformers@3.20.0", "", { "dependencies": { "@shikijs/core": "3.20.0", "@shikijs/types": "3.20.0" } }, "sha512-PrHHMRr3Q5W1qB/42kJW6laqFyWdhrPF2hNR9qjOm1xcSiAO3hAHo7HaVyHE6pMyevmy3i51O8kuGGXC78uK3g=="], - - "@opentui/core/diff": ["diff@9.0.0", "", {}, "sha512-svtcdpS8CgJyqAjEQIXdb3OjhFVVYjzGAPO8WGCmRbrml64SPw/jJD4GoE98aR7r25A0XcgrK3F02yw9R/vhQw=="], - - "@opentui/solid/@babel/core": ["@babel/core@7.28.0", "", { "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.0", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.27.3", "@babel/helpers": "^7.27.6", "@babel/parser": "^7.28.0", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.0", "@babel/types": "^7.28.0", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ=="], + "@openauthjs/openauth/jose": ["jose@5.9.6", "", {}, "sha512-AMlnetc9+CV9asI19zHmrgS/WYsWUwCn2R7RzlbJWD7F9eWYUTGyBmU9o6PxngtLGOiDGPRu+Uc4fhKzbpteZQ=="], "@oslojs/jwt/@oslojs/encoding": ["@oslojs/encoding@0.4.1", "", {}, "sha512-hkjo6MuIK/kQR5CrGNdAPZhS01ZCXuWDRJ187zh6qqF2+yMHZpD9fAYpX8q2bOO6Ryhl3XpCT6kUX76N8hhm4Q=="], "@pierre/diffs/@shikijs/transformers": ["@shikijs/transformers@3.20.0", "", { "dependencies": { "@shikijs/core": "3.20.0", "@shikijs/types": "3.20.0" } }, "sha512-PrHHMRr3Q5W1qB/42kJW6laqFyWdhrPF2hNR9qjOm1xcSiAO3hAHo7HaVyHE6pMyevmy3i51O8kuGGXC78uK3g=="], - "@pierre/diffs/diff": ["diff@8.0.3", "", {}, "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ=="], - - "@poppinss/dumper/@sindresorhus/is": ["@sindresorhus/is@7.2.0", "", {}, "sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw=="], - - "@poppinss/dumper/supports-color": ["supports-color@10.2.2", "", {}, "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g=="], - "@protobuf-ts/plugin/typescript": ["typescript@3.9.10", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q=="], - "@rollup/pluginutils/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], - - "@sentry/bundler-plugin-core/glob": ["glob@9.3.5", "", { "dependencies": { "fs.realpath": "^1.0.0", "minimatch": "^8.0.2", "minipass": "^4.2.4", "path-scurry": "^1.6.1" } }, "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q=="], - - "@sentry/bundler-plugin-core/magic-string": ["magic-string@0.30.8", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" } }, "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ=="], - - "@sentry/cli/https-proxy-agent": ["https-proxy-agent@5.0.1", "", { "dependencies": { "agent-base": "6", "debug": "4" } }, "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA=="], - - "@sentry/cli/proxy-from-env": ["proxy-from-env@1.1.0", "", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="], - - "@sentry/cli/which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], - "@shikijs/engine-javascript/@shikijs/types": ["@shikijs/types@3.20.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-lhYAATn10nkZcBQ0BlzSbJA3wcmL5MXUUF8d2Zzon6saZDlToKaiRX60n2+ZaHJCmXEcZRWNzn+k9vplr8Jhsw=="], "@shikijs/engine-oniguruma/@shikijs/types": ["@shikijs/types@3.20.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-lhYAATn10nkZcBQ0BlzSbJA3wcmL5MXUUF8d2Zzon6saZDlToKaiRX60n2+ZaHJCmXEcZRWNzn+k9vplr8Jhsw=="], @@ -5608,36 +3340,8 @@ "@shikijs/themes/@shikijs/types": ["@shikijs/types@3.20.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-lhYAATn10nkZcBQ0BlzSbJA3wcmL5MXUUF8d2Zzon6saZDlToKaiRX60n2+ZaHJCmXEcZRWNzn+k9vplr8Jhsw=="], - "@slack/bolt/path-to-regexp": ["path-to-regexp@8.4.2", "", {}, "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA=="], - - "@slack/logger/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], - - "@slack/oauth/@slack/logger": ["@slack/logger@3.0.0", "", { "dependencies": { "@types/node": ">=12.0.0" } }, "sha512-DTuBFbqu4gGfajREEMrkq5jBhcnskinhr4+AnfJEk48zhVeEv3XnUKGIX98B74kxhYsIMfApGGySTn7V3b5yBA=="], - - "@slack/oauth/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], - - "@slack/socket-mode/@slack/logger": ["@slack/logger@3.0.0", "", { "dependencies": { "@types/node": ">=12.0.0" } }, "sha512-DTuBFbqu4gGfajREEMrkq5jBhcnskinhr4+AnfJEk48zhVeEv3XnUKGIX98B74kxhYsIMfApGGySTn7V3b5yBA=="], - - "@slack/socket-mode/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], - - "@slack/socket-mode/@types/ws": ["@types/ws@7.4.7", "", { "dependencies": { "@types/node": "*" } }, "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww=="], - - "@slack/socket-mode/ws": ["ws@7.5.10", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ=="], - - "@slack/web-api/@slack/logger": ["@slack/logger@3.0.0", "", { "dependencies": { "@types/node": ">=12.0.0" } }, "sha512-DTuBFbqu4gGfajREEMrkq5jBhcnskinhr4+AnfJEk48zhVeEv3XnUKGIX98B74kxhYsIMfApGGySTn7V3b5yBA=="], - - "@slack/web-api/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], - - "@slack/web-api/eventemitter3": ["eventemitter3@3.1.2", "", {}, "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q=="], - - "@slack/web-api/form-data": ["form-data@2.5.5", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.35", "safe-buffer": "^5.2.1" } }, "sha512-jqdObeR2rxZZbPSGL+3VckHMYtu+f9//KXBsVny6JSX/pa38Fy+bGjuG8eW/H6USNQWhLi8Num++cU2yOCNz4A=="], - - "@slack/web-api/p-queue": ["p-queue@6.6.2", "", { "dependencies": { "eventemitter3": "^4.0.4", "p-timeout": "^3.2.0" } }, "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ=="], - "@smithy/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - "@smithy/eventstream-serde-universal/@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.13", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.14.0", "@smithy/util-hex-encoding": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-vYahwBAtRaAcFbOmE9aLr12z7RiHYDSLcnogSdxfm7kKfsNa3wH+NU5r7vTeB5rKvLsWyPjVX8iH94brP7umiQ=="], - "@smithy/hash-node/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], "@smithy/hash-stream-node/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], @@ -5650,20 +3354,12 @@ "@smithy/util-stream/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - "@solidjs/start/path-to-regexp": ["path-to-regexp@8.4.2", "", {}, "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA=="], - - "@solidjs/start/shiki": ["shiki@1.29.2", "", { "dependencies": { "@shikijs/core": "1.29.2", "@shikijs/engine-javascript": "1.29.2", "@shikijs/engine-oniguruma": "1.29.2", "@shikijs/langs": "1.29.2", "@shikijs/themes": "1.29.2", "@shikijs/types": "1.29.2", "@shikijs/vscode-textmate": "^10.0.1", "@types/hast": "^3.0.4" } }, "sha512-njXuliz/cP+67jU2hukkxCNuH1yUi4QfdZZY+sMr5PPrIyXSu5iTb/qYC4BiWWB0vZ+7TbdvYUCeL23zpwCfbg=="], - - "@solidjs/start/vite": ["vite@7.1.10", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-CmuvUBzVJ/e3HGxhg6cYk88NGgTnBoOo7ogtfJJ0fefUWAxN/WDSUa50o+oVBxuIhO8FoEZW0j2eW7sfjs5EtA=="], - - "@solidjs/start/vite-plugin-solid": ["vite-plugin-solid@2.11.12", "", { "dependencies": { "@babel/core": "^7.23.3", "@types/babel__core": "^7.20.4", "babel-preset-solid": "^1.8.4", "merge-anything": "^5.1.7", "solid-refresh": "^0.6.3", "vitefu": "^1.0.4" }, "peerDependencies": { "@testing-library/jest-dom": "^5.16.6 || ^5.17.0 || ^6.*", "solid-js": "^1.7.2", "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["@testing-library/jest-dom"] }, "sha512-FgjPcx2OwX9h6f28jli7A4bG7PP3te8uyakE5iqsmpq3Jqi1TWLgSroC9N6cMfGRU2zXsl4Q6ISvTr2VL0QHpA=="], + "@solid-primitives/bounds/@solid-primitives/resize-observer": ["@solid-primitives/resize-observer@2.1.5", "", { "dependencies": { "@solid-primitives/event-listener": "^2.4.5", "@solid-primitives/rootless": "^1.5.3", "@solid-primitives/static-store": "^0.1.3", "@solid-primitives/utils": "^6.4.0" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-AiyTknKcNBaKHbcSMuxtSNM8FjIuiSuFyFghdD0TcCMU9hKi9EmsC5pjfjDwxE+5EueB1a+T/34PLRI5vbBbKw=="], "@standard-community/standard-json/effect": ["effect@4.0.0-beta.48", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "fast-check": "^4.6.0", "find-my-way-ts": "^0.1.6", "ini": "^6.0.0", "kubernetes-types": "^1.30.0", "msgpackr": "^1.11.9", "multipasta": "^0.2.7", "toml": "^4.1.1", "uuid": "^13.0.0", "yaml": "^2.8.3" } }, "sha512-MMAM/ZabuNdNmgXiin+BAanQXK7qM8mlt7nfXDoJ/Gn9V8i89JlCq+2N0AiWmqFLXjGLA0u3FjiOjSOYQk5uMw=="], "@standard-community/standard-openapi/effect": ["effect@4.0.0-beta.48", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "fast-check": "^4.6.0", "find-my-way-ts": "^0.1.6", "ini": "^6.0.0", "kubernetes-types": "^1.30.0", "msgpackr": "^1.11.9", "multipasta": "^0.2.7", "toml": "^4.1.1", "uuid": "^13.0.0", "yaml": "^2.8.3" } }, "sha512-MMAM/ZabuNdNmgXiin+BAanQXK7qM8mlt7nfXDoJ/Gn9V8i89JlCq+2N0AiWmqFLXjGLA0u3FjiOjSOYQk5uMw=="], - "@storybook/csf-plugin/unplugin": ["unplugin@2.3.11", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "acorn": "^8.15.0", "picomatch": "^4.0.3", "webpack-virtual-modules": "^0.6.2" } }, "sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww=="], - "@tailwindcss/oxide/detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.9.2", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" }, "bundled": true }, "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA=="], @@ -5678,881 +3374,353 @@ "@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "@tanstack/directive-functions-plugin/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="], + "@types/babel__core/@babel/parser": ["@babel/parser@7.29.2", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": "./bin/babel-parser.js" }, "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA=="], - "@tanstack/router-utils/diff": ["diff@8.0.3", "", {}, "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ=="], + "@types/babel__template/@babel/parser": ["@babel/parser@7.29.2", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": "./bin/babel-parser.js" }, "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA=="], - "@tanstack/server-functions-plugin/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="], + "@typespec/ts-http-runtime/https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], - "@testing-library/dom/aria-query": ["aria-query@5.3.0", "", { "dependencies": { "dequal": "^2.0.3" } }, "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A=="], + "ai-gateway-provider/@ai-sdk/amazon-bedrock": ["@ai-sdk/amazon-bedrock@4.0.93", "", { "dependencies": { "@ai-sdk/anthropic": "3.0.69", "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.23", "@smithy/eventstream-codec": "^4.0.1", "@smithy/util-utf8": "^4.0.0", "aws4fetch": "^1.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-hcXDU8QDwpAzLVTuY932TQVlIij9+iaVTxc5mPGY6yb//JMAAC5hMVhg93IrxlrxWLvMgjezNgoZGwquR+SGnw=="], - "@testing-library/dom/dom-accessibility-api": ["dom-accessibility-api@0.5.16", "", {}, "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg=="], + "ai-gateway-provider/@ai-sdk/anthropic": ["@ai-sdk/anthropic@3.0.69", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.23" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-LshR7X3pFugY0o41G2VKTmg1XoGpSl7uoYWfzk6zjVZLhCfeFiwgpOga+eTV4XY1VVpZwKVqRnkDbIL7K2eH5g=="], - "@types/body-parser/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], + "ai-gateway-provider/@ai-sdk/google": ["@ai-sdk/google@3.0.53", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.21" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-uz8tIlkDgQJG9Js2Wh9JHzd4kI9+hYJqf9XXJLx60vyN5mRIqhr49iwR5zGP5Gl8odp2PeR3Gh2k+5bh3Z1HHw=="], - "@types/cacache/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], + "ai-gateway-provider/@ai-sdk/google-vertex": ["@ai-sdk/google-vertex@4.0.95", "", { "dependencies": { "@ai-sdk/anthropic": "3.0.64", "@ai-sdk/google": "3.0.53", "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.21", "google-auth-library": "^10.5.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-xL44fHlTtDM7RLkMTgyqMfkfthA38JS91bbMaHItObIhte1PAIY936ZV1PLl/Z9A/oBAXjHWbXo5xDoHzB7LEg=="], - "@types/cacheable-request/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], + "ai-gateway-provider/@ai-sdk/openai": ["@ai-sdk/openai@3.0.48", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.21" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-ALmj/53EXpcRqMbGpPJPP4UOSWw0q4VGpnDo7YctvsynjkrKDmoneDG/1a7VQnSPYHnJp6tTRMf5ZdxZ5whulg=="], - "@types/connect/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], + "ai-gateway-provider/@ai-sdk/xai": ["@ai-sdk/xai@3.0.75", "", { "dependencies": { "@ai-sdk/openai-compatible": "2.0.37", "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.21" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-V8UKK4fNpI9cnrtsZBvUp9O9J6Y9fTKBRoSLyEaNGPirACewixmLDbXsSgAeownPVWiWpK34bFysd+XouI5Ywg=="], - "@types/cross-spawn/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], + "ai-gateway-provider/@openrouter/ai-sdk-provider": ["@openrouter/ai-sdk-provider@2.5.1", "", { "peerDependencies": { "ai": "^6.0.0", "zod": "^3.25.0 || ^4.0.0" } }, "sha512-r1fJL1Cb3gQDa2MpWH/sfx1BsEW0uzlRriJM6eihaKqbtKDmZoBisF32VcVaQYassighX7NGCkF68EsrZA43uQ=="], - "@types/express-serve-static-core/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], + "archiver-utils/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="], - "@types/fontkit/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], + "aws-sdk/events": ["events@1.1.1", "", {}, "sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw=="], - "@types/fs-extra/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], + "babel-plugin-jsx-dom-expressions/@babel/helper-module-imports": ["@babel/helper-module-imports@7.18.6", "", { "dependencies": { "@babel/types": "^7.18.6" } }, "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA=="], - "@types/is-stream/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], + "babel-plugin-module-resolver/glob": ["glob@9.3.5", "", { "dependencies": { "fs.realpath": "^1.0.0", "minimatch": "^8.0.2", "minipass": "^4.2.4", "path-scurry": "^1.6.1" } }, "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q=="], - "@types/jsonwebtoken/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], + "bl/buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="], - "@types/keyv/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], + "body-parser/content-type": ["content-type@2.0.0", "", {}, "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ=="], - "@types/mssql/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], + "body-parser/type-is": ["type-is@2.1.0", "", { "dependencies": { "content-type": "^2.0.0", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA=="], - "@types/node-fetch/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], + "buffer/ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="], - "@types/npm-registry-fetch/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], + "c12/chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "^5.0.0" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="], - "@types/npmcli__arborist/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], + "cross-fetch/node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], - "@types/npmlog/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], + "cross-spawn/which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], - "@types/pacote/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], + "dom-serializer/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], - "@types/plist/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], + "effect/@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], - "@types/plist/xmlbuilder": ["xmlbuilder@15.1.1", "", {}, "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg=="], + "encoding/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], - "@types/readable-stream/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], + "es-set-tostringtag/hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="], - "@types/responselike/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], + "eventsource/eventsource-parser": ["eventsource-parser@3.0.6", "", {}, "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg=="], - "@types/sax/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], + "execa/is-stream": ["is-stream@3.0.0", "", {}, "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA=="], - "@types/send/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], + "form-data/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], - "@types/serve-static/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], + "framer-motion/motion-dom": ["motion-dom@12.38.0", "", { "dependencies": { "motion-utils": "^12.36.0" } }, "sha512-pdkHLD8QYRp8VfiNLb8xIBJis1byQ9gPT3Jnh2jqfFtAsWUA3dEepDlsWe/xMpO8McV+VdpKVcp+E+TGJEtOoA=="], - "@types/ssri/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], + "framer-motion/motion-utils": ["motion-utils@12.36.0", "", {}, "sha512-eHWisygbiwVvf6PZ1vhaHCLamvkSbPIeAYxWUuL3a2PD/TROgE7FvfHWTIH4vMl798QLfMw15nRqIaRDXTlYRg=="], - "@types/tunnel/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], + "gaxios/https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], - "@types/ws/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], + "get-intrinsic/hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="], - "@types/yauzl/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], + "gitlab-ai-provider/@anthropic-ai/sdk": ["@anthropic-ai/sdk@0.71.2", "", { "dependencies": { "json-schema-to-ts": "^3.1.1" }, "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" }, "optionalPeers": ["zod"], "bin": { "anthropic-ai-sdk": "bin/cli" } }, "sha512-TGNDEUuEstk/DKu0/TflXAEt+p+p/WhTlFzEnoosvbaDU2LTjm42igSdlL0VijrKpWejtOKxX0b8A7uc+XiSAQ=="], - "@vitest/expect/@vitest/utils": ["@vitest/utils@3.2.4", "", { "dependencies": { "@vitest/pretty-format": "3.2.4", "loupe": "^3.1.4", "tinyrainbow": "^2.0.0" } }, "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA=="], + "gitlab-ai-provider/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - "@vitest/expect/tinyrainbow": ["tinyrainbow@2.0.0", "", {}, "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw=="], + "http-proxy-agent/agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], - "@vitest/mocker/@vitest/spy": ["@vitest/spy@4.1.4", "", {}, "sha512-XxNdAsKW7C+FLydqFJLb5KhJtl3PGCMmYwFRfhvIgxJvLSXhhVI1zM8f1qD3Zg7RCjTSzDVyct6sghs9UEgBEQ=="], + "is-core-module/hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="], - "@vscode/emmet-helper/jsonc-parser": ["jsonc-parser@2.3.1", "", {}, "sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg=="], + "is-regex/hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="], - "accepts/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], + "katex/commander": ["commander@8.3.0", "", {}, "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww=="], - "accepts/negotiator": ["negotiator@0.6.3", "", {}, "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="], + "lazystream/readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="], - "ai-gateway-provider/@ai-sdk/amazon-bedrock": ["@ai-sdk/amazon-bedrock@4.0.93", "", { "dependencies": { "@ai-sdk/anthropic": "3.0.69", "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.23", "@smithy/eventstream-codec": "^4.0.1", "@smithy/util-utf8": "^4.0.0", "aws4fetch": "^1.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-hcXDU8QDwpAzLVTuY932TQVlIij9+iaVTxc5mPGY6yb//JMAAC5hMVhg93IrxlrxWLvMgjezNgoZGwquR+SGnw=="], + "light-my-request/cookie": ["cookie@1.1.1", "", {}, "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ=="], - "ai-gateway-provider/@ai-sdk/anthropic": ["@ai-sdk/anthropic@3.0.69", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.23" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-LshR7X3pFugY0o41G2VKTmg1XoGpSl7uoYWfzk6zjVZLhCfeFiwgpOga+eTV4XY1VVpZwKVqRnkDbIL7K2eH5g=="], + "light-my-request/process-warning": ["process-warning@4.0.1", "", {}, "sha512-3c2LzQ3rY9d0hc1emcsHhfT9Jwz0cChib/QN89oME2R451w5fy3f0afAhERFZAwrbDU43wk12d0ORBpDVME50Q=="], - "ai-gateway-provider/@ai-sdk/google": ["@ai-sdk/google@3.0.53", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.21" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-uz8tIlkDgQJG9Js2Wh9JHzd4kI9+hYJqf9XXJLx60vyN5mRIqhr49iwR5zGP5Gl8odp2PeR3Gh2k+5bh3Z1HHw=="], + "lightningcss/detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], - "ai-gateway-provider/@ai-sdk/google-vertex": ["@ai-sdk/google-vertex@4.0.95", "", { "dependencies": { "@ai-sdk/anthropic": "3.0.64", "@ai-sdk/google": "3.0.53", "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.21", "google-auth-library": "^10.5.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-xL44fHlTtDM7RLkMTgyqMfkfthA38JS91bbMaHItObIhte1PAIY936ZV1PLl/Z9A/oBAXjHWbXo5xDoHzB7LEg=="], + "mendcode/minimatch": ["minimatch@10.2.3", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-Rwi3pnapEqirPSbWbrZaa6N3nmqq4Xer/2XooiOKyV3q12ML06f7MOuc5DVH8ONZIFhwIYQ3yzPH4nt7iWHaTg=="], - "ai-gateway-provider/@ai-sdk/xai": ["@ai-sdk/xai@3.0.75", "", { "dependencies": { "@ai-sdk/openai-compatible": "2.0.37", "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.21" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-V8UKK4fNpI9cnrtsZBvUp9O9J6Y9fTKBRoSLyEaNGPirACewixmLDbXsSgAeownPVWiWpK34bFysd+XouI5Ywg=="], + "micromatch/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], - "ai-gateway-provider/@openrouter/ai-sdk-provider": ["@openrouter/ai-sdk-provider@2.5.1", "", { "peerDependencies": { "ai": "^6.0.0", "zod": "^3.25.0 || ^4.0.0" } }, "sha512-r1fJL1Cb3gQDa2MpWH/sfx1BsEW0uzlRriJM6eihaKqbtKDmZoBisF32VcVaQYassighX7NGCkF68EsrZA43uQ=="], + "minipass-flush/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], - "ajv-keywords/ajv": ["ajv@6.14.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw=="], + "minipass-pipeline/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], - "ansi-align/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + "mssql/commander": ["commander@11.1.0", "", {}, "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ=="], - "anymatch/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], + "mssql/tedious": ["tedious@18.6.2", "", { "dependencies": { "@azure/core-auth": "^1.7.2", "@azure/identity": "^4.2.1", "@azure/keyvault-keys": "^4.4.0", "@js-joda/core": "^5.6.1", "@types/node": ">=18", "bl": "^6.0.11", "iconv-lite": "^0.6.3", "js-md4": "^0.3.2", "native-duplexpair": "^1.0.0", "sprintf-js": "^1.1.3" } }, "sha512-g7jC56o3MzLkE3lHkaFe2ZdOVFBahq5bsB60/M4NYUbocw/MCrS89IOEQUFr+ba6pb8ZHczZ/VqCyYeYq0xBAg=="], - "app-builder-lib/@electron/get": ["@electron/get@3.1.0", "", { "dependencies": { "debug": "^4.1.1", "env-paths": "^2.2.0", "fs-extra": "^8.1.0", "got": "^11.8.5", "progress": "^2.0.3", "semver": "^6.2.0", "sumchecker": "^3.0.1" }, "optionalDependencies": { "global-agent": "^3.0.0" } }, "sha512-F+nKc0xW+kVbBRhFzaMgPy3KwmuNTYX1fx6+FxxoSnNgwYX6LD7AKBTWkU0MQ6IBoe7dz069CNkR673sPAgkCQ=="], + "node-gyp-build-optional-packages/detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], - "app-builder-lib/ci-info": ["ci-info@4.3.1", "", {}, "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA=="], + "npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="], - "app-builder-lib/hosted-git-info": ["hosted-git-info@4.1.0", "", { "dependencies": { "lru-cache": "^6.0.0" } }, "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA=="], + "opencode-gitlab-auth/open": ["open@10.2.0", "", { "dependencies": { "default-browser": "^5.2.1", "define-lazy-prop": "^3.0.0", "is-inside-container": "^1.0.0", "wsl-utils": "^0.1.0" } }, "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA=="], - "app-builder-lib/which": ["which@5.0.0", "", { "dependencies": { "isexe": "^3.1.1" }, "bin": { "node-which": "bin/which.js" } }, "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ=="], + "opencode-poe-auth/open": ["open@10.2.0", "", { "dependencies": { "default-browser": "^5.2.1", "define-lazy-prop": "^3.0.0", "is-inside-container": "^1.0.0", "wsl-utils": "^0.1.0" } }, "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA=="], - "archiver-utils/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="], + "opencontrol/@tsconfig/bun": ["@tsconfig/bun@1.0.7", "", {}, "sha512-udGrGJBNQdXGVulehc1aWT73wkR9wdaGBtB6yL70RJsqwW/yJhIg6ZbRlPOfIUiFNrnBuYLBi9CSmMKfDC7dvA=="], - "archiver-utils/is-stream": ["is-stream@2.0.1", "", {}, "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="], + "opencontrol/zod": ["zod@3.24.2", "", {}, "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ=="], - "astro/@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.6.1", "", {}, "sha512-l5Pqf6uZu31aG+3Lv8nl/3s4DbUzdlxTWDof4pEpto6GUJNhhCbelVi9dEyurOVyqaelwmS9oSyOWOENSfgo9A=="], + "opencontrol/zod-to-json-schema": ["zod-to-json-schema@3.24.3", "", { "peerDependencies": { "zod": "^3.24.1" } }, "sha512-HIAfWdYIt1sssHfYZFCXp4rU1w2r8hVVXYIlmoa0r0gABLs5di3RCqPU5DDROogVz1pAdYBaz7HK5n9pSUNs3A=="], - "astro/common-ancestor-path": ["common-ancestor-path@1.0.1", "", {}, "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w=="], + "openid-client/jose": ["jose@4.15.9", "", {}, "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA=="], - "astro/diff": ["diff@5.2.2", "", {}, "sha512-vtcDfH3TOjP8UekytvnHH1o1P4FcUdt4eQ1Y+Abap1tk/OB2MWQvcwS2ClCd1zuIhc3JKOx6p3kod8Vfys3E+A=="], + "openid-client/lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="], - "astro/unstorage": ["unstorage@1.17.5", "", { "dependencies": { "anymatch": "^3.1.3", "chokidar": "^5.0.0", "destr": "^2.0.5", "h3": "^1.15.10", "lru-cache": "^11.2.7", "node-fetch-native": "^1.6.7", "ofetch": "^1.5.1", "ufo": "^1.6.3" }, "peerDependencies": { "@azure/app-configuration": "^1.8.0", "@azure/cosmos": "^4.2.0", "@azure/data-tables": "^13.3.0", "@azure/identity": "^4.6.0", "@azure/keyvault-secrets": "^4.9.0", "@azure/storage-blob": "^12.26.0", "@capacitor/preferences": "^6 || ^7 || ^8", "@deno/kv": ">=0.9.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.34.3", "@vercel/blob": ">=0.27.1", "@vercel/functions": "^2.2.12 || ^3.0.0", "@vercel/kv": "^1 || ^2 || ^3", "aws4fetch": "^1.0.20", "db0": ">=0.2.1", "idb-keyval": "^6.2.1", "ioredis": "^5.4.2", "uploadthing": "^7.4.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/functions", "@vercel/kv", "aws4fetch", "db0", "idb-keyval", "ioredis", "uploadthing"] }, "sha512-0i3iqvRfx29hkNntHyQvJTpf5W9dQ9ZadSoRU8+xVlhVtT7jAX57fazYO9EHvcRCfBCyi5YRya7XCDOsbTgkPg=="], + "opentui-spinner/@opentui/core": ["@opentui/core@0.1.105", "", { "dependencies": { "bun-ffi-structs": "0.1.2", "diff": "8.0.2", "jimp": "1.6.0", "marked": "17.0.1", "yoga-layout": "3.2.1" }, "optionalDependencies": { "@dimforge/rapier2d-simd-compat": "^0.17.3", "@opentui/core-darwin-arm64": "0.1.105", "@opentui/core-darwin-x64": "0.1.105", "@opentui/core-linux-arm64": "0.1.105", "@opentui/core-linux-x64": "0.1.105", "@opentui/core-win32-arm64": "0.1.105", "@opentui/core-win32-x64": "0.1.105", "bun-webgpu": "0.1.5", "planck": "^1.4.2", "three": "0.177.0" }, "peerDependencies": { "web-tree-sitter": "0.25.10" } }, "sha512-vllSOOCW6VIThV/96GRLJ1IxIBuR+ci6FDvnPIAG4s7SJ/FW6zAkqDn1xrtBwwk/lM3QWjLqy8BZc+zwWvveJA=="], - "astro/vite": ["vite@6.4.2", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-2N/55r4JDJ4gdrCvGgINMy+HH3iRpNIz8K6SFwVsA+JbQScLiC+clmAxBgwiSPgcG9U15QmvqCGWzMbqda5zGQ=="], + "opentui-spinner/@opentui/solid": ["@opentui/solid@0.1.105", "", { "dependencies": { "@babel/core": "7.28.0", "@babel/preset-typescript": "7.27.1", "@opentui/core": "0.1.105", "babel-plugin-module-resolver": "5.0.2", "babel-preset-solid": "1.9.10", "entities": "7.0.1", "s-js": "^0.4.9" }, "peerDependencies": { "solid-js": "1.9.11" } }, "sha512-uxnaMP802sCI487pv/Hk9xdFdIj9mkg3eNliAqbqR0Shmd4phcjKEZvPRpijjmI99j4s9nul71jzF3h1oz31Nw=="], - "astro/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], + "p-queue/eventemitter3": ["eventemitter3@4.0.7", "", {}, "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw=="], - "aws-sdk/events": ["events@1.1.1", "", {}, "sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw=="], + "parse-bmfont-xml/xml2js": ["xml2js@0.5.0", "", { "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" } }, "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA=="], - "aws-sdk/uuid": ["uuid@8.0.0", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw=="], + "parse5/entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="], - "babel-plugin-jsx-dom-expressions/@babel/helper-module-imports": ["@babel/helper-module-imports@7.18.6", "", { "dependencies": { "@babel/types": "^7.18.6" } }, "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA=="], + "pixelmatch/pngjs": ["pngjs@6.0.0", "", {}, "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg=="], - "babel-plugin-module-resolver/glob": ["glob@9.3.5", "", { "dependencies": { "fs.realpath": "^1.0.0", "minimatch": "^8.0.2", "minipass": "^4.2.4", "path-scurry": "^1.6.1" } }, "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q=="], + "readable-stream/buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="], - "bl/buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="], + "readdir-glob/minimatch": ["minimatch@5.1.9", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw=="], - "body-parser/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], + "shiki/@shikijs/core": ["@shikijs/core@3.20.0", "", { "dependencies": { "@shikijs/types": "3.20.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-f2ED7HYV4JEk827mtMDwe/yQ25pRiXZmtHjWF8uzZKuKiEsJR7Ce1nuQ+HhV9FzDcbIo4ObBCD9GPTzNuy9S1g=="], - "body-parser/iconv-lite": ["iconv-lite@0.4.24", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3" } }, "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA=="], + "shiki/@shikijs/types": ["@shikijs/types@3.20.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-lhYAATn10nkZcBQ0BlzSbJA3wcmL5MXUUF8d2Zzon6saZDlToKaiRX60n2+ZaHJCmXEcZRWNzn+k9vplr8Jhsw=="], - "body-parser/qs": ["qs@6.14.2", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q=="], + "socks-proxy-agent/agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], - "buffer/ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="], + "solid-refresh/@babel/generator": ["@babel/generator@7.29.1", "", { "dependencies": { "@babel/parser": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw=="], - "builder-util/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], + "sst/jose": ["jose@5.2.3", "", {}, "sha512-KUXdbctm1uHVL8BYhnyHkgp3zDX5KW8ZhAKVFEfUbU2P8Alpzjb+48hHvjOdQIyPshoblhzsuqOwEEAbtHVirA=="], - "builder-util-runtime/sax": ["sax@1.6.0", "", {}, "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA=="], + "string-width-cjs/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], - "bun-types/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], + "string-width-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - "bun-webgpu/@webgpu/types": ["@webgpu/types@0.1.69", "", {}, "sha512-RPmm6kgRbI8e98zSD3RVACvnuktIja5+yLgDAkTmxLr90BEwdTXRQWNLF3ETTTyH/8mKhznZuN5AveXYFEsMGQ=="], + "strip-ansi-cjs/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - "c12/chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "^5.0.0" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="], + "tar/yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="], - "c12/dotenv": ["dotenv@17.4.2", "", {}, "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw=="], + "token-types/ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="], - "clone-response/mimic-response": ["mimic-response@1.0.1", "", {}, "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ=="], + "tree-sitter-bash/node-addon-api": ["node-addon-api@8.7.0", "", {}, "sha512-9MdFxmkKaOYVTV+XVRG8ArDwwQ77XIgIPyKASB1k3JPq3M8fGQQQE3YpMOrKm6g//Ktx8ivZr8xo1Qmtqub+GA=="], - "cloudflare/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], + "vite-plugin-icons-spritesheet/glob": ["glob@11.1.0", "", { "dependencies": { "foreground-child": "^3.3.1", "jackspeak": "^4.1.1", "minimatch": "^10.1.1", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^2.0.0" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw=="], - "compress-commons/is-stream": ["is-stream@2.0.1", "", {}, "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="], + "wrap-ansi-cjs/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], - "condense-newlines/kind-of": ["kind-of@3.2.2", "", { "dependencies": { "is-buffer": "^1.1.5" } }, "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ=="], + "wrap-ansi-cjs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], - "conf/dot-prop": ["dot-prop@9.0.0", "", { "dependencies": { "type-fest": "^4.18.2" } }, "sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ=="], + "wrap-ansi-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - "conf/env-paths": ["env-paths@3.0.0", "", {}, "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A=="], + "xml2js/sax": ["sax@1.6.0", "", {}, "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA=="], - "config-chain/ini": ["ini@1.3.8", "", {}, "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="], + "zod-to-json-schema/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - "crc/buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="], + "@actions/artifact/@actions/core/@actions/exec": ["@actions/exec@2.0.0", "", { "dependencies": { "@actions/io": "^2.0.0" } }, "sha512-k8ngrX2voJ/RIN6r9xB82NVqKpnMRtxDoiO+g3olkIUpQNqjArXrCQceduQZCQj3P3xm32pChRLqRrtXTlqhIw=="], - "cross-spawn/which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], + "@actions/github/@octokit/plugin-paginate-rest/@octokit/types": ["@octokit/types@12.6.0", "", { "dependencies": { "@octokit/openapi-types": "^20.0.0" } }, "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw=="], - "defaults/clone": ["clone@1.0.4", "", {}, "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg=="], + "@actions/github/@octokit/plugin-rest-endpoint-methods/@octokit/types": ["@octokit/types@12.6.0", "", { "dependencies": { "@octokit/openapi-types": "^20.0.0" } }, "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw=="], - "dir-compare/minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="], + "@aws-crypto/sha1-browser/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@2.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA=="], - "dir-compare/p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="], + "@aws-crypto/sha256-browser/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@2.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA=="], - "dmg-builder/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], + "@aws-crypto/util/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@2.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA=="], - "dmg-license/ajv": ["ajv@6.14.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw=="], + "@aws-sdk/client-cognito-identity/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.17", "", { "dependencies": { "@smithy/types": "^4.14.0", "fast-xml-parser": "5.5.8", "tslib": "^2.6.2" } }, "sha512-Ra7hjqAZf1OXRRMueB13qex7mFJRDK/pgCvdSFemXBT8KCGnQDPoKzHY1SjN+TjJVmnpSF14W5tJ1vDamFu+Gg=="], - "dom-serializer/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], + "@aws-sdk/client-cognito-identity/@aws-sdk/middleware-user-agent/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.996.6", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "@smithy/util-endpoints": "^3.3.4", "tslib": "^2.6.2" } }, "sha512-2nUQ+2ih7CShuKHpGSIYvvAIOHy52dOZguYG36zptBukhw6iFwcvGfG0tes0oZFWQqEWvgZe9HLWaNlvXGdOrg=="], - "dot-prop/type-fest": ["type-fest@3.13.1", "", {}, "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g=="], + "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/nested-clients/@aws-sdk/core": ["@aws-sdk/core@3.973.27", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@aws-sdk/xml-builder": "^3.972.17", "@smithy/core": "^3.23.14", "@smithy/node-config-provider": "^4.3.13", "@smithy/property-provider": "^4.2.13", "@smithy/protocol-http": "^5.3.13", "@smithy/signature-v4": "^5.3.13", "@smithy/smithy-client": "^4.12.9", "@smithy/types": "^4.14.0", "@smithy/util-base64": "^4.3.2", "@smithy/util-middleware": "^4.2.13", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-CUZ5m8hwMCH6OYI4Li/WgMfIEx10Q2PLI9Y3XOUTPGZJ53aZ0007jCv+X/ywsaERyKPdw5MRZWk877roQksQ4A=="], - "editorconfig/commander": ["commander@10.0.1", "", {}, "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug=="], + "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/nested-clients/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-je5vRdNw4SkuTnmRbFZLdye4sQ0faLt8kwka5wnnSU30q1mHO4X+idGEJOOE+Tn1ME7Oryn05xxkDvIb3UaLaQ=="], - "editorconfig/minimatch": ["minimatch@9.0.9", "", { "dependencies": { "brace-expansion": "^2.0.2" } }, "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg=="], + "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/nested-clients/@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-HsVgDrruhqI28RkaXALm8grJ7Agc1wF6Et0xh6pom8NdO2VdO/SD9U/tPwUjewwK/pVoka+EShBxyCvgsPCtog=="], - "effect/@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], + "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/nested-clients/@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.972.10", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-RVQQbq5orQ/GHUnXvqEOj2HHPBJm+mM+ySwZKS5UaLBwra5ugRtiH09PLUoOZRl7a1YzaOzXSuGbn9iD5j60WQ=="], - "electron/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], + "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/nested-clients/@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.972.29", "", { "dependencies": { "@aws-sdk/core": "^3.973.27", "@aws-sdk/types": "^3.973.7", "@aws-sdk/util-endpoints": "^3.996.6", "@smithy/core": "^3.23.14", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "@smithy/util-retry": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-f/sIRzuTfEjg6NsbMYvye2VsmnQoNgntntleQyx5uGacUYzszbfIlO3GcI6G6daWUmTm0IDZc11qMHWwF0o0mQ=="], - "electron-builder/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], + "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/nested-clients/@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.972.11", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/config-resolver": "^4.4.14", "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-6Q8B1dcx6BBqUTY1Mc/eROKA0FImEEY5VPSd6AGPEUf0ErjExz4snVqa9kNJSoVDV1rKaNf3qrWojgcKW+SdDg=="], - "electron-builder/yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="], + "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/nested-clients/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.996.6", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "@smithy/util-endpoints": "^3.3.4", "tslib": "^2.6.2" } }, "sha512-2nUQ+2ih7CShuKHpGSIYvvAIOHy52dOZguYG36zptBukhw6iFwcvGfG0tes0oZFWQqEWvgZe9HLWaNlvXGdOrg=="], - "electron-publish/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], + "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/nested-clients/@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-sn/LMzTbGjYqCCF24390WxPd6hkpoSptiUn5DzVp4cD71yqw+yGEGm1YCxyEoPXyc8qciM8UzLJcZBFslxo5Uw=="], - "electron-publish/mime": ["mime@2.6.0", "", { "bin": { "mime": "cli.js" } }, "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg=="], + "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/nested-clients/@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.973.15", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "^3.972.29", "@aws-sdk/types": "^3.973.7", "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "@smithy/util-config-provider": "^4.2.2", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-fYn3s9PtKdgQkczGZCFMgkNEe8aq1JCVbnRqjqN9RSVW43xn2RV9xdcZ3z01a48Jpkuh/xCmBKJxdLOo4Ozg7w=="], - "electron-winstaller/fs-extra": ["fs-extra@7.0.1", "", { "dependencies": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw=="], + "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/nested-clients/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - "encoding/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], + "@aws-sdk/credential-provider-env/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.17", "", { "dependencies": { "@smithy/types": "^4.14.0", "fast-xml-parser": "5.5.8", "tslib": "^2.6.2" } }, "sha512-Ra7hjqAZf1OXRRMueB13qex7mFJRDK/pgCvdSFemXBT8KCGnQDPoKzHY1SjN+TjJVmnpSF14W5tJ1vDamFu+Gg=="], - "engine.io-client/ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="], + "@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - "es-get-iterator/isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="], + "@aws-sdk/credential-provider-http/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.17", "", { "dependencies": { "@smithy/types": "^4.14.0", "fast-xml-parser": "5.5.8", "tslib": "^2.6.2" } }, "sha512-Ra7hjqAZf1OXRRMueB13qex7mFJRDK/pgCvdSFemXBT8KCGnQDPoKzHY1SjN+TjJVmnpSF14W5tJ1vDamFu+Gg=="], - "esbuild-plugin-copy/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], + "@aws-sdk/credential-provider-http/@aws-sdk/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - "esbuild-plugin-copy/chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="], + "@aws-sdk/credential-provider-ini/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.17", "", { "dependencies": { "@smithy/types": "^4.14.0", "fast-xml-parser": "5.5.8", "tslib": "^2.6.2" } }, "sha512-Ra7hjqAZf1OXRRMueB13qex7mFJRDK/pgCvdSFemXBT8KCGnQDPoKzHY1SjN+TjJVmnpSF14W5tJ1vDamFu+Gg=="], - "estree-util-to-js/source-map": ["source-map@0.7.6", "", {}, "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ=="], + "@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - "execa/get-stream": ["get-stream@8.0.1", "", {}, "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA=="], + "@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-je5vRdNw4SkuTnmRbFZLdye4sQ0faLt8kwka5wnnSU30q1mHO4X+idGEJOOE+Tn1ME7Oryn05xxkDvIb3UaLaQ=="], - "execa/is-stream": ["is-stream@3.0.0", "", {}, "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA=="], + "@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-HsVgDrruhqI28RkaXALm8grJ7Agc1wF6Et0xh6pom8NdO2VdO/SD9U/tPwUjewwK/pVoka+EShBxyCvgsPCtog=="], - "express/cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="], + "@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.972.10", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-RVQQbq5orQ/GHUnXvqEOj2HHPBJm+mM+ySwZKS5UaLBwra5ugRtiH09PLUoOZRl7a1YzaOzXSuGbn9iD5j60WQ=="], - "express/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], + "@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.972.29", "", { "dependencies": { "@aws-sdk/core": "^3.973.27", "@aws-sdk/types": "^3.973.7", "@aws-sdk/util-endpoints": "^3.996.6", "@smithy/core": "^3.23.14", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "@smithy/util-retry": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-f/sIRzuTfEjg6NsbMYvye2VsmnQoNgntntleQyx5uGacUYzszbfIlO3GcI6G6daWUmTm0IDZc11qMHWwF0o0mQ=="], - "express/path-to-regexp": ["path-to-regexp@0.1.13", "", {}, "sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA=="], + "@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.972.11", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/config-resolver": "^4.4.14", "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-6Q8B1dcx6BBqUTY1Mc/eROKA0FImEEY5VPSd6AGPEUf0ErjExz4snVqa9kNJSoVDV1rKaNf3qrWojgcKW+SdDg=="], - "express/qs": ["qs@6.14.2", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q=="], + "@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.996.6", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "@smithy/util-endpoints": "^3.3.4", "tslib": "^2.6.2" } }, "sha512-2nUQ+2ih7CShuKHpGSIYvvAIOHy52dOZguYG36zptBukhw6iFwcvGfG0tes0oZFWQqEWvgZe9HLWaNlvXGdOrg=="], - "fetch-blob/web-streams-polyfill": ["web-streams-polyfill@3.3.3", "", {}, "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw=="], + "@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-sn/LMzTbGjYqCCF24390WxPd6hkpoSptiUn5DzVp4cD71yqw+yGEGm1YCxyEoPXyc8qciM8UzLJcZBFslxo5Uw=="], - "filelist/minimatch": ["minimatch@5.1.9", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw=="], + "@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.973.15", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "^3.972.29", "@aws-sdk/types": "^3.973.7", "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "@smithy/util-config-provider": "^4.2.2", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-fYn3s9PtKdgQkczGZCFMgkNEe8aq1JCVbnRqjqN9RSVW43xn2RV9xdcZ3z01a48Jpkuh/xCmBKJxdLOo4Ozg7w=="], - "finalhandler/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], + "@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - "form-data/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], + "@aws-sdk/credential-provider-login/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.17", "", { "dependencies": { "@smithy/types": "^4.14.0", "fast-xml-parser": "5.5.8", "tslib": "^2.6.2" } }, "sha512-Ra7hjqAZf1OXRRMueB13qex7mFJRDK/pgCvdSFemXBT8KCGnQDPoKzHY1SjN+TjJVmnpSF14W5tJ1vDamFu+Gg=="], - "fs-extra/jsonfile": ["jsonfile@6.2.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg=="], + "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - "gaxios/node-fetch": ["node-fetch@3.3.2", "", { "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", "formdata-polyfill": "^4.0.10" } }, "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA=="], + "@aws-sdk/credential-provider-login/@aws-sdk/nested-clients/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-je5vRdNw4SkuTnmRbFZLdye4sQ0faLt8kwka5wnnSU30q1mHO4X+idGEJOOE+Tn1ME7Oryn05xxkDvIb3UaLaQ=="], - "gitlab-ai-provider/openai": ["openai@6.34.0", "", { "peerDependencies": { "ws": "^8.18.0", "zod": "^3.25 || ^4.0" }, "optionalPeers": ["ws", "zod"], "bin": { "openai": "bin/cli" } }, "sha512-yEr2jdGf4tVFYG6ohmr3pF6VJuveP0EA/sS8TBx+4Eq5NT10alu5zg2dmxMXMgqpihRDQlFGpRt2XwsGj+Fyxw=="], + "@aws-sdk/credential-provider-login/@aws-sdk/nested-clients/@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-HsVgDrruhqI28RkaXALm8grJ7Agc1wF6Et0xh6pom8NdO2VdO/SD9U/tPwUjewwK/pVoka+EShBxyCvgsPCtog=="], - "gitlab-ai-provider/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], + "@aws-sdk/credential-provider-login/@aws-sdk/nested-clients/@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.972.10", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-RVQQbq5orQ/GHUnXvqEOj2HHPBJm+mM+ySwZKS5UaLBwra5ugRtiH09PLUoOZRl7a1YzaOzXSuGbn9iD5j60WQ=="], - "globby/ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="], + "@aws-sdk/credential-provider-login/@aws-sdk/nested-clients/@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.972.29", "", { "dependencies": { "@aws-sdk/core": "^3.973.27", "@aws-sdk/types": "^3.973.7", "@aws-sdk/util-endpoints": "^3.996.6", "@smithy/core": "^3.23.14", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "@smithy/util-retry": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-f/sIRzuTfEjg6NsbMYvye2VsmnQoNgntntleQyx5uGacUYzszbfIlO3GcI6G6daWUmTm0IDZc11qMHWwF0o0mQ=="], - "gray-matter/js-yaml": ["js-yaml@3.14.2", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg=="], + "@aws-sdk/credential-provider-login/@aws-sdk/nested-clients/@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.972.11", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/config-resolver": "^4.4.14", "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-6Q8B1dcx6BBqUTY1Mc/eROKA0FImEEY5VPSd6AGPEUf0ErjExz4snVqa9kNJSoVDV1rKaNf3qrWojgcKW+SdDg=="], - "happy-dom/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], + "@aws-sdk/credential-provider-login/@aws-sdk/nested-clients/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.996.6", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "@smithy/util-endpoints": "^3.3.4", "tslib": "^2.6.2" } }, "sha512-2nUQ+2ih7CShuKHpGSIYvvAIOHy52dOZguYG36zptBukhw6iFwcvGfG0tes0oZFWQqEWvgZe9HLWaNlvXGdOrg=="], - "happy-dom/ws": ["ws@8.20.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA=="], + "@aws-sdk/credential-provider-login/@aws-sdk/nested-clients/@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-sn/LMzTbGjYqCCF24390WxPd6hkpoSptiUn5DzVp4cD71yqw+yGEGm1YCxyEoPXyc8qciM8UzLJcZBFslxo5Uw=="], - "html-minifier-terser/commander": ["commander@10.0.1", "", {}, "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug=="], + "@aws-sdk/credential-provider-login/@aws-sdk/nested-clients/@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.973.15", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "^3.972.29", "@aws-sdk/types": "^3.973.7", "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "@smithy/util-config-provider": "^4.2.2", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-fYn3s9PtKdgQkczGZCFMgkNEe8aq1JCVbnRqjqN9RSVW43xn2RV9xdcZ3z01a48Jpkuh/xCmBKJxdLOo4Ozg7w=="], - "html-minifier-terser/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], + "@aws-sdk/credential-provider-login/@aws-sdk/nested-clients/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - "htmlparser2/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], + "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.933.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.932.0", "@aws-sdk/middleware-host-header": "3.930.0", "@aws-sdk/middleware-logger": "3.930.0", "@aws-sdk/middleware-recursion-detection": "3.933.0", "@aws-sdk/middleware-user-agent": "3.932.0", "@aws-sdk/region-config-resolver": "3.930.0", "@aws-sdk/types": "3.930.0", "@aws-sdk/util-endpoints": "3.930.0", "@aws-sdk/util-user-agent-browser": "3.930.0", "@aws-sdk/util-user-agent-node": "3.932.0", "@smithy/config-resolver": "^4.4.3", "@smithy/core": "^3.18.2", "@smithy/fetch-http-handler": "^5.3.6", "@smithy/hash-node": "^4.2.5", "@smithy/invalid-dependency": "^4.2.5", "@smithy/middleware-content-length": "^4.2.5", "@smithy/middleware-endpoint": "^4.3.9", "@smithy/middleware-retry": "^4.4.9", "@smithy/middleware-serde": "^4.2.5", "@smithy/middleware-stack": "^4.2.5", "@smithy/node-config-provider": "^4.3.5", "@smithy/node-http-handler": "^4.4.5", "@smithy/protocol-http": "^5.3.5", "@smithy/smithy-client": "^4.9.5", "@smithy/types": "^4.9.0", "@smithy/url-parser": "^4.2.5", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.8", "@smithy/util-defaults-mode-node": "^4.2.11", "@smithy/util-endpoints": "^3.2.5", "@smithy/util-middleware": "^4.2.5", "@smithy/util-retry": "^4.2.5", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-o1GX0+IPlFi/D8ei9y/jj3yucJWNfPnbB5appVBWevAyUdZA5KzQ2nK/hDxiu9olTZlFEFpf1m1Rn3FaGxHqsw=="], - "iconv-corefoundation/cli-truncate": ["cli-truncate@2.1.0", "", { "dependencies": { "slice-ansi": "^3.0.0", "string-width": "^4.2.0" } }, "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg=="], + "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.933.0", "", { "dependencies": { "@aws-sdk/core": "3.932.0", "@aws-sdk/nested-clients": "3.933.0", "@aws-sdk/types": "3.930.0", "@smithy/property-provider": "^4.2.5", "@smithy/shared-ini-file-loader": "^4.4.0", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-Qzq7zj9yXUgAAJEbbmqRhm0jmUndl8nHG0AbxFEfCfQRVZWL96Qzx0mf8lYwT9hIMrXncLwy31HOthmbXwFRwQ=="], - "iconv-corefoundation/node-addon-api": ["node-addon-api@1.7.2", "", {}, "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg=="], + "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.933.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.932.0", "@aws-sdk/middleware-host-header": "3.930.0", "@aws-sdk/middleware-logger": "3.930.0", "@aws-sdk/middleware-recursion-detection": "3.933.0", "@aws-sdk/middleware-user-agent": "3.932.0", "@aws-sdk/region-config-resolver": "3.930.0", "@aws-sdk/types": "3.930.0", "@aws-sdk/util-endpoints": "3.930.0", "@aws-sdk/util-user-agent-browser": "3.930.0", "@aws-sdk/util-user-agent-node": "3.932.0", "@smithy/config-resolver": "^4.4.3", "@smithy/core": "^3.18.2", "@smithy/fetch-http-handler": "^5.3.6", "@smithy/hash-node": "^4.2.5", "@smithy/invalid-dependency": "^4.2.5", "@smithy/middleware-content-length": "^4.2.5", "@smithy/middleware-endpoint": "^4.3.9", "@smithy/middleware-retry": "^4.4.9", "@smithy/middleware-serde": "^4.2.5", "@smithy/middleware-stack": "^4.2.5", "@smithy/node-config-provider": "^4.3.5", "@smithy/node-http-handler": "^4.4.5", "@smithy/protocol-http": "^5.3.5", "@smithy/smithy-client": "^4.9.5", "@smithy/types": "^4.9.0", "@smithy/url-parser": "^4.2.5", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.8", "@smithy/util-defaults-mode-node": "^4.2.11", "@smithy/util-endpoints": "^3.2.5", "@smithy/util-middleware": "^4.2.5", "@smithy/util-retry": "^4.2.5", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-o1GX0+IPlFi/D8ei9y/jj3yucJWNfPnbB5appVBWevAyUdZA5KzQ2nK/hDxiu9olTZlFEFpf1m1Rn3FaGxHqsw=="], - "image-q/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], + "@aws-sdk/credential-provider-process/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.17", "", { "dependencies": { "@smithy/types": "^4.14.0", "fast-xml-parser": "5.5.8", "tslib": "^2.6.2" } }, "sha512-Ra7hjqAZf1OXRRMueB13qex7mFJRDK/pgCvdSFemXBT8KCGnQDPoKzHY1SjN+TjJVmnpSF14W5tJ1vDamFu+Gg=="], - "js-beautify/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="], + "@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - "js-beautify/nopt": ["nopt@7.2.1", "", { "dependencies": { "abbrev": "^2.0.0" }, "bin": { "nopt": "bin/nopt.js" } }, "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w=="], + "@aws-sdk/credential-provider-sso/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.17", "", { "dependencies": { "@smithy/types": "^4.14.0", "fast-xml-parser": "5.5.8", "tslib": "^2.6.2" } }, "sha512-Ra7hjqAZf1OXRRMueB13qex7mFJRDK/pgCvdSFemXBT8KCGnQDPoKzHY1SjN+TjJVmnpSF14W5tJ1vDamFu+Gg=="], - "katex/commander": ["commander@8.3.0", "", {}, "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww=="], + "@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - "lazystream/readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="], + "@aws-sdk/credential-provider-sso/@aws-sdk/nested-clients/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-je5vRdNw4SkuTnmRbFZLdye4sQ0faLt8kwka5wnnSU30q1mHO4X+idGEJOOE+Tn1ME7Oryn05xxkDvIb3UaLaQ=="], - "light-my-request/process-warning": ["process-warning@4.0.1", "", {}, "sha512-3c2LzQ3rY9d0hc1emcsHhfT9Jwz0cChib/QN89oME2R451w5fy3f0afAhERFZAwrbDU43wk12d0ORBpDVME50Q=="], + "@aws-sdk/credential-provider-sso/@aws-sdk/nested-clients/@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-HsVgDrruhqI28RkaXALm8grJ7Agc1wF6Et0xh6pom8NdO2VdO/SD9U/tPwUjewwK/pVoka+EShBxyCvgsPCtog=="], - "lightningcss/detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], + "@aws-sdk/credential-provider-sso/@aws-sdk/nested-clients/@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.972.10", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-RVQQbq5orQ/GHUnXvqEOj2HHPBJm+mM+ySwZKS5UaLBwra5ugRtiH09PLUoOZRl7a1YzaOzXSuGbn9iD5j60WQ=="], - "log-symbols/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], + "@aws-sdk/credential-provider-sso/@aws-sdk/nested-clients/@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.972.29", "", { "dependencies": { "@aws-sdk/core": "^3.973.27", "@aws-sdk/types": "^3.973.7", "@aws-sdk/util-endpoints": "^3.996.6", "@smithy/core": "^3.23.14", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "@smithy/util-retry": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-f/sIRzuTfEjg6NsbMYvye2VsmnQoNgntntleQyx5uGacUYzszbfIlO3GcI6G6daWUmTm0IDZc11qMHWwF0o0mQ=="], - "matcher/escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="], + "@aws-sdk/credential-provider-sso/@aws-sdk/nested-clients/@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.972.11", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/config-resolver": "^4.4.14", "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-6Q8B1dcx6BBqUTY1Mc/eROKA0FImEEY5VPSd6AGPEUf0ErjExz4snVqa9kNJSoVDV1rKaNf3qrWojgcKW+SdDg=="], - "md-to-react-email/marked": ["marked@7.0.4", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-t8eP0dXRJMtMvBojtkcsA7n48BkauktUKzfkPSCq85ZMTJ0v76Rke4DYz01omYpPTUh4p/f7HePgRo3ebG8+QQ=="], + "@aws-sdk/credential-provider-sso/@aws-sdk/nested-clients/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.996.6", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "@smithy/util-endpoints": "^3.3.4", "tslib": "^2.6.2" } }, "sha512-2nUQ+2ih7CShuKHpGSIYvvAIOHy52dOZguYG36zptBukhw6iFwcvGfG0tes0oZFWQqEWvgZe9HLWaNlvXGdOrg=="], - "mendcode-runtime-cli/@ai-sdk/anthropic": ["@ai-sdk/anthropic@3.0.71", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.23" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-bUWOzrzR0gJKJO/PLGMR4uH2dqEgqGhrsCV+sSpk4KtOEnUQlfjZI/F7BFlqSvVpFbjdgYRRLysAeEZpJ6S1lg=="], + "@aws-sdk/credential-provider-sso/@aws-sdk/nested-clients/@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-sn/LMzTbGjYqCCF24390WxPd6hkpoSptiUn5DzVp4cD71yqw+yGEGm1YCxyEoPXyc8qciM8UzLJcZBFslxo5Uw=="], - "mendcode-runtime-cli/@ai-sdk/openai": ["@ai-sdk/openai@3.0.53", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.23" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-Wld+Rbc05KaUn08uBt06eEuwcgalcIFtIl32Yp+GxuZXUQwOb6YeAuq+C6da4ch6BurFoqEaLemJVwjBb7x+PQ=="], + "@aws-sdk/credential-provider-sso/@aws-sdk/nested-clients/@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.973.15", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "^3.972.29", "@aws-sdk/types": "^3.973.7", "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "@smithy/util-config-provider": "^4.2.2", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-fYn3s9PtKdgQkczGZCFMgkNEe8aq1JCVbnRqjqN9RSVW43xn2RV9xdcZ3z01a48Jpkuh/xCmBKJxdLOo4Ozg7w=="], - "mendcode-runtime-cli/@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@2.0.41", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.23" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-kNAGINk71AlOXx10Dq/PXw4t/9XjdK8uxfpVElRwtSFMdeSiLVt58p9TPx4/FJD+hxZuVhvxYj9r42osxWq79g=="], + "@aws-sdk/credential-provider-sso/@aws-sdk/nested-clients/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - "mendcode-runtime-cli/minimatch": ["minimatch@10.0.3", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw=="], + "@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.17", "", { "dependencies": { "@smithy/types": "^4.14.0", "fast-xml-parser": "5.5.8", "tslib": "^2.6.2" } }, "sha512-Ra7hjqAZf1OXRRMueB13qex7mFJRDK/pgCvdSFemXBT8KCGnQDPoKzHY1SjN+TjJVmnpSF14W5tJ1vDamFu+Gg=="], - "micromatch/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], + "@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - "miniflare/acorn": ["acorn@8.14.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA=="], + "@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-je5vRdNw4SkuTnmRbFZLdye4sQ0faLt8kwka5wnnSU30q1mHO4X+idGEJOOE+Tn1ME7Oryn05xxkDvIb3UaLaQ=="], - "miniflare/undici": ["undici@7.14.0", "", {}, "sha512-Vqs8HTzjpQXZeXdpsfChQTlafcMQaaIwnGwLam1wudSSjlJeQ3bw1j+TLPePgrCnCpUXx7Ba5Pdpf5OBih62NQ=="], + "@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-HsVgDrruhqI28RkaXALm8grJ7Agc1wF6Et0xh6pom8NdO2VdO/SD9U/tPwUjewwK/pVoka+EShBxyCvgsPCtog=="], - "miniflare/zod": ["zod@3.22.3", "", {}, "sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug=="], + "@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.972.10", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-RVQQbq5orQ/GHUnXvqEOj2HHPBJm+mM+ySwZKS5UaLBwra5ugRtiH09PLUoOZRl7a1YzaOzXSuGbn9iD5j60WQ=="], - "minipass-flush/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + "@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.972.29", "", { "dependencies": { "@aws-sdk/core": "^3.973.27", "@aws-sdk/types": "^3.973.7", "@aws-sdk/util-endpoints": "^3.996.6", "@smithy/core": "^3.23.14", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "@smithy/util-retry": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-f/sIRzuTfEjg6NsbMYvye2VsmnQoNgntntleQyx5uGacUYzszbfIlO3GcI6G6daWUmTm0IDZc11qMHWwF0o0mQ=="], - "minipass-pipeline/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + "@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.972.11", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/config-resolver": "^4.4.14", "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-6Q8B1dcx6BBqUTY1Mc/eROKA0FImEEY5VPSd6AGPEUf0ErjExz4snVqa9kNJSoVDV1rKaNf3qrWojgcKW+SdDg=="], - "motion/framer-motion": ["framer-motion@12.38.0", "", { "dependencies": { "motion-dom": "^12.38.0", "motion-utils": "^12.36.0", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-rFYkY/pigbcswl1XQSb7q424kSTQ8q6eAC+YUsSKooHQYuLdzdHjrt6uxUC+PRAO++q5IS7+TamgIw1AphxR+g=="], + "@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.996.6", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "@smithy/util-endpoints": "^3.3.4", "tslib": "^2.6.2" } }, "sha512-2nUQ+2ih7CShuKHpGSIYvvAIOHy52dOZguYG36zptBukhw6iFwcvGfG0tes0oZFWQqEWvgZe9HLWaNlvXGdOrg=="], - "mssql/commander": ["commander@11.1.0", "", {}, "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ=="], + "@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-sn/LMzTbGjYqCCF24390WxPd6hkpoSptiUn5DzVp4cD71yqw+yGEGm1YCxyEoPXyc8qciM8UzLJcZBFslxo5Uw=="], - "mssql/tedious": ["tedious@18.6.2", "", { "dependencies": { "@azure/core-auth": "^1.7.2", "@azure/identity": "^4.2.1", "@azure/keyvault-keys": "^4.4.0", "@js-joda/core": "^5.6.1", "@types/node": ">=18", "bl": "^6.0.11", "iconv-lite": "^0.6.3", "js-md4": "^0.3.2", "native-duplexpair": "^1.0.0", "sprintf-js": "^1.1.3" } }, "sha512-g7jC56o3MzLkE3lHkaFe2ZdOVFBahq5bsB60/M4NYUbocw/MCrS89IOEQUFr+ba6pb8ZHczZ/VqCyYeYq0xBAg=="], + "@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.973.15", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "^3.972.29", "@aws-sdk/types": "^3.973.7", "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "@smithy/util-config-provider": "^4.2.2", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-fYn3s9PtKdgQkczGZCFMgkNEe8aq1JCVbnRqjqN9RSVW43xn2RV9xdcZ3z01a48Jpkuh/xCmBKJxdLOo4Ozg7w=="], - "nitro/h3": ["h3@2.0.1-rc.5", "", { "dependencies": { "rou3": "^0.7.9", "srvx": "^0.9.1" }, "peerDependencies": { "crossws": "^0.4.1" }, "optionalPeers": ["crossws"] }, "sha512-qkohAzCab0nLzXNm78tBjZDvtKMTmtygS8BJLT3VPczAQofdqlFXDPkXdLMJN4r05+xqneG8snZJ0HgkERCZTg=="], + "@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - "node-gyp-build-optional-packages/detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], + "@aws-sdk/credential-providers/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.17", "", { "dependencies": { "@smithy/types": "^4.14.0", "fast-xml-parser": "5.5.8", "tslib": "^2.6.2" } }, "sha512-Ra7hjqAZf1OXRRMueB13qex7mFJRDK/pgCvdSFemXBT8KCGnQDPoKzHY1SjN+TjJVmnpSF14W5tJ1vDamFu+Gg=="], - "npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="], + "@aws-sdk/credential-providers/@aws-sdk/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - "nypm/citty": ["citty@0.2.2", "", {}, "sha512-+6vJA3L98yv+IdfKGZHBNiGW5KHn22e/JwID0Strsz8h4S/csAu/OuICwxrg44k5MRiZHWIo8XXuJgQTriRP4w=="], + "@aws-sdk/nested-clients/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.17", "", { "dependencies": { "@smithy/types": "^4.14.0", "fast-xml-parser": "5.5.8", "tslib": "^2.6.2" } }, "sha512-Ra7hjqAZf1OXRRMueB13qex7mFJRDK/pgCvdSFemXBT8KCGnQDPoKzHY1SjN+TjJVmnpSF14W5tJ1vDamFu+Gg=="], - "nypm/tinyexec": ["tinyexec@1.1.1", "", {}, "sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg=="], + "@aws-sdk/nested-clients/@aws-sdk/middleware-user-agent/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.996.6", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "@smithy/util-endpoints": "^3.3.4", "tslib": "^2.6.2" } }, "sha512-2nUQ+2ih7CShuKHpGSIYvvAIOHy52dOZguYG36zptBukhw6iFwcvGfG0tes0oZFWQqEWvgZe9HLWaNlvXGdOrg=="], - "opencode/@ai-sdk/anthropic": ["@ai-sdk/anthropic@3.0.71", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.23" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-bUWOzrzR0gJKJO/PLGMR4uH2dqEgqGhrsCV+sSpk4KtOEnUQlfjZI/F7BFlqSvVpFbjdgYRRLysAeEZpJ6S1lg=="], + "@aws-sdk/token-providers/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.17", "", { "dependencies": { "@smithy/types": "^4.14.0", "fast-xml-parser": "5.5.8", "tslib": "^2.6.2" } }, "sha512-Ra7hjqAZf1OXRRMueB13qex7mFJRDK/pgCvdSFemXBT8KCGnQDPoKzHY1SjN+TjJVmnpSF14W5tJ1vDamFu+Gg=="], - "opencode/@ai-sdk/openai": ["@ai-sdk/openai@3.0.53", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.23" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-Wld+Rbc05KaUn08uBt06eEuwcgalcIFtIl32Yp+GxuZXUQwOb6YeAuq+C6da4ch6BurFoqEaLemJVwjBb7x+PQ=="], + "@aws-sdk/token-providers/@aws-sdk/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - "opencode/@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@2.0.41", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.23" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-kNAGINk71AlOXx10Dq/PXw4t/9XjdK8uxfpVElRwtSFMdeSiLVt58p9TPx4/FJD+hxZuVhvxYj9r42osxWq79g=="], + "@aws-sdk/token-providers/@aws-sdk/nested-clients/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-je5vRdNw4SkuTnmRbFZLdye4sQ0faLt8kwka5wnnSU30q1mHO4X+idGEJOOE+Tn1ME7Oryn05xxkDvIb3UaLaQ=="], - "opencode/minimatch": ["minimatch@10.0.3", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw=="], + "@aws-sdk/token-providers/@aws-sdk/nested-clients/@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-HsVgDrruhqI28RkaXALm8grJ7Agc1wF6Et0xh6pom8NdO2VdO/SD9U/tPwUjewwK/pVoka+EShBxyCvgsPCtog=="], - "opencode-gitlab-auth/open": ["open@10.2.0", "", { "dependencies": { "default-browser": "^5.2.1", "define-lazy-prop": "^3.0.0", "is-inside-container": "^1.0.0", "wsl-utils": "^0.1.0" } }, "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA=="], + "@aws-sdk/token-providers/@aws-sdk/nested-clients/@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.972.10", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-RVQQbq5orQ/GHUnXvqEOj2HHPBJm+mM+ySwZKS5UaLBwra5ugRtiH09PLUoOZRl7a1YzaOzXSuGbn9iD5j60WQ=="], - "opencode-poe-auth/open": ["open@10.2.0", "", { "dependencies": { "default-browser": "^5.2.1", "define-lazy-prop": "^3.0.0", "is-inside-container": "^1.0.0", "wsl-utils": "^0.1.0" } }, "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA=="], + "@aws-sdk/token-providers/@aws-sdk/nested-clients/@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.972.29", "", { "dependencies": { "@aws-sdk/core": "^3.973.27", "@aws-sdk/types": "^3.973.7", "@aws-sdk/util-endpoints": "^3.996.6", "@smithy/core": "^3.23.14", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "@smithy/util-retry": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-f/sIRzuTfEjg6NsbMYvye2VsmnQoNgntntleQyx5uGacUYzszbfIlO3GcI6G6daWUmTm0IDZc11qMHWwF0o0mQ=="], - "opencontrol/@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.6.1", "", { "dependencies": { "content-type": "^1.0.5", "cors": "^2.8.5", "eventsource": "^3.0.2", "express": "^5.0.1", "express-rate-limit": "^7.5.0", "pkce-challenge": "^4.1.0", "raw-body": "^3.0.0", "zod": "^3.23.8", "zod-to-json-schema": "^3.24.1" } }, "sha512-oxzMzYCkZHMntzuyerehK3fV6A2Kwh5BD6CGEJSVDU2QNEhfLOptf2X7esQgaHZXHZY0oHmMsOtIDLP71UJXgA=="], + "@aws-sdk/token-providers/@aws-sdk/nested-clients/@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.972.11", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/config-resolver": "^4.4.14", "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-6Q8B1dcx6BBqUTY1Mc/eROKA0FImEEY5VPSd6AGPEUf0ErjExz4snVqa9kNJSoVDV1rKaNf3qrWojgcKW+SdDg=="], - "opencontrol/@tsconfig/bun": ["@tsconfig/bun@1.0.7", "", {}, "sha512-udGrGJBNQdXGVulehc1aWT73wkR9wdaGBtB6yL70RJsqwW/yJhIg6ZbRlPOfIUiFNrnBuYLBi9CSmMKfDC7dvA=="], + "@aws-sdk/token-providers/@aws-sdk/nested-clients/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.996.6", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "@smithy/util-endpoints": "^3.3.4", "tslib": "^2.6.2" } }, "sha512-2nUQ+2ih7CShuKHpGSIYvvAIOHy52dOZguYG36zptBukhw6iFwcvGfG0tes0oZFWQqEWvgZe9HLWaNlvXGdOrg=="], - "opencontrol/hono": ["hono@4.7.4", "", {}, "sha512-Pst8FuGqz3L7tFF+u9Pu70eI0xa5S3LPUmrNd5Jm8nTHze9FxLTK9Kaj5g/k4UcwuJSXTP65SyHOPLrffpcAJg=="], + "@aws-sdk/token-providers/@aws-sdk/nested-clients/@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-sn/LMzTbGjYqCCF24390WxPd6hkpoSptiUn5DzVp4cD71yqw+yGEGm1YCxyEoPXyc8qciM8UzLJcZBFslxo5Uw=="], - "opencontrol/zod": ["zod@3.24.2", "", {}, "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ=="], + "@aws-sdk/token-providers/@aws-sdk/nested-clients/@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.973.15", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "^3.972.29", "@aws-sdk/types": "^3.973.7", "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "@smithy/util-config-provider": "^4.2.2", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-fYn3s9PtKdgQkczGZCFMgkNEe8aq1JCVbnRqjqN9RSVW43xn2RV9xdcZ3z01a48Jpkuh/xCmBKJxdLOo4Ozg7w=="], - "opencontrol/zod-to-json-schema": ["zod-to-json-schema@3.24.3", "", { "peerDependencies": { "zod": "^3.24.1" } }, "sha512-HIAfWdYIt1sssHfYZFCXp4rU1w2r8hVVXYIlmoa0r0gABLs5di3RCqPU5DDROogVz1pAdYBaz7HK5n9pSUNs3A=="], + "@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - "openid-client/jose": ["jose@4.15.9", "", {}, "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA=="], + "@babel/generator/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.29.7", "", {}, "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw=="], - "openid-client/lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="], + "@babel/generator/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.29.7", "", {}, "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg=="], - "opentui-spinner/@opentui/core": ["@opentui/core@0.1.105", "", { "dependencies": { "bun-ffi-structs": "0.1.2", "diff": "8.0.2", "jimp": "1.6.0", "marked": "17.0.1", "yoga-layout": "3.2.1" }, "optionalDependencies": { "@dimforge/rapier2d-simd-compat": "^0.17.3", "@opentui/core-darwin-arm64": "0.1.105", "@opentui/core-darwin-x64": "0.1.105", "@opentui/core-linux-arm64": "0.1.105", "@opentui/core-linux-x64": "0.1.105", "@opentui/core-win32-arm64": "0.1.105", "@opentui/core-win32-x64": "0.1.105", "bun-webgpu": "0.1.5", "planck": "^1.4.2", "three": "0.177.0" }, "peerDependencies": { "web-tree-sitter": "0.25.10" } }, "sha512-vllSOOCW6VIThV/96GRLJ1IxIBuR+ci6FDvnPIAG4s7SJ/FW6zAkqDn1xrtBwwk/lM3QWjLqy8BZc+zwWvveJA=="], + "@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], - "opentui-spinner/@opentui/solid": ["@opentui/solid@0.1.105", "", { "dependencies": { "@babel/core": "7.28.0", "@babel/preset-typescript": "7.27.1", "@opentui/core": "0.1.105", "babel-plugin-module-resolver": "5.0.2", "babel-preset-solid": "1.9.10", "entities": "7.0.1", "s-js": "^0.4.9" }, "peerDependencies": { "solid-js": "1.9.11" } }, "sha512-uxnaMP802sCI487pv/Hk9xdFdIj9mkg3eNliAqbqR0Shmd4phcjKEZvPRpijjmI99j4s9nul71jzF3h1oz31Nw=="], + "@babel/parser/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.29.7", "", {}, "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw=="], - "ora/bl": ["bl@4.1.0", "", { "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w=="], + "@babel/parser/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.29.7", "", {}, "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg=="], - "ora/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], - - "ora/cli-spinners": ["cli-spinners@2.9.2", "", {}, "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg=="], - - "ora/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - - "p-locate/p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="], - - "p-retry/retry": ["retry@0.13.1", "", {}, "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg=="], - - "parse-bmfont-xml/xml2js": ["xml2js@0.5.0", "", { "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" } }, "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA=="], - - "parse-entities/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="], - - "parse5/entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="], - - "pixelmatch/pngjs": ["pngjs@6.0.0", "", {}, "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg=="], - - "pkg-dir/find-up": ["find-up@4.1.0", "", { "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw=="], - - "pkg-up/find-up": ["find-up@3.0.0", "", { "dependencies": { "locate-path": "^3.0.0" } }, "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg=="], - - "playwright/fsevents": ["fsevents@2.3.2", "", { "os": "darwin" }, "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA=="], - - "plist/xmlbuilder": ["xmlbuilder@15.1.1", "", {}, "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg=="], - - "postcss-css-variables/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], - - "postcss-css-variables/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="], - - "postcss-load-config/lilconfig": ["lilconfig@3.1.3", "", {}, "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw=="], - - "postject/commander": ["commander@9.5.0", "", {}, "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ=="], - - "pretty-format/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - - "pretty-format/ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="], - - "prompts/kleur": ["kleur@3.0.3", "", {}, "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w=="], - - "proper-lockfile/signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="], - - "protobufjs/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], - - "raw-body/iconv-lite": ["iconv-lite@0.4.24", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3" } }, "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA=="], - - "readable-stream/buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="], - - "readdir-glob/minimatch": ["minimatch@5.1.9", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw=="], - - "restore-cursor/onetime": ["onetime@5.1.2", "", { "dependencies": { "mimic-fn": "^2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="], - - "restore-cursor/signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="], - - "rimraf/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="], - - "router/path-to-regexp": ["path-to-regexp@8.4.2", "", {}, "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA=="], - - "safe-array-concat/isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="], - - "safe-push-apply/isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="], - - "send/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], - - "send/mime": ["mime@1.6.0", "", { "bin": { "mime": "cli.js" } }, "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="], - - "serialize-error/type-fest": ["type-fest@0.13.1", "", {}, "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg=="], - - "sharp/detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], - - "shiki/@shikijs/core": ["@shikijs/core@3.20.0", "", { "dependencies": { "@shikijs/types": "3.20.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-f2ED7HYV4JEk827mtMDwe/yQ25pRiXZmtHjWF8uzZKuKiEsJR7Ce1nuQ+HhV9FzDcbIo4ObBCD9GPTzNuy9S1g=="], - - "shiki/@shikijs/types": ["@shikijs/types@3.20.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-lhYAATn10nkZcBQ0BlzSbJA3wcmL5MXUUF8d2Zzon6saZDlToKaiRX60n2+ZaHJCmXEcZRWNzn+k9vplr8Jhsw=="], - - "sitemap/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], - - "sitemap/sax": ["sax@1.6.0", "", {}, "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA=="], - - "slice-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], - - "slice-ansi/is-fullwidth-code-point": ["is-fullwidth-code-point@4.0.0", "", {}, "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ=="], - - "sort-keys/is-plain-obj": ["is-plain-obj@1.1.0", "", {}, "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg=="], - - "sst/aws4fetch": ["aws4fetch@1.0.18", "", {}, "sha512-3Cf+YaUl07p24MoQ46rFwulAmiyCwH2+1zw1ZyPAX5OtJ34Hh185DwB8y/qRLb6cYYYtSFJ9pthyLc0MD4e8sQ=="], - - "sst/jose": ["jose@5.2.3", "", {}, "sha512-KUXdbctm1uHVL8BYhnyHkgp3zDX5KW8ZhAKVFEfUbU2P8Alpzjb+48hHvjOdQIyPshoblhzsuqOwEEAbtHVirA=="], - - "storybook/open": ["open@10.2.0", "", { "dependencies": { "default-browser": "^5.2.1", "define-lazy-prop": "^3.0.0", "is-inside-container": "^1.0.0", "wsl-utils": "^0.1.0" } }, "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA=="], - - "storybook-solidjs-vite/vite-plugin-solid": ["vite-plugin-solid@2.11.12", "", { "dependencies": { "@babel/core": "^7.23.3", "@types/babel__core": "^7.20.4", "babel-preset-solid": "^1.8.4", "merge-anything": "^5.1.7", "solid-refresh": "^0.6.3", "vitefu": "^1.0.4" }, "peerDependencies": { "@testing-library/jest-dom": "^5.16.6 || ^5.17.0 || ^6.*", "solid-js": "^1.7.2", "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["@testing-library/jest-dom"] }, "sha512-FgjPcx2OwX9h6f28jli7A4bG7PP3te8uyakE5iqsmpq3Jqi1TWLgSroC9N6cMfGRU2zXsl4Q6ISvTr2VL0QHpA=="], - - "string-width-cjs/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], - - "string-width-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - - "strip-ansi-cjs/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - - "stripe/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], - - "sucrase/commander": ["commander@4.1.1", "", {}, "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="], - - "tar/yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="], - - "tedious/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], - - "terser/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="], - - "tiny-async-pool/semver": ["semver@5.7.2", "", { "bin": { "semver": "bin/semver" } }, "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g=="], - - "token-types/ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="], - - "tree-sitter-bash/node-addon-api": ["node-addon-api@8.7.0", "", {}, "sha512-9MdFxmkKaOYVTV+XVRG8ArDwwQ77XIgIPyKASB1k3JPq3M8fGQQQE3YpMOrKm6g//Ktx8ivZr8xo1Qmtqub+GA=="], - - "tw-to-css/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="], - - "tw-to-css/tailwindcss": ["tailwindcss@3.3.2", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", "chokidar": "^3.5.3", "didyoumean": "^1.2.2", "dlv": "^1.1.3", "fast-glob": "^3.2.12", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", "jiti": "^1.18.2", "lilconfig": "^2.1.0", "micromatch": "^4.0.5", "normalize-path": "^3.0.0", "object-hash": "^3.0.0", "picocolors": "^1.0.0", "postcss": "^8.4.23", "postcss-import": "^15.1.0", "postcss-js": "^4.0.1", "postcss-load-config": "^4.0.1", "postcss-nested": "^6.0.1", "postcss-selector-parser": "^6.0.11", "postcss-value-parser": "^4.2.0", "resolve": "^1.22.2", "sucrase": "^3.32.0" }, "bin": { "tailwind": "lib/cli.js", "tailwindcss": "lib/cli.js" } }, "sha512-9jPkMiIBXvPc2KywkraqsUfbfj+dHDb+JPWtSJa9MLFdrPyazI7q6WX2sUrm7R9eVR7qqv3Pas7EvQFzxKnI6w=="], - - "type-is/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], - - "unifont/ofetch": ["ofetch@1.5.1", "", { "dependencies": { "destr": "^2.0.5", "node-fetch-native": "^1.6.7", "ufo": "^1.6.1" } }, "sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA=="], - - "unplugin/chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="], - - "unused-filename/path-exists": ["path-exists@5.0.0", "", {}, "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ=="], - - "uri-js/punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], - - "utif2/pako": ["pako@1.0.11", "", {}, "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="], - - "venice-ai-sdk-provider/@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@2.0.41", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.23" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-kNAGINk71AlOXx10Dq/PXw4t/9XjdK8uxfpVElRwtSFMdeSiLVt58p9TPx4/FJD+hxZuVhvxYj9r42osxWq79g=="], - - "vite-plugin-icons-spritesheet/glob": ["glob@11.1.0", "", { "dependencies": { "foreground-child": "^3.3.1", "jackspeak": "^4.1.1", "minimatch": "^10.1.1", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^2.0.0" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw=="], - - "vitest/@vitest/expect": ["@vitest/expect@4.1.4", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", "@vitest/spy": "4.1.4", "@vitest/utils": "4.1.4", "chai": "^6.2.2", "tinyrainbow": "^3.1.0" } }, "sha512-iPBpra+VDuXmBFI3FMKHSFXp3Gx5HfmSCE8X67Dn+bwephCnQCaB7qWK2ldHa+8ncN8hJU8VTMcxjPpyMkUjww=="], - - "vitest/@vitest/spy": ["@vitest/spy@4.1.4", "", {}, "sha512-XxNdAsKW7C+FLydqFJLb5KhJtl3PGCMmYwFRfhvIgxJvLSXhhVI1zM8f1qD3Zg7RCjTSzDVyct6sghs9UEgBEQ=="], - - "vitest/es-module-lexer": ["es-module-lexer@2.0.0", "", {}, "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw=="], - - "vitest/tinyexec": ["tinyexec@1.1.1", "", {}, "sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg=="], - - "vitest/vite": ["vite@7.1.10", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-CmuvUBzVJ/e3HGxhg6cYk88NGgTnBoOo7ogtfJJ0fefUWAxN/WDSUa50o+oVBxuIhO8FoEZW0j2eW7sfjs5EtA=="], - - "vitest/why-is-node-running": ["why-is-node-running@2.3.0", "", { "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" }, "bin": { "why-is-node-running": "cli.js" } }, "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w=="], - - "vscode-languageserver-protocol/vscode-jsonrpc": ["vscode-jsonrpc@8.2.0", "", {}, "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA=="], - - "which-builtin-type/isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="], - - "wrangler/esbuild": ["esbuild@0.25.4", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.4", "@esbuild/android-arm": "0.25.4", "@esbuild/android-arm64": "0.25.4", "@esbuild/android-x64": "0.25.4", "@esbuild/darwin-arm64": "0.25.4", "@esbuild/darwin-x64": "0.25.4", "@esbuild/freebsd-arm64": "0.25.4", "@esbuild/freebsd-x64": "0.25.4", "@esbuild/linux-arm": "0.25.4", "@esbuild/linux-arm64": "0.25.4", "@esbuild/linux-ia32": "0.25.4", "@esbuild/linux-loong64": "0.25.4", "@esbuild/linux-mips64el": "0.25.4", "@esbuild/linux-ppc64": "0.25.4", "@esbuild/linux-riscv64": "0.25.4", "@esbuild/linux-s390x": "0.25.4", "@esbuild/linux-x64": "0.25.4", "@esbuild/netbsd-arm64": "0.25.4", "@esbuild/netbsd-x64": "0.25.4", "@esbuild/openbsd-arm64": "0.25.4", "@esbuild/openbsd-x64": "0.25.4", "@esbuild/sunos-x64": "0.25.4", "@esbuild/win32-arm64": "0.25.4", "@esbuild/win32-ia32": "0.25.4", "@esbuild/win32-x64": "0.25.4" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q=="], - - "wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], - - "wrap-ansi-cjs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], - - "wrap-ansi-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - - "xml2js/sax": ["sax@1.6.0", "", {}, "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA=="], - - "yaml-language-server/request-light": ["request-light@0.5.8", "", {}, "sha512-3Zjgh+8b5fhRJBQZoy+zbVKpAQGLyka0MPgW3zruTF4dFFJ8Fqcfu9YsAvi/rvdcaTeWG3MkbZv4WKxAn/84Lg=="], - - "yaml-language-server/yaml": ["yaml@2.7.1", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ=="], - - "yargs/yargs-parser": ["yargs-parser@22.0.0", "", {}, "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw=="], - - "yauzl/buffer-crc32": ["buffer-crc32@0.2.13", "", {}, "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ=="], - - "zod-to-json-schema/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - - "zod-to-ts/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - - "@actions/artifact/@actions/core/@actions/exec": ["@actions/exec@2.0.0", "", { "dependencies": { "@actions/io": "^2.0.0" } }, "sha512-k8ngrX2voJ/RIN6r9xB82NVqKpnMRtxDoiO+g3olkIUpQNqjArXrCQceduQZCQj3P3xm32pChRLqRrtXTlqhIw=="], - - "@actions/core/@actions/http-client/undici": ["undici@5.29.0", "", { "dependencies": { "@fastify/busboy": "^2.0.0" } }, "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg=="], - - "@actions/github/@octokit/plugin-paginate-rest/@octokit/types": ["@octokit/types@12.6.0", "", { "dependencies": { "@octokit/openapi-types": "^20.0.0" } }, "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw=="], - - "@actions/github/@octokit/plugin-rest-endpoint-methods/@octokit/types": ["@octokit/types@12.6.0", "", { "dependencies": { "@octokit/openapi-types": "^20.0.0" } }, "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw=="], - - "@ai-sdk/anthropic/@ai-sdk/provider-utils/@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], - - "@ai-sdk/azure/@ai-sdk/provider-utils/@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], - - "@ai-sdk/cerebras/@ai-sdk/provider-utils/@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], - - "@ai-sdk/cohere/@ai-sdk/provider-utils/@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], - - "@ai-sdk/deepinfra/@ai-sdk/provider-utils/@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], - - "@ai-sdk/groq/@ai-sdk/provider-utils/@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], - - "@ai-sdk/mistral/@ai-sdk/provider-utils/@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], - - "@ai-sdk/openai-compatible/@ai-sdk/provider-utils/@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], - - "@ai-sdk/openai/@ai-sdk/provider-utils/@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], - - "@ai-sdk/perplexity/@ai-sdk/provider-utils/@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], - - "@ai-sdk/togetherai/@ai-sdk/provider-utils/@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], - - "@ai-sdk/vercel/@ai-sdk/provider-utils/@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], - - "@astrojs/check/yargs/cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="], - - "@astrojs/check/yargs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], - - "@astrojs/mdx/@astrojs/markdown-remark/@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.7.6", "", {}, "sha512-GOle7smBWKfMSP8osUIGOlB5kaHdQLV3foCsf+5Q9Wsuu+C6Fs3Ez/ttXmhjZ1HkSgsogcM1RXSjjOVieHq16Q=="], - - "@astrojs/mdx/@astrojs/markdown-remark/@astrojs/prism": ["@astrojs/prism@3.3.0", "", { "dependencies": { "prismjs": "^1.30.0" } }, "sha512-q8VwfU/fDZNoDOf+r7jUnMC2//H2l0TuQ6FkGJL8vD8nw/q5KiL3DS1KKBI3QhI9UQhpJ5dc7AtqfbXWuOgLCQ=="], - - "@astrojs/mdx/@astrojs/markdown-remark/shiki": ["shiki@3.23.0", "", { "dependencies": { "@shikijs/core": "3.23.0", "@shikijs/engine-javascript": "3.23.0", "@shikijs/engine-oniguruma": "3.23.0", "@shikijs/langs": "3.23.0", "@shikijs/themes": "3.23.0", "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-55Dj73uq9ZXL5zyeRPzHQsK7Nbyt6Y10k5s7OjuFZGMhpp4r/rsLBH0o/0fstIzX1Lep9VxefWljK/SKCzygIA=="], - - "@aws-crypto/sha1-browser/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@2.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA=="], - - "@aws-crypto/sha256-browser/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@2.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA=="], - - "@aws-crypto/util/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@2.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA=="], - - "@aws-sdk/client-cognito-identity/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.17", "", { "dependencies": { "@smithy/types": "^4.14.0", "fast-xml-parser": "5.5.8", "tslib": "^2.6.2" } }, "sha512-Ra7hjqAZf1OXRRMueB13qex7mFJRDK/pgCvdSFemXBT8KCGnQDPoKzHY1SjN+TjJVmnpSF14W5tJ1vDamFu+Gg=="], - - "@aws-sdk/client-cognito-identity/@aws-sdk/middleware-user-agent/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.996.6", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "@smithy/util-endpoints": "^3.3.4", "tslib": "^2.6.2" } }, "sha512-2nUQ+2ih7CShuKHpGSIYvvAIOHy52dOZguYG36zptBukhw6iFwcvGfG0tes0oZFWQqEWvgZe9HLWaNlvXGdOrg=="], - - "@aws-sdk/client-sts/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.775.0", "", { "dependencies": { "@aws-sdk/core": "3.775.0", "@aws-sdk/types": "3.775.0", "@smithy/property-provider": "^4.0.2", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-6ESVxwCbGm7WZ17kY1fjmxQud43vzJFoLd4bmlR+idQSWdqlzGDYdcfzpjDKTcivdtNrVYmFvcH1JBUwCRAZhw=="], - - "@aws-sdk/client-sts/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.775.0", "", { "dependencies": { "@aws-sdk/core": "3.775.0", "@aws-sdk/types": "3.775.0", "@smithy/fetch-http-handler": "^5.0.2", "@smithy/node-http-handler": "^4.0.4", "@smithy/property-provider": "^4.0.2", "@smithy/protocol-http": "^5.1.0", "@smithy/smithy-client": "^4.2.0", "@smithy/types": "^4.2.0", "@smithy/util-stream": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-PjDQeDH/J1S0yWV32wCj2k5liRo0ssXMseCBEkCsD3SqsU8o5cU82b0hMX4sAib/RkglCSZqGO0xMiN0/7ndww=="], - - "@aws-sdk/client-sts/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.782.0", "", { "dependencies": { "@aws-sdk/core": "3.775.0", "@aws-sdk/credential-provider-env": "3.775.0", "@aws-sdk/credential-provider-http": "3.775.0", "@aws-sdk/credential-provider-process": "3.775.0", "@aws-sdk/credential-provider-sso": "3.782.0", "@aws-sdk/credential-provider-web-identity": "3.782.0", "@aws-sdk/nested-clients": "3.782.0", "@aws-sdk/types": "3.775.0", "@smithy/credential-provider-imds": "^4.0.2", "@smithy/property-provider": "^4.0.2", "@smithy/shared-ini-file-loader": "^4.0.2", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-wd4KdRy2YjLsE4Y7pz00470Iip06GlRHkG4dyLW7/hFMzEO2o7ixswCWp6J2VGZVAX64acknlv2Q0z02ebjmhw=="], - - "@aws-sdk/client-sts/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.775.0", "", { "dependencies": { "@aws-sdk/core": "3.775.0", "@aws-sdk/types": "3.775.0", "@smithy/property-provider": "^4.0.2", "@smithy/shared-ini-file-loader": "^4.0.2", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-A6k68H9rQp+2+7P7SGO90Csw6nrUEm0Qfjpn9Etc4EboZhhCLs9b66umUsTsSBHus4FDIe5JQxfCUyt1wgNogg=="], - - "@aws-sdk/client-sts/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.782.0", "", { "dependencies": { "@aws-sdk/client-sso": "3.782.0", "@aws-sdk/core": "3.775.0", "@aws-sdk/token-providers": "3.782.0", "@aws-sdk/types": "3.775.0", "@smithy/property-provider": "^4.0.2", "@smithy/shared-ini-file-loader": "^4.0.2", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-1y1ucxTtTIGDSNSNxriQY8msinilhe9gGvQpUDYW9gboyC7WQJPDw66imy258V6osdtdi+xoHzVCbCz3WhosMQ=="], - - "@aws-sdk/client-sts/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.782.0", "", { "dependencies": { "@aws-sdk/core": "3.775.0", "@aws-sdk/nested-clients": "3.782.0", "@aws-sdk/types": "3.775.0", "@smithy/property-provider": "^4.0.2", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-xCna0opVPaueEbJoclj5C6OpDNi0Gynj+4d7tnuXGgQhTHPyAz8ZyClkVqpi5qvHTgxROdUEDxWqEO5jqRHZHQ=="], - - "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/nested-clients/@aws-sdk/core": ["@aws-sdk/core@3.973.27", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@aws-sdk/xml-builder": "^3.972.17", "@smithy/core": "^3.23.14", "@smithy/node-config-provider": "^4.3.13", "@smithy/property-provider": "^4.2.13", "@smithy/protocol-http": "^5.3.13", "@smithy/signature-v4": "^5.3.13", "@smithy/smithy-client": "^4.12.9", "@smithy/types": "^4.14.0", "@smithy/util-base64": "^4.3.2", "@smithy/util-middleware": "^4.2.13", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-CUZ5m8hwMCH6OYI4Li/WgMfIEx10Q2PLI9Y3XOUTPGZJ53aZ0007jCv+X/ywsaERyKPdw5MRZWk877roQksQ4A=="], - - "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/nested-clients/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-je5vRdNw4SkuTnmRbFZLdye4sQ0faLt8kwka5wnnSU30q1mHO4X+idGEJOOE+Tn1ME7Oryn05xxkDvIb3UaLaQ=="], - - "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/nested-clients/@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-HsVgDrruhqI28RkaXALm8grJ7Agc1wF6Et0xh6pom8NdO2VdO/SD9U/tPwUjewwK/pVoka+EShBxyCvgsPCtog=="], - - "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/nested-clients/@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.972.10", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-RVQQbq5orQ/GHUnXvqEOj2HHPBJm+mM+ySwZKS5UaLBwra5ugRtiH09PLUoOZRl7a1YzaOzXSuGbn9iD5j60WQ=="], - - "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/nested-clients/@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.972.29", "", { "dependencies": { "@aws-sdk/core": "^3.973.27", "@aws-sdk/types": "^3.973.7", "@aws-sdk/util-endpoints": "^3.996.6", "@smithy/core": "^3.23.14", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "@smithy/util-retry": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-f/sIRzuTfEjg6NsbMYvye2VsmnQoNgntntleQyx5uGacUYzszbfIlO3GcI6G6daWUmTm0IDZc11qMHWwF0o0mQ=="], - - "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/nested-clients/@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.972.11", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/config-resolver": "^4.4.14", "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-6Q8B1dcx6BBqUTY1Mc/eROKA0FImEEY5VPSd6AGPEUf0ErjExz4snVqa9kNJSoVDV1rKaNf3qrWojgcKW+SdDg=="], - - "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/nested-clients/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.996.6", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "@smithy/util-endpoints": "^3.3.4", "tslib": "^2.6.2" } }, "sha512-2nUQ+2ih7CShuKHpGSIYvvAIOHy52dOZguYG36zptBukhw6iFwcvGfG0tes0oZFWQqEWvgZe9HLWaNlvXGdOrg=="], - - "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/nested-clients/@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-sn/LMzTbGjYqCCF24390WxPd6hkpoSptiUn5DzVp4cD71yqw+yGEGm1YCxyEoPXyc8qciM8UzLJcZBFslxo5Uw=="], - - "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/nested-clients/@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.973.15", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "^3.972.29", "@aws-sdk/types": "^3.973.7", "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "@smithy/util-config-provider": "^4.2.2", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-fYn3s9PtKdgQkczGZCFMgkNEe8aq1JCVbnRqjqN9RSVW43xn2RV9xdcZ3z01a48Jpkuh/xCmBKJxdLOo4Ozg7w=="], - - "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/nested-clients/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - - "@aws-sdk/credential-provider-env/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.17", "", { "dependencies": { "@smithy/types": "^4.14.0", "fast-xml-parser": "5.5.8", "tslib": "^2.6.2" } }, "sha512-Ra7hjqAZf1OXRRMueB13qex7mFJRDK/pgCvdSFemXBT8KCGnQDPoKzHY1SjN+TjJVmnpSF14W5tJ1vDamFu+Gg=="], - - "@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - - "@aws-sdk/credential-provider-http/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.17", "", { "dependencies": { "@smithy/types": "^4.14.0", "fast-xml-parser": "5.5.8", "tslib": "^2.6.2" } }, "sha512-Ra7hjqAZf1OXRRMueB13qex7mFJRDK/pgCvdSFemXBT8KCGnQDPoKzHY1SjN+TjJVmnpSF14W5tJ1vDamFu+Gg=="], - - "@aws-sdk/credential-provider-http/@aws-sdk/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - - "@aws-sdk/credential-provider-ini/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.17", "", { "dependencies": { "@smithy/types": "^4.14.0", "fast-xml-parser": "5.5.8", "tslib": "^2.6.2" } }, "sha512-Ra7hjqAZf1OXRRMueB13qex7mFJRDK/pgCvdSFemXBT8KCGnQDPoKzHY1SjN+TjJVmnpSF14W5tJ1vDamFu+Gg=="], - - "@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - - "@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-je5vRdNw4SkuTnmRbFZLdye4sQ0faLt8kwka5wnnSU30q1mHO4X+idGEJOOE+Tn1ME7Oryn05xxkDvIb3UaLaQ=="], - - "@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-HsVgDrruhqI28RkaXALm8grJ7Agc1wF6Et0xh6pom8NdO2VdO/SD9U/tPwUjewwK/pVoka+EShBxyCvgsPCtog=="], - - "@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.972.10", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-RVQQbq5orQ/GHUnXvqEOj2HHPBJm+mM+ySwZKS5UaLBwra5ugRtiH09PLUoOZRl7a1YzaOzXSuGbn9iD5j60WQ=="], - - "@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.972.29", "", { "dependencies": { "@aws-sdk/core": "^3.973.27", "@aws-sdk/types": "^3.973.7", "@aws-sdk/util-endpoints": "^3.996.6", "@smithy/core": "^3.23.14", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "@smithy/util-retry": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-f/sIRzuTfEjg6NsbMYvye2VsmnQoNgntntleQyx5uGacUYzszbfIlO3GcI6G6daWUmTm0IDZc11qMHWwF0o0mQ=="], - - "@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.972.11", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/config-resolver": "^4.4.14", "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-6Q8B1dcx6BBqUTY1Mc/eROKA0FImEEY5VPSd6AGPEUf0ErjExz4snVqa9kNJSoVDV1rKaNf3qrWojgcKW+SdDg=="], - - "@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.996.6", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "@smithy/util-endpoints": "^3.3.4", "tslib": "^2.6.2" } }, "sha512-2nUQ+2ih7CShuKHpGSIYvvAIOHy52dOZguYG36zptBukhw6iFwcvGfG0tes0oZFWQqEWvgZe9HLWaNlvXGdOrg=="], - - "@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-sn/LMzTbGjYqCCF24390WxPd6hkpoSptiUn5DzVp4cD71yqw+yGEGm1YCxyEoPXyc8qciM8UzLJcZBFslxo5Uw=="], - - "@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.973.15", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "^3.972.29", "@aws-sdk/types": "^3.973.7", "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "@smithy/util-config-provider": "^4.2.2", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-fYn3s9PtKdgQkczGZCFMgkNEe8aq1JCVbnRqjqN9RSVW43xn2RV9xdcZ3z01a48Jpkuh/xCmBKJxdLOo4Ozg7w=="], - - "@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - - "@aws-sdk/credential-provider-login/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.17", "", { "dependencies": { "@smithy/types": "^4.14.0", "fast-xml-parser": "5.5.8", "tslib": "^2.6.2" } }, "sha512-Ra7hjqAZf1OXRRMueB13qex7mFJRDK/pgCvdSFemXBT8KCGnQDPoKzHY1SjN+TjJVmnpSF14W5tJ1vDamFu+Gg=="], - - "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - - "@aws-sdk/credential-provider-login/@aws-sdk/nested-clients/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-je5vRdNw4SkuTnmRbFZLdye4sQ0faLt8kwka5wnnSU30q1mHO4X+idGEJOOE+Tn1ME7Oryn05xxkDvIb3UaLaQ=="], - - "@aws-sdk/credential-provider-login/@aws-sdk/nested-clients/@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-HsVgDrruhqI28RkaXALm8grJ7Agc1wF6Et0xh6pom8NdO2VdO/SD9U/tPwUjewwK/pVoka+EShBxyCvgsPCtog=="], - - "@aws-sdk/credential-provider-login/@aws-sdk/nested-clients/@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.972.10", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-RVQQbq5orQ/GHUnXvqEOj2HHPBJm+mM+ySwZKS5UaLBwra5ugRtiH09PLUoOZRl7a1YzaOzXSuGbn9iD5j60WQ=="], - - "@aws-sdk/credential-provider-login/@aws-sdk/nested-clients/@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.972.29", "", { "dependencies": { "@aws-sdk/core": "^3.973.27", "@aws-sdk/types": "^3.973.7", "@aws-sdk/util-endpoints": "^3.996.6", "@smithy/core": "^3.23.14", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "@smithy/util-retry": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-f/sIRzuTfEjg6NsbMYvye2VsmnQoNgntntleQyx5uGacUYzszbfIlO3GcI6G6daWUmTm0IDZc11qMHWwF0o0mQ=="], - - "@aws-sdk/credential-provider-login/@aws-sdk/nested-clients/@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.972.11", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/config-resolver": "^4.4.14", "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-6Q8B1dcx6BBqUTY1Mc/eROKA0FImEEY5VPSd6AGPEUf0ErjExz4snVqa9kNJSoVDV1rKaNf3qrWojgcKW+SdDg=="], - - "@aws-sdk/credential-provider-login/@aws-sdk/nested-clients/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.996.6", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "@smithy/util-endpoints": "^3.3.4", "tslib": "^2.6.2" } }, "sha512-2nUQ+2ih7CShuKHpGSIYvvAIOHy52dOZguYG36zptBukhw6iFwcvGfG0tes0oZFWQqEWvgZe9HLWaNlvXGdOrg=="], - - "@aws-sdk/credential-provider-login/@aws-sdk/nested-clients/@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-sn/LMzTbGjYqCCF24390WxPd6hkpoSptiUn5DzVp4cD71yqw+yGEGm1YCxyEoPXyc8qciM8UzLJcZBFslxo5Uw=="], - - "@aws-sdk/credential-provider-login/@aws-sdk/nested-clients/@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.973.15", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "^3.972.29", "@aws-sdk/types": "^3.973.7", "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "@smithy/util-config-provider": "^4.2.2", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-fYn3s9PtKdgQkczGZCFMgkNEe8aq1JCVbnRqjqN9RSVW43xn2RV9xdcZ3z01a48Jpkuh/xCmBKJxdLOo4Ozg7w=="], - - "@aws-sdk/credential-provider-login/@aws-sdk/nested-clients/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - - "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.933.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.932.0", "@aws-sdk/middleware-host-header": "3.930.0", "@aws-sdk/middleware-logger": "3.930.0", "@aws-sdk/middleware-recursion-detection": "3.933.0", "@aws-sdk/middleware-user-agent": "3.932.0", "@aws-sdk/region-config-resolver": "3.930.0", "@aws-sdk/types": "3.930.0", "@aws-sdk/util-endpoints": "3.930.0", "@aws-sdk/util-user-agent-browser": "3.930.0", "@aws-sdk/util-user-agent-node": "3.932.0", "@smithy/config-resolver": "^4.4.3", "@smithy/core": "^3.18.2", "@smithy/fetch-http-handler": "^5.3.6", "@smithy/hash-node": "^4.2.5", "@smithy/invalid-dependency": "^4.2.5", "@smithy/middleware-content-length": "^4.2.5", "@smithy/middleware-endpoint": "^4.3.9", "@smithy/middleware-retry": "^4.4.9", "@smithy/middleware-serde": "^4.2.5", "@smithy/middleware-stack": "^4.2.5", "@smithy/node-config-provider": "^4.3.5", "@smithy/node-http-handler": "^4.4.5", "@smithy/protocol-http": "^5.3.5", "@smithy/smithy-client": "^4.9.5", "@smithy/types": "^4.9.0", "@smithy/url-parser": "^4.2.5", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.8", "@smithy/util-defaults-mode-node": "^4.2.11", "@smithy/util-endpoints": "^3.2.5", "@smithy/util-middleware": "^4.2.5", "@smithy/util-retry": "^4.2.5", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-o1GX0+IPlFi/D8ei9y/jj3yucJWNfPnbB5appVBWevAyUdZA5KzQ2nK/hDxiu9olTZlFEFpf1m1Rn3FaGxHqsw=="], - - "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.933.0", "", { "dependencies": { "@aws-sdk/core": "3.932.0", "@aws-sdk/nested-clients": "3.933.0", "@aws-sdk/types": "3.930.0", "@smithy/property-provider": "^4.2.5", "@smithy/shared-ini-file-loader": "^4.4.0", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-Qzq7zj9yXUgAAJEbbmqRhm0jmUndl8nHG0AbxFEfCfQRVZWL96Qzx0mf8lYwT9hIMrXncLwy31HOthmbXwFRwQ=="], - - "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.933.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.932.0", "@aws-sdk/middleware-host-header": "3.930.0", "@aws-sdk/middleware-logger": "3.930.0", "@aws-sdk/middleware-recursion-detection": "3.933.0", "@aws-sdk/middleware-user-agent": "3.932.0", "@aws-sdk/region-config-resolver": "3.930.0", "@aws-sdk/types": "3.930.0", "@aws-sdk/util-endpoints": "3.930.0", "@aws-sdk/util-user-agent-browser": "3.930.0", "@aws-sdk/util-user-agent-node": "3.932.0", "@smithy/config-resolver": "^4.4.3", "@smithy/core": "^3.18.2", "@smithy/fetch-http-handler": "^5.3.6", "@smithy/hash-node": "^4.2.5", "@smithy/invalid-dependency": "^4.2.5", "@smithy/middleware-content-length": "^4.2.5", "@smithy/middleware-endpoint": "^4.3.9", "@smithy/middleware-retry": "^4.4.9", "@smithy/middleware-serde": "^4.2.5", "@smithy/middleware-stack": "^4.2.5", "@smithy/node-config-provider": "^4.3.5", "@smithy/node-http-handler": "^4.4.5", "@smithy/protocol-http": "^5.3.5", "@smithy/smithy-client": "^4.9.5", "@smithy/types": "^4.9.0", "@smithy/url-parser": "^4.2.5", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.8", "@smithy/util-defaults-mode-node": "^4.2.11", "@smithy/util-endpoints": "^3.2.5", "@smithy/util-middleware": "^4.2.5", "@smithy/util-retry": "^4.2.5", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-o1GX0+IPlFi/D8ei9y/jj3yucJWNfPnbB5appVBWevAyUdZA5KzQ2nK/hDxiu9olTZlFEFpf1m1Rn3FaGxHqsw=="], - - "@aws-sdk/credential-provider-process/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.17", "", { "dependencies": { "@smithy/types": "^4.14.0", "fast-xml-parser": "5.5.8", "tslib": "^2.6.2" } }, "sha512-Ra7hjqAZf1OXRRMueB13qex7mFJRDK/pgCvdSFemXBT8KCGnQDPoKzHY1SjN+TjJVmnpSF14W5tJ1vDamFu+Gg=="], - - "@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - - "@aws-sdk/credential-provider-sso/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.17", "", { "dependencies": { "@smithy/types": "^4.14.0", "fast-xml-parser": "5.5.8", "tslib": "^2.6.2" } }, "sha512-Ra7hjqAZf1OXRRMueB13qex7mFJRDK/pgCvdSFemXBT8KCGnQDPoKzHY1SjN+TjJVmnpSF14W5tJ1vDamFu+Gg=="], - - "@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - - "@aws-sdk/credential-provider-sso/@aws-sdk/nested-clients/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-je5vRdNw4SkuTnmRbFZLdye4sQ0faLt8kwka5wnnSU30q1mHO4X+idGEJOOE+Tn1ME7Oryn05xxkDvIb3UaLaQ=="], - - "@aws-sdk/credential-provider-sso/@aws-sdk/nested-clients/@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-HsVgDrruhqI28RkaXALm8grJ7Agc1wF6Et0xh6pom8NdO2VdO/SD9U/tPwUjewwK/pVoka+EShBxyCvgsPCtog=="], - - "@aws-sdk/credential-provider-sso/@aws-sdk/nested-clients/@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.972.10", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-RVQQbq5orQ/GHUnXvqEOj2HHPBJm+mM+ySwZKS5UaLBwra5ugRtiH09PLUoOZRl7a1YzaOzXSuGbn9iD5j60WQ=="], - - "@aws-sdk/credential-provider-sso/@aws-sdk/nested-clients/@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.972.29", "", { "dependencies": { "@aws-sdk/core": "^3.973.27", "@aws-sdk/types": "^3.973.7", "@aws-sdk/util-endpoints": "^3.996.6", "@smithy/core": "^3.23.14", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "@smithy/util-retry": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-f/sIRzuTfEjg6NsbMYvye2VsmnQoNgntntleQyx5uGacUYzszbfIlO3GcI6G6daWUmTm0IDZc11qMHWwF0o0mQ=="], - - "@aws-sdk/credential-provider-sso/@aws-sdk/nested-clients/@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.972.11", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/config-resolver": "^4.4.14", "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-6Q8B1dcx6BBqUTY1Mc/eROKA0FImEEY5VPSd6AGPEUf0ErjExz4snVqa9kNJSoVDV1rKaNf3qrWojgcKW+SdDg=="], - - "@aws-sdk/credential-provider-sso/@aws-sdk/nested-clients/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.996.6", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "@smithy/util-endpoints": "^3.3.4", "tslib": "^2.6.2" } }, "sha512-2nUQ+2ih7CShuKHpGSIYvvAIOHy52dOZguYG36zptBukhw6iFwcvGfG0tes0oZFWQqEWvgZe9HLWaNlvXGdOrg=="], - - "@aws-sdk/credential-provider-sso/@aws-sdk/nested-clients/@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-sn/LMzTbGjYqCCF24390WxPd6hkpoSptiUn5DzVp4cD71yqw+yGEGm1YCxyEoPXyc8qciM8UzLJcZBFslxo5Uw=="], - - "@aws-sdk/credential-provider-sso/@aws-sdk/nested-clients/@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.973.15", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "^3.972.29", "@aws-sdk/types": "^3.973.7", "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "@smithy/util-config-provider": "^4.2.2", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-fYn3s9PtKdgQkczGZCFMgkNEe8aq1JCVbnRqjqN9RSVW43xn2RV9xdcZ3z01a48Jpkuh/xCmBKJxdLOo4Ozg7w=="], - - "@aws-sdk/credential-provider-sso/@aws-sdk/nested-clients/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - - "@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.17", "", { "dependencies": { "@smithy/types": "^4.14.0", "fast-xml-parser": "5.5.8", "tslib": "^2.6.2" } }, "sha512-Ra7hjqAZf1OXRRMueB13qex7mFJRDK/pgCvdSFemXBT8KCGnQDPoKzHY1SjN+TjJVmnpSF14W5tJ1vDamFu+Gg=="], - - "@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - - "@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-je5vRdNw4SkuTnmRbFZLdye4sQ0faLt8kwka5wnnSU30q1mHO4X+idGEJOOE+Tn1ME7Oryn05xxkDvIb3UaLaQ=="], - - "@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-HsVgDrruhqI28RkaXALm8grJ7Agc1wF6Et0xh6pom8NdO2VdO/SD9U/tPwUjewwK/pVoka+EShBxyCvgsPCtog=="], - - "@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.972.10", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-RVQQbq5orQ/GHUnXvqEOj2HHPBJm+mM+ySwZKS5UaLBwra5ugRtiH09PLUoOZRl7a1YzaOzXSuGbn9iD5j60WQ=="], - - "@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.972.29", "", { "dependencies": { "@aws-sdk/core": "^3.973.27", "@aws-sdk/types": "^3.973.7", "@aws-sdk/util-endpoints": "^3.996.6", "@smithy/core": "^3.23.14", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "@smithy/util-retry": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-f/sIRzuTfEjg6NsbMYvye2VsmnQoNgntntleQyx5uGacUYzszbfIlO3GcI6G6daWUmTm0IDZc11qMHWwF0o0mQ=="], - - "@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.972.11", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/config-resolver": "^4.4.14", "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-6Q8B1dcx6BBqUTY1Mc/eROKA0FImEEY5VPSd6AGPEUf0ErjExz4snVqa9kNJSoVDV1rKaNf3qrWojgcKW+SdDg=="], - - "@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.996.6", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "@smithy/util-endpoints": "^3.3.4", "tslib": "^2.6.2" } }, "sha512-2nUQ+2ih7CShuKHpGSIYvvAIOHy52dOZguYG36zptBukhw6iFwcvGfG0tes0oZFWQqEWvgZe9HLWaNlvXGdOrg=="], - - "@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-sn/LMzTbGjYqCCF24390WxPd6hkpoSptiUn5DzVp4cD71yqw+yGEGm1YCxyEoPXyc8qciM8UzLJcZBFslxo5Uw=="], - - "@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.973.15", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "^3.972.29", "@aws-sdk/types": "^3.973.7", "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "@smithy/util-config-provider": "^4.2.2", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-fYn3s9PtKdgQkczGZCFMgkNEe8aq1JCVbnRqjqN9RSVW43xn2RV9xdcZ3z01a48Jpkuh/xCmBKJxdLOo4Ozg7w=="], - - "@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - - "@aws-sdk/credential-providers/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.17", "", { "dependencies": { "@smithy/types": "^4.14.0", "fast-xml-parser": "5.5.8", "tslib": "^2.6.2" } }, "sha512-Ra7hjqAZf1OXRRMueB13qex7mFJRDK/pgCvdSFemXBT8KCGnQDPoKzHY1SjN+TjJVmnpSF14W5tJ1vDamFu+Gg=="], - - "@aws-sdk/credential-providers/@aws-sdk/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - - "@aws-sdk/nested-clients/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.17", "", { "dependencies": { "@smithy/types": "^4.14.0", "fast-xml-parser": "5.5.8", "tslib": "^2.6.2" } }, "sha512-Ra7hjqAZf1OXRRMueB13qex7mFJRDK/pgCvdSFemXBT8KCGnQDPoKzHY1SjN+TjJVmnpSF14W5tJ1vDamFu+Gg=="], - - "@aws-sdk/nested-clients/@aws-sdk/middleware-user-agent/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.996.6", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "@smithy/util-endpoints": "^3.3.4", "tslib": "^2.6.2" } }, "sha512-2nUQ+2ih7CShuKHpGSIYvvAIOHy52dOZguYG36zptBukhw6iFwcvGfG0tes0oZFWQqEWvgZe9HLWaNlvXGdOrg=="], - - "@aws-sdk/token-providers/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.17", "", { "dependencies": { "@smithy/types": "^4.14.0", "fast-xml-parser": "5.5.8", "tslib": "^2.6.2" } }, "sha512-Ra7hjqAZf1OXRRMueB13qex7mFJRDK/pgCvdSFemXBT8KCGnQDPoKzHY1SjN+TjJVmnpSF14W5tJ1vDamFu+Gg=="], - - "@aws-sdk/token-providers/@aws-sdk/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - - "@aws-sdk/token-providers/@aws-sdk/nested-clients/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-je5vRdNw4SkuTnmRbFZLdye4sQ0faLt8kwka5wnnSU30q1mHO4X+idGEJOOE+Tn1ME7Oryn05xxkDvIb3UaLaQ=="], - - "@aws-sdk/token-providers/@aws-sdk/nested-clients/@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-HsVgDrruhqI28RkaXALm8grJ7Agc1wF6Et0xh6pom8NdO2VdO/SD9U/tPwUjewwK/pVoka+EShBxyCvgsPCtog=="], - - "@aws-sdk/token-providers/@aws-sdk/nested-clients/@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.972.10", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-RVQQbq5orQ/GHUnXvqEOj2HHPBJm+mM+ySwZKS5UaLBwra5ugRtiH09PLUoOZRl7a1YzaOzXSuGbn9iD5j60WQ=="], - - "@aws-sdk/token-providers/@aws-sdk/nested-clients/@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.972.29", "", { "dependencies": { "@aws-sdk/core": "^3.973.27", "@aws-sdk/types": "^3.973.7", "@aws-sdk/util-endpoints": "^3.996.6", "@smithy/core": "^3.23.14", "@smithy/protocol-http": "^5.3.13", "@smithy/types": "^4.14.0", "@smithy/util-retry": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-f/sIRzuTfEjg6NsbMYvye2VsmnQoNgntntleQyx5uGacUYzszbfIlO3GcI6G6daWUmTm0IDZc11qMHWwF0o0mQ=="], - - "@aws-sdk/token-providers/@aws-sdk/nested-clients/@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.972.11", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/config-resolver": "^4.4.14", "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "tslib": "^2.6.2" } }, "sha512-6Q8B1dcx6BBqUTY1Mc/eROKA0FImEEY5VPSd6AGPEUf0ErjExz4snVqa9kNJSoVDV1rKaNf3qrWojgcKW+SdDg=="], - - "@aws-sdk/token-providers/@aws-sdk/nested-clients/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.996.6", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "@smithy/url-parser": "^4.2.13", "@smithy/util-endpoints": "^3.3.4", "tslib": "^2.6.2" } }, "sha512-2nUQ+2ih7CShuKHpGSIYvvAIOHy52dOZguYG36zptBukhw6iFwcvGfG0tes0oZFWQqEWvgZe9HLWaNlvXGdOrg=="], - - "@aws-sdk/token-providers/@aws-sdk/nested-clients/@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.7", "@smithy/types": "^4.14.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-sn/LMzTbGjYqCCF24390WxPd6hkpoSptiUn5DzVp4cD71yqw+yGEGm1YCxyEoPXyc8qciM8UzLJcZBFslxo5Uw=="], - - "@aws-sdk/token-providers/@aws-sdk/nested-clients/@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.973.15", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "^3.972.29", "@aws-sdk/types": "^3.973.7", "@smithy/node-config-provider": "^4.3.13", "@smithy/types": "^4.14.0", "@smithy/util-config-provider": "^4.2.2", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-fYn3s9PtKdgQkczGZCFMgkNEe8aq1JCVbnRqjqN9RSVW43xn2RV9xdcZ3z01a48Jpkuh/xCmBKJxdLOo4Ozg7w=="], - - "@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - - "@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.2.3", "", {}, "sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg=="], - - "@azure/core-http/xml2js/sax": ["sax@1.6.0", "", {}, "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA=="], - - "@azure/core-xml/fast-xml-parser/strnum": ["strnum@2.2.3", "", {}, "sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg=="], - - "@azure/identity/open/wsl-utils": ["wsl-utils@0.1.0", "", { "dependencies": { "is-wsl": "^3.1.0" } }, "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw=="], - - "@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], - - "@develar/schema-utils/ajv/json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], - - "@electron/asar/minimatch/brace-expansion": ["brace-expansion@1.1.14", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g=="], - - "@electron/fuses/fs-extra/jsonfile": ["jsonfile@6.2.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg=="], - - "@electron/get/fs-extra/universalify": ["universalify@0.1.2", "", {}, "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="], - - "@electron/notarize/fs-extra/jsonfile": ["jsonfile@6.2.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg=="], - - "@electron/rebuild/node-gyp/make-fetch-happen": ["make-fetch-happen@14.0.3", "", { "dependencies": { "@npmcli/agent": "^3.0.0", "cacache": "^19.0.1", "http-cache-semantics": "^4.1.1", "minipass": "^7.0.2", "minipass-fetch": "^4.0.0", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "negotiator": "^1.0.0", "proc-log": "^5.0.0", "promise-retry": "^2.0.1", "ssri": "^12.0.0" } }, "sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ=="], - - "@electron/rebuild/node-gyp/nopt": ["nopt@8.1.0", "", { "dependencies": { "abbrev": "^3.0.0" }, "bin": { "nopt": "bin/nopt.js" } }, "sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A=="], - - "@electron/rebuild/node-gyp/proc-log": ["proc-log@5.0.0", "", {}, "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ=="], - - "@electron/rebuild/node-gyp/which": ["which@5.0.0", "", { "dependencies": { "isexe": "^3.1.1" }, "bin": { "node-which": "bin/which.js" } }, "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ=="], - - "@electron/rebuild/yargs/cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="], - - "@electron/rebuild/yargs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], - - "@electron/universal/fs-extra/jsonfile": ["jsonfile@6.2.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg=="], - - "@electron/universal/minimatch/brace-expansion": ["brace-expansion@2.1.0", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w=="], - - "@electron/windows-sign/fs-extra/jsonfile": ["jsonfile@6.2.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg=="], - - "@expressive-code/plugin-shiki/shiki/@shikijs/core": ["@shikijs/core@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA=="], - - "@expressive-code/plugin-shiki/shiki/@shikijs/engine-javascript": ["@shikijs/engine-javascript@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.4" } }, "sha512-aHt9eiGFobmWR5uqJUViySI1bHMqrAgamWE1TYSUoftkAeCCAiGawPMwM+VCadylQtF4V3VNOZ5LmfItH5f3yA=="], - - "@expressive-code/plugin-shiki/shiki/@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g=="], - - "@expressive-code/plugin-shiki/shiki/@shikijs/langs": ["@shikijs/langs@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0" } }, "sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg=="], - - "@expressive-code/plugin-shiki/shiki/@shikijs/themes": ["@shikijs/themes@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0" } }, "sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA=="], - - "@expressive-code/plugin-shiki/shiki/@shikijs/types": ["@shikijs/types@3.23.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ=="], - - "@gitlab/opencode-gitlab-auth/open/wsl-utils": ["wsl-utils@0.1.0", "", { "dependencies": { "is-wsl": "^3.1.0" } }, "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw=="], - - "@happy-dom/global-registrator/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@jsx-email/cli/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.19.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA=="], - - "@jsx-email/cli/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.19.12", "", { "os": "android", "cpu": "arm" }, "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w=="], - - "@jsx-email/cli/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.19.12", "", { "os": "android", "cpu": "arm64" }, "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA=="], - - "@jsx-email/cli/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.19.12", "", { "os": "android", "cpu": "x64" }, "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew=="], - - "@jsx-email/cli/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.19.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g=="], - - "@jsx-email/cli/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.19.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A=="], - - "@jsx-email/cli/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.19.12", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA=="], - - "@jsx-email/cli/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.19.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg=="], - - "@jsx-email/cli/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.19.12", "", { "os": "linux", "cpu": "arm" }, "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w=="], - - "@jsx-email/cli/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.19.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA=="], - - "@jsx-email/cli/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.19.12", "", { "os": "linux", "cpu": "ia32" }, "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA=="], - - "@jsx-email/cli/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.19.12", "", { "os": "linux", "cpu": "none" }, "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA=="], - - "@jsx-email/cli/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.19.12", "", { "os": "linux", "cpu": "none" }, "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w=="], - - "@jsx-email/cli/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.19.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg=="], - - "@jsx-email/cli/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.19.12", "", { "os": "linux", "cpu": "none" }, "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg=="], - - "@jsx-email/cli/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.19.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg=="], - - "@jsx-email/cli/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.19.12", "", { "os": "linux", "cpu": "x64" }, "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg=="], - - "@jsx-email/cli/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.19.12", "", { "os": "none", "cpu": "x64" }, "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA=="], - - "@jsx-email/cli/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.19.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw=="], - - "@jsx-email/cli/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.19.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA=="], - - "@jsx-email/cli/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.19.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A=="], - - "@jsx-email/cli/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.19.12", "", { "os": "win32", "cpu": "ia32" }, "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ=="], - - "@jsx-email/cli/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.19.12", "", { "os": "win32", "cpu": "x64" }, "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA=="], - - "@jsx-email/cli/tailwindcss/chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="], - - "@jsx-email/cli/tailwindcss/glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="], - - "@jsx-email/cli/tailwindcss/jiti": ["jiti@1.21.7", "", { "bin": { "jiti": "bin/jiti.js" } }, "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A=="], - - "@jsx-email/cli/tailwindcss/object-hash": ["object-hash@3.0.0", "", {}, "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw=="], - - "@jsx-email/cli/vite/esbuild": ["esbuild@0.18.20", "", { "optionalDependencies": { "@esbuild/android-arm": "0.18.20", "@esbuild/android-arm64": "0.18.20", "@esbuild/android-x64": "0.18.20", "@esbuild/darwin-arm64": "0.18.20", "@esbuild/darwin-x64": "0.18.20", "@esbuild/freebsd-arm64": "0.18.20", "@esbuild/freebsd-x64": "0.18.20", "@esbuild/linux-arm": "0.18.20", "@esbuild/linux-arm64": "0.18.20", "@esbuild/linux-ia32": "0.18.20", "@esbuild/linux-loong64": "0.18.20", "@esbuild/linux-mips64el": "0.18.20", "@esbuild/linux-ppc64": "0.18.20", "@esbuild/linux-riscv64": "0.18.20", "@esbuild/linux-s390x": "0.18.20", "@esbuild/linux-x64": "0.18.20", "@esbuild/netbsd-x64": "0.18.20", "@esbuild/openbsd-x64": "0.18.20", "@esbuild/sunos-x64": "0.18.20", "@esbuild/win32-arm64": "0.18.20", "@esbuild/win32-ia32": "0.18.20", "@esbuild/win32-x64": "0.18.20" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA=="], - - "@jsx-email/cli/vite/rollup": ["rollup@3.30.0", "", { "optionalDependencies": { "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-kQvGasUgN+AlWGliFn2POSajRQEsULVYFGTvOZmK06d7vCD+YhZztt70kGk3qaeAXeWYL5eO7zx+rAubBc55eA=="], - - "@jsx-email/doiuse-email/htmlparser2/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], - - "@malept/flatpak-bundler/fs-extra/jsonfile": ["jsonfile@6.2.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg=="], - - "@modelcontextprotocol/sdk/express/accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="], - - "@modelcontextprotocol/sdk/express/body-parser": ["body-parser@2.2.2", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.3", "http-errors": "^2.0.0", "iconv-lite": "^0.7.0", "on-finished": "^2.4.1", "qs": "^6.14.1", "raw-body": "^3.0.1", "type-is": "^2.0.1" } }, "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA=="], - - "@modelcontextprotocol/sdk/express/content-disposition": ["content-disposition@1.1.0", "", {}, "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g=="], - - "@modelcontextprotocol/sdk/express/cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="], - - "@modelcontextprotocol/sdk/express/cookie-signature": ["cookie-signature@1.2.2", "", {}, "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg=="], - - "@modelcontextprotocol/sdk/express/finalhandler": ["finalhandler@2.1.1", "", { "dependencies": { "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "on-finished": "^2.4.1", "parseurl": "^1.3.3", "statuses": "^2.0.1" } }, "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA=="], - - "@modelcontextprotocol/sdk/express/fresh": ["fresh@2.0.0", "", {}, "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A=="], - - "@modelcontextprotocol/sdk/express/merge-descriptors": ["merge-descriptors@2.0.0", "", {}, "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g=="], - - "@modelcontextprotocol/sdk/express/send": ["send@1.2.1", "", { "dependencies": { "debug": "^4.4.3", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.1", "mime-types": "^3.0.2", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.2" } }, "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ=="], - - "@modelcontextprotocol/sdk/express/serve-static": ["serve-static@2.2.1", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw=="], - - "@modelcontextprotocol/sdk/express/type-is": ["type-is@2.0.1", "", { "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw=="], + "@hey-api/shared/open/wsl-utils": ["wsl-utils@0.3.1", "", { "dependencies": { "is-wsl": "^3.1.0", "powershell-utils": "^0.1.0" } }, "sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg=="], "@octokit/auth-app/@octokit/request/@octokit/endpoint": ["@octokit/endpoint@11.0.3", "", { "dependencies": { "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag=="], @@ -6560,449 +3728,157 @@ "@octokit/auth-app/@octokit/request-error/@octokit/types": ["@octokit/types@16.0.0", "", { "dependencies": { "@octokit/openapi-types": "^27.0.0" } }, "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg=="], - "@octokit/auth-oauth-app/@octokit/request/@octokit/endpoint": ["@octokit/endpoint@11.0.3", "", { "dependencies": { "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag=="], - - "@octokit/auth-oauth-app/@octokit/request/@octokit/request-error": ["@octokit/request-error@7.1.0", "", { "dependencies": { "@octokit/types": "^16.0.0" } }, "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw=="], - - "@octokit/auth-oauth-app/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="], - - "@octokit/auth-oauth-device/@octokit/request/@octokit/endpoint": ["@octokit/endpoint@11.0.3", "", { "dependencies": { "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag=="], - - "@octokit/auth-oauth-device/@octokit/request/@octokit/request-error": ["@octokit/request-error@7.1.0", "", { "dependencies": { "@octokit/types": "^16.0.0" } }, "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw=="], - - "@octokit/auth-oauth-device/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="], - - "@octokit/auth-oauth-user/@octokit/request/@octokit/endpoint": ["@octokit/endpoint@11.0.3", "", { "dependencies": { "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag=="], - - "@octokit/auth-oauth-user/@octokit/request/@octokit/request-error": ["@octokit/request-error@7.1.0", "", { "dependencies": { "@octokit/types": "^16.0.0" } }, "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw=="], - - "@octokit/auth-oauth-user/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="], - - "@octokit/core/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@24.2.0", "", {}, "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg=="], - - "@octokit/endpoint/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@24.2.0", "", {}, "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg=="], - - "@octokit/graphql/@octokit/request/@octokit/endpoint": ["@octokit/endpoint@11.0.3", "", { "dependencies": { "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag=="], - - "@octokit/graphql/@octokit/request/@octokit/request-error": ["@octokit/request-error@7.1.0", "", { "dependencies": { "@octokit/types": "^16.0.0" } }, "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw=="], - - "@octokit/graphql/@octokit/request/@octokit/types": ["@octokit/types@16.0.0", "", { "dependencies": { "@octokit/openapi-types": "^27.0.0" } }, "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg=="], - - "@octokit/graphql/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@26.0.0", "", {}, "sha512-7AtcfKtpo77j7Ts73b4OWhOZHTKo/gGY8bB3bNBQz4H+GRSWqx2yvj8TXRsbdTE0eRmYmXOEY66jM7mJ7LzfsA=="], - - "@octokit/oauth-methods/@octokit/request/@octokit/endpoint": ["@octokit/endpoint@11.0.3", "", { "dependencies": { "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag=="], - - "@octokit/oauth-methods/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="], - - "@octokit/plugin-paginate-rest/@octokit/core/@octokit/auth-token": ["@octokit/auth-token@6.0.0", "", {}, "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w=="], - - "@octokit/plugin-paginate-rest/@octokit/core/@octokit/graphql": ["@octokit/graphql@9.0.3", "", { "dependencies": { "@octokit/request": "^10.0.6", "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.0" } }, "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA=="], - - "@octokit/plugin-paginate-rest/@octokit/core/@octokit/request": ["@octokit/request@10.0.8", "", { "dependencies": { "@octokit/endpoint": "^11.0.3", "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0", "fast-content-type-parse": "^3.0.0", "json-with-bigint": "^3.5.3", "universal-user-agent": "^7.0.2" } }, "sha512-SJZNwY9pur9Agf7l87ywFi14W+Hd9Jg6Ifivsd33+/bGUQIjNujdFiXII2/qSlN2ybqUHfp5xpekMEjIBTjlSw=="], - - "@octokit/plugin-paginate-rest/@octokit/core/@octokit/request-error": ["@octokit/request-error@7.1.0", "", { "dependencies": { "@octokit/types": "^16.0.0" } }, "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw=="], - - "@octokit/plugin-paginate-rest/@octokit/core/@octokit/types": ["@octokit/types@16.0.0", "", { "dependencies": { "@octokit/openapi-types": "^27.0.0" } }, "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg=="], - - "@octokit/plugin-paginate-rest/@octokit/core/before-after-hook": ["before-after-hook@4.0.0", "", {}, "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ=="], - - "@octokit/plugin-paginate-rest/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@26.0.0", "", {}, "sha512-7AtcfKtpo77j7Ts73b4OWhOZHTKo/gGY8bB3bNBQz4H+GRSWqx2yvj8TXRsbdTE0eRmYmXOEY66jM7mJ7LzfsA=="], - - "@octokit/plugin-rest-endpoint-methods/@octokit/core/@octokit/auth-token": ["@octokit/auth-token@6.0.0", "", {}, "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w=="], - - "@octokit/plugin-rest-endpoint-methods/@octokit/core/@octokit/graphql": ["@octokit/graphql@9.0.3", "", { "dependencies": { "@octokit/request": "^10.0.6", "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.0" } }, "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA=="], - - "@octokit/plugin-rest-endpoint-methods/@octokit/core/@octokit/request": ["@octokit/request@10.0.8", "", { "dependencies": { "@octokit/endpoint": "^11.0.3", "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0", "fast-content-type-parse": "^3.0.0", "json-with-bigint": "^3.5.3", "universal-user-agent": "^7.0.2" } }, "sha512-SJZNwY9pur9Agf7l87ywFi14W+Hd9Jg6Ifivsd33+/bGUQIjNujdFiXII2/qSlN2ybqUHfp5xpekMEjIBTjlSw=="], - - "@octokit/plugin-rest-endpoint-methods/@octokit/core/@octokit/request-error": ["@octokit/request-error@7.1.0", "", { "dependencies": { "@octokit/types": "^16.0.0" } }, "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw=="], - - "@octokit/plugin-rest-endpoint-methods/@octokit/core/@octokit/types": ["@octokit/types@16.0.0", "", { "dependencies": { "@octokit/openapi-types": "^27.0.0" } }, "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg=="], - - "@octokit/plugin-rest-endpoint-methods/@octokit/core/before-after-hook": ["before-after-hook@4.0.0", "", {}, "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ=="], - - "@octokit/plugin-rest-endpoint-methods/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@26.0.0", "", {}, "sha512-7AtcfKtpo77j7Ts73b4OWhOZHTKo/gGY8bB3bNBQz4H+GRSWqx2yvj8TXRsbdTE0eRmYmXOEY66jM7mJ7LzfsA=="], - - "@octokit/plugin-retry/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@12.11.0", "", {}, "sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ=="], - - "@octokit/request-error/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@24.2.0", "", {}, "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg=="], - - "@octokit/request/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@24.2.0", "", {}, "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg=="], - - "@octokit/rest/@octokit/core/@octokit/auth-token": ["@octokit/auth-token@6.0.0", "", {}, "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w=="], - - "@octokit/rest/@octokit/core/@octokit/graphql": ["@octokit/graphql@9.0.3", "", { "dependencies": { "@octokit/request": "^10.0.6", "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.0" } }, "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA=="], - - "@octokit/rest/@octokit/core/@octokit/request": ["@octokit/request@10.0.8", "", { "dependencies": { "@octokit/endpoint": "^11.0.3", "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0", "fast-content-type-parse": "^3.0.0", "json-with-bigint": "^3.5.3", "universal-user-agent": "^7.0.2" } }, "sha512-SJZNwY9pur9Agf7l87ywFi14W+Hd9Jg6Ifivsd33+/bGUQIjNujdFiXII2/qSlN2ybqUHfp5xpekMEjIBTjlSw=="], - - "@octokit/rest/@octokit/core/@octokit/request-error": ["@octokit/request-error@7.1.0", "", { "dependencies": { "@octokit/types": "^16.0.0" } }, "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw=="], - - "@octokit/rest/@octokit/core/@octokit/types": ["@octokit/types@16.0.0", "", { "dependencies": { "@octokit/openapi-types": "^27.0.0" } }, "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg=="], - - "@octokit/rest/@octokit/core/before-after-hook": ["before-after-hook@4.0.0", "", {}, "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ=="], - - "@mendcode/desktop/@actions/artifact/@actions/http-client": ["@actions/http-client@2.2.3", "", { "dependencies": { "tunnel": "^0.0.6", "undici": "^5.25.4" } }, "sha512-mx8hyJi/hjFvbPokCg4uRd4ZX78t+YyRPtnKWwIl+RzNaVuFpQHfmlGVfsKEJN8LwTCvL+DfVgAM04XaHkm6bA=="], - - "@mendcode/web/@shikijs/transformers/@shikijs/core": ["@shikijs/core@3.20.0", "", { "dependencies": { "@shikijs/types": "3.20.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-f2ED7HYV4JEk827mtMDwe/yQ25pRiXZmtHjWF8uzZKuKiEsJR7Ce1nuQ+HhV9FzDcbIo4ObBCD9GPTzNuy9S1g=="], - - "@mendcode/web/@shikijs/transformers/@shikijs/types": ["@shikijs/types@3.20.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-lhYAATn10nkZcBQ0BlzSbJA3wcmL5MXUUF8d2Zzon6saZDlToKaiRX60n2+ZaHJCmXEcZRWNzn+k9vplr8Jhsw=="], - - "@opentui/solid/@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], - - "@pierre/diffs/@shikijs/transformers/@shikijs/core": ["@shikijs/core@3.20.0", "", { "dependencies": { "@shikijs/types": "3.20.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-f2ED7HYV4JEk827mtMDwe/yQ25pRiXZmtHjWF8uzZKuKiEsJR7Ce1nuQ+HhV9FzDcbIo4ObBCD9GPTzNuy9S1g=="], - - "@pierre/diffs/@shikijs/transformers/@shikijs/types": ["@shikijs/types@3.20.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-lhYAATn10nkZcBQ0BlzSbJA3wcmL5MXUUF8d2Zzon6saZDlToKaiRX60n2+ZaHJCmXEcZRWNzn+k9vplr8Jhsw=="], - - "@sentry/bundler-plugin-core/glob/minimatch": ["minimatch@8.0.7", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-V+1uQNdzybxa14e/p00HZnQNNcTjnRJjDxg2V8wtkjFctq4M7hXFws4oekyTP0Jebeq7QYtpFyOeBAjc88zvYg=="], - - "@sentry/bundler-plugin-core/glob/minipass": ["minipass@4.2.8", "", {}, "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ=="], - - "@sentry/bundler-plugin-core/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="], - - "@sentry/cli/https-proxy-agent/agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="], - - "@sentry/cli/which/isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], - - "@slack/logger/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@slack/oauth/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@slack/socket-mode/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@slack/web-api/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@slack/web-api/form-data/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], - - "@slack/web-api/p-queue/eventemitter3": ["eventemitter3@4.0.7", "", {}, "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw=="], - - "@slack/web-api/p-queue/p-timeout": ["p-timeout@3.2.0", "", { "dependencies": { "p-finally": "^1.0.0" } }, "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg=="], - - "@solidjs/start/shiki/@shikijs/core": ["@shikijs/core@1.29.2", "", { "dependencies": { "@shikijs/engine-javascript": "1.29.2", "@shikijs/engine-oniguruma": "1.29.2", "@shikijs/types": "1.29.2", "@shikijs/vscode-textmate": "^10.0.1", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.4" } }, "sha512-vju0lY9r27jJfOY4Z7+Rt/nIOjzJpZ3y+nYpqtUZInVoXQ/TJZcfGnNOGnKjFdVZb8qexiCuSlZRKcGfhhTTZQ=="], - - "@solidjs/start/shiki/@shikijs/engine-javascript": ["@shikijs/engine-javascript@1.29.2", "", { "dependencies": { "@shikijs/types": "1.29.2", "@shikijs/vscode-textmate": "^10.0.1", "oniguruma-to-es": "^2.2.0" } }, "sha512-iNEZv4IrLYPv64Q6k7EPpOCE/nuvGiKl7zxdq0WFuRPF5PAE9PRo2JGq/d8crLusM59BRemJ4eOqrFrC4wiQ+A=="], - - "@solidjs/start/shiki/@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@1.29.2", "", { "dependencies": { "@shikijs/types": "1.29.2", "@shikijs/vscode-textmate": "^10.0.1" } }, "sha512-7iiOx3SG8+g1MnlzZVDYiaeHe7Ez2Kf2HrJzdmGwkRisT7r4rak0e655AcM/tF9JG/kg5fMNYlLLKglbN7gBqA=="], - - "@solidjs/start/shiki/@shikijs/langs": ["@shikijs/langs@1.29.2", "", { "dependencies": { "@shikijs/types": "1.29.2" } }, "sha512-FIBA7N3LZ+223U7cJDUYd5shmciFQlYkFXlkKVaHsCPgfVLiO+e12FmQE6Tf9vuyEsFe3dIl8qGWKXgEHL9wmQ=="], - - "@solidjs/start/shiki/@shikijs/themes": ["@shikijs/themes@1.29.2", "", { "dependencies": { "@shikijs/types": "1.29.2" } }, "sha512-i9TNZlsq4uoyqSbluIcZkmPL9Bfi3djVxRnofUHwvx/h6SRW3cwgBC5SML7vsDcWyukY0eCzVN980rqP6qNl9g=="], - - "@solidjs/start/shiki/@shikijs/types": ["@shikijs/types@1.29.2", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.1", "@types/hast": "^3.0.4" } }, "sha512-VJjK0eIijTZf0QSTODEXCqinjBn0joAHQ+aPSBzrv4O2d/QSbsMw+ZeSRx03kV34Hy7NzUvV/7NqfYGRLrASmw=="], - - "@standard-community/standard-json/effect/@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], - - "@standard-community/standard-openapi/effect/@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], - - "@storybook/csf-plugin/unplugin/webpack-virtual-modules": ["webpack-virtual-modules@0.6.2", "", {}, "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ=="], - - "@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime/@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="], - - "@types/body-parser/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/cacache/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/cacheable-request/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/connect/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/cross-spawn/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/express-serve-static-core/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/fontkit/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/fs-extra/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/is-stream/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/jsonwebtoken/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/keyv/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/mssql/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/node-fetch/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/npm-registry-fetch/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/npmcli__arborist/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/npmlog/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/pacote/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/plist/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/readable-stream/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/responselike/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/sax/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/send/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/serve-static/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/ssri/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/tunnel/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/ws/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/yauzl/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@vitest/expect/@vitest/utils/@vitest/pretty-format": ["@vitest/pretty-format@3.2.4", "", { "dependencies": { "tinyrainbow": "^2.0.0" } }, "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA=="], - - "accepts/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], - - "ai-gateway-provider/@ai-sdk/google/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@4.0.21", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-MtFUYI1/8mgDvRmaBDjbLJPFFrMG777AvSgyIFQtZHIMzm88R/12vYBBpnk7pfiWLFE1DSZzY4WDYzGbKAcmiw=="], - - "ai-gateway-provider/@ai-sdk/google-vertex/@ai-sdk/anthropic": ["@ai-sdk/anthropic@3.0.64", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.21" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-rwLi/Rsuj2pYniQXIrvClHvXDzgM4UQHHnvHTWEF14efnlKclG/1ghpNC+adsRujAbCTr6gRsSbDE2vEqriV7g=="], - - "ai-gateway-provider/@ai-sdk/google-vertex/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@4.0.21", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-MtFUYI1/8mgDvRmaBDjbLJPFFrMG777AvSgyIFQtZHIMzm88R/12vYBBpnk7pfiWLFE1DSZzY4WDYzGbKAcmiw=="], - - "ai-gateway-provider/@ai-sdk/xai/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@4.0.21", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-MtFUYI1/8mgDvRmaBDjbLJPFFrMG777AvSgyIFQtZHIMzm88R/12vYBBpnk7pfiWLFE1DSZzY4WDYzGbKAcmiw=="], - - "ajv-keywords/ajv/json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], - - "ansi-align/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], - - "ansi-align/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - - "app-builder-lib/@electron/get/fs-extra": ["fs-extra@8.1.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g=="], - - "app-builder-lib/@electron/get/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], - - "app-builder-lib/hosted-git-info/lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="], - - "app-builder-lib/which/isexe": ["isexe@3.1.5", "", {}, "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w=="], - - "archiver-utils/glob/jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="], - - "archiver-utils/glob/minimatch": ["minimatch@9.0.9", "", { "dependencies": { "brace-expansion": "^2.0.2" } }, "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg=="], - - "archiver-utils/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="], - - "astro/unstorage/chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "^5.0.0" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="], - - "astro/unstorage/h3": ["h3@1.15.11", "", { "dependencies": { "cookie-es": "^1.2.3", "crossws": "^0.3.5", "defu": "^6.1.6", "destr": "^2.0.5", "iron-webcrypto": "^1.2.1", "node-mock-http": "^1.0.4", "radix3": "^1.1.2", "ufo": "^1.6.3", "uncrypto": "^0.1.3" } }, "sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg=="], - - "astro/unstorage/ofetch": ["ofetch@1.5.1", "", { "dependencies": { "destr": "^2.0.5", "node-fetch-native": "^1.6.7", "ufo": "^1.6.1" } }, "sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA=="], - - "babel-plugin-module-resolver/glob/minimatch": ["minimatch@8.0.7", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-V+1uQNdzybxa14e/p00HZnQNNcTjnRJjDxg2V8wtkjFctq4M7hXFws4oekyTP0Jebeq7QYtpFyOeBAjc88zvYg=="], - - "babel-plugin-module-resolver/glob/minipass": ["minipass@4.2.8", "", {}, "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ=="], - - "babel-plugin-module-resolver/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="], - - "bl/buffer/ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="], - - "body-parser/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], - - "bun-types/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "c12/chokidar/readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="], - - "cloudflare/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "crc/buffer/ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="], - - "cross-spawn/which/isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], - - "dir-compare/minimatch/brace-expansion": ["brace-expansion@1.1.14", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g=="], - - "dir-compare/p-limit/yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="], - - "dmg-license/ajv/json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], - - "editorconfig/minimatch/brace-expansion": ["brace-expansion@2.1.0", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w=="], - - "electron-builder/yargs/cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="], - - "electron-builder/yargs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], - - "electron-winstaller/fs-extra/universalify": ["universalify@0.1.2", "", {}, "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="], - - "electron/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "esbuild-plugin-copy/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], - - "express/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], - - "filelist/minimatch/brace-expansion": ["brace-expansion@2.1.0", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w=="], - - "finalhandler/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], - - "form-data/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], - - "gray-matter/js-yaml/argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="], - - "happy-dom/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "iconv-corefoundation/cli-truncate/slice-ansi": ["slice-ansi@3.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", "is-fullwidth-code-point": "^3.0.0" } }, "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ=="], - - "iconv-corefoundation/cli-truncate/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], - - "image-q/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "js-beautify/glob/jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="], - - "js-beautify/glob/minimatch": ["minimatch@9.0.9", "", { "dependencies": { "brace-expansion": "^2.0.2" } }, "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg=="], - - "js-beautify/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="], - - "js-beautify/nopt/abbrev": ["abbrev@2.0.0", "", {}, "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ=="], - - "lazystream/readable-stream/core-util-is": ["core-util-is@1.0.3", "", {}, "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="], + "@octokit/auth-oauth-app/@octokit/request/@octokit/endpoint": ["@octokit/endpoint@11.0.3", "", { "dependencies": { "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag=="], - "lazystream/readable-stream/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="], + "@octokit/auth-oauth-app/@octokit/request/@octokit/request-error": ["@octokit/request-error@7.1.0", "", { "dependencies": { "@octokit/types": "^16.0.0" } }, "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw=="], - "lazystream/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="], + "@octokit/auth-oauth-app/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="], - "motion/framer-motion/motion-dom": ["motion-dom@12.38.0", "", { "dependencies": { "motion-utils": "^12.36.0" } }, "sha512-pdkHLD8QYRp8VfiNLb8xIBJis1byQ9gPT3Jnh2jqfFtAsWUA3dEepDlsWe/xMpO8McV+VdpKVcp+E+TGJEtOoA=="], + "@octokit/auth-oauth-device/@octokit/request/@octokit/endpoint": ["@octokit/endpoint@11.0.3", "", { "dependencies": { "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag=="], - "motion/framer-motion/motion-utils": ["motion-utils@12.36.0", "", {}, "sha512-eHWisygbiwVvf6PZ1vhaHCLamvkSbPIeAYxWUuL3a2PD/TROgE7FvfHWTIH4vMl798QLfMw15nRqIaRDXTlYRg=="], + "@octokit/auth-oauth-device/@octokit/request/@octokit/request-error": ["@octokit/request-error@7.1.0", "", { "dependencies": { "@octokit/types": "^16.0.0" } }, "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw=="], - "mssql/tedious/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], + "@octokit/auth-oauth-device/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="], - "mssql/tedious/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], + "@octokit/auth-oauth-user/@octokit/request/@octokit/endpoint": ["@octokit/endpoint@11.0.3", "", { "dependencies": { "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag=="], - "opencode-gitlab-auth/open/wsl-utils": ["wsl-utils@0.1.0", "", { "dependencies": { "is-wsl": "^3.1.0" } }, "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw=="], + "@octokit/auth-oauth-user/@octokit/request/@octokit/request-error": ["@octokit/request-error@7.1.0", "", { "dependencies": { "@octokit/types": "^16.0.0" } }, "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw=="], - "opencode-poe-auth/open/wsl-utils": ["wsl-utils@0.1.0", "", { "dependencies": { "is-wsl": "^3.1.0" } }, "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw=="], + "@octokit/auth-oauth-user/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="], - "opencontrol/@modelcontextprotocol/sdk/express": ["express@5.2.1", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "depd": "^2.0.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" } }, "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw=="], + "@octokit/core/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@24.2.0", "", {}, "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg=="], - "opencontrol/@modelcontextprotocol/sdk/express-rate-limit": ["express-rate-limit@7.5.1", "", { "peerDependencies": { "express": ">= 4.11" } }, "sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw=="], + "@octokit/endpoint/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@24.2.0", "", {}, "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg=="], - "opencontrol/@modelcontextprotocol/sdk/pkce-challenge": ["pkce-challenge@4.1.0", "", {}, "sha512-ZBmhE1C9LcPoH9XZSdwiPtbPHZROwAnMy+kIFQVrnMCxY4Cudlz3gBOpzilgc0jOgRaiT3sIWfpMomW2ar2orQ=="], + "@octokit/graphql/@octokit/request/@octokit/endpoint": ["@octokit/endpoint@11.0.3", "", { "dependencies": { "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag=="], - "opencontrol/@modelcontextprotocol/sdk/raw-body": ["raw-body@3.0.2", "", { "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", "iconv-lite": "~0.7.0", "unpipe": "~1.0.0" } }, "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA=="], + "@octokit/graphql/@octokit/request/@octokit/request-error": ["@octokit/request-error@7.1.0", "", { "dependencies": { "@octokit/types": "^16.0.0" } }, "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw=="], - "opencontrol/@modelcontextprotocol/sdk/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], + "@octokit/graphql/@octokit/request/@octokit/types": ["@octokit/types@16.0.0", "", { "dependencies": { "@octokit/openapi-types": "^27.0.0" } }, "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg=="], - "opencontrol/@modelcontextprotocol/sdk/zod-to-json-schema": ["zod-to-json-schema@3.25.2", "", { "peerDependencies": { "zod": "^3.25.28 || ^4" } }, "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA=="], + "@octokit/graphql/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@26.0.0", "", {}, "sha512-7AtcfKtpo77j7Ts73b4OWhOZHTKo/gGY8bB3bNBQz4H+GRSWqx2yvj8TXRsbdTE0eRmYmXOEY66jM7mJ7LzfsA=="], - "opentui-spinner/@opentui/core/@opentui/core-darwin-arm64": ["@opentui/core-darwin-arm64@0.1.105", "", { "os": "darwin", "cpu": "arm64" }, "sha512-1pIL7aer9amwj8EpYoMNtvavKetIe+nX8uBRmYsMQb+KvJoUAZUqENfRW+qHE5WrsOyxx8/QoyXTHw15GG5iLQ=="], + "@octokit/oauth-methods/@octokit/request/@octokit/endpoint": ["@octokit/endpoint@11.0.3", "", { "dependencies": { "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag=="], - "opentui-spinner/@opentui/core/@opentui/core-darwin-x64": ["@opentui/core-darwin-x64@0.1.105", "", { "os": "darwin", "cpu": "x64" }, "sha512-hLIRSWlK3gY2NRXJGWiTBiMYSmRDjOYFZF6WtUVXhY2SL3sp08dhmr/6dmAVH+3pKCsCipLEsrrcQX6SAihCTA=="], + "@octokit/oauth-methods/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="], - "opentui-spinner/@opentui/core/@opentui/core-linux-arm64": ["@opentui/core-linux-arm64@0.1.105", "", { "os": "linux", "cpu": "arm64" }, "sha512-jlRKfPkozTZEkHEePuCWYcTIUtPm+ieInAwGVqGmjbvqjxdVv1/W/Dt6LEZ/9jpRiOPd+FjXAfLe6wa/XWHr+w=="], + "@octokit/plugin-paginate-rest/@octokit/core/@octokit/auth-token": ["@octokit/auth-token@6.0.0", "", {}, "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w=="], - "opentui-spinner/@opentui/core/@opentui/core-linux-x64": ["@opentui/core-linux-x64@0.1.105", "", { "os": "linux", "cpu": "x64" }, "sha512-kfWS1WMg6qHShmxZX9s1tZc/8JcXw6uyy2UtyTbJdRFExtXGH37oKHi8QK8iPL2ExCx4z7zqVnVJfO3X/Wh7lA=="], + "@octokit/plugin-paginate-rest/@octokit/core/@octokit/graphql": ["@octokit/graphql@9.0.3", "", { "dependencies": { "@octokit/request": "^10.0.6", "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.0" } }, "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA=="], - "opentui-spinner/@opentui/core/@opentui/core-win32-arm64": ["@opentui/core-win32-arm64@0.1.105", "", { "os": "win32", "cpu": "arm64" }, "sha512-UFx6A8OpBVbGWK6OAw4GqAqKZgIITJfSOd35pG9yDVKQouHN2OGc2HeeXrH2A4h42p40Xl6IfcqqfllkpC13Dg=="], + "@octokit/plugin-paginate-rest/@octokit/core/@octokit/request": ["@octokit/request@10.0.8", "", { "dependencies": { "@octokit/endpoint": "^11.0.3", "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0", "fast-content-type-parse": "^3.0.0", "json-with-bigint": "^3.5.3", "universal-user-agent": "^7.0.2" } }, "sha512-SJZNwY9pur9Agf7l87ywFi14W+Hd9Jg6Ifivsd33+/bGUQIjNujdFiXII2/qSlN2ybqUHfp5xpekMEjIBTjlSw=="], - "opentui-spinner/@opentui/core/@opentui/core-win32-x64": ["@opentui/core-win32-x64@0.1.105", "", { "os": "win32", "cpu": "x64" }, "sha512-f9FqqUmxehwhF+cgyazm0YT0v0BYTTCPzd6eztqhl74N3x/kC+jOOz2rdJDC/tTBo1JVsF64KupOnhIs6/Cogg=="], + "@octokit/plugin-paginate-rest/@octokit/core/@octokit/request-error": ["@octokit/request-error@7.1.0", "", { "dependencies": { "@octokit/types": "^16.0.0" } }, "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw=="], - "opentui-spinner/@opentui/core/bun-ffi-structs": ["bun-ffi-structs@0.1.2", "", { "peerDependencies": { "typescript": "^5" } }, "sha512-Lh1oQAYHDcnesJauieA4UNkWGXY9hYck7OA5IaRwE3Bp6K2F2pJSNYqq+hIy7P3uOvo3km3oxS8304g5gDMl/w=="], + "@octokit/plugin-paginate-rest/@octokit/core/@octokit/types": ["@octokit/types@16.0.0", "", { "dependencies": { "@octokit/openapi-types": "^27.0.0" } }, "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg=="], - "opentui-spinner/@opentui/solid/@babel/core": ["@babel/core@7.28.0", "", { "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.0", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.27.3", "@babel/helpers": "^7.27.6", "@babel/parser": "^7.28.0", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.0", "@babel/types": "^7.28.0", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ=="], + "@octokit/plugin-paginate-rest/@octokit/core/before-after-hook": ["before-after-hook@4.0.0", "", {}, "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ=="], - "opentui-spinner/@opentui/solid/babel-preset-solid": ["babel-preset-solid@1.9.10", "", { "dependencies": { "babel-plugin-jsx-dom-expressions": "^0.40.3" }, "peerDependencies": { "@babel/core": "^7.0.0", "solid-js": "^1.9.10" }, "optionalPeers": ["solid-js"] }, "sha512-HCelrgua/Y+kqO8RyL04JBWS/cVdrtUv/h45GntgQY+cJl4eBcKkCDV3TdMjtKx1nXwRaR9QXslM/Npm1dxdZQ=="], + "@octokit/plugin-paginate-rest/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@26.0.0", "", {}, "sha512-7AtcfKtpo77j7Ts73b4OWhOZHTKo/gGY8bB3bNBQz4H+GRSWqx2yvj8TXRsbdTE0eRmYmXOEY66jM7mJ7LzfsA=="], - "ora/bl/buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="], + "@octokit/plugin-rest-endpoint-methods/@octokit/core/@octokit/auth-token": ["@octokit/auth-token@6.0.0", "", {}, "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w=="], - "ora/bl/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], + "@octokit/plugin-rest-endpoint-methods/@octokit/core/@octokit/graphql": ["@octokit/graphql@9.0.3", "", { "dependencies": { "@octokit/request": "^10.0.6", "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.0" } }, "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA=="], - "ora/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + "@octokit/plugin-rest-endpoint-methods/@octokit/core/@octokit/request": ["@octokit/request@10.0.8", "", { "dependencies": { "@octokit/endpoint": "^11.0.3", "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0", "fast-content-type-parse": "^3.0.0", "json-with-bigint": "^3.5.3", "universal-user-agent": "^7.0.2" } }, "sha512-SJZNwY9pur9Agf7l87ywFi14W+Hd9Jg6Ifivsd33+/bGUQIjNujdFiXII2/qSlN2ybqUHfp5xpekMEjIBTjlSw=="], - "p-locate/p-limit/yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="], + "@octokit/plugin-rest-endpoint-methods/@octokit/core/@octokit/request-error": ["@octokit/request-error@7.1.0", "", { "dependencies": { "@octokit/types": "^16.0.0" } }, "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw=="], - "parse-bmfont-xml/xml2js/sax": ["sax@1.6.0", "", {}, "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA=="], + "@octokit/plugin-rest-endpoint-methods/@octokit/core/@octokit/types": ["@octokit/types@16.0.0", "", { "dependencies": { "@octokit/openapi-types": "^27.0.0" } }, "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg=="], - "pkg-dir/find-up/locate-path": ["locate-path@5.0.0", "", { "dependencies": { "p-locate": "^4.1.0" } }, "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="], + "@octokit/plugin-rest-endpoint-methods/@octokit/core/before-after-hook": ["before-after-hook@4.0.0", "", {}, "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ=="], - "pkg-up/find-up/locate-path": ["locate-path@3.0.0", "", { "dependencies": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" } }, "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A=="], + "@octokit/plugin-rest-endpoint-methods/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@26.0.0", "", {}, "sha512-7AtcfKtpo77j7Ts73b4OWhOZHTKo/gGY8bB3bNBQz4H+GRSWqx2yvj8TXRsbdTE0eRmYmXOEY66jM7mJ7LzfsA=="], - "protobufjs/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], + "@octokit/plugin-retry/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@12.11.0", "", {}, "sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ=="], - "readable-stream/buffer/ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="], + "@octokit/request-error/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@24.2.0", "", {}, "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg=="], - "readdir-glob/minimatch/brace-expansion": ["brace-expansion@2.1.0", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w=="], + "@octokit/request/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@24.2.0", "", {}, "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg=="], - "restore-cursor/onetime/mimic-fn": ["mimic-fn@2.1.0", "", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="], + "@octokit/rest/@octokit/core/@octokit/auth-token": ["@octokit/auth-token@6.0.0", "", {}, "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w=="], - "rimraf/glob/minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="], + "@octokit/rest/@octokit/core/@octokit/graphql": ["@octokit/graphql@9.0.3", "", { "dependencies": { "@octokit/request": "^10.0.6", "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.0" } }, "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA=="], - "send/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], + "@octokit/rest/@octokit/core/@octokit/request": ["@octokit/request@10.0.8", "", { "dependencies": { "@octokit/endpoint": "^11.0.3", "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0", "fast-content-type-parse": "^3.0.0", "json-with-bigint": "^3.5.3", "universal-user-agent": "^7.0.2" } }, "sha512-SJZNwY9pur9Agf7l87ywFi14W+Hd9Jg6Ifivsd33+/bGUQIjNujdFiXII2/qSlN2ybqUHfp5xpekMEjIBTjlSw=="], - "sitemap/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], + "@octokit/rest/@octokit/core/@octokit/request-error": ["@octokit/request-error@7.1.0", "", { "dependencies": { "@octokit/types": "^16.0.0" } }, "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw=="], - "storybook/open/wsl-utils": ["wsl-utils@0.1.0", "", { "dependencies": { "is-wsl": "^3.1.0" } }, "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw=="], + "@octokit/rest/@octokit/core/@octokit/types": ["@octokit/types@16.0.0", "", { "dependencies": { "@octokit/openapi-types": "^27.0.0" } }, "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg=="], - "string-width-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + "@octokit/rest/@octokit/core/before-after-hook": ["before-after-hook@4.0.0", "", {}, "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ=="], - "stripe/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], + "@pierre/diffs/@shikijs/transformers/@shikijs/core": ["@shikijs/core@3.20.0", "", { "dependencies": { "@shikijs/types": "3.20.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-f2ED7HYV4JEk827mtMDwe/yQ25pRiXZmtHjWF8uzZKuKiEsJR7Ce1nuQ+HhV9FzDcbIo4ObBCD9GPTzNuy9S1g=="], - "tedious/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], + "@pierre/diffs/@shikijs/transformers/@shikijs/types": ["@shikijs/types@3.20.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-lhYAATn10nkZcBQ0BlzSbJA3wcmL5MXUUF8d2Zzon6saZDlToKaiRX60n2+ZaHJCmXEcZRWNzn+k9vplr8Jhsw=="], - "tw-to-css/tailwindcss/chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="], + "@standard-community/standard-json/effect/@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], - "tw-to-css/tailwindcss/glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="], + "@standard-community/standard-openapi/effect/@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], - "tw-to-css/tailwindcss/jiti": ["jiti@1.21.7", "", { "bin": { "jiti": "bin/jiti.js" } }, "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A=="], + "@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime/@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="], - "tw-to-css/tailwindcss/object-hash": ["object-hash@3.0.0", "", {}, "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw=="], + "@typespec/ts-http-runtime/https-proxy-agent/agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], - "tw-to-css/tailwindcss/postcss": ["postcss@8.5.9", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw=="], + "ai-gateway-provider/@ai-sdk/amazon-bedrock/@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.7", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.11.0", "@smithy/util-hex-encoding": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-DrpkEoM3j9cBBWhufqBwnbbn+3nf1N9FP6xuVJ+e220jbactKuQgaZwjwP5CP1t+O94brm2JgVMD2atMGX3xIQ=="], - "type-is/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], + "ai-gateway-provider/@ai-sdk/amazon-bedrock/aws4fetch": ["aws4fetch@1.0.20", "", {}, "sha512-/djoAN709iY65ETD6LKCtyyEI04XIBP5xVvfmNxsEP0uJB5tyaGBztSryRr4HqMStr9R06PisQE7m9zDTXKu6g=="], - "unplugin/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], + "ai-gateway-provider/@ai-sdk/google-vertex/@ai-sdk/anthropic": ["@ai-sdk/anthropic@3.0.64", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.21" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-rwLi/Rsuj2pYniQXIrvClHvXDzgM4UQHHnvHTWEF14efnlKclG/1ghpNC+adsRujAbCTr6gRsSbDE2vEqriV7g=="], - "vitest/@vitest/expect/@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], + "ai-gateway-provider/@ai-sdk/xai/@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@2.0.37", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.21" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-+POSFVcgiu47BK64dhsI6OpcDC0/VAE2ZSaXdXGNNhpC/ava++uSRJYks0k2bpfY0wwCTgpAWZsXn/dG2Yppiw=="], - "vitest/@vitest/expect/chai": ["chai@6.2.2", "", {}, "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg=="], + "archiver-utils/glob/jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="], - "wrangler/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.4", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q=="], + "archiver-utils/glob/minimatch": ["minimatch@9.0.9", "", { "dependencies": { "brace-expansion": "^2.0.2" } }, "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg=="], - "wrangler/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.4", "", { "os": "android", "cpu": "arm" }, "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ=="], + "archiver-utils/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="], - "wrangler/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.4", "", { "os": "android", "cpu": "arm64" }, "sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A=="], + "babel-plugin-module-resolver/glob/minimatch": ["minimatch@8.0.7", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-V+1uQNdzybxa14e/p00HZnQNNcTjnRJjDxg2V8wtkjFctq4M7hXFws4oekyTP0Jebeq7QYtpFyOeBAjc88zvYg=="], - "wrangler/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.25.4", "", { "os": "android", "cpu": "x64" }, "sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ=="], + "babel-plugin-module-resolver/glob/minipass": ["minipass@4.2.8", "", {}, "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ=="], - "wrangler/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g=="], + "babel-plugin-module-resolver/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="], - "wrangler/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A=="], + "bl/buffer/ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="], - "wrangler/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.4", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ=="], + "c12/chokidar/readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="], - "wrangler/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.4", "", { "os": "freebsd", "cpu": "x64" }, "sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ=="], + "cross-spawn/which/isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], - "wrangler/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.4", "", { "os": "linux", "cpu": "arm" }, "sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ=="], + "form-data/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], - "wrangler/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ=="], + "gaxios/https-proxy-agent/agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], - "wrangler/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.4", "", { "os": "linux", "cpu": "ia32" }, "sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ=="], + "lazystream/readable-stream/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="], - "wrangler/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.4", "", { "os": "linux", "cpu": "none" }, "sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA=="], + "lazystream/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="], - "wrangler/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.4", "", { "os": "linux", "cpu": "none" }, "sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg=="], + "mssql/tedious/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], - "wrangler/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag=="], + "opentui-spinner/@opentui/core/@opentui/core-darwin-arm64": ["@opentui/core-darwin-arm64@0.1.105", "", { "os": "darwin", "cpu": "arm64" }, "sha512-1pIL7aer9amwj8EpYoMNtvavKetIe+nX8uBRmYsMQb+KvJoUAZUqENfRW+qHE5WrsOyxx8/QoyXTHw15GG5iLQ=="], - "wrangler/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.4", "", { "os": "linux", "cpu": "none" }, "sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA=="], + "opentui-spinner/@opentui/core/@opentui/core-darwin-x64": ["@opentui/core-darwin-x64@0.1.105", "", { "os": "darwin", "cpu": "x64" }, "sha512-hLIRSWlK3gY2NRXJGWiTBiMYSmRDjOYFZF6WtUVXhY2SL3sp08dhmr/6dmAVH+3pKCsCipLEsrrcQX6SAihCTA=="], - "wrangler/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g=="], + "opentui-spinner/@opentui/core/@opentui/core-linux-arm64": ["@opentui/core-linux-arm64@0.1.105", "", { "os": "linux", "cpu": "arm64" }, "sha512-jlRKfPkozTZEkHEePuCWYcTIUtPm+ieInAwGVqGmjbvqjxdVv1/W/Dt6LEZ/9jpRiOPd+FjXAfLe6wa/XWHr+w=="], - "wrangler/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.4", "", { "os": "linux", "cpu": "x64" }, "sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA=="], + "opentui-spinner/@opentui/core/@opentui/core-linux-x64": ["@opentui/core-linux-x64@0.1.105", "", { "os": "linux", "cpu": "x64" }, "sha512-kfWS1WMg6qHShmxZX9s1tZc/8JcXw6uyy2UtyTbJdRFExtXGH37oKHi8QK8iPL2ExCx4z7zqVnVJfO3X/Wh7lA=="], - "wrangler/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.4", "", { "os": "none", "cpu": "arm64" }, "sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ=="], + "opentui-spinner/@opentui/core/@opentui/core-win32-arm64": ["@opentui/core-win32-arm64@0.1.105", "", { "os": "win32", "cpu": "arm64" }, "sha512-UFx6A8OpBVbGWK6OAw4GqAqKZgIITJfSOd35pG9yDVKQouHN2OGc2HeeXrH2A4h42p40Xl6IfcqqfllkpC13Dg=="], - "wrangler/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.4", "", { "os": "none", "cpu": "x64" }, "sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw=="], + "opentui-spinner/@opentui/core/@opentui/core-win32-x64": ["@opentui/core-win32-x64@0.1.105", "", { "os": "win32", "cpu": "x64" }, "sha512-f9FqqUmxehwhF+cgyazm0YT0v0BYTTCPzd6eztqhl74N3x/kC+jOOz2rdJDC/tTBo1JVsF64KupOnhIs6/Cogg=="], - "wrangler/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.4", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A=="], + "opentui-spinner/@opentui/core/bun-ffi-structs": ["bun-ffi-structs@0.1.2", "", { "peerDependencies": { "typescript": "^5" } }, "sha512-Lh1oQAYHDcnesJauieA4UNkWGXY9hYck7OA5IaRwE3Bp6K2F2pJSNYqq+hIy7P3uOvo3km3oxS8304g5gDMl/w=="], - "wrangler/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.4", "", { "os": "openbsd", "cpu": "x64" }, "sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw=="], + "opentui-spinner/@opentui/solid/babel-preset-solid": ["babel-preset-solid@1.9.10", "", { "dependencies": { "babel-plugin-jsx-dom-expressions": "^0.40.3" }, "peerDependencies": { "@babel/core": "^7.0.0", "solid-js": "^1.9.10" }, "optionalPeers": ["solid-js"] }, "sha512-HCelrgua/Y+kqO8RyL04JBWS/cVdrtUv/h45GntgQY+cJl4eBcKkCDV3TdMjtKx1nXwRaR9QXslM/Npm1dxdZQ=="], - "wrangler/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.4", "", { "os": "sunos", "cpu": "x64" }, "sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q=="], + "parse-bmfont-xml/xml2js/sax": ["sax@1.6.0", "", {}, "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA=="], - "wrangler/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ=="], + "readable-stream/buffer/ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="], - "wrangler/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.4", "", { "os": "win32", "cpu": "ia32" }, "sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg=="], + "solid-refresh/@babel/generator/@babel/parser": ["@babel/parser@7.29.2", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": "./bin/babel-parser.js" }, "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA=="], - "wrangler/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.4", "", { "os": "win32", "cpu": "x64" }, "sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ=="], + "string-width-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], "wrap-ansi-cjs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], @@ -7014,144 +3890,20 @@ "@actions/github/@octokit/plugin-rest-endpoint-methods/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@20.0.0", "", {}, "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA=="], - "@astrojs/check/yargs/cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - - "@astrojs/check/yargs/cliui/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], - - "@astrojs/check/yargs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], - - "@astrojs/check/yargs/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - - "@astrojs/mdx/@astrojs/markdown-remark/shiki/@shikijs/core": ["@shikijs/core@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA=="], - - "@astrojs/mdx/@astrojs/markdown-remark/shiki/@shikijs/engine-javascript": ["@shikijs/engine-javascript@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.4" } }, "sha512-aHt9eiGFobmWR5uqJUViySI1bHMqrAgamWE1TYSUoftkAeCCAiGawPMwM+VCadylQtF4V3VNOZ5LmfItH5f3yA=="], - - "@astrojs/mdx/@astrojs/markdown-remark/shiki/@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g=="], - - "@astrojs/mdx/@astrojs/markdown-remark/shiki/@shikijs/langs": ["@shikijs/langs@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0" } }, "sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg=="], - - "@astrojs/mdx/@astrojs/markdown-remark/shiki/@shikijs/themes": ["@shikijs/themes@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0" } }, "sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA=="], - - "@astrojs/mdx/@astrojs/markdown-remark/shiki/@shikijs/types": ["@shikijs/types@3.23.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ=="], - "@aws-crypto/sha1-browser/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@2.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA=="], "@aws-crypto/sha256-browser/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@2.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA=="], "@aws-crypto/util/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@2.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA=="], - "@aws-sdk/client-cognito-identity/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.5.8", "", { "dependencies": { "fast-xml-builder": "^1.1.4", "path-expression-matcher": "^1.2.0", "strnum": "^2.2.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-Z7Fh2nVQSb2d+poDViM063ix2ZGt9jmY1nWhPfHBOK2Hgnb/OW3P4Et3P/81SEej0J7QbWtJqxO05h8QYfK7LQ=="], - - "@aws-sdk/client-sts/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.782.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.775.0", "@aws-sdk/middleware-host-header": "3.775.0", "@aws-sdk/middleware-logger": "3.775.0", "@aws-sdk/middleware-recursion-detection": "3.775.0", "@aws-sdk/middleware-user-agent": "3.782.0", "@aws-sdk/region-config-resolver": "3.775.0", "@aws-sdk/types": "3.775.0", "@aws-sdk/util-endpoints": "3.782.0", "@aws-sdk/util-user-agent-browser": "3.775.0", "@aws-sdk/util-user-agent-node": "3.782.0", "@smithy/config-resolver": "^4.1.0", "@smithy/core": "^3.2.0", "@smithy/fetch-http-handler": "^5.0.2", "@smithy/hash-node": "^4.0.2", "@smithy/invalid-dependency": "^4.0.2", "@smithy/middleware-content-length": "^4.0.2", "@smithy/middleware-endpoint": "^4.1.0", "@smithy/middleware-retry": "^4.1.0", "@smithy/middleware-serde": "^4.0.3", "@smithy/middleware-stack": "^4.0.2", "@smithy/node-config-provider": "^4.0.2", "@smithy/node-http-handler": "^4.0.4", "@smithy/protocol-http": "^5.1.0", "@smithy/smithy-client": "^4.2.0", "@smithy/types": "^4.2.0", "@smithy/url-parser": "^4.0.2", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", "@smithy/util-defaults-mode-browser": "^4.0.8", "@smithy/util-defaults-mode-node": "^4.0.8", "@smithy/util-endpoints": "^3.0.2", "@smithy/util-middleware": "^4.0.2", "@smithy/util-retry": "^4.0.2", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-QOYC8q7luzHFXrP0xYAqBctoPkynjfV0r9dqntFu4/IWMTyC1vlo1UTxFAjIPyclYw92XJyEkVCVg9v/nQnsUA=="], - - "@aws-sdk/client-sts/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso": ["@aws-sdk/client-sso@3.782.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.775.0", "@aws-sdk/middleware-host-header": "3.775.0", "@aws-sdk/middleware-logger": "3.775.0", "@aws-sdk/middleware-recursion-detection": "3.775.0", "@aws-sdk/middleware-user-agent": "3.782.0", "@aws-sdk/region-config-resolver": "3.775.0", "@aws-sdk/types": "3.775.0", "@aws-sdk/util-endpoints": "3.782.0", "@aws-sdk/util-user-agent-browser": "3.775.0", "@aws-sdk/util-user-agent-node": "3.782.0", "@smithy/config-resolver": "^4.1.0", "@smithy/core": "^3.2.0", "@smithy/fetch-http-handler": "^5.0.2", "@smithy/hash-node": "^4.0.2", "@smithy/invalid-dependency": "^4.0.2", "@smithy/middleware-content-length": "^4.0.2", "@smithy/middleware-endpoint": "^4.1.0", "@smithy/middleware-retry": "^4.1.0", "@smithy/middleware-serde": "^4.0.3", "@smithy/middleware-stack": "^4.0.2", "@smithy/node-config-provider": "^4.0.2", "@smithy/node-http-handler": "^4.0.4", "@smithy/protocol-http": "^5.1.0", "@smithy/smithy-client": "^4.2.0", "@smithy/types": "^4.2.0", "@smithy/url-parser": "^4.0.2", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", "@smithy/util-defaults-mode-browser": "^4.0.8", "@smithy/util-defaults-mode-node": "^4.0.8", "@smithy/util-endpoints": "^3.0.2", "@smithy/util-middleware": "^4.0.2", "@smithy/util-retry": "^4.0.2", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-5GlJBejo8wqMpSSEKb45WE82YxI2k73YuebjLH/eWDNQeE6VI5Bh9lA1YQ7xNkLLH8hIsb0pSfKVuwh0VEzVrg=="], - - "@aws-sdk/client-sts/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.782.0", "", { "dependencies": { "@aws-sdk/nested-clients": "3.782.0", "@aws-sdk/types": "3.775.0", "@smithy/property-provider": "^4.0.2", "@smithy/shared-ini-file-loader": "^4.0.2", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-4tPuk/3+THPrzKaXW4jE2R67UyGwHLFizZ47pcjJWbhb78IIJAy94vbeqEQ+veS84KF5TXcU7g5jGTXC0D70Wg=="], - - "@aws-sdk/client-sts/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.782.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.775.0", "@aws-sdk/middleware-host-header": "3.775.0", "@aws-sdk/middleware-logger": "3.775.0", "@aws-sdk/middleware-recursion-detection": "3.775.0", "@aws-sdk/middleware-user-agent": "3.782.0", "@aws-sdk/region-config-resolver": "3.775.0", "@aws-sdk/types": "3.775.0", "@aws-sdk/util-endpoints": "3.782.0", "@aws-sdk/util-user-agent-browser": "3.775.0", "@aws-sdk/util-user-agent-node": "3.782.0", "@smithy/config-resolver": "^4.1.0", "@smithy/core": "^3.2.0", "@smithy/fetch-http-handler": "^5.0.2", "@smithy/hash-node": "^4.0.2", "@smithy/invalid-dependency": "^4.0.2", "@smithy/middleware-content-length": "^4.0.2", "@smithy/middleware-endpoint": "^4.1.0", "@smithy/middleware-retry": "^4.1.0", "@smithy/middleware-serde": "^4.0.3", "@smithy/middleware-stack": "^4.0.2", "@smithy/node-config-provider": "^4.0.2", "@smithy/node-http-handler": "^4.0.4", "@smithy/protocol-http": "^5.1.0", "@smithy/smithy-client": "^4.2.0", "@smithy/types": "^4.2.0", "@smithy/url-parser": "^4.0.2", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", "@smithy/util-defaults-mode-browser": "^4.0.8", "@smithy/util-defaults-mode-node": "^4.0.8", "@smithy/util-endpoints": "^3.0.2", "@smithy/util-middleware": "^4.0.2", "@smithy/util-retry": "^4.0.2", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-QOYC8q7luzHFXrP0xYAqBctoPkynjfV0r9dqntFu4/IWMTyC1vlo1UTxFAjIPyclYw92XJyEkVCVg9v/nQnsUA=="], - "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/nested-clients/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.17", "", { "dependencies": { "@smithy/types": "^4.14.0", "fast-xml-parser": "5.5.8", "tslib": "^2.6.2" } }, "sha512-Ra7hjqAZf1OXRRMueB13qex7mFJRDK/pgCvdSFemXBT8KCGnQDPoKzHY1SjN+TjJVmnpSF14W5tJ1vDamFu+Gg=="], - "@aws-sdk/credential-provider-env/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.5.8", "", { "dependencies": { "fast-xml-builder": "^1.1.4", "path-expression-matcher": "^1.2.0", "strnum": "^2.2.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-Z7Fh2nVQSb2d+poDViM063ix2ZGt9jmY1nWhPfHBOK2Hgnb/OW3P4Et3P/81SEej0J7QbWtJqxO05h8QYfK7LQ=="], - - "@aws-sdk/credential-provider-http/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.5.8", "", { "dependencies": { "fast-xml-builder": "^1.1.4", "path-expression-matcher": "^1.2.0", "strnum": "^2.2.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-Z7Fh2nVQSb2d+poDViM063ix2ZGt9jmY1nWhPfHBOK2Hgnb/OW3P4Et3P/81SEej0J7QbWtJqxO05h8QYfK7LQ=="], - - "@aws-sdk/credential-provider-ini/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.5.8", "", { "dependencies": { "fast-xml-builder": "^1.1.4", "path-expression-matcher": "^1.2.0", "strnum": "^2.2.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-Z7Fh2nVQSb2d+poDViM063ix2ZGt9jmY1nWhPfHBOK2Hgnb/OW3P4Et3P/81SEej0J7QbWtJqxO05h8QYfK7LQ=="], - - "@aws-sdk/credential-provider-login/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.5.8", "", { "dependencies": { "fast-xml-builder": "^1.1.4", "path-expression-matcher": "^1.2.0", "strnum": "^2.2.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-Z7Fh2nVQSb2d+poDViM063ix2ZGt9jmY1nWhPfHBOK2Hgnb/OW3P4Et3P/81SEej0J7QbWtJqxO05h8QYfK7LQ=="], - "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.933.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.932.0", "@aws-sdk/middleware-host-header": "3.930.0", "@aws-sdk/middleware-logger": "3.930.0", "@aws-sdk/middleware-recursion-detection": "3.933.0", "@aws-sdk/middleware-user-agent": "3.932.0", "@aws-sdk/region-config-resolver": "3.930.0", "@aws-sdk/types": "3.930.0", "@aws-sdk/util-endpoints": "3.930.0", "@aws-sdk/util-user-agent-browser": "3.930.0", "@aws-sdk/util-user-agent-node": "3.932.0", "@smithy/config-resolver": "^4.4.3", "@smithy/core": "^3.18.2", "@smithy/fetch-http-handler": "^5.3.6", "@smithy/hash-node": "^4.2.5", "@smithy/invalid-dependency": "^4.2.5", "@smithy/middleware-content-length": "^4.2.5", "@smithy/middleware-endpoint": "^4.3.9", "@smithy/middleware-retry": "^4.4.9", "@smithy/middleware-serde": "^4.2.5", "@smithy/middleware-stack": "^4.2.5", "@smithy/node-config-provider": "^4.3.5", "@smithy/node-http-handler": "^4.4.5", "@smithy/protocol-http": "^5.3.5", "@smithy/smithy-client": "^4.9.5", "@smithy/types": "^4.9.0", "@smithy/url-parser": "^4.2.5", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.8", "@smithy/util-defaults-mode-node": "^4.2.11", "@smithy/util-endpoints": "^3.2.5", "@smithy/util-middleware": "^4.2.5", "@smithy/util-retry": "^4.2.5", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-o1GX0+IPlFi/D8ei9y/jj3yucJWNfPnbB5appVBWevAyUdZA5KzQ2nK/hDxiu9olTZlFEFpf1m1Rn3FaGxHqsw=="], "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - "@aws-sdk/credential-provider-process/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.5.8", "", { "dependencies": { "fast-xml-builder": "^1.1.4", "path-expression-matcher": "^1.2.0", "strnum": "^2.2.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-Z7Fh2nVQSb2d+poDViM063ix2ZGt9jmY1nWhPfHBOK2Hgnb/OW3P4Et3P/81SEej0J7QbWtJqxO05h8QYfK7LQ=="], - - "@aws-sdk/credential-provider-sso/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.5.8", "", { "dependencies": { "fast-xml-builder": "^1.1.4", "path-expression-matcher": "^1.2.0", "strnum": "^2.2.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-Z7Fh2nVQSb2d+poDViM063ix2ZGt9jmY1nWhPfHBOK2Hgnb/OW3P4Et3P/81SEej0J7QbWtJqxO05h8QYfK7LQ=="], - - "@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.5.8", "", { "dependencies": { "fast-xml-builder": "^1.1.4", "path-expression-matcher": "^1.2.0", "strnum": "^2.2.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-Z7Fh2nVQSb2d+poDViM063ix2ZGt9jmY1nWhPfHBOK2Hgnb/OW3P4Et3P/81SEej0J7QbWtJqxO05h8QYfK7LQ=="], - - "@aws-sdk/credential-providers/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.5.8", "", { "dependencies": { "fast-xml-builder": "^1.1.4", "path-expression-matcher": "^1.2.0", "strnum": "^2.2.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-Z7Fh2nVQSb2d+poDViM063ix2ZGt9jmY1nWhPfHBOK2Hgnb/OW3P4Et3P/81SEej0J7QbWtJqxO05h8QYfK7LQ=="], - - "@aws-sdk/nested-clients/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.5.8", "", { "dependencies": { "fast-xml-builder": "^1.1.4", "path-expression-matcher": "^1.2.0", "strnum": "^2.2.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-Z7Fh2nVQSb2d+poDViM063ix2ZGt9jmY1nWhPfHBOK2Hgnb/OW3P4Et3P/81SEej0J7QbWtJqxO05h8QYfK7LQ=="], - - "@aws-sdk/token-providers/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.5.8", "", { "dependencies": { "fast-xml-builder": "^1.1.4", "path-expression-matcher": "^1.2.0", "strnum": "^2.2.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-Z7Fh2nVQSb2d+poDViM063ix2ZGt9jmY1nWhPfHBOK2Hgnb/OW3P4Et3P/81SEej0J7QbWtJqxO05h8QYfK7LQ=="], - - "@electron/asar/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], - - "@electron/rebuild/node-gyp/make-fetch-happen/@npmcli/agent": ["@npmcli/agent@3.0.0", "", { "dependencies": { "agent-base": "^7.1.0", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.1", "lru-cache": "^10.0.1", "socks-proxy-agent": "^8.0.3" } }, "sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q=="], - - "@electron/rebuild/node-gyp/make-fetch-happen/cacache": ["cacache@19.0.1", "", { "dependencies": { "@npmcli/fs": "^4.0.0", "fs-minipass": "^3.0.0", "glob": "^10.2.2", "lru-cache": "^10.0.1", "minipass": "^7.0.3", "minipass-collect": "^2.0.1", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "p-map": "^7.0.2", "ssri": "^12.0.0", "tar": "^7.4.3", "unique-filename": "^4.0.0" } }, "sha512-hdsUxulXCi5STId78vRVYEtDAjq99ICAUktLTeTYsLoTE6Z8dS0c8pWNCxwdrk9YfJeobDZc2Y186hD/5ZQgFQ=="], - - "@electron/rebuild/node-gyp/make-fetch-happen/minipass-fetch": ["minipass-fetch@4.0.1", "", { "dependencies": { "minipass": "^7.0.3", "minipass-sized": "^1.0.3", "minizlib": "^3.0.1" }, "optionalDependencies": { "encoding": "^0.1.13" } }, "sha512-j7U11C5HXigVuutxebFadoYBbd7VSdZWggSe64NVdvWNBqGAiXPL2QVCehjmw7lY1oF9gOllYbORh+hiNgfPgQ=="], - - "@electron/rebuild/node-gyp/make-fetch-happen/ssri": ["ssri@12.0.0", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ=="], - - "@electron/rebuild/node-gyp/nopt/abbrev": ["abbrev@3.0.1", "", {}, "sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg=="], - - "@electron/rebuild/node-gyp/which/isexe": ["isexe@3.1.5", "", {}, "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w=="], - - "@electron/rebuild/yargs/cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - - "@electron/rebuild/yargs/cliui/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], - - "@electron/rebuild/yargs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], - - "@electron/rebuild/yargs/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - - "@electron/universal/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], - - "@jsx-email/cli/tailwindcss/chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], - - "@jsx-email/cli/tailwindcss/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], - - "@jsx-email/cli/vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.18.20", "", { "os": "android", "cpu": "arm" }, "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw=="], - - "@jsx-email/cli/vite/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.18.20", "", { "os": "android", "cpu": "arm64" }, "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ=="], - - "@jsx-email/cli/vite/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.18.20", "", { "os": "android", "cpu": "x64" }, "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg=="], - - "@jsx-email/cli/vite/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.18.20", "", { "os": "darwin", "cpu": "arm64" }, "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA=="], - - "@jsx-email/cli/vite/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.18.20", "", { "os": "darwin", "cpu": "x64" }, "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ=="], - - "@jsx-email/cli/vite/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.18.20", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw=="], - - "@jsx-email/cli/vite/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.18.20", "", { "os": "freebsd", "cpu": "x64" }, "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ=="], - - "@jsx-email/cli/vite/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.18.20", "", { "os": "linux", "cpu": "arm" }, "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg=="], - - "@jsx-email/cli/vite/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.18.20", "", { "os": "linux", "cpu": "arm64" }, "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA=="], - - "@jsx-email/cli/vite/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.18.20", "", { "os": "linux", "cpu": "ia32" }, "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA=="], - - "@jsx-email/cli/vite/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.18.20", "", { "os": "linux", "cpu": "none" }, "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg=="], - - "@jsx-email/cli/vite/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.18.20", "", { "os": "linux", "cpu": "none" }, "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ=="], - - "@jsx-email/cli/vite/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.18.20", "", { "os": "linux", "cpu": "ppc64" }, "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA=="], - - "@jsx-email/cli/vite/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.18.20", "", { "os": "linux", "cpu": "none" }, "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A=="], - - "@jsx-email/cli/vite/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.18.20", "", { "os": "linux", "cpu": "s390x" }, "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ=="], - - "@jsx-email/cli/vite/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.18.20", "", { "os": "linux", "cpu": "x64" }, "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w=="], - - "@jsx-email/cli/vite/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.18.20", "", { "os": "none", "cpu": "x64" }, "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A=="], - - "@jsx-email/cli/vite/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.18.20", "", { "os": "openbsd", "cpu": "x64" }, "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg=="], - - "@jsx-email/cli/vite/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.18.20", "", { "os": "sunos", "cpu": "x64" }, "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ=="], - - "@jsx-email/cli/vite/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.18.20", "", { "os": "win32", "cpu": "arm64" }, "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg=="], - - "@jsx-email/cli/vite/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.18.20", "", { "os": "win32", "cpu": "ia32" }, "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g=="], - - "@jsx-email/cli/vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.18.20", "", { "os": "win32", "cpu": "x64" }, "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ=="], - - "@modelcontextprotocol/sdk/express/type-is/media-typer": ["media-typer@1.1.0", "", {}, "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw=="], - "@octokit/auth-app/@octokit/request-error/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="], "@octokit/auth-app/@octokit/request/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="], @@ -7170,240 +3922,20 @@ "@octokit/rest/@octokit/core/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="], - "@mendcode/desktop/@actions/artifact/@actions/http-client/undici": ["undici@5.29.0", "", { "dependencies": { "@fastify/busboy": "^2.0.0" } }, "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg=="], - - "@sentry/bundler-plugin-core/glob/minimatch/brace-expansion": ["brace-expansion@2.1.0", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w=="], - - "@sentry/bundler-plugin-core/glob/path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], - - "@sentry/bundler-plugin-core/glob/path-scurry/minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="], - - "@slack/web-api/form-data/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], - - "@solidjs/start/shiki/@shikijs/engine-javascript/oniguruma-to-es": ["oniguruma-to-es@2.3.0", "", { "dependencies": { "emoji-regex-xs": "^1.0.0", "regex": "^5.1.1", "regex-recursion": "^5.1.1" } }, "sha512-bwALDxriqfKGfUufKGGepCzu9x7nJQuoRoAFp4AnwehhC2crqrDIAP/uN2qdlsAvSMpeRC3+Yzhqc7hLmle5+g=="], - - "ai-gateway-provider/@ai-sdk/google-vertex/@ai-sdk/provider-utils/@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], - - "ai-gateway-provider/@ai-sdk/google/@ai-sdk/provider-utils/@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], - - "ai-gateway-provider/@ai-sdk/xai/@ai-sdk/provider-utils/@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], - - "ansi-align/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - - "app-builder-lib/@electron/get/fs-extra/universalify": ["universalify@0.1.2", "", {}, "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="], - "archiver-utils/glob/jackspeak/@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="], - "archiver-utils/glob/minimatch/brace-expansion": ["brace-expansion@2.1.0", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w=="], - "archiver-utils/glob/path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], - "astro/unstorage/chokidar/readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="], - - "astro/unstorage/h3/cookie-es": ["cookie-es@1.2.3", "", {}, "sha512-lXVyvUvrNXblMqzIRrxHb57UUVmqsSWlxqt3XIjCkUP0wDAf6uicO6KMbEgYrMNtEvWgWHwe42CKxPu9MYAnWw=="], - - "astro/unstorage/h3/crossws": ["crossws@0.3.5", "", { "dependencies": { "uncrypto": "^0.1.3" } }, "sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA=="], - - "babel-plugin-module-resolver/glob/minimatch/brace-expansion": ["brace-expansion@2.1.0", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w=="], - "babel-plugin-module-resolver/glob/path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], "babel-plugin-module-resolver/glob/path-scurry/minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="], - "dir-compare/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], - - "editorconfig/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], - - "electron-builder/yargs/cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - - "electron-builder/yargs/cliui/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], - - "electron-builder/yargs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], - - "electron-builder/yargs/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - - "esbuild-plugin-copy/chokidar/readdirp/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], - - "filelist/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], - - "gray-matter/js-yaml/argparse/sprintf-js": ["sprintf-js@1.0.3", "", {}, "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="], - - "iconv-corefoundation/cli-truncate/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], - - "iconv-corefoundation/cli-truncate/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - - "js-beautify/glob/jackspeak/@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="], - - "js-beautify/glob/minimatch/brace-expansion": ["brace-expansion@2.1.0", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w=="], - - "js-beautify/glob/path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], - - "mssql/tedious/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "opencontrol/@modelcontextprotocol/sdk/express/accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="], - - "opencontrol/@modelcontextprotocol/sdk/express/body-parser": ["body-parser@2.2.2", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.3", "http-errors": "^2.0.0", "iconv-lite": "^0.7.0", "on-finished": "^2.4.1", "qs": "^6.14.1", "raw-body": "^3.0.1", "type-is": "^2.0.1" } }, "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA=="], - - "opencontrol/@modelcontextprotocol/sdk/express/content-disposition": ["content-disposition@1.1.0", "", {}, "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g=="], - - "opencontrol/@modelcontextprotocol/sdk/express/cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="], - - "opencontrol/@modelcontextprotocol/sdk/express/cookie-signature": ["cookie-signature@1.2.2", "", {}, "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg=="], - - "opencontrol/@modelcontextprotocol/sdk/express/finalhandler": ["finalhandler@2.1.1", "", { "dependencies": { "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "on-finished": "^2.4.1", "parseurl": "^1.3.3", "statuses": "^2.0.1" } }, "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA=="], - - "opencontrol/@modelcontextprotocol/sdk/express/fresh": ["fresh@2.0.0", "", {}, "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A=="], - - "opencontrol/@modelcontextprotocol/sdk/express/merge-descriptors": ["merge-descriptors@2.0.0", "", {}, "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g=="], - - "opencontrol/@modelcontextprotocol/sdk/express/send": ["send@1.2.1", "", { "dependencies": { "debug": "^4.4.3", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.1", "mime-types": "^3.0.2", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.2" } }, "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ=="], - - "opencontrol/@modelcontextprotocol/sdk/express/serve-static": ["serve-static@2.2.1", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw=="], - - "opencontrol/@modelcontextprotocol/sdk/express/type-is": ["type-is@2.0.1", "", { "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw=="], - - "opentui-spinner/@opentui/solid/@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], - - "ora/bl/buffer/ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="], - - "pkg-dir/find-up/locate-path/p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="], - - "pkg-up/find-up/locate-path/p-locate": ["p-locate@3.0.0", "", { "dependencies": { "p-limit": "^2.0.0" } }, "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ=="], - - "pkg-up/find-up/locate-path/path-exists": ["path-exists@3.0.0", "", {}, "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ=="], - - "readdir-glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], - - "rimraf/glob/minimatch/brace-expansion": ["brace-expansion@1.1.14", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g=="], - - "tw-to-css/tailwindcss/chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], - - "tw-to-css/tailwindcss/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], - - "unplugin/chokidar/readdirp/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], - - "@astrojs/check/yargs/cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - - "@astrojs/check/yargs/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - - "@aws-sdk/client-cognito-identity/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.2.3", "", {}, "sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg=="], - - "@aws-sdk/client-sts/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - - "@aws-sdk/client-sts/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - - "@aws-sdk/client-sts/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.782.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.775.0", "@aws-sdk/middleware-host-header": "3.775.0", "@aws-sdk/middleware-logger": "3.775.0", "@aws-sdk/middleware-recursion-detection": "3.775.0", "@aws-sdk/middleware-user-agent": "3.782.0", "@aws-sdk/region-config-resolver": "3.775.0", "@aws-sdk/types": "3.775.0", "@aws-sdk/util-endpoints": "3.782.0", "@aws-sdk/util-user-agent-browser": "3.775.0", "@aws-sdk/util-user-agent-node": "3.782.0", "@smithy/config-resolver": "^4.1.0", "@smithy/core": "^3.2.0", "@smithy/fetch-http-handler": "^5.0.2", "@smithy/hash-node": "^4.0.2", "@smithy/invalid-dependency": "^4.0.2", "@smithy/middleware-content-length": "^4.0.2", "@smithy/middleware-endpoint": "^4.1.0", "@smithy/middleware-retry": "^4.1.0", "@smithy/middleware-serde": "^4.0.3", "@smithy/middleware-stack": "^4.0.2", "@smithy/node-config-provider": "^4.0.2", "@smithy/node-http-handler": "^4.0.4", "@smithy/protocol-http": "^5.1.0", "@smithy/smithy-client": "^4.2.0", "@smithy/types": "^4.2.0", "@smithy/url-parser": "^4.0.2", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", "@smithy/util-defaults-mode-browser": "^4.0.8", "@smithy/util-defaults-mode-node": "^4.0.8", "@smithy/util-endpoints": "^3.0.2", "@smithy/util-middleware": "^4.0.2", "@smithy/util-retry": "^4.0.2", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-QOYC8q7luzHFXrP0xYAqBctoPkynjfV0r9dqntFu4/IWMTyC1vlo1UTxFAjIPyclYw92XJyEkVCVg9v/nQnsUA=="], - - "@aws-sdk/client-sts/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - - "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/nested-clients/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.5.8", "", { "dependencies": { "fast-xml-builder": "^1.1.4", "path-expression-matcher": "^1.2.0", "strnum": "^2.2.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-Z7Fh2nVQSb2d+poDViM063ix2ZGt9jmY1nWhPfHBOK2Hgnb/OW3P4Et3P/81SEej0J7QbWtJqxO05h8QYfK7LQ=="], - - "@aws-sdk/credential-provider-env/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.2.3", "", {}, "sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg=="], - - "@aws-sdk/credential-provider-http/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.2.3", "", {}, "sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg=="], - - "@aws-sdk/credential-provider-ini/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.2.3", "", {}, "sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg=="], - - "@aws-sdk/credential-provider-login/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.2.3", "", {}, "sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg=="], - "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - "@aws-sdk/credential-provider-process/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.2.3", "", {}, "sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg=="], - - "@aws-sdk/credential-provider-sso/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.2.3", "", {}, "sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg=="], - - "@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.2.3", "", {}, "sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg=="], - - "@aws-sdk/credential-providers/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.2.3", "", {}, "sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg=="], - - "@aws-sdk/nested-clients/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.2.3", "", {}, "sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg=="], - - "@aws-sdk/token-providers/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.2.3", "", {}, "sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg=="], - - "@electron/rebuild/node-gyp/make-fetch-happen/@npmcli/agent/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], - - "@electron/rebuild/node-gyp/make-fetch-happen/cacache/@npmcli/fs": ["@npmcli/fs@4.0.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q=="], - - "@electron/rebuild/node-gyp/make-fetch-happen/cacache/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="], - - "@electron/rebuild/node-gyp/make-fetch-happen/cacache/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], - - "@electron/rebuild/node-gyp/make-fetch-happen/minipass-fetch/minipass-sized": ["minipass-sized@1.0.3", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g=="], - - "@electron/rebuild/yargs/cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - - "@electron/rebuild/yargs/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - - "@jsx-email/cli/tailwindcss/chokidar/readdirp/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], - - "@sentry/bundler-plugin-core/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], - - "@solidjs/start/shiki/@shikijs/engine-javascript/oniguruma-to-es/regex": ["regex@5.1.1", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-dN5I359AVGPnwzJm2jN1k0W9LPZ+ePvoOeVMMfqIMFz53sSwXkxaJoxr50ptnsC771lK95BnTrVSZxq0b9yCGw=="], - - "@solidjs/start/shiki/@shikijs/engine-javascript/oniguruma-to-es/regex-recursion": ["regex-recursion@5.1.1", "", { "dependencies": { "regex": "^5.1.1", "regex-utilities": "^2.3.0" } }, "sha512-ae7SBCbzVNrIjgSbh7wMznPcQel1DNlDtzensnFxpiNpXt1U2ju/bHugH422r+4LAVS1FpW1YCwilmnNsjum9w=="], - "archiver-utils/glob/jackspeak/@isaacs/cliui/string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="], "archiver-utils/glob/jackspeak/@isaacs/cliui/wrap-ansi": ["wrap-ansi@8.1.0", "", { "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" } }, "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ=="], - "archiver-utils/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], - - "babel-plugin-module-resolver/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], - - "electron-builder/yargs/cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - - "electron-builder/yargs/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - - "iconv-corefoundation/cli-truncate/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - - "js-beautify/glob/jackspeak/@isaacs/cliui/string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="], - - "js-beautify/glob/jackspeak/@isaacs/cliui/wrap-ansi": ["wrap-ansi@8.1.0", "", { "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" } }, "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ=="], - - "js-beautify/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], - - "opencontrol/@modelcontextprotocol/sdk/express/type-is/media-typer": ["media-typer@1.1.0", "", {}, "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw=="], - - "pkg-dir/find-up/locate-path/p-locate/p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="], - - "pkg-up/find-up/locate-path/p-locate/p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="], - - "rimraf/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], - - "tw-to-css/tailwindcss/chokidar/readdirp/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], - - "@aws-sdk/client-sts/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - - "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/nested-clients/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.2.3", "", {}, "sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg=="], - - "@electron/rebuild/node-gyp/make-fetch-happen/cacache/glob/jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="], - - "@electron/rebuild/node-gyp/make-fetch-happen/cacache/glob/minimatch": ["minimatch@9.0.9", "", { "dependencies": { "brace-expansion": "^2.0.2" } }, "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg=="], - - "@electron/rebuild/node-gyp/make-fetch-happen/cacache/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="], - - "@electron/rebuild/node-gyp/make-fetch-happen/minipass-fetch/minipass-sized/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], - "archiver-utils/glob/jackspeak/@isaacs/cliui/string-width/emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="], - - "archiver-utils/glob/jackspeak/@isaacs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], - - "js-beautify/glob/jackspeak/@isaacs/cliui/string-width/emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="], - - "js-beautify/glob/jackspeak/@isaacs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], - - "@electron/rebuild/node-gyp/make-fetch-happen/cacache/glob/jackspeak/@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="], - - "@electron/rebuild/node-gyp/make-fetch-happen/cacache/glob/minimatch/brace-expansion": ["brace-expansion@2.1.0", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w=="], - - "@electron/rebuild/node-gyp/make-fetch-happen/cacache/glob/jackspeak/@isaacs/cliui/string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="], - - "@electron/rebuild/node-gyp/make-fetch-happen/cacache/glob/jackspeak/@isaacs/cliui/wrap-ansi": ["wrap-ansi@8.1.0", "", { "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" } }, "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ=="], - - "@electron/rebuild/node-gyp/make-fetch-happen/cacache/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], - - "@electron/rebuild/node-gyp/make-fetch-happen/cacache/glob/jackspeak/@isaacs/cliui/string-width/emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="], - - "@electron/rebuild/node-gyp/make-fetch-happen/cacache/glob/jackspeak/@isaacs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], } } diff --git a/src/mendcode/bunfig.toml b/src/mendcode/bunfig.toml index 05de1b9e..6d0cfec4 100644 --- a/src/mendcode/bunfig.toml +++ b/src/mendcode/bunfig.toml @@ -1,6 +1,7 @@ [install] exact = true minimumReleaseAge = 604800 +minimumReleaseAgeExcludes = ["brace-expansion", "dompurify", "fast-uri", "hono", "undici"] [test] root = "./do-not-run-tests-from-root" diff --git a/src/mendcode/infra/app.ts b/src/mendcode/infra/app.ts index bb627f51..fabc0b61 100644 --- a/src/mendcode/infra/app.ts +++ b/src/mendcode/infra/app.ts @@ -8,6 +8,8 @@ const DISCORD_SUPPORT_BOT_TOKEN = new sst.Secret("DISCORD_SUPPORT_BOT_TOKEN") const DISCORD_SUPPORT_CHANNEL_ID = new sst.Secret("DISCORD_SUPPORT_CHANNEL_ID") const FEISHU_APP_ID = new sst.Secret("FEISHU_APP_ID") const FEISHU_APP_SECRET = new sst.Secret("FEISHU_APP_SECRET") +const FEISHU_VERIFICATION_TOKEN = new sst.Secret("FEISHU_VERIFICATION_TOKEN") +const FEISHU_ENCRYPT_KEY = new sst.Secret("FEISHU_ENCRYPT_KEY") const bucket = new sst.cloudflare.Bucket("Bucket") export const api = new sst.cloudflare.Worker("Api", { @@ -26,6 +28,8 @@ export const api = new sst.cloudflare.Worker("Api", { DISCORD_SUPPORT_CHANNEL_ID, FEISHU_APP_ID, FEISHU_APP_SECRET, + FEISHU_VERIFICATION_TOKEN, + FEISHU_ENCRYPT_KEY, ], transform: { worker: (args) => { diff --git a/src/mendcode/install b/src/mendcode/install index d79df202..90ca11ff 100755 --- a/src/mendcode/install +++ b/src/mendcode/install @@ -9,7 +9,12 @@ ARCHIVE_BINARY=mendcode MUTED='\033[0;2m' RED='\033[0;31m' -ORANGE='\033[38;5;214m' +MOSS_SOFT='\033[38;2;103;126;108m' +MOSS_BG='\033[48;2;10;30;23m' +PARCHMENT='\033[38;2;217;219;204m' +CORAL='\033[38;2;255;126;87m' +GREEN='\033[38;2;126;169;125m' +BOLD='\033[1m' NC='\033[0m' # No Color usage() { @@ -23,9 +28,14 @@ Options: -v, --version Install a specific version (e.g., 1.0.180) -b, --binary Install from a local binary instead of downloading --no-modify-path Don't modify shell config files (.zshrc, .bashrc, etc.) + --setup Open MendCode setup after install + --skip-setup Do not ask to open setup after install + --recover-lock Recover a lock only when its recorded process has exited Examples: curl -fsSL https://raw.githubusercontent.com/MendCode/MendCode/main/src/mendcode/install | bash + curl -fsSL https://raw.githubusercontent.com/MendCode/MendCode/main/src/mendcode/install | bash -s -- --setup + curl -fsSL https://raw.githubusercontent.com/MendCode/MendCode/main/src/mendcode/install | bash -s -- --skip-setup curl -fsSL https://raw.githubusercontent.com/MendCode/MendCode/main/src/mendcode/install | bash -s -- --version 1.0.180 ./install --binary /path/to/mendcode EOF @@ -34,6 +44,22 @@ EOF requested_version=${VERSION:-} no_modify_path=false binary_path="" +setup_mode="ask" +recover_lock=false + +print_message() { + local level=$1 + local message=$2 + local color="" + + case $level in + info) color="${NC}" ;; + warning) color="${NC}" ;; + error) color="${RED}" ;; + esac + + echo -e "${color}${message}${NC}" +} while [[ $# -gt 0 ]]; do case "$1" in @@ -63,16 +89,200 @@ while [[ $# -gt 0 ]]; do no_modify_path=true shift ;; + --setup) + setup_mode="run" + shift + ;; + --skip-setup) + setup_mode="skip" + shift + ;; + --recover-lock) + recover_lock=true + shift + ;; *) - echo -e "${ORANGE}Warning: Unknown option '$1'${NC}" >&2 + echo -e "${CORAL}Warning: Unknown option '$1'${NC}" >&2 shift ;; esac done INSTALL_DIR=$HOME/.mendcode/bin +GLOBAL_LAYOUT_SELECTION_FILE=$HOME/.mendcode/.global-layout-v1 +XDG_DATA_HOME=${XDG_DATA_HOME:-$HOME/.local/share} +MENDCODE_DATA_DIR=$XDG_DATA_HOME/mendcode +LEGACY_DATA_DIR=$XDG_DATA_HOME/opencode +had_mendcode_binary=false +if [ -x "$INSTALL_DIR/$BINARY_NAME" ] || [ -x "$INSTALL_DIR/$BINARY_NAME.exe" ]; then + had_mendcode_binary=true +fi mkdir -p "$INSTALL_DIR" +data_dir_has_identity() { + local dir=$1 + [ -d "$dir" ] || return 1 + find "$dir" -mindepth 1 -maxdepth 1 \( \ + -name storage -o \ + -name auth.json -o \ + -name mcp-auth.json -o \ + -name '*.db' -o \ + -name '.mendcode-json-storage-migration-v0.done' -o \ + -name '.mendcode-global-layout-v0.done' \ + \) -print -quit 2>/dev/null | grep -q . +} + +legacy_data_has_mendcode_identity() { + [ -d "$LEGACY_DATA_DIR" ] || return 1 + find "$LEGACY_DATA_DIR" -mindepth 1 -maxdepth 1 \( \ + -name 'mendcode*.db' -o \ + -name '.mendcode-json-storage-migration-v0.done' -o \ + -name '.mendcode-global-layout-v0.done' \ + \) -print -quit 2>/dev/null | grep -q . +} + +read_layout_selection() { + [ -f "$GLOBAL_LAYOUT_SELECTION_FILE" ] || return 1 + local value + value=$(tr -d '[:space:]' < "$GLOBAL_LAYOUT_SELECTION_FILE" | tr '[:upper:]' '[:lower:]') + case "$value" in + legacy|mendcode) + PERSISTED_GLOBAL_LAYOUT=$value + ;; + *) + print_message error "Invalid MendCode layout selection in $GLOBAL_LAYOUT_SELECTION_FILE. Expected legacy or mendcode." + exit 1 + ;; + esac +} + +resolve_install_layout() { + local requested=${MENDCODE_GLOBAL_LAYOUT:-} + requested=$(printf '%s' "$requested" | tr '[:upper:]' '[:lower:]' | tr -d '[:space:]') + case "$requested" in + legacy|mendcode) + SELECTED_GLOBAL_LAYOUT=$requested + return 0 + ;; + ""|auto) + ;; + *) + print_message error "Invalid MENDCODE_GLOBAL_LAYOUT value: $requested. Expected legacy, mendcode, or auto." + exit 1 + ;; + esac + + PERSISTED_GLOBAL_LAYOUT="" + if read_layout_selection; then + SELECTED_GLOBAL_LAYOUT=$PERSISTED_GLOBAL_LAYOUT + return 0 + fi + if data_dir_has_identity "$MENDCODE_DATA_DIR"; then + SELECTED_GLOBAL_LAYOUT=mendcode + return 0 + fi + if legacy_data_has_mendcode_identity; then + SELECTED_GLOBAL_LAYOUT=legacy + return 0 + fi + if [ "$had_mendcode_binary" = "true" ] && data_dir_has_identity "$LEGACY_DATA_DIR"; then + print_message error "Cannot safely identify $LEGACY_DATA_DIR as MendCode or external OpenCode data." + print_message info "Re-run with MENDCODE_GLOBAL_LAYOUT=legacy only if this data belongs to MendCode." + print_message info "Otherwise re-run with MENDCODE_GLOBAL_LAYOUT=mendcode to keep both applications isolated." + exit 1 + fi + if data_dir_has_identity "$LEGACY_DATA_DIR"; then + print_message warning "Existing OpenCode data detected at $LEGACY_DATA_DIR; MendCode will use its own isolated layout." + print_message info "If this is an uninstalled legacy MendCode layout, re-run with MENDCODE_GLOBAL_LAYOUT=legacy." + fi + SELECTED_GLOBAL_LAYOUT=mendcode +} + +SELECTED_GLOBAL_LAYOUT="" +resolve_install_layout + +persist_install_layout() { + local tmp="$GLOBAL_LAYOUT_SELECTION_FILE.$$" + mkdir -p "$(dirname "$GLOBAL_LAYOUT_SELECTION_FILE")" + printf '%s\n' "$SELECTED_GLOBAL_LAYOUT" > "$tmp" + mv "$tmp" "$GLOBAL_LAYOUT_SELECTION_FILE" +} + +operation="" +update_phase=checking +installed_sha256="" +previous_sha256="" +download_pid="" +update_lock="$INSTALL_DIR/.update-lock" +owns_update_lock=false + +record_update() { + [ -n "$operation" ] || return 0 + printf 'version=%s\nphase=%s\nowner_pid=%s\nexit_code=%s\nbinary_sha256=%s\nprevious_sha256=%s\n' \ + "${specific_version:-${requested_version:-unknown}}" "$update_phase" "$$" "${1:-}" "$installed_sha256" "$previous_sha256" > "$operation/status.next" + mv -f "$operation/status.next" "$operation/status" + printf 'MENDCODE_UPDATE_PHASE=%s\n' "$update_phase" +} + +finish_update() { + local code=$? + trap - EXIT + if [ -n "$download_pid" ]; then + kill -KILL "$download_pid" 2>/dev/null || true + wait "$download_pid" 2>/dev/null || true + fi + if [ "$owns_update_lock" = true ]; then + if [ "$code" -ne 0 ]; then + print_message error "Update failed during $update_phase. Recovery record: $operation/status" + fi + record_update "$code" || true + # Retain ownership evidence without leaving a lock after a normal exit. + mv "$update_lock" "$operation/lock" || true + fi + exit "$code" +} + +begin_update() { + operation=$(mktemp -d "$INSTALL_DIR/.update.XXXXXXXX") + chmod 700 "$operation" + if ! mkdir "$update_lock" 2>/dev/null; then + if [ "$recover_lock" != true ]; then + print_message error "Another update owns $update_lock. Inspect its owner record; use --recover-lock only after its process has exited." + exit 1 + fi + local owner + owner=$(sed -n 's/^pid=//p' "$update_lock/owner" 2>/dev/null || true) + if [[ ! "$owner" =~ ^[1-9][0-9]*$ ]] || kill -0 "$owner" 2>/dev/null || ps -p "$owner" >/dev/null 2>&1; then + print_message error "Cannot recover update lock: owner is live or ownership cannot be verified." + exit 1 + fi + # Elect one recoverer inside the old lock; contenders cannot move a new owner's lock. + if ! mkdir "$update_lock/recovering" 2>/dev/null; then + print_message error "Update lock recovery is already in progress." + exit 1 + fi + if [ "$(sed -n 's/^pid=//p' "$update_lock/owner" 2>/dev/null || true)" != "$owner" ] || \ + kill -0 "$owner" 2>/dev/null || ps -p "$owner" >/dev/null 2>&1; then + print_message error "Update lock ownership changed during recovery. No installation was changed." + exit 1 + fi + mv "$update_lock" "$operation/recovered-lock" + if ! mkdir "$update_lock" 2>/dev/null; then + print_message error "Another updater acquired the recovered lock. Retry after it exits." + exit 1 + fi + fi + owns_update_lock=true + trap finish_update EXIT + trap 'exit 130' INT + trap 'exit 143' TERM + chmod 700 "$update_lock" + printf 'pid=%s\noperation=%s\n' "$$" "$operation" > "$update_lock/owner" + record_update +} + +begin_update + # If --binary is provided, skip all download/detection logic if [ -n "$binary_path" ]; then if [ ! -f "$binary_path" ]; then @@ -186,8 +396,7 @@ else fi if [ -z "$requested_version" ]; then - url="$GITHUB_BASE_URL/releases/latest/download/$filename" - specific_version=$(curl -s "$GITHUB_API_URL/releases/latest" | sed -n 's/.*"tag_name": *"v\([^"]*\)".*/\1/p') + specific_version=$(curl --fail --show-error --silent --location --connect-timeout 15 --max-time 30 "$GITHUB_API_URL/releases/latest" | sed -n 's/.*"tag_name": *"v\([^"]*\)".*/\1/p') if [[ $? -ne 0 || -z "$specific_version" ]]; then echo -e "${RED}Failed to fetch version information${NC}" @@ -199,180 +408,180 @@ else url="$GITHUB_BASE_URL/releases/download/v${requested_version}/$filename" specific_version=$requested_version - # Verify the release exists before downloading - http_status=$(curl -sI -o /dev/null -w "%{http_code}" "$GITHUB_BASE_URL/releases/tag/v${requested_version}") - if [ "$http_status" = "404" ]; then - echo -e "${RED}Error: Release v${requested_version} not found${NC}" - echo -e "${MUTED}Available releases: $GITHUB_BASE_URL/releases${NC}" - exit 1 - fi fi + # Resolve latest once so the archive and checksums always belong to one release. + if [[ ! "$specific_version" =~ ^[0-9]+\.[0-9]+\.[0-9]+([-+][a-zA-Z0-9.+-]+)?$ ]]; then + print_message error "Invalid release version: $specific_version" + exit 1 + fi + url="$GITHUB_BASE_URL/releases/download/v${specific_version}/$filename" fi -print_message() { - local level=$1 - local message=$2 - local color="" - - case $level in - info) color="${NC}" ;; - warning) color="${NC}" ;; - error) color="${RED}" ;; - esac - - echo -e "${color}${message}${NC}" +print_banner() { + echo -e "" + echo -e "${MOSS_BG}${PARCHMENT} MendCode install deck ${NC} ${MOSS_SOFT}terminal-first coding${NC}" + printf "%b%s%b\n" "$PARCHMENT" "█▄ ▄█ █▀▀▀ █▄ █ █▀▀▄ █▀▀▀ █▀▀█ █▀▀▄ █▀▀▀ " "$NC" + printf "%b%s%b\n" "$PARCHMENT" "█ ▀ █ █▀▀▀ █ ▀ █ █ █ █ █ █ █ █ █▀▀▀ " "$NC" + printf "%b%s%b\n" "$PARCHMENT" "▀ ▀ ▀▀▀▀ ▀ ▀ ▀▀▀ ▀▀▀▀ ▀▀▀▀ ▀▀▀ ▀▀▀▀ " "$NC" + echo -e "" + printf "%b%s%b\n" "$MOSS_SOFT" ' .-.' "$NC" + printf "%b%s%b\n" "$MOSS_SOFT" ' (o o)' "$NC" + printf "%b%s%b\n" "$MOSS_SOFT" ' /|[+]|\' "$NC" + printf "%b%s%b\n" "$MOSS_SOFT" ' /_|___|_\' "$NC" + printf "%b%s%b\n" "$MOSS_SOFT" ' \_/' "$NC" + echo -e "" + echo -e "${BOLD}${PARCHMENT}MendCode installer${NC}" + echo -e "${MUTED}Version:${NC} $specific_version ${MUTED}Target:${NC} ${target:-local}" + echo -e "${MUTED}Install dir:${NC} $INSTALL_DIR" } -check_version() { - if command -v "$BINARY_NAME" >/dev/null 2>&1; then - installed_path=$(which "$BINARY_NAME") - - ## Check the installed version - installed_version=$("$installed_path" --version 2>/dev/null || echo "") - - if [[ "$installed_version" != "$specific_version" ]]; then - print_message info "${MUTED}Installed version: ${NC}$installed_version." - else - print_message info "${MUTED}Version ${NC}$specific_version${MUTED} already installed" - exit 0 - fi - fi +print_step() { + local current="$1" + local total="$2" + local message="$3" + echo -e "${CORAL}◆ $current/$total${NC} ${BOLD}$message${NC}" } -unbuffered_sed() { - if echo | sed -u -e "" >/dev/null 2>&1; then - sed -nu "$@" - elif echo | sed -l -e "" >/dev/null 2>&1; then - sed -nl "$@" - else - local pad="$(printf "\n%512s" "")" - sed -ne "s/$/\\${pad}/" "$@" - fi +print_success() { + echo -e "${GREEN}✓${NC} $1" } -print_progress() { - local bytes="$1" - local length="$2" - [ "$length" -gt 0 ] || return 0 - - local width=50 - local percent=$(( bytes * 100 / length )) - [ "$percent" -gt 100 ] && percent=100 - local on=$(( percent * width / 100 )) - local off=$(( width - on )) - - local filled=$(printf "%*s" "$on" "") - filled=${filled// /■} - local empty=$(printf "%*s" "$off" "") - empty=${empty// /・} - - printf "\r${ORANGE}%s%s %3d%%${NC}" "$filled" "$empty" "$percent" >&4 -} - -download_with_progress() { - local url="$1" - local output="$2" - - if [ -t 2 ]; then - exec 4>&2 - else - exec 4>/dev/null - fi - - local tmp_dir=${TMPDIR:-/tmp} - local basename="${tmp_dir}/mendcode_install_$$" - local tracefile="${basename}.trace" - - rm -f "$tracefile" - mkfifo "$tracefile" - - # Hide cursor - printf "\033[?25l" >&4 - - trap "trap - RETURN; rm -f \"$tracefile\"; printf '\033[?25h' >&4; exec 4>&-" RETURN - - ( - curl --trace-ascii "$tracefile" -s -L -o "$output" "$url" - ) & - local curl_pid=$! - - unbuffered_sed \ - -e 'y/ACDEGHLNORTV/acdeghlnortv/' \ - -e '/^0000: content-length:/p' \ - -e '/^<= recv data/p' \ - "$tracefile" | \ - { - local length=0 - local bytes=0 - - while IFS=" " read -r -a line; do - [ "${#line[@]}" -lt 2 ] && continue - local tag="${line[0]} ${line[1]}" - - if [ "$tag" = "0000: content-length:" ]; then - length="${line[2]}" - length=$(echo "$length" | tr -d '\r') - bytes=0 - elif [ "$tag" = "<= recv" ]; then - local size="${line[3]}" - bytes=$(( bytes + size )) - if [ "$length" -gt 0 ]; then - print_progress "$bytes" "$length" - fi - fi - done - } - - wait $curl_pid - local ret=$? - echo "" >&4 - return $ret -} +STEP_TOTAL=4 +PATH_STEP=4 download_and_install() { - print_message info "\n${MUTED}Installing ${NC}MendCode ${MUTED}version: ${NC}$specific_version" - local tmp_dir="${TMPDIR:-/tmp}/mendcode_install_$$" - mkdir -p "$tmp_dir" - - if [[ "$os" == "windows" ]] || ! [ -t 2 ] || ! download_with_progress "$url" "$tmp_dir/$filename"; then - # Fallback to standard curl on Windows, non-TTY environments, or if custom progress fails - curl -# -L -o "$tmp_dir/$filename" "$url" + print_banner + print_step 1 4 "Preparing download" + local tmp_dir=$operation + + print_step 2 4 "Downloading release asset" + update_phase=downloading + record_update + curl --fail --show-error --silent --location --connect-timeout 15 --speed-limit 1 --speed-time 60 --max-time 900 \ + --dump-header "$tmp_dir/download.headers" -o "$tmp_dir/$filename" "$url" & + download_pid=$! + while kill -0 "$download_pid" 2>/dev/null; do + if [ -f "$tmp_dir/$filename" ]; then + local bytes total + bytes=$(wc -c < "$tmp_dir/$filename" | tr -d '[:space:]') + total="" + if [ -f "$tmp_dir/download.headers" ]; then + total=$(awk '/^HTTP\// {size=""} tolower($1) == "content-length:" {size=$2} END {gsub("\\r", "", size); print size}' "$tmp_dir/download.headers") + fi + [[ "$total" =~ ^[0-9]+$ ]] || total="" + printf 'MENDCODE_UPDATE_BYTES=%s/%s\n' "$bytes" "$total" + fi + sleep 1 + done + if ! wait "$download_pid"; then + download_pid="" + print_message error "Downloading failed. Current binary preserved; staging: $tmp_dir" + exit 1 fi - - if [ "$os" = "linux" ]; then - tar -xzf "$tmp_dir/$filename" -C "$tmp_dir" + download_pid="" + printf 'MENDCODE_UPDATE_BYTES=%s/\n' "$(wc -c < "$tmp_dir/$filename" | tr -d '[:space:]')" + print_success "Downloaded $filename" + + print_step 3 4 "Verifying release checksum" + update_phase=verifying + record_update + if [ -n "${MENDCODE_VERIFIED_SUMS_FILE:-}" ]; then + cp "$MENDCODE_VERIFIED_SUMS_FILE" "$tmp_dir/SHA256SUMS" + elif ! curl --fail --show-error --silent --location --connect-timeout 15 --max-time 30 \ + -o "$tmp_dir/SHA256SUMS" "${url%/*}/SHA256SUMS"; then + print_message error "Verifying failed: cannot download SHA256SUMS. Current binary preserved." + exit 1 + fi + local expected actual + expected=$(awk -v name="$filename" '$2 == name || $2 == "./" name {print $1}' "$tmp_dir/SHA256SUMS") + if [[ ! "$expected" =~ ^[a-fA-F0-9]{64}$ ]]; then + print_message error "Verifying failed: missing, duplicate, or invalid checksum for $filename." + exit 1 + fi + if command -v sha256sum >/dev/null 2>&1; then + actual=$(sha256sum "$tmp_dir/$filename" | awk '{print $1}') + elif command -v shasum >/dev/null 2>&1; then + actual=$(shasum -a 256 "$tmp_dir/$filename" | awk '{print $1}') else - unzip -q "$tmp_dir/$filename" -d "$tmp_dir" + print_message error "Verifying failed: sha256sum or shasum is required." + exit 1 fi - + if [[ "$(printf '%s' "$actual" | tr 'A-F' 'a-f')" != "$(printf '%s' "$expected" | tr 'A-F' 'a-f')" ]]; then + print_message error "Verifying failed: checksum mismatch. Current binary preserved; staging: $tmp_dir" + exit 1 + fi + # Extract only the executable, never archive-controlled paths or symlinks. local extracted="$tmp_dir/$ARCHIVE_BINARY" - if [ "$os" = "windows" ] && [ -f "$tmp_dir/$ARCHIVE_BINARY.exe" ]; then - extracted="$tmp_dir/$ARCHIVE_BINARY.exe" - BINARY_NAME=mendcode.exe + if [ "$os" = "linux" ]; then + tar -xOzf "$tmp_dir/$filename" "$ARCHIVE_BINARY" > "$extracted" + else + if [ "$os" = "windows" ]; then + BINARY_NAME=mendcode.exe + extracted="$tmp_dir/$BINARY_NAME" + unzip -p "$tmp_dir/$filename" "$ARCHIVE_BINARY.exe" > "$extracted" + else + unzip -p "$tmp_dir/$filename" "$ARCHIVE_BINARY" > "$extracted" + fi fi - if [ ! -f "$extracted" ]; then + if [ ! -s "$extracted" ]; then echo -e "${RED}Error: Release asset did not contain $ARCHIVE_BINARY${NC}" exit 1 fi - mv "$extracted" "$INSTALL_DIR/$BINARY_NAME" - chmod 755 "${INSTALL_DIR}/$BINARY_NAME" - rm -rf "$tmp_dir" + activate_binary "$extracted" "$tmp_dir" + print_success "Installed ${INSTALL_DIR}/$BINARY_NAME" +} + +activate_binary() { + local staged=$1 + local operation=$2 + if command -v sha256sum >/dev/null 2>&1; then + installed_sha256=$(sha256sum "$staged" | awk '{print $1}') + elif command -v shasum >/dev/null 2>&1; then + installed_sha256=$(shasum -a 256 "$staged" | awk '{print $1}') + else + print_message error "Cannot record executable identity: sha256sum or shasum is required." + exit 1 + fi + chmod 755 "$staged" + if [ -f "$INSTALL_DIR/$BINARY_NAME" ]; then + cp -p "$INSTALL_DIR/$BINARY_NAME" "$operation/previous" + if command -v sha256sum >/dev/null 2>&1; then + previous_sha256=$(sha256sum "$operation/previous" | awk '{print $1}') + else + previous_sha256=$(shasum -a 256 "$operation/previous" | awk '{print $1}') + fi + fi + update_phase=activating + record_update + mv -f "$staged" "$INSTALL_DIR/$BINARY_NAME" + update_phase=activated + record_update + print_message info "Recovery files retained at $operation; startup readiness has not been checked." } install_from_binary() { - print_message info "\n${MUTED}Installing ${NC}MendCode ${MUTED}from: ${NC}$binary_path" - cp "$binary_path" "${INSTALL_DIR}/$BINARY_NAME" - chmod 755 "${INSTALL_DIR}/$BINARY_NAME" + specific_version="local" + target="local" + STEP_TOTAL=2 + PATH_STEP=2 + print_banner + print_step 1 "$STEP_TOTAL" "Installing local binary" + cp "$binary_path" "$operation/candidate" + activate_binary "$operation/candidate" "$operation" + print_success "Installed ${INSTALL_DIR}/$BINARY_NAME" } if [ -n "$binary_path" ]; then install_from_binary else - check_version + # Recovery must work even when the currently installed executable cannot start. download_and_install fi +persist_install_layout + +print_message info "Existing sessions and services keep running. Restart them when their work is finished." add_to_path() { local config_file=$1 @@ -416,6 +625,7 @@ case $current_shell in esac if [[ "$no_modify_path" != "true" ]]; then + print_step "$PATH_STEP" "$STEP_TOTAL" "Updating PATH" config_file="" for file in $config_files; do if [[ -f $file ]]; then @@ -450,7 +660,11 @@ if [[ "$no_modify_path" != "true" ]]; then print_message info " export PATH=$INSTALL_DIR:\$PATH" ;; esac + else + print_success "PATH already includes $INSTALL_DIR" fi +else + print_message info "${MUTED}Skipping PATH update because --no-modify-path was set.${NC}" fi if [ -n "${GITHUB_ACTIONS-}" ] && [ "${GITHUB_ACTIONS}" == "true" ]; then @@ -458,13 +672,65 @@ if [ -n "${GITHUB_ACTIONS-}" ] && [ "${GITHUB_ACTIONS}" == "true" ]; then print_message info "Added $INSTALL_DIR to \$GITHUB_PATH" fi +launch_setup() { + local bin_path="$INSTALL_DIR/$BINARY_NAME" + if [ ! -x "$bin_path" ]; then + print_message warning "Setup is available after the binary is executable: $bin_path" + return 0 + fi + + echo -e "" + print_message info "${MOSS_SOFT}Opening MendCode setup...${NC}" + MENDCODE_GLOBAL_LAYOUT="$SELECTED_GLOBAL_LAYOUT" OPENCODE_ROUTE='{"type":"setup"}' "$bin_path" +} + +print_setup_command() { + local route='{"type":"setup"}' + print_message info "${MUTED}Setup later:${NC} MENDCODE_GLOBAL_LAYOUT='$SELECTED_GLOBAL_LAYOUT' OPENCODE_ROUTE='$route' \"$INSTALL_DIR/$BINARY_NAME\"" +} + +maybe_launch_setup() { + if [ "$setup_mode" = "skip" ]; then + print_setup_command + return 0 + fi + + if [ "$setup_mode" = "run" ]; then + launch_setup + return 0 + fi + + if [ ! -r /dev/tty ] || [ ! -w /dev/tty ] || ! { : < /dev/tty > /dev/tty; } 2>/dev/null; then + print_setup_command + return 0 + fi + + echo -e "" + echo -e "${BOLD}${PARCHMENT}Finish setup now?${NC} ${MOSS_SOFT}Providers, models, packages, memory, and permissions.${NC}" + printf "%b" "${CORAL}Open setup now?${NC} ${MUTED}[Y/n]${NC} " > /dev/tty + local answer="" + read -r answer < /dev/tty || answer="" + answer=$(printf "%s" "$answer" | tr '[:upper:]' '[:lower:]') + case "$answer" in + ""|y|yes|s|si|sí|setup|open) + launch_setup + ;; + *) + print_setup_command + ;; + esac +} + echo -e "" -echo -e "${MUTED}MendCode includes free models, to start:${NC}" +echo -e "${GREEN}MendCode is ready.${NC}" echo -e "" -echo -e "cd ${MUTED}# Open directory${NC}" +echo -e " cd ${MUTED}# open your repo${NC}" +echo -e " ${INSTALL_DIR}/$BINARY_NAME ${MUTED}# run now in this terminal${NC}" echo -e "" -echo -e "mendcode ${MUTED}# Open MendCode; first run opens setup${NC}" +echo -e "${MUTED}Open a new terminal to use:${NC} mendcode" +echo -e "${MUTED}Or update this terminal now:${NC} export PATH=$INSTALL_DIR:\$PATH" echo -e "" -echo -e "${MUTED}For more information visit ${NC}$GITHUB_BASE_URL" +echo -e "${MUTED}Docs and releases:${NC} $GITHUB_BASE_URL" +maybe_launch_setup echo -e "" echo -e "" diff --git a/src/mendcode/install.cmd b/src/mendcode/install.cmd new file mode 100644 index 00000000..83956006 --- /dev/null +++ b/src/mendcode/install.cmd @@ -0,0 +1,93 @@ +@echo off +setlocal EnableExtensions EnableDelayedExpansion + +set "APP=mendcode" +set "BASE_URL=https://github.com/MendCode/MendCode" +if defined MENDCODE_GITHUB_BASE_URL set "BASE_URL=%MENDCODE_GITHUB_BASE_URL%" + +set "TARGET=%MENDCODE_WINDOWS_TARGET%" +if not defined TARGET ( + set "ARCH=%PROCESSOR_ARCHITEW6432%" + if not defined ARCH set "ARCH=%PROCESSOR_ARCHITECTURE%" + if /I "!ARCH!"=="AMD64" set "TARGET=windows-x64-baseline" + if /I "!ARCH!"=="ARM64" set "TARGET=windows-arm64" +) + +if not defined TARGET ( + echo Unsupported Windows architecture: %PROCESSOR_ARCHITEW6432% %PROCESSOR_ARCHITECTURE% + exit /b 1 +) + +if defined MENDCODE_VERSION ( + set "DOWNLOAD_URL=!BASE_URL!/releases/download/v%MENDCODE_VERSION%/%APP%-!TARGET!.zip" +) else ( + set "DOWNLOAD_URL=!BASE_URL!/releases/latest/download/%APP%-!TARGET!.zip" +) + +where.exe curl.exe >nul 2>&1 +if errorlevel 1 ( + echo curl.exe is required. Download the Windows ZIP directly from: + echo !DOWNLOAD_URL! + exit /b 1 +) + +where.exe tar.exe >nul 2>&1 +if errorlevel 1 ( + echo tar.exe is required to extract the release. Download the Windows ZIP directly from: + echo !DOWNLOAD_URL! + exit /b 1 +) + +set "INSTALL_DIR=%USERPROFILE%\.mendcode\bin" +set "TEMP_DIR=%TEMP%\mendcode-install-%RANDOM%-%RANDOM%" +set "ZIP_FILE=!TEMP_DIR!\%APP%-!TARGET!.zip" +mkdir "!TEMP_DIR!" >nul 2>&1 +if errorlevel 1 ( + echo Could not create temporary directory: !TEMP_DIR! + exit /b 1 +) + +echo Downloading MendCode (!TARGET!)... +curl.exe --fail --silent --show-error --location "!DOWNLOAD_URL!" --output "!ZIP_FILE!" +if errorlevel 1 ( + rmdir /s /q "!TEMP_DIR!" >nul 2>&1 + echo Download failed. + exit /b 1 +) + +mkdir "!INSTALL_DIR!" >nul 2>&1 +tar.exe -xf "!ZIP_FILE!" -C "!TEMP_DIR!" +if errorlevel 1 ( + rmdir /s /q "!TEMP_DIR!" >nul 2>&1 + echo Could not extract the MendCode ZIP. + exit /b 1 +) + +set "BINARY=" +for /r "!TEMP_DIR!" %%F in (mendcode.exe) do if not defined BINARY set "BINARY=%%~fF" +if not defined BINARY ( + rmdir /s /q "!TEMP_DIR!" >nul 2>&1 + echo Release asset did not contain mendcode.exe. + exit /b 1 +) + +copy /y "!BINARY!" "!INSTALL_DIR!\mendcode.exe" >nul +if errorlevel 1 ( + rmdir /s /q "!TEMP_DIR!" >nul 2>&1 + echo Could not install MendCode to !INSTALL_DIR!. + exit /b 1 +) +rmdir /s /q "!TEMP_DIR!" >nul 2>&1 + +set "USER_PATH=" +for /f "tokens=2,*" %%A in ('reg.exe query HKCU\Environment /v Path 2^>nul') do if /I "%%A"=="Path" set "USER_PATH=%%B" +if not defined USER_PATH set "USER_PATH=!INSTALL_DIR!" +echo;!USER_PATH!;| findstr.exe /I /C:";!INSTALL_DIR!;" >nul +if errorlevel 1 reg.exe add HKCU\Environment /v Path /t REG_EXPAND_SZ /d "!USER_PATH!;!INSTALL_DIR!" /f >nul +set "PATH=!INSTALL_DIR!;!PATH!" + +echo. +echo MendCode is ready at !INSTALL_DIR!\mendcode.exe +"!INSTALL_DIR!\mendcode.exe" --version +echo Open a new terminal to use: mendcode +endlocal diff --git a/src/mendcode/install.ps1 b/src/mendcode/install.ps1 new file mode 100644 index 00000000..24d6e8e4 --- /dev/null +++ b/src/mendcode/install.ps1 @@ -0,0 +1,572 @@ +param( + [string]$Version = $env:VERSION, + [switch]$NoModifyPath, + [switch]$Setup, + [switch]$SkipSetup, + [int]$WaitForExitPid = 0, + [long]$WaitForExitStartedAt = 0, + [switch]$RecoverLock, + [string]$ActivateOperation, + [string]$OperationToken +) + +$ErrorActionPreference = "Stop" + +$App = "mendcode" +if ($env:MENDCODE_NO_MODIFY_PATH -eq "1") { $NoModifyPath = $true } +$SetupMode = if ($SkipSetup) { "skip" } elseif ($Setup) { "run" } else { "ask" } +$Repo = if ($env:MENDCODE_GITHUB_REPO) { $env:MENDCODE_GITHUB_REPO } else { "MendCode/MendCode" } +$BaseUrl = if ($env:MENDCODE_GITHUB_BASE_URL) { $env:MENDCODE_GITHUB_BASE_URL } else { "https://github.com/$Repo" } +$ApiUrl = if ($env:MENDCODE_GITHUB_API_URL) { $env:MENDCODE_GITHUB_API_URL } else { "https://api.github.com/repos/$Repo" } +$InstallHome = if ($env:OPENCODE_TEST_HOME) { $env:OPENCODE_TEST_HOME } else { $HOME } +$InstallDir = [IO.Path]::GetFullPath((Join-Path $InstallHome ".mendcode\bin")) +$LockDir = Join-Path $InstallDir ".update-lock" +$Utf8 = New-Object System.Text.UTF8Encoding($false) +$script:HaveLock = $false +$script:Operation = $null +$script:Phase = "checking" +$script:BinaryDigest = "" +$script:PreviousDigest = "" +$script:Token = [Guid]::NewGuid().ToString("N") + +function Assert-RegularPath([string]$Path) { + if ((Test-Path -LiteralPath $Path) -and ((Get-Item -LiteralPath $Path -Force).Attributes -band [IO.FileAttributes]::ReparsePoint)) { + throw "Refusing a redirected update path: $Path" + } +} + +function Get-MendCodeFileDigest([string]$Path) { + # Avoid module auto-loading differences when PowerShell 7 launches 5.1. + $hash = [Security.Cryptography.SHA256]::Create() + $stream = [IO.File]::OpenRead($Path) + try { return [BitConverter]::ToString($hash.ComputeHash($stream)).Replace("-", "").ToLowerInvariant() } + finally { $stream.Dispose(); $hash.Dispose() } +} + +function Write-AtomicText([string]$Path, [string]$Text) { + Assert-RegularPath $Path + $temporary = "$Path.$([Guid]::NewGuid().ToString('N')).tmp" + $stream = [IO.File]::Open($temporary, [IO.FileMode]::CreateNew, [IO.FileAccess]::Write, [IO.FileShare]::None) + try { + $bytes = $Utf8.GetBytes($Text) + $stream.Write($bytes, 0, $bytes.Length) + $stream.Flush($true) + } finally { $stream.Dispose() } + # A plain $null becomes an empty backup path in Windows PowerShell 5.1. + if ([IO.File]::Exists($Path)) { [IO.File]::Replace($temporary, $Path, [System.Management.Automation.Language.NullString]::Value) } + else { [IO.File]::Move($temporary, $Path) } +} + +function Write-UpdateStatus([int]$ExitCode = 0) { + if (-not $script:Operation) { return } + # LF and BOM-free UTF-8 are shared with the startup receipt reader. + Write-AtomicText (Join-Path $script:Operation "status") ( + "version=$Version`nphase=$script:Phase`nowner_pid=$PID`nexit_code=$ExitCode`nbinary_sha256=$script:BinaryDigest`nprevious_sha256=$script:PreviousDigest`n" + ) + Write-Host "MENDCODE_UPDATE_PHASE=$script:Phase" +} + +function Read-LockOwner { + Assert-RegularPath $LockDir + $file = Join-Path $LockDir "owner.json" + Assert-RegularPath $file + if (-not [IO.File]::Exists($file) -or (Get-Item -LiteralPath $file).Length -gt 4096) { throw "Update lock owner cannot be verified." } + $owner = [IO.File]::ReadAllText($file) | ConvertFrom-Json + if (-not $owner.pid -or [long]$owner.pid -le 0 -or -not $owner.token) { throw "Update lock owner is invalid." } + return $owner +} + +function Write-LockOwner { + Write-AtomicText (Join-Path $LockDir "owner.json") ((@{ + pid = $PID; startedAt = (Get-Process -Id $PID).StartTime.ToUniversalTime().Ticks + token = $script:Token; operation = $script:Operation + } | ConvertTo-Json -Compress) + "`n") +} + +function Acquire-UpdateLock { + if (Test-Path -LiteralPath $LockDir) { + $owner = Read-LockOwner + if (-not $RecoverLock -or (Get-Process -Id $owner.pid -ErrorAction SilentlyContinue)) { + throw "Another updater owns the lock (PID $($owner.pid)). Recover only a dead owner with -RecoverLock." + } + # Election prevents concurrent recoverers from moving a newly acquired lock. + $election = [IO.File]::Open((Join-Path $LockDir "recovering"), [IO.FileMode]::CreateNew, [IO.FileAccess]::Write, [IO.FileShare]::None) + try { + $current = Read-LockOwner + if ($current.token -ne $owner.token -or $current.pid -ne $owner.pid -or (Get-Process -Id $current.pid -ErrorAction SilentlyContinue)) { + throw "Update lock ownership changed; recovery stopped." + } + } finally { $election.Dispose() } + [IO.Directory]::Move($LockDir, (Join-Path $script:Operation "recovered-lock")) + } + New-Item -ItemType Directory -Path $LockDir -ErrorAction Stop | Out-Null + $script:HaveLock = $true + Write-LockOwner +} + +function Release-UpdateLock { + if (-not $script:HaveLock) { return } + $owner = Read-LockOwner + if ($owner.token -ne $script:Token -or [long]$owner.pid -ne $PID) { throw "Updater no longer owns its lock." } + [IO.Directory]::Move($LockDir, (Join-Path $script:Operation "lock")) + $script:HaveLock = $false +} + +function Receive-UpdateFile([string]$Url, [string]$Destination, [long]$MaxBytes = 2147483648) { + $uri = [Uri]$Url + if ($uri.Scheme -ne "https" -and -not ($uri.Scheme -eq "http" -and $uri.IsLoopback)) { throw "Downloads require HTTPS." } + Add-Type -AssemblyName System.Net.Http + $client = New-Object System.Net.Http.HttpClient + $client.Timeout = [Threading.Timeout]::InfiniteTimeSpan + $client.DefaultRequestHeaders.UserAgent.ParseAdd("MendCode-Updater") + $cancel = New-Object Threading.CancellationTokenSource + $watch = [Diagnostics.Stopwatch]::StartNew() + $response = $null; $source = $null; $output = $null + try { + # Works on Windows PowerShell 5.1: the header deadline includes connection setup. + $headers = $client.GetAsync($uri, [Net.Http.HttpCompletionOption]::ResponseHeadersRead, $cancel.Token) + if (-not $headers.Wait(15000)) { throw "Connection/response headers timed out after 15 seconds." } + $response = $headers.GetAwaiter().GetResult() + $response.EnsureSuccessStatusCode() | Out-Null + $source = $response.Content.ReadAsStreamAsync().GetAwaiter().GetResult() + $output = [IO.File]::Open($Destination, [IO.FileMode]::CreateNew, [IO.FileAccess]::Write, [IO.FileShare]::Read) + $buffer = New-Object byte[] 65536 + [long]$received = 0 + $lastReport = -1000 + while ($true) { + $remaining = 900000 - $watch.ElapsedMilliseconds + if ($remaining -le 0) { throw "Download exceeded 15 minutes." } + $read = $source.ReadAsync($buffer, 0, $buffer.Length, $cancel.Token) + if (-not $read.Wait([int][Math]::Min(60000, $remaining))) { throw "Download stalled for 60 seconds or exceeded its total deadline." } + $count = $read.GetAwaiter().GetResult() + if ($count -eq 0) { break } + $received += $count + if ($received -gt $MaxBytes) { throw "Download exceeds the size limit." } + $output.Write($buffer, 0, $count) + if ($watch.ElapsedMilliseconds - $lastReport -ge 1000) { + Write-Host "MENDCODE_UPDATE_BYTES=$received/$($response.Content.Headers.ContentLength)" + $lastReport = $watch.ElapsedMilliseconds + } + } + if ($null -ne $response.Content.Headers.ContentLength -and $received -ne $response.Content.Headers.ContentLength) { throw "Downloaded file was truncated." } + $output.Flush($true) + Write-Host "MENDCODE_UPDATE_BYTES=$received/$received" + } finally { + $cancel.Cancel() + if ($output) { $output.Dispose() } + if ($source) { $source.Dispose() } + if ($response) { $response.Dispose() } + $client.Dispose(); $cancel.Dispose() + } +} + +function Write-MendCodeBanner { + param( + [string]$VersionLabel, + [string]$Target + ) + + Write-Host "" + Write-Host ' MendCode install deck · terminal-first coding' -ForegroundColor DarkGreen + Write-Host '█▄ ▄█ █▀▀▀ █▄ █ █▀▀▄ █▀▀▀ █▀▀█ █▀▀▄ █▀▀▀ ' -ForegroundColor Yellow + Write-Host '█ ▀ █ █▀▀▀ █ ▀ █ █ █ █ █ █ █ █ █▀▀▀ ' -ForegroundColor Yellow + Write-Host '▀ ▀ ▀▀▀▀ ▀ ▀ ▀▀▀ ▀▀▀▀ ▀▀▀▀ ▀▀▀ ▀▀▀▀ ' -ForegroundColor Yellow + Write-Host '' + Write-Host ' .-.' -ForegroundColor DarkGreen + Write-Host ' (o o)' -ForegroundColor DarkGreen + Write-Host ' /|[+]|\' -ForegroundColor DarkGreen + Write-Host ' /_|___|_\' -ForegroundColor DarkGreen + Write-Host ' \_/' -ForegroundColor DarkGreen + Write-Host "" + Write-Host "MendCode installer" + Write-Host "Version: $VersionLabel Target: $Target" + Write-Host "Install dir: $InstallDir" +} + +function Write-Step { + param( + [int]$Current, + [int]$Total, + [string]$Message + ) + Write-Host "◆ $Current/$Total $Message" -ForegroundColor Yellow +} + +function Write-Ok { + param([string]$Message) + # Windows PowerShell 5.1 reads BOM-less scripts using the system code page. + Write-Host "$([char]0x2713) $Message" -ForegroundColor Green +} + +function Invoke-MendCodeSetup { + $binary = Join-Path $InstallDir "mendcode.exe" + if (-not (Test-Path $binary)) { + Write-Host "Setup is available after the binary is installed: $binary" -ForegroundColor Yellow + return + } + + Write-Host "" + Write-Host "Opening MendCode setup..." -ForegroundColor DarkGreen + $previousRoute = $env:OPENCODE_ROUTE + $env:OPENCODE_ROUTE = '{"type":"setup"}' + try { + & $binary + } finally { + if ($null -eq $previousRoute) { Remove-Item Env:OPENCODE_ROUTE -ErrorAction SilentlyContinue } + else { $env:OPENCODE_ROUTE = $previousRoute } + } +} + +function Write-SetupCommand { + $binary = Join-Path $InstallDir "mendcode.exe" + Write-Host ('Setup later: $env:OPENCODE_ROUTE=''{"type":"setup"}''; & "' + $binary + '"') -ForegroundColor DarkGray +} + +function Wait-MendCodeProcessExit { + param([int]$ProcessId, [long]$StartedAt) + if ($ProcessId -le 0) { return } + if ($StartedAt -le 0) { throw "Cannot verify the process identity to wait for." } + $script:Phase = "waiting-for-restart" + Write-UpdateStatus + $deadline = [DateTime]::UtcNow.AddHours(24) + Write-AtomicText (Join-Path $script:Operation "waiting.json") ((@{ pid = $ProcessId; startedAt = $StartedAt; deadline = $deadline.ToString("o") } | ConvertTo-Json) + "`n") + while ($true) { + $parent = Get-Process -Id $ProcessId -ErrorAction SilentlyContinue + if (-not $parent) { return } + # PID reuse must never wait on or stop an unrelated process. + if ($parent.StartTime.ToUniversalTime().Ticks -ne $StartedAt) { return } + if ([DateTime]::UtcNow -ge $deadline) { throw "Still waiting for MendCode to close after 24 hours. Current binary preserved; run upgrade again after closing it." } + Start-Sleep -Milliseconds 500 + } +} + +function Start-DeferredUpdate { + if (-not $env:MENDCODE_UPDATE_PARENT_PID) { return $false } + + [int]$parentPid = 0 + if (-not [int]::TryParse($env:MENDCODE_UPDATE_PARENT_PID, [ref]$parentPid) -or $parentPid -le 0) { + throw "MendCode could not schedule the Windows updater: invalid parent process id." + } + $parent = Get-Process -Id $parentPid -ErrorAction SilentlyContinue + if (-not $parent) { return $false } + $parentStartedAt = $parent.StartTime.ToUniversalTime().Ticks + + $shell = Get-Command powershell.exe -ErrorAction SilentlyContinue + if (-not $shell) { $shell = Get-Command pwsh.exe -ErrorAction SilentlyContinue } + if (-not $shell) { + throw "MendCode could not schedule the Windows updater because PowerShell is unavailable." + } + + $workerArguments = [System.Collections.Generic.List[string]]::new() + $workerArguments.Add("-NoProfile") + $workerArguments.Add("-NonInteractive") + $workerArguments.Add("-ExecutionPolicy") + $workerArguments.Add("Bypass") + $workerArguments.Add("-File") + # Retain the exact verified installer with this operation, rather than a shared TEMP script. + $workerScript = Join-Path $script:Operation "installer.ps1" + [IO.File]::Copy($PSCommandPath, $workerScript) + $workerArguments.Add('"' + $workerScript + '"') + if ($Version) { + $workerArguments.Add("-Version") + $workerArguments.Add($Version) + } + if ($NoModifyPath) { $workerArguments.Add("-NoModifyPath") } + $workerArguments.Add("-SkipSetup") + $workerArguments.Add("-WaitForExitPid") + $workerArguments.Add($parentPid.ToString()) + $workerArguments.Add("-WaitForExitStartedAt") + $workerArguments.Add($parentStartedAt.ToString()) + $workerArguments.Add("-ActivateOperation") + $workerArguments.Add('"' + $script:Operation + '"') + $workerArguments.Add("-OperationToken") + $workerArguments.Add($script:Token) + $script:Phase = "waiting-for-restart" + Write-UpdateStatus + $worker = Start-Process -FilePath $shell.Source -ArgumentList $workerArguments -WindowStyle Hidden -PassThru ` + -RedirectStandardOutput (Join-Path $script:Operation "worker.stdout.log") ` + -RedirectStandardError (Join-Path $script:Operation "worker.stderr.log") + # Child takes ownership using the operation token. Parent cannot release its lock afterwards. + $script:HaveLock = $false + $accepted = $false + $deadline = [DateTime]::UtcNow.AddSeconds(15) + while ([DateTime]::UtcNow -lt $deadline) { + $owner = Read-LockOwner + if ([long]$owner.pid -eq $worker.Id -and $owner.token -eq $script:Token) { $accepted = $true; break } + $worker.Refresh() + if ($worker.HasExited) { break } + Start-Sleep -Milliseconds 100 + } + if (-not $accepted) { throw "Deferred updater did not confirm ownership. Recovery files: $script:Operation" } + Write-Host "Update scheduled; it will finish after MendCode closes." -ForegroundColor DarkGreen + return $true +} + +function Maybe-LaunchSetup { + if ($SetupMode -eq "skip") { + Write-SetupCommand + return + } + + if ($SetupMode -eq "run") { + Invoke-MendCodeSetup + return + } + + Write-Host "" + Write-Host "Finish setup now? Providers, models, packages, memory, and permissions." -ForegroundColor Yellow + try { + $answer = (Read-Host "Open setup now? [Y/n]").Trim().ToLowerInvariant() + } catch { + Write-SetupCommand + return + } + if ($answer -eq "" -or $answer -eq "y" -or $answer -eq "yes" -or $answer -eq "s" -or $answer -eq "si" -or $answer -eq "sí" -or $answer -eq "setup" -or $answer -eq "open") { + Invoke-MendCodeSetup + return + } + Write-SetupCommand +} + +function Get-MendCodeTarget { + # PROCESSOR_ARCHITEW6432 exposes the host architecture when a 32-bit + # PowerShell process runs on 64-bit Windows. Prefer it so x64/ARM64 hosts do + # not get misidentified as x86. + $rawArchitecture = if ($env:PROCESSOR_ARCHITEW6432) { + $env:PROCESSOR_ARCHITEW6432 + } elseif ($env:PROCESSOR_ARCHITECTURE) { + $env:PROCESSOR_ARCHITECTURE + } else { + [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture.ToString() + } + $architecture = $rawArchitecture.ToUpperInvariant() + + if ($architecture -eq "ARM64") { + return "windows-arm64" + } + + if ($architecture -eq "X64" -or ($architecture -eq "X86" -and [Environment]::Is64BitOperatingSystem)) { + $architecture = "AMD64" + } + + if ($architecture -ne "AMD64") { + throw "Unsupported Windows architecture: $rawArchitecture" + } + + try { + $kernel32 = Add-Type -MemberDefinition '[DllImport("kernel32.dll")] public static extern bool IsProcessorFeaturePresent(int ProcessorFeature);' -Name MendCodeKernel32 -Namespace MendCode -PassThru + if (-not $kernel32::IsProcessorFeaturePresent(40)) { + return "windows-x64-baseline" + } + } catch { + # A restricted PowerShell/.NET host may reject the probe. The baseline + # binary is the compatible fallback and does not require AVX2. + return "windows-x64-baseline" + } + + return "windows-x64" +} + +function Add-MendCodeToPath { + if ($NoModifyPath) { + Write-Host "Skipping PATH update because -NoModifyPath was set." + return + } + + $userPath = [Environment]::GetEnvironmentVariable("Path", "User") + $entries = if ($userPath) { $userPath -split ";" } else { @() } + if ($entries -notcontains $InstallDir) { + $nextPath = if ($userPath) { "$userPath;$InstallDir" } else { $InstallDir } + [Environment]::SetEnvironmentVariable("Path", $nextPath, "User") + } + + if (($env:Path -split ";") -notcontains $InstallDir) { + $env:Path = "$env:Path;$InstallDir" + } +} + +function Expand-VerifiedExecutable([string]$Archive, [string]$Destination) { + Add-Type -AssemblyName System.IO.Compression.FileSystem + $zip = [IO.Compression.ZipFile]::OpenRead($Archive) + try { + $entries = @($zip.Entries | Where-Object { $_.FullName -ceq "mendcode.exe" }) + if ($entries.Count -ne 1 -or $entries[0].Length -le 0 -or $entries[0].Length -gt 2147483648) { + throw "Archive must contain exactly one root mendcode.exe of valid size." + } + $source = $entries[0].Open() + $output = [IO.File]::Open($Destination, [IO.FileMode]::CreateNew, [IO.FileAccess]::Write, [IO.FileShare]::None) + try { $source.CopyTo($output); $output.Flush($true) } + finally { $output.Dispose(); $source.Dispose() } + } finally { $zip.Dispose() } +} + +function Assert-Candidate([string]$Candidate, [string]$Target) { + Assert-RegularPath $Candidate + $stream = [IO.File]::OpenRead($Candidate) + $reader = New-Object IO.BinaryReader($stream) + try { + if ($stream.Length -lt 64 -or $reader.ReadUInt16() -ne 0x5a4d) { throw "Candidate is not a Windows executable." } + $stream.Position = 60 + $offset = $reader.ReadUInt32() + if ($offset -gt ($stream.Length - 6)) { throw "Candidate PE header is truncated." } + $stream.Position = $offset + if ($reader.ReadUInt32() -ne 0x00004550) { throw "Candidate PE signature is invalid." } + $machine = $reader.ReadUInt16() + $expectedMachine = if ($Target -eq "windows-arm64") { 0xaa64 } else { 0x8664 } + if ($machine -ne $expectedMachine) { throw "Candidate architecture does not match $Target." } + } finally { $reader.Dispose() } + $info = New-Object Diagnostics.ProcessStartInfo + $info.FileName = $Candidate; $info.Arguments = "--version" + $info.UseShellExecute = $false; $info.CreateNoWindow = $true + $info.RedirectStandardOutput = $true; $info.RedirectStandardError = $true + $process = New-Object Diagnostics.Process + $process.StartInfo = $info + try { + if (-not $process.Start()) { throw "Could not verify candidate version." } + $stdout = $process.StandardOutput.ReadToEndAsync() + $stderr = $process.StandardError.ReadToEndAsync() + if (-not $process.WaitForExit(30000)) { + $process.Kill() + throw "Candidate --version exceeded 30 seconds. Current binary preserved." + } + if ($process.ExitCode -ne 0 -or $stdout.GetAwaiter().GetResult().Trim() -ne $Version) { + throw "Candidate version check failed. Expected $Version." + } + } finally { $process.Dispose() } +} + +function Activate-Candidate { + $candidate = Join-Path $script:Operation "candidate.exe" + Assert-RegularPath $candidate + if ((Get-MendCodeFileDigest $candidate) -ne $script:BinaryDigest) { + throw "Staged executable changed before activation." + } + $destination = Join-Path $InstallDir "mendcode.exe" + Assert-RegularPath $destination + $previous = Join-Path $script:Operation "previous" + if (Test-Path -LiteralPath $previous) { throw "Previous executable is already retained; inspect this operation before retrying." } + if ([IO.File]::Exists($destination)) { + $script:PreviousDigest = Get-MendCodeFileDigest $destination + } + $script:Phase = "activating" + Write-UpdateStatus + if ([IO.File]::Exists($destination)) { + # Windows security scanners can briefly hold a freshly executed binary. + # Keep the replace atomic while allowing that bounded transient lock to clear. + $maxAttempts = 8 + for ($attempt = 1; $attempt -le $maxAttempts; $attempt++) { + try { + # File.Replace is one same-volume operation and preserves the original as its backup. + [IO.File]::Replace($candidate, $destination, $previous) + break + } catch { + $exception = $_.Exception + $inner = $exception.InnerException + $isIoFailure = $exception -is [IO.IOException] -or $inner -is [IO.IOException] + $isAccessFailure = $exception -is [UnauthorizedAccessException] -or $inner -is [UnauthorizedAccessException] + $isSharingViolation = $exception.HResult -in @(-2147024864, -2147024863) -or $inner.HResult -in @(-2147024864, -2147024863) + if (-not ($isIoFailure -or $isAccessFailure -or $isSharingViolation) -or $attempt -eq $maxAttempts) { throw } + $delay = 250 * $attempt + Write-Warning "Executable activation is temporarily locked; retrying in ${delay}ms (attempt $attempt/$maxAttempts)." + Start-Sleep -Milliseconds $delay + } + } + } else { [IO.File]::Move($candidate, $destination) } + $script:Phase = "activated" + Write-UpdateStatus + Write-Ok "Installed $destination" + Write-Host "Restart required to verify backend and TUI readiness. Recovery files: $script:Operation" + Write-Host "Existing loop services were left running. Restart them when their work finishes." +} + +if ([Environment]::OSVersion.Platform -ne [PlatformID]::Win32NT) { throw "install.ps1 requires Windows." } +$failure = $null +$deferred = $false +try { + New-Item -ItemType Directory -Force $InstallDir | Out-Null + Assert-RegularPath (Split-Path $InstallDir -Parent) + Assert-RegularPath $InstallDir + if ($ActivateOperation) { + $script:Operation = [IO.Path]::GetFullPath($ActivateOperation) + if ((Split-Path $script:Operation -Parent) -ne $InstallDir -or (Split-Path $script:Operation -Leaf) -notmatch '^\.update\.[a-f0-9]{32}$') { + throw "Invalid deferred operation path." + } + Assert-RegularPath $script:Operation + $owner = Read-LockOwner + if ($OperationToken -notmatch '^[a-f0-9]{32}$' -or $owner.token -ne $OperationToken -or $owner.operation -ne $script:Operation) { throw "Deferred updater ownership changed." } + $script:Token = $OperationToken + $statusFile = Join-Path $script:Operation "status" + Assert-RegularPath $statusFile + if ((Get-Item -LiteralPath $statusFile).Length -gt 4096) { throw "Invalid operation status." } + $fields = @{} + foreach ($line in [IO.File]::ReadAllLines($statusFile)) { + $entry = $line.Split(@('='), 2) + if ($entry.Length -eq 2) { $fields[$entry[0]] = $entry[1] } + } + if ($fields.version -ne $Version -or $fields.phase -ne "waiting-for-restart" -or $fields.binary_sha256 -notmatch '^[a-f0-9]{64}$') { throw "Deferred operation was not verified." } + $script:BinaryDigest = $fields.binary_sha256 + Write-LockOwner + $script:HaveLock = $true + Wait-MendCodeProcessExit -ProcessId $WaitForExitPid -StartedAt $WaitForExitStartedAt + Activate-Candidate + } else { + $script:Operation = Join-Path $InstallDir (".update." + [Guid]::NewGuid().ToString("N")) + New-Item -ItemType Directory -Path $script:Operation | Out-Null + Acquire-UpdateLock + Write-UpdateStatus + $target = Get-MendCodeTarget + if (-not $Version) { + $releaseFile = Join-Path $script:Operation "release.json" + Receive-UpdateFile "$ApiUrl/releases/latest" $releaseFile 524288 + $Version = ([IO.File]::ReadAllText($releaseFile) | ConvertFrom-Json).tag_name + } + $Version = $Version.TrimStart('v') + if ($Version -notmatch '^\d+\.\d+\.\d+([-+][a-zA-Z0-9.+-]+)?$') { throw "Invalid release version." } + Write-MendCodeBanner -VersionLabel $Version -Target $target + $filename = "$App-$target.zip" + $url = "$BaseUrl/releases/download/v$Version/$filename" + $archive = Join-Path $script:Operation $filename + $script:Phase = "downloading" + Write-UpdateStatus + Receive-UpdateFile $url $archive + $script:Phase = "verifying" + Write-UpdateStatus + $sums = Join-Path $script:Operation "SHA256SUMS" + if ($env:MENDCODE_VERIFIED_SUMS_FILE) { + Assert-RegularPath $env:MENDCODE_VERIFIED_SUMS_FILE + [IO.File]::Copy($env:MENDCODE_VERIFIED_SUMS_FILE, $sums) + } else { Receive-UpdateFile "$BaseUrl/releases/download/v$Version/SHA256SUMS" $sums 524288 } + if ((Get-Item -LiteralPath $sums).Length -gt 524288) { throw "Checksums exceed the size limit." } + $digests = @([IO.File]::ReadAllLines($sums) | ForEach-Object { + if ($_ -match ('^([a-fA-F0-9]{64})\s+\*?(?:\./)?' + [Regex]::Escape($filename) + '$')) { $Matches[1].ToLowerInvariant() } + }) + if ($digests.Count -ne 1) { throw "Missing, duplicate, or invalid release checksum." } + if ((Get-MendCodeFileDigest $archive) -ne $digests[0]) { throw "Release checksum mismatch. Current binary preserved." } + $candidate = Join-Path $script:Operation "candidate.exe" + Expand-VerifiedExecutable $archive $candidate + Assert-Candidate $candidate $target + $script:BinaryDigest = Get-MendCodeFileDigest $candidate + Write-UpdateStatus + $deferred = Start-DeferredUpdate + if (-not $deferred) { + if ($WaitForExitPid -gt 0) { Wait-MendCodeProcessExit -ProcessId $WaitForExitPid -StartedAt $WaitForExitStartedAt } + Activate-Candidate + Add-MendCodeToPath + } + } +} catch { + $failure = $_ + if ($script:HaveLock) { + try { + Write-AtomicText (Join-Path $script:Operation "failure.txt") ("$script:Phase`: $($_.Exception.Message)`n") + $script:Phase = "failed" + Write-UpdateStatus 1 + } catch { Write-Warning "Could not record update failure: $($_.Exception.Message)" } + } +} finally { + if ($script:HaveLock) { + try { Release-UpdateLock } catch { if (-not $failure) { $failure = $_ } } + } +} +if ($failure) { Write-Error $failure; exit 1 } +if (-not $deferred -and -not $ActivateOperation) { Maybe-LaunchSetup } diff --git a/src/mendcode/package.json b/src/mendcode/package.json index 40340450..830f94ee 100644 --- a/src/mendcode/package.json +++ b/src/mendcode/package.json @@ -7,6 +7,8 @@ "packageManager": "bun@1.3.13", "scripts": { "dev": "bun run --cwd packages/opencode --conditions=browser src/index.ts", + "dev:rearm": "bun run --cwd packages/opencode script/dev-rearm.ts", + "test:dev-rearm:smoke": "bun run --cwd packages/opencode script/dev-rearm-smoke.ts", "dev:desktop": "bun --cwd packages/desktop dev", "dev:web": "bun --cwd packages/app dev", "dev:console": "ulimit -n 10240 2>/dev/null; bun run --cwd packages/console/app dev", @@ -50,14 +52,14 @@ "opentui-spinner": "0.0.6", "@solid-primitives/storage": "4.3.3", "@tailwindcss/vite": "4.1.11", - "diff": "8.0.2", - "dompurify": "3.3.1", - "drizzle-kit": "1.0.0-beta.19-d95b7a4", - "drizzle-orm": "1.0.0-beta.19-d95b7a4", + "diff": "8.0.3", + "dompurify": "3.4.13", + "drizzle-kit": "1.0.0-beta.20", + "drizzle-orm": "1.0.0-beta.20", "effect": "4.0.0-beta.59", "ai": "6.0.168", "cross-spawn": "7.0.6", - "hono": "4.10.7", + "hono": "4.13.5", "hono-openapi": "1.1.2", "fuzzysort": "3.1.0", "luxon": "3.6.1", @@ -74,7 +76,7 @@ "solid-list": "0.3.0", "tailwindcss": "4.1.11", "virtua": "0.42.3", - "vite": "7.1.4", + "vite": "7.3.5", "@solidjs/meta": "0.29.4", "@solidjs/router": "0.15.4", "@solidjs/start": "https://pkg.pr.new/@solidjs/start@dfb2020", @@ -96,7 +98,8 @@ "prettier": "3.6.2", "semver": "^7.6.0", "sst": "3.18.10", - "turbo": "2.9.14" + "turbo": "2.9.14", + "valibot": "1.4.2" }, "dependencies": { "@aws-sdk/client-s3": "3.933.0", @@ -126,8 +129,56 @@ "electron" ], "overrides": { + "@ai-sdk/provider": "3.0.12", + "@ai-sdk/provider-utils": "4.0.33", + "@hono/node-server": "2.0.10", + "@modelcontextprotocol/sdk": "1.27.1", + "@sigstore/core": "3.2.1", + "@sigstore/verify": "3.1.1", + "@opentelemetry/context-async-hooks": "2.8.0", + "@opentelemetry/core": "2.8.0", + "@opentelemetry/exporter-trace-otlp-http": "0.219.0", + "@opentelemetry/otlp-exporter-base": "0.219.0", + "@opentelemetry/otlp-transformer": "0.219.0", + "@opentelemetry/resources": "2.8.0", + "@opentelemetry/sdk-logs": "0.219.0", + "@opentelemetry/sdk-metrics": "2.8.0", + "@opentelemetry/sdk-trace-base": "2.8.0", + "@opentelemetry/sdk-trace-node": "2.8.0", + "@babel/core": "7.29.6", "@types/bun": "catalog:", - "@types/node": "catalog:" + "@types/node": "catalog:", + "axios": "1.18.0", + "body-parser": "2.3.0", + "brace-expansion": "5.0.9", + "browserslist": "4.28.7", + "fast-uri": "3.1.6", + "fastify": "5.12.1", + "fast-xml-builder": "1.1.7", + "find-my-way": "9.7.0", + "fast-xml-parser": "5.7.0", + "diff": "8.0.3", + "file-type": "21.3.2", + "hono": "4.13.5", + "ip-address": "10.3.1", + "postcss": "8.5.23", + "js-yaml": "4.3.2", + "mysql2": "3.23.1", + "postcss-selector-parser": "7.1.3", + "protobufjs": "7.6.3", + "qs": "6.16.0", + "seroval": "1.5.3", + "shell-quote": "1.9.0", + "sigstore": "4.1.1", + "socket.io-parser": "4.2.7", + "esbuild": "0.28.1", + "form-data": "4.0.6", + "undici": "8.9.0", + "uuid": "13.0.1", + "tar": "7.5.21", + "toml": "4.2.0", + "valibot": "1.4.2", + "ws": "8.21.0" }, "patchedDependencies": { "@npmcli/agent@4.0.0": "patches/@npmcli%2Fagent@4.0.0.patch", diff --git a/src/mendcode/packages/core/package.json b/src/mendcode/packages/core/package.json index 3ed9dfea..92b7b875 100644 --- a/src/mendcode/packages/core/package.json +++ b/src/mendcode/packages/core/package.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/package.json", - "version": "1.14.39", + "version": "0.1.9", "name": "@mendcode/core", "type": "module", "license": "MIT", @@ -31,9 +31,9 @@ "@npmcli/arborist": "9.4.0", "@npmcli/config": "10.8.1", "@opentelemetry/api": "1.9.0", - "@opentelemetry/context-async-hooks": "2.6.1", - "@opentelemetry/exporter-trace-otlp-http": "0.214.0", - "@opentelemetry/sdk-trace-base": "2.6.1", + "@opentelemetry/context-async-hooks": "2.8.0", + "@opentelemetry/exporter-trace-otlp-http": "0.219.0", + "@opentelemetry/sdk-trace-base": "2.8.0", "effect": "catalog:", "cross-spawn": "catalog:", "glob": "13.0.5", diff --git a/src/mendcode/packages/core/src/filesystem.ts b/src/mendcode/packages/core/src/filesystem.ts index 8a1cc3a0..552cad52 100644 --- a/src/mendcode/packages/core/src/filesystem.ts +++ b/src/mendcode/packages/core/src/filesystem.ts @@ -1,5 +1,5 @@ import { NodeFileSystem } from "@effect/platform-node" -import { dirname, join, relative, resolve as pathResolve } from "path" +import { basename, dirname, isAbsolute, join, relative, resolve as pathResolve, sep } from "path" import { realpathSync } from "fs" import * as NFS from "fs/promises" import { lookup } from "mime-types" @@ -215,11 +215,18 @@ export namespace AppFileSystem { export function resolve(p: string): string { const resolved = pathResolve(windowsPath(p)) - try { - return normalizePath(realpathSync(resolved)) - } catch (e: any) { - if (e?.code === "ENOENT") return normalizePath(resolved) - throw e + const suffix: string[] = [] + let current = resolved + while (true) { + try { + return normalizePath(join(realpathSync.native(current), ...suffix.toReversed())) + } catch (e: any) { + if (e?.code !== "ENOENT") throw e + const parent = dirname(current) + if (parent === current) return normalizePath(resolved) + suffix.push(basename(current)) + current = parent + } } } @@ -235,10 +242,14 @@ export namespace AppFileSystem { export function overlaps(a: string, b: string) { const relA = relative(a, b) const relB = relative(b, a) - return !relA || !relA.startsWith("..") || !relB || !relB.startsWith("..") + return internalRelative(relA) || internalRelative(relB) } export function contains(parent: string, child: string) { - return !relative(parent, child).startsWith("..") + return internalRelative(relative(parent, child)) + } + + function internalRelative(value: string) { + return value === "" || (value !== ".." && !value.startsWith(`..${sep}`) && !isAbsolute(value)) } } diff --git a/src/mendcode/packages/core/src/flag/flag.ts b/src/mendcode/packages/core/src/flag/flag.ts index 881bd3db..94797b54 100644 --- a/src/mendcode/packages/core/src/flag/flag.ts +++ b/src/mendcode/packages/core/src/flag/flag.ts @@ -123,6 +123,7 @@ export const Flag = { (!falsyOpen("OPENCODE_EXPERIMENTAL_HTTPAPI") && HTTPAPI_DEFAULT_ON_CHANNELS.has(InstallationChannel)), OPENCODE_EXPERIMENTAL_WORKSPACES: OPENCODE_EXPERIMENTAL || truthyOpen("OPENCODE_EXPERIMENTAL_WORKSPACES"), OPENCODE_EXPERIMENTAL_EVENT_SYSTEM: OPENCODE_EXPERIMENTAL || truthyOpen("OPENCODE_EXPERIMENTAL_EVENT_SYSTEM"), + OPENCODE_EXPERIMENTAL_SESSION_V2_DEBUG: truthyOpen("OPENCODE_EXPERIMENTAL_SESSION_V2_DEBUG"), // Evaluated at access time (not module load) because tests, the CLI, and // external tooling set these env vars at runtime. diff --git a/src/mendcode/packages/core/src/global-layout.ts b/src/mendcode/packages/core/src/global-layout.ts index 7f13bf1f..883a87c8 100644 --- a/src/mendcode/packages/core/src/global-layout.ts +++ b/src/mendcode/packages/core/src/global-layout.ts @@ -1,6 +1,6 @@ import path from "path" import os from "os" -import { existsSync, readdirSync } from "fs" +import { existsSync, readFileSync, readdirSync } from "fs" import { xdgData, xdgCache, xdgConfig, xdgState } from "xdg-basedir" /** XDG app directory name: donor-era installs and legacy layout root. */ @@ -15,18 +15,12 @@ export const XDG_APP_SEGMENT_MEND = "mendcode" */ export const GLOBAL_LAYOUT_MIGRATION_DONE_BASENAME = ".mendcode-global-layout-v0.done" +/** Installer-owned selection; keeps MendCode layout choice scoped to MendCode instead of shell config. */ +export const GLOBAL_LAYOUT_INSTALL_SELECTION_BASENAME = ".global-layout-v1" + /** Keep in sync with `JSON_STORAGE_MIGRATION_DONE_BASENAME` in `packages/opencode/src/storage/json-migration.ts`. */ const JSON_STORAGE_MIGRATION_DONE_BASENAME = ".mendcode-json-storage-migration-v0.done" -function envOpen(openKey: string) { - const mendKey = `MENDCODE_${openKey.slice("OPENCODE_".length)}` - const primary = process.env[mendKey] - if (primary !== undefined && primary !== "") return primary - const fallback = process.env[openKey] - if (fallback !== undefined && fallback !== "") return fallback - return undefined -} - export interface GlobalRoots { readonly data: string readonly cache: string @@ -78,29 +72,81 @@ export function legacyDataHasIdentityArtifacts(legacyDataDir: string): boolean { return false } +/** Strong ownership only: generic OpenCode auth/storage/db names are intentionally excluded. */ +export function legacyDataHasMendCodeIdentityArtifacts(legacyDataDir: string): boolean { + for (const name of safeReadDir(legacyDataDir)) { + if (name.startsWith("mendcode") && name.endsWith(".db")) return true + if (name === JSON_STORAGE_MIGRATION_DONE_BASENAME) return true + if (name === GLOBAL_LAYOUT_MIGRATION_DONE_BASENAME) return true + } + return false +} + export function globalLayoutMigrationMarkerPath(mendDataDir: string) { return path.join(mendDataDir, GLOBAL_LAYOUT_MIGRATION_DONE_BASENAME) } +export function globalLayoutInstallSelectionPath(home = process.env.OPENCODE_TEST_HOME ?? os.homedir()) { + return path.join(home, ".mendcode", GLOBAL_LAYOUT_INSTALL_SELECTION_BASENAME) +} + +export type GlobalLayoutSelection = "legacy" | "mendcode" + +export function normalizeGlobalLayoutSelection(value: string | undefined): GlobalLayoutSelection | undefined { + const normalized = value?.trim().toLowerCase() + if (normalized === "legacy" || normalized === "mendcode") return normalized + return undefined +} + +export function readGlobalLayoutInstallSelection(home?: string): GlobalLayoutSelection | undefined { + try { + const file = globalLayoutInstallSelectionPath(home) + const value = normalizeGlobalLayoutSelection(readFileSync(file, "utf8")) + if (!value) throw new Error(`Invalid MendCode layout selection in ${file}; expected legacy or mendcode`) + return value + } catch (error) { + if ((error as NodeJS.ErrnoException).code === "ENOENT") return undefined + throw error + } +} + +export function resolveActiveAppSegmentFromDirs(input: { + environmentSelection?: string + installSelection?: string + legacyEnvironmentSelection?: string + legacyDataDir: string + mendDataDir: string +}): typeof XDG_APP_SEGMENT_LEGACY | typeof XDG_APP_SEGMENT_MEND { + const selected = + normalizeGlobalLayoutSelection(input.environmentSelection) ?? + normalizeGlobalLayoutSelection(input.installSelection) ?? + normalizeGlobalLayoutSelection(input.legacyEnvironmentSelection) + if (selected === "legacy") return XDG_APP_SEGMENT_LEGACY + if (selected === "mendcode") return XDG_APP_SEGMENT_MEND + if (existsSync(globalLayoutMigrationMarkerPath(input.mendDataDir))) return XDG_APP_SEGMENT_MEND + if (legacyDataHasIdentityArtifacts(input.legacyDataDir)) return XDG_APP_SEGMENT_LEGACY + return XDG_APP_SEGMENT_MEND +} + /** * Resolves XDG app segment for {@link Global.Path}. * - * - `OPENCODE_GLOBAL_LAYOUT` / `MENDCODE_GLOBAL_LAYOUT`: `legacy` | `mendcode` | `auto` (default). + * - `MENDCODE_GLOBAL_LAYOUT`: primary explicit override (`legacy` | `mendcode` | `auto`). * - `legacy`: always `opencode`. * - `mendcode`: always `mendcode` (operator override; ensure data exists or run migration first). + * - Installer selection: persists the installer choice without changing global shell configuration. + * - `OPENCODE_GLOBAL_LAYOUT`: donor-era fallback only when no MendCode-owned selection exists. * - `auto`: `mendcode` if migration marker exists under mend data, else `opencode` if legacy data has - * artifacts, else `mendcode` (greenfield installs use Mend segment without a marker). + * artifacts, else `mendcode` (manual/greenfield runs without installer metadata preserve compatibility). */ export function resolveActiveAppSegment(): typeof XDG_APP_SEGMENT_LEGACY | typeof XDG_APP_SEGMENT_MEND { - const raw = envOpen("OPENCODE_GLOBAL_LAYOUT")?.trim().toLowerCase() - if (raw === "legacy") return XDG_APP_SEGMENT_LEGACY - if (raw === "mendcode") return XDG_APP_SEGMENT_MEND - const mendRoots = computeGlobalRoots(XDG_APP_SEGMENT_MEND) - if (existsSync(globalLayoutMigrationMarkerPath(mendRoots.data))) return XDG_APP_SEGMENT_MEND - const legacyRoots = computeGlobalRoots(XDG_APP_SEGMENT_LEGACY) - if (legacyDataHasIdentityArtifacts(legacyRoots.data)) return XDG_APP_SEGMENT_LEGACY - - return XDG_APP_SEGMENT_MEND + return resolveActiveAppSegmentFromDirs({ + environmentSelection: process.env.MENDCODE_GLOBAL_LAYOUT, + installSelection: readGlobalLayoutInstallSelection(), + legacyEnvironmentSelection: process.env.OPENCODE_GLOBAL_LAYOUT, + legacyDataDir: legacyRoots.data, + mendDataDir: mendRoots.data, + }) } diff --git a/src/mendcode/packages/core/src/util/identifier.ts b/src/mendcode/packages/core/src/util/identifier.ts index ba28a351..4dc5e633 100644 --- a/src/mendcode/packages/core/src/util/identifier.ts +++ b/src/mendcode/packages/core/src/util/identifier.ts @@ -1,4 +1,4 @@ -import { randomBytes } from "crypto" +import { randomInt } from "node:crypto" export namespace Identifier { const LENGTH = 26 @@ -18,9 +18,8 @@ export namespace Identifier { function randomBase62(length: number): string { const chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" let result = "" - const bytes = randomBytes(length) for (let i = 0; i < length; i++) { - result += chars[bytes[i] % 62] + result += chars[randomInt(chars.length)] } return result } diff --git a/src/mendcode/packages/core/src/util/log.ts b/src/mendcode/packages/core/src/util/log.ts index e1962aed..39d6e24d 100644 --- a/src/mendcode/packages/core/src/util/log.ts +++ b/src/mendcode/packages/core/src/util/log.ts @@ -17,6 +17,8 @@ const levelPriority: Record = { ERROR: 3, } const keep = 10 +const defaultMaxFileBytes = 16 * 1024 * 1024 +const defaultMaxEntryBytes = 128 * 1024 let level: Level = "INFO" @@ -26,6 +28,7 @@ function shouldLog(input: Level): boolean { export type Logger = { debug(message?: any, extra?: Record): void + trace(message?: any, extra?: Record): void info(message?: any, extra?: Record): void error(message?: any, extra?: Record): void warn(message?: any, extra?: Record): void @@ -54,11 +57,34 @@ let logpath = "" export function file() { return logpath } -let write = (msg: any) => { +let write: (msg: string) => number | Promise = (msg) => { process.stderr.write(msg) return msg.length } +function envBytes(name: string, fallback: number) { + const value = Number(process.env[name]) + return Number.isFinite(value) && value > 0 ? Math.floor(value) : fallback +} + +function truncateEntry(msg: string, maxBytes: number) { + if (Buffer.byteLength(msg) <= maxBytes) return msg + let next = msg.slice(0, Math.max(0, maxBytes - 256)) + while (Buffer.byteLength(next) > maxBytes - 128 && next.length > 0) { + next = next.slice(0, Math.floor(next.length * 0.9)) + } + return next.replace(/\n?$/, "") + " [log entry truncated]\n" +} + +function streamWrite(stream: ReturnType, msg: string) { + return new Promise((resolve, reject) => { + stream.write(msg, (err) => { + if (err) reject(err) + else resolve(Buffer.byteLength(msg)) + }) + }) +} + export async function init(options: Options) { if (options.level) level = options.level void cleanup(Global.Path.log) @@ -69,13 +95,27 @@ export async function init(options: Options) { ) await fs.truncate(logpath).catch(() => {}) const stream = createWriteStream(logpath, { flags: "a" }) - write = async (msg: any) => { - return new Promise((resolve, reject) => { - stream.write(msg, (err) => { - if (err) reject(err) - else resolve(msg.length) - }) - }) + const maxFileBytes = envBytes("MENDCODE_LOG_MAX_BYTES", defaultMaxFileBytes) + const maxEntryBytes = envBytes("MENDCODE_LOG_ENTRY_MAX_BYTES", defaultMaxEntryBytes) + let bytesWritten = 0 + let capped = false + write = async (input) => { + if (capped) return 0 + const msg = truncateEntry(String(input), maxEntryBytes) + const bytes = Buffer.byteLength(msg) + if (bytesWritten + bytes > maxFileBytes) { + capped = true + const notice = `WARN ${new Date().toISOString().split(".")[0]} +0ms service=log file log cap reached; suppressing further file logs max_bytes=${maxFileBytes}\n` + const noticeBytes = Buffer.byteLength(notice) + if (bytesWritten + noticeBytes <= maxFileBytes) { + bytesWritten += noticeBytes + await streamWrite(stream, notice) + } + return 0 + } + bytesWritten += bytes + await streamWrite(stream, msg) + return bytes } } @@ -138,6 +178,10 @@ export function create(tags?: Record) { write("DEBUG " + build(message, extra)) } }, + trace(message?: any, extra?: Record) { + if (process.env.MENDCODE_TRACE !== "1") return + write("TRACE " + build(message, extra)) + }, info(message?: any, extra?: Record) { if (shouldLog("INFO")) { write("INFO " + build(message, extra)) diff --git a/src/mendcode/packages/core/test/filesystem/filesystem.test.ts b/src/mendcode/packages/core/test/filesystem/filesystem.test.ts index 340ffc0e..648c4f22 100644 --- a/src/mendcode/packages/core/test/filesystem/filesystem.test.ts +++ b/src/mendcode/packages/core/test/filesystem/filesystem.test.ts @@ -4,6 +4,7 @@ import { NodeFileSystem } from "@effect/platform-node" import { AppFileSystem } from "@mendcode/core/filesystem" import { testEffect } from "../lib/effect" import path from "path" +import { symlink } from "node:fs/promises" const live = AppFileSystem.layer.pipe(Layer.provideMerge(NodeFileSystem.layer)) const { effect: it } = testEffect(live) @@ -357,6 +358,31 @@ describe("AppFileSystem", () => { expect(AppFileSystem.contains("/a/b", "/a/c")).toBe(false) }) + it( + "resolves missing paths through the nearest existing symlink parent", + Effect.gen(function* () { + const filesys = yield* FileSystem.FileSystem + const tmp = yield* filesys.makeTempDirectoryScoped() + const project = path.join(tmp, "project") + const outside = path.join(tmp, "outside") + const link = path.join(project, "linked") + yield* filesys.makeDirectory(project) + yield* filesys.makeDirectory(outside) + yield* Effect.promise(() => symlink(outside, link, "dir")) + + expect(AppFileSystem.resolve(path.join(link, "missing.txt"))).toBe( + path.join(AppFileSystem.resolve(outside), "missing.txt"), + ) + expect(AppFileSystem.contains(AppFileSystem.resolve(project), AppFileSystem.resolve(path.join(link, "missing.txt")))).toBe(false) + }), + ) + + if (process.platform === "win32") { + test("contains rejects a child on another drive", () => { + expect(AppFileSystem.contains("C:\\project", "D:\\project\\file.txt")).toBe(false) + }) + } + test("overlaps detects overlapping paths", () => { expect(AppFileSystem.overlaps("/a/b", "/a/b/c")).toBe(true) expect(AppFileSystem.overlaps("/a/b/c", "/a/b")).toBe(true) diff --git a/src/mendcode/packages/core/test/global-layout.test.ts b/src/mendcode/packages/core/test/global-layout.test.ts index edfcbb4e..c53d447a 100644 --- a/src/mendcode/packages/core/test/global-layout.test.ts +++ b/src/mendcode/packages/core/test/global-layout.test.ts @@ -3,12 +3,16 @@ import os from "os" import path from "path" import { computeGlobalRoots, + GLOBAL_LAYOUT_INSTALL_SELECTION_BASENAME, GLOBAL_LAYOUT_MIGRATION_DONE_BASENAME, + globalLayoutInstallSelectionPath, legacyDataHasIdentityArtifacts, + readGlobalLayoutInstallSelection, + resolveActiveAppSegmentFromDirs, XDG_APP_SEGMENT_LEGACY, XDG_APP_SEGMENT_MEND, } from "@mendcode/core/global-layout" -import { mkdtempSync, rmSync, writeFileSync } from "fs" +import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "fs" describe("global-layout", () => { test("legacy and mend segments produce distinct root sets", () => { @@ -23,6 +27,7 @@ describe("global-layout", () => { test("migration marker basename is stable", () => { expect(GLOBAL_LAYOUT_MIGRATION_DONE_BASENAME).toMatch(/^\.mendcode-global-layout-v/) + expect(GLOBAL_LAYOUT_INSTALL_SELECTION_BASENAME).toBe(".global-layout-v1") }) test("legacyDataHasIdentityArtifacts detects sqlite and storage", () => { @@ -35,4 +40,67 @@ describe("global-layout", () => { rmSync(dir, { recursive: true, force: true }) } }) + + test("installer selection keeps a new MendCode install separate from OpenCode data", () => { + const dir = mkdtempSync(path.join(os.tmpdir(), "mend-gl-select-")) + const legacy = path.join(dir, "opencode") + const mend = path.join(dir, "mendcode") + try { + mkdirSync(legacy) + writeFileSync(path.join(legacy, "opencode.db"), "external-opencode") + expect( + resolveActiveAppSegmentFromDirs({ + installSelection: "mendcode\n", + legacyDataDir: legacy, + mendDataDir: mend, + }), + ).toBe(XDG_APP_SEGMENT_MEND) + } finally { + rmSync(dir, { recursive: true, force: true }) + } + }) + + test("explicit environment selection wins over installer metadata", () => { + const dir = mkdtempSync(path.join(os.tmpdir(), "mend-gl-env-")) + try { + expect( + resolveActiveAppSegmentFromDirs({ + environmentSelection: "legacy", + installSelection: "mendcode", + legacyDataDir: path.join(dir, "opencode"), + mendDataDir: path.join(dir, "mendcode"), + }), + ).toBe(XDG_APP_SEGMENT_LEGACY) + } finally { + rmSync(dir, { recursive: true, force: true }) + } + }) + + test("installer metadata isolates MendCode from a donor environment variable", () => { + const dir = mkdtempSync(path.join(os.tmpdir(), "mend-gl-donor-env-")) + try { + expect( + resolveActiveAppSegmentFromDirs({ + installSelection: "mendcode", + legacyEnvironmentSelection: "legacy", + legacyDataDir: path.join(dir, "opencode"), + mendDataDir: path.join(dir, "mendcode"), + }), + ).toBe(XDG_APP_SEGMENT_MEND) + } finally { + rmSync(dir, { recursive: true, force: true }) + } + }) + + test("invalid installer metadata fails closed instead of falling back to donor data", () => { + const dir = mkdtempSync(path.join(os.tmpdir(), "mend-gl-invalid-selection-")) + try { + const selection = globalLayoutInstallSelectionPath(dir) + mkdirSync(path.dirname(selection), { recursive: true }) + writeFileSync(selection, "corrupt\n") + expect(() => readGlobalLayoutInstallSelection(dir)).toThrow("Invalid MendCode layout selection") + } finally { + rmSync(dir, { recursive: true, force: true }) + } + }) }) diff --git a/src/mendcode/packages/extensions/zed/extension.toml b/src/mendcode/packages/extensions/zed/extension.toml index 83bb4650..ee5763b8 100644 --- a/src/mendcode/packages/extensions/zed/extension.toml +++ b/src/mendcode/packages/extensions/zed/extension.toml @@ -1,36 +1,36 @@ -id = "opencode" +id = "mendcode" name = "MendCode" description = "The open source coding agent." -version = "1.14.39" +version = "0.1.44" schema_version = 1 -authors = ["Anomaly"] -repository = "https://mendcode.ai" +authors = ["MendCode"] +repository = "https://github.com/MendCode/MendCode" [agent_servers.mendcode] name = "MendCode" icon = "./icons/opencode.svg" [agent_servers.mendcode.targets.darwin-aarch64] -archive = "https://mendcode.ai/releases/download/v1.14.39/opencode-darwin-arm64.zip" -cmd = "./opencode" +archive = "https://github.com/MendCode/MendCode/releases/download/v0.1.44/mendcode-darwin-arm64.zip" +cmd = "./mendcode" args = ["acp"] [agent_servers.mendcode.targets.darwin-x86_64] -archive = "https://mendcode.ai/releases/download/v1.14.39/opencode-darwin-x64.zip" -cmd = "./opencode" +archive = "https://github.com/MendCode/MendCode/releases/download/v0.1.44/mendcode-darwin-x64.zip" +cmd = "./mendcode" args = ["acp"] [agent_servers.mendcode.targets.linux-aarch64] -archive = "https://mendcode.ai/releases/download/v1.14.39/opencode-linux-arm64.tar.gz" -cmd = "./opencode" +archive = "https://github.com/MendCode/MendCode/releases/download/v0.1.44/mendcode-linux-arm64.tar.gz" +cmd = "./mendcode" args = ["acp"] [agent_servers.mendcode.targets.linux-x86_64] -archive = "https://mendcode.ai/releases/download/v1.14.39/opencode-linux-x64.tar.gz" -cmd = "./opencode" +archive = "https://github.com/MendCode/MendCode/releases/download/v0.1.44/mendcode-linux-x64.tar.gz" +cmd = "./mendcode" args = ["acp"] [agent_servers.mendcode.targets.windows-x86_64] -archive = "https://mendcode.ai/releases/download/v1.14.39/opencode-windows-x64.zip" -cmd = "./opencode.exe" +archive = "https://github.com/MendCode/MendCode/releases/download/v0.1.44/mendcode-windows-x64.zip" +cmd = "./mendcode.exe" args = ["acp"] diff --git a/src/mendcode/packages/function/package.json b/src/mendcode/packages/function/package.json index dee9e1cb..8d371fe4 100644 --- a/src/mendcode/packages/function/package.json +++ b/src/mendcode/packages/function/package.json @@ -1,6 +1,6 @@ { "name": "@mendcode/function", - "version": "1.14.39", + "version": "0.1.9", "$schema": "https://json.schemastore.org/package.json", "private": true, "type": "module", diff --git a/src/mendcode/packages/function/src/api.ts b/src/mendcode/packages/function/src/api.ts index 58c74fe3..898f6871 100644 --- a/src/mendcode/packages/function/src/api.ts +++ b/src/mendcode/packages/function/src/api.ts @@ -5,6 +5,7 @@ import { jwtVerify, createRemoteJWKSet } from "jose" import { createAppAuth } from "@octokit/auth-app" import { Octokit } from "@octokit/rest" import { Resource } from "sst" +import { verifyFeishuRequest, verifyFeishuToken, FEISHU_REQUEST_MAX_AGE_SECONDS } from "./feishu-security" type Env = { SYNC_SERVER: DurableObjectNamespace @@ -67,7 +68,10 @@ export class SyncServer extends DurableObject { public async share(sessionID: string) { let secret = await this.getSecret() - if (secret) return secret + if (secret) { + if ((await this.getSessionID()) !== sessionID) throw new Error("Share identifier collision") + return secret + } secret = randomUUID() await this.ctx.storage.put("secret", secret) @@ -87,6 +91,27 @@ export class SyncServer extends DurableObject { if (secret !== (await this.getSecret())) throw new Error("Invalid secret") } + public async assertAccess(sessionID: string, secret: string) { + if (sessionID !== (await this.getSessionID())) throw new Error("Invalid session") + await this.assertSecret(secret) + } + + public async claimReplay(key: string, now: number, expiresAt: number) { + const storageKey = `feishu/replay/${key}` + const accepted = await this.ctx.storage.transaction(async (txn) => { + const existing = await txn.get(storageKey) + if (existing && existing >= now) return false + await txn.put(storageKey, expiresAt) + return true + }) + if (!accepted) return false + + const entries = await this.ctx.storage.list({ prefix: "feishu/replay/", limit: 128 }) + const expired = Array.from(entries).flatMap(([entry, expiry]) => (expiry < now ? [entry] : [])) + if (expired.length) await this.ctx.storage.delete(expired) + return true + } + private async getSecret() { return this.ctx.storage.get("secret") } @@ -133,7 +158,7 @@ export default new Hono<{ Bindings: Env }>() const secret = body.secret const id = c.env.SYNC_SERVER.idFromName(SyncServer.shortName(sessionID)) const stub = c.env.SYNC_SERVER.get(id) - await stub.assertSecret(secret) + await stub.assertAccess(sessionID, secret) await stub.clear() return c.json({}) }) @@ -157,7 +182,7 @@ export default new Hono<{ Bindings: Env }>() const name = SyncServer.shortName(body.sessionID) const id = c.env.SYNC_SERVER.idFromName(name) const stub = c.env.SYNC_SERVER.get(id) - await stub.assertSecret(body.secret) + await stub.assertAccess(body.sessionID, body.secret) await stub.publish(body.key, body.content) return c.json({}) }) @@ -202,7 +227,10 @@ export default new Hono<{ Bindings: Env }>() return c.json({ info, messages }) }) .post("/feishu", async (c) => { - const body = (await c.req.json()) as { + const rawBody = await c.req.text() + let body: { + token?: string + header?: { token?: string } challenge?: string event?: { message?: { @@ -214,7 +242,34 @@ export default new Hono<{ Bindings: Env }>() } } } - console.log(JSON.stringify(body, null, 2)) + try { + body = JSON.parse(rawBody) + } catch { + return c.json({ error: "Invalid JSON" }, { status: 400 }) + } + + const timestamp = c.req.header("x-lark-request-timestamp") + const nonce = c.req.header("x-lark-request-nonce") + const signature = c.req.header("x-lark-signature") + if ( + !verifyFeishuRequest({ + body: rawBody, + timestamp, + nonce, + signature, + encryptKey: Resource.FEISHU_ENCRYPT_KEY.value, + }) || + !verifyFeishuToken(body, Resource.FEISHU_VERIFICATION_TOKEN.value) + ) { + return c.json({ error: "Invalid Feishu signature" }, { status: 401 }) + } + + const replay = c.env.SYNC_SERVER.get(c.env.SYNC_SERVER.idFromName("feishu-webhook-replay-v1")) + const now = Date.now() + if (!(await replay.claimReplay(signature!, now, now + FEISHU_REQUEST_MAX_AGE_SECONDS * 1_000))) { + return c.json({ error: "Replayed Feishu request" }, { status: 409 }) + } + const challenge = body.challenge if (challenge) return c.json({ challenge }) @@ -302,6 +357,7 @@ export default new Hono<{ Bindings: Env }>() const installationAuth = await auth({ type: "installation", installationId: installation.id, + repositoryNames: [repo], }) return c.json({ token: installationAuth.token }) @@ -344,6 +400,7 @@ export default new Hono<{ Bindings: Env }>() const installationAuth = await auth({ type: "installation", installationId: installation.id, + repositoryIds: [repoData.id], }) return c.json({ token: installationAuth.token }) diff --git a/src/mendcode/packages/function/src/feishu-security.ts b/src/mendcode/packages/function/src/feishu-security.ts new file mode 100644 index 00000000..9ebd8ef3 --- /dev/null +++ b/src/mendcode/packages/function/src/feishu-security.ts @@ -0,0 +1,37 @@ +import { createHash, timingSafeEqual } from "node:crypto" + +export const FEISHU_REQUEST_MAX_AGE_SECONDS = 300 + +function constantTimeEqual(left: string, right: string) { + const a = Buffer.from(left) + const b = Buffer.from(right) + return a.length === b.length && timingSafeEqual(a, b) +} + +export function verifyFeishuRequest(input: { + body: string + timestamp?: string + nonce?: string + signature?: string + encryptKey: string + now?: number +}) { + if (!input.timestamp || !input.nonce || !input.signature || !input.encryptKey) return false + if (!/^\d+$/.test(input.timestamp) || !/^[a-f0-9]{64}$/i.test(input.signature)) return false + + const now = Math.floor((input.now ?? Date.now()) / 1_000) + const timestamp = Number(input.timestamp) + if (!Number.isSafeInteger(timestamp) || Math.abs(now - timestamp) > FEISHU_REQUEST_MAX_AGE_SECONDS) return false + + const expected = createHash("sha256") + .update(input.timestamp + input.nonce + input.encryptKey + input.body) + .digest("hex") + return constantTimeEqual(expected, input.signature.toLowerCase()) +} + +export function verifyFeishuToken(body: unknown, verificationToken: string) { + if (!verificationToken || !body || typeof body !== "object") return false + const record = body as { token?: unknown; header?: { token?: unknown } } + const token = typeof record.header?.token === "string" ? record.header.token : record.token + return typeof token === "string" && constantTimeEqual(token, verificationToken) +} diff --git a/src/mendcode/packages/function/sst-env.d.ts b/src/mendcode/packages/function/sst-env.d.ts index bc56bd78..6e5f08f8 100644 --- a/src/mendcode/packages/function/sst-env.d.ts +++ b/src/mendcode/packages/function/sst-env.d.ts @@ -67,6 +67,14 @@ declare module "sst" { "type": "sst.sst.Secret" "value": string } + "FEISHU_ENCRYPT_KEY": { + "type": "sst.sst.Secret" + "value": string + } + "FEISHU_VERIFICATION_TOKEN": { + "type": "sst.sst.Secret" + "value": string + } "GITHUB_APP_ID": { "type": "sst.sst.Secret" "value": string @@ -304,4 +312,4 @@ declare module "sst" { } import "sst" -export {} \ No newline at end of file +export {} diff --git a/src/mendcode/packages/function/test/feishu-security.test.ts b/src/mendcode/packages/function/test/feishu-security.test.ts new file mode 100644 index 00000000..b667239a --- /dev/null +++ b/src/mendcode/packages/function/test/feishu-security.test.ts @@ -0,0 +1,43 @@ +import { createHash } from "node:crypto" +import { describe, expect, test } from "bun:test" +import { FEISHU_REQUEST_MAX_AGE_SECONDS, verifyFeishuRequest, verifyFeishuToken } from "../src/feishu-security" + +describe("Feishu webhook security", () => { + test("accepts a fresh request with the official SHA-256 signature shape", () => { + const now = 1_800_000_000_000 + const timestamp = String(now / 1_000) + const nonce = "nonce" + const encryptKey = "encrypt-key" + const body = JSON.stringify({ schema: "2.0", header: { token: "verify" } }) + const signature = createHash("sha256").update(timestamp + nonce + encryptKey + body).digest("hex") + + expect(verifyFeishuRequest({ body, timestamp, nonce, signature, encryptKey, now })).toBe(true) + expect(verifyFeishuToken(JSON.parse(body), "verify")).toBe(true) + }) + + test("rejects stale, malformed, and tampered requests", () => { + const now = 1_800_000_000_000 + const timestamp = String(now / 1_000 - FEISHU_REQUEST_MAX_AGE_SECONDS - 1) + expect( + verifyFeishuRequest({ + body: "{}", + timestamp, + nonce: "nonce", + signature: "0".repeat(64), + encryptKey: "encrypt-key", + now, + }), + ).toBe(false) + expect( + verifyFeishuRequest({ + body: "{}", + timestamp: String(now / 1_000), + nonce: "nonce", + signature: "not-hex", + encryptKey: "encrypt-key", + now, + }), + ).toBe(false) + expect(verifyFeishuToken({ header: { token: "wrong" } }, "verify")).toBe(false) + }) +}) diff --git a/src/mendcode/packages/opencode/.18c5bddfdfd554f9-00000000.bun-build b/src/mendcode/packages/opencode/.18c5bddfdfd554f9-00000000.bun-build new file mode 100755 index 00000000..e9fea8db Binary files /dev/null and b/src/mendcode/packages/opencode/.18c5bddfdfd554f9-00000000.bun-build differ diff --git a/src/mendcode/packages/opencode/AGENTS.md b/src/mendcode/packages/opencode/AGENTS.md index 2a39b6c1..b738dc6f 100644 --- a/src/mendcode/packages/opencode/AGENTS.md +++ b/src/mendcode/packages/opencode/AGENTS.md @@ -135,3 +135,7 @@ const cb = Instance.bind((err, evts) => { }) nativeAddon.subscribe(dir, cb) ``` + +# Project context + +- 2026-08-04: Background subagent completion is a durable lifecycle contract. Persist terminal notifications and acknowledge them only after the owner-wake or superseding user prompt is stored; replay unacknowledged events after instance/server restart, keep the shared server alive while tasks are active, and classify assistant results without a terminal `finish` as `interrupted`, not `completed`. diff --git a/src/mendcode/packages/opencode/bin/opencode b/src/mendcode/packages/opencode/bin/opencode index e688e189..0b07630c 100755 --- a/src/mendcode/packages/opencode/bin/opencode +++ b/src/mendcode/packages/opencode/bin/opencode @@ -17,7 +17,7 @@ function run(target) { process.exit(code) } -const envPath = process.env.OPENCODE_BIN_PATH +const envPath = process.env.MENDCODE_BIN_PATH || process.env.OPENCODE_BIN_PATH if (envPath) { run(envPath) } @@ -26,9 +26,9 @@ const scriptPath = fs.realpathSync(__filename) const scriptDir = path.dirname(scriptPath) // -const cached = path.join(scriptDir, ".opencode") -if (fs.existsSync(cached)) { - run(cached) +for (const name of [".mendcode", ".opencode"]) { + const cached = path.join(scriptDir, name) + if (fs.existsSync(cached)) run(cached) } const platformMap = { @@ -50,8 +50,8 @@ let arch = archMap[os.arch()] if (!arch) { arch = os.arch() } -const base = "opencode-" + platform + "-" + arch -const binary = platform === "windows" ? "opencode.exe" : "opencode" +const base = "mendcode-" + platform + "-" + arch +const binary = platform === "windows" ? "mendcode.exe" : "mendcode" function supportsAvx2() { if (arch !== "x64") return false diff --git a/src/mendcode/packages/opencode/examples/memory-graph-page-package/.mendcode/mendcode.json b/src/mendcode/packages/opencode/examples/memory-graph-page-package/.mendcode/mendcode.json new file mode 100644 index 00000000..1e84e32e --- /dev/null +++ b/src/mendcode/packages/opencode/examples/memory-graph-page-package/.mendcode/mendcode.json @@ -0,0 +1,10 @@ +{ + "$schema": "https://mendcode.ai/config.json", + "version": 0, + "package": { + "id": "memory-graph-page-example", + "title": "Memory Graph Page Example", + "version": "1.0.0" + }, + "plugin": ["./pages/memory-graph.tsx"] +} diff --git a/src/mendcode/packages/opencode/examples/memory-graph-page-package/.mendcode/pages/memory-graph.tsx b/src/mendcode/packages/opencode/examples/memory-graph-page-package/.mendcode/pages/memory-graph.tsx new file mode 100644 index 00000000..d85dacf7 --- /dev/null +++ b/src/mendcode/packages/opencode/examples/memory-graph-page-package/.mendcode/pages/memory-graph.tsx @@ -0,0 +1,409 @@ +/** @jsxImportSource @opentui/solid */ + +import { BoxRenderable, MouseButton, MouseEvent } from "@opentui/core" +import { useKeyboard, useTerminalDimensions } from "@opentui/solid" +import { For, Show, createEffect, createMemo, createResource, createSignal } from "solid-js" +import { + asciiGraphCellToWorld, + asciiGraphNearestNode, + asciiGraphRuns, + asciiGraphWithNodePosition, + layoutAsciiGraph, + renderAsciiGraph, + type AsciiGraphCell, + type AsciiGraphFrame, + type AsciiGraphPoint, + type TuiMemoryGraphCategory, + type TuiPluginApi, +} from "@mendcode/plugin/tui" + +function compact(value: string | undefined, width: number) { + const text = (value ?? "").replace(/\s+/g, " ").trim() + if (text.length <= width) return text + return width <= 1 ? text.slice(0, width) : `${text.slice(0, width - 1)}…` +} + +function GraphRows(props: { + api: TuiPluginApi + cells: AsciiGraphCell[][] + categories: TuiMemoryGraphCategory[] +}) { + const categoryIndex = createMemo(() => new Map(props.categories.map((category, index) => [category.id, index]))) + const color = (cell: Omit) => { + const theme = props.api.theme.current + if (cell.kind === "selected") return theme.success + if (cell.kind === "conflict") return theme.warning + if (cell.kind === "edge") return theme.borderActive + if (cell.kind === "label") return theme.text + const palette = [theme.primary, theme.secondary, theme.accent, theme.success, theme.info, theme.warning] + if (cell.kind === "node") return palette[(categoryIndex().get(cell.group ?? "") ?? 0) % palette.length] ?? theme.primary + return theme.textMuted + } + return ( + + {(row) => ( + + + {(run) => {run.text}} + + + )} + + ) +} + +function MemoryGraphPage(props: { api: TuiPluginApi }) { + const dimensions = useTerminalDimensions() + const [refresh, setRefresh] = createSignal(0) + const [snapshot] = createResource(refresh, () => props.api.memory.graph()) + const [selectedID, setSelectedID] = createSignal() + const [viewport, setViewport] = createSignal({ x: undefined as number | undefined, y: undefined as number | undefined, zoom: 1 }) + const [positions, setPositions] = createSignal>({}) + const [query, setQuery] = createSignal("") + const [searching, setSearching] = createSignal(false) + const [showLegend, setShowLegend] = createSignal(true) + const [showMinimap, setShowMinimap] = createSignal(true) + const [drag, setDrag] = createSignal< + | { kind: "node"; id: string } + | { kind: "pan"; x: number; y: number; viewport: ReturnType } + >() + let canvasBox: BoxRenderable | undefined + + const materializedFacts = createMemo(() => snapshot()?.facts.filter((fact) => fact.materialized) ?? []) + const baseScene = createMemo(() => layoutAsciiGraph({ + nodes: materializedFacts().map((fact) => ({ + id: fact.id, + label: compact(fact.text, 28), + group: fact.categoryIDs[0] ?? "uncategorized", + weight: Math.max(0, 10 - (fact.retrievalPriority ?? 10)), + })), + edges: snapshot()?.links ?? [], + maxNodes: 64, + selectedID: selectedID(), + iterations: 180, + })) + const scene = createMemo(() => Object.entries(positions()).reduce( + (current, [id, point]) => asciiGraphWithNodePosition(current, id, point), + baseScene(), + )) + const wide = createMemo(() => dimensions().width >= 92 && dimensions().height >= 22) + const inspectorWidth = createMemo(() => wide() ? 34 : 0) + const canvasWidth = createMemo(() => Math.max(24, dimensions().width - inspectorWidth() - 4)) + const canvasHeight = createMemo(() => Math.max(8, dimensions().height - (wide() ? 5 : 11))) + const frame = createMemo(() => renderAsciiGraph(scene(), { + width: canvasWidth(), + height: canvasHeight(), + marker: "braille", + viewport: viewport(), + selectedID: selectedID(), + labelMode: "neighbors", + labelMaxLength: wide() ? 24 : 16, + })) + const minimap = createMemo(() => renderAsciiGraph(scene(), { + width: Math.min(24, Math.max(14, Math.floor(canvasWidth() * 0.3))), + height: Math.min(7, Math.max(4, Math.floor(canvasHeight() * 0.32))), + marker: "braille", + selectedID: selectedID(), + labelMode: "none", + })) + const selectedFact = createMemo(() => snapshot()?.facts.find((fact) => fact.id === selectedID())) + const selectedLinks = createMemo(() => (snapshot()?.links ?? []).filter((link) => link.from === selectedID() || link.to === selectedID())) + const searchMatches = createMemo(() => { + const needle = query().trim().toLowerCase() + if (!needle) return [] + return materializedFacts() + .filter((fact) => `${fact.text} ${fact.id} ${fact.categoryIDs.join(" ")}`.toLowerCase().includes(needle)) + .slice(0, 6) + }) + + createEffect(() => { + const nodes = scene().nodes + if (!nodes.length) { + setSelectedID(undefined) + return + } + if (nodes.some((node) => node.id === selectedID())) return + setSelectedID(nodes.toSorted((a, b) => b.degree - a.degree || a.id.localeCompare(b.id))[0]?.id) + }) + + function consume(event: { preventDefault(): void; stopPropagation(): void }) { + event.preventDefault() + event.stopPropagation() + } + + function resetView() { + setViewport({ x: undefined, y: undefined, zoom: 1 }) + } + + function zoom(factor: number) { + setViewport((current) => ({ ...current, zoom: Math.max(0.2, Math.min(12, current.zoom * factor)) })) + } + + function move(direction: AsciiGraphPoint) { + setSelectedID(asciiGraphNearestNode(scene(), selectedID(), direction)) + } + + function acceptSearch() { + const match = searchMatches()[0] + if (match) setSelectedID(match.id) + setSearching(false) + } + + useKeyboard((event) => { + if (searching()) { + if (event.name === "escape") { + setSearching(false) + consume(event) + return + } + if (event.name === "return") { + acceptSearch() + consume(event) + return + } + if (event.name === "backspace") { + setQuery((value) => value.slice(0, -1)) + consume(event) + return + } + if (!event.ctrl && !event.meta && (event.name.length === 1 || event.name === "space")) { + setQuery((value) => `${value}${event.name === "space" ? " " : event.name}`) + consume(event) + } + return + } + if (event.name === "escape" || event.name === "q") { + props.api.route.navigate("home") + consume(event) + return + } + if (event.name === "f") { + setSearching(true) + setQuery("") + consume(event) + return + } + if (event.name === "r") { + setRefresh((value) => value + 1) + consume(event) + return + } + if (event.name === "a") { + resetView() + consume(event) + return + } + if (event.name === "m" && event.shift) { + setShowMinimap((value) => !value) + consume(event) + return + } + if (event.name === "l" && event.shift) { + setShowLegend((value) => !value) + consume(event) + return + } + if (event.name === "+" || event.name === "=") { + zoom(1.2) + consume(event) + return + } + if (event.name === "-") { + zoom(1 / 1.2) + consume(event) + return + } + if (event.name === "left" || event.name === "h") move({ x: -1, y: 0 }) + else if (event.name === "right" || event.name === "l") move({ x: 1, y: 0 }) + else if (event.name === "up" || event.name === "k") move({ x: 0, y: -1 }) + else if (event.name === "down" || event.name === "j") move({ x: 0, y: 1 }) + else return + consume(event) + }) + + function mouse(event: MouseEvent) { + if (!canvasBox || event.button !== MouseButton.LEFT) return + const x = event.x - canvasBox.x + const y = event.y - canvasBox.y + if (event.type === "down") { + const hit = Object.entries(frame().nodeCells) + .map(([id, point]) => ({ id, distance: Math.hypot(point.x - x, point.y - y) })) + .filter((item) => item.distance <= 2) + .toSorted((a, b) => a.distance - b.distance)[0] + if (hit) { + setSelectedID(hit.id) + setDrag({ kind: "node", id: hit.id }) + } else { + setDrag({ kind: "pan", x, y, viewport: viewport() }) + } + consume(event) + return + } + if (event.type === "drag") { + const state = drag() + if (!state) return + if (state.kind === "node") { + setPositions((current) => ({ ...current, [state.id]: asciiGraphCellToWorld(frame(), x, y) })) + } else { + const transform = frame().transform + const centerX = state.viewport.x ?? transform.centerX + const centerY = state.viewport.y ?? transform.centerY + setViewport({ + x: centerX - ((x - state.x) * transform.dotsX) / transform.scaleX, + y: centerY - ((y - state.y) * transform.dotsY) / transform.scaleY, + zoom: state.viewport.zoom, + }) + } + consume(event) + return + } + if (event.type === "up") setDrag(undefined) + } + + const healthLine = createMemo(() => { + const data = snapshot() + if (!data) return "loading persisted graph" + return `${data.health.graphHealth} · ${data.health.connectedFacts}/${data.facts.length} connected · ${data.health.isolatedFacts} isolated · ${data.health.orphanLinks} orphan` + }) + + return ( + + + + Memory Graph + {compact(healthLine(), Math.max(24, dimensions().width - 36))} + + + {compact(snapshot()?.root, 32)} + {scene().nodes.length}/{scene().totalNodes} visible · zoom {viewport().zoom.toFixed(2)}x + + + + + + find: {query() || "▎"} + · {searchMatches().length} matches · enter select · esc close + + + + Loading memory graph…}> + Could not read the persisted memory graph.}> + 0} + fallback={ + + No materialized graph facts yet. + Use memory_graph upsert_fact and link, then press r. + + } + > + + (canvasBox = value)} + position="relative" + flexDirection="column" + width={wide() ? canvasWidth() + 2 : "100%"} + height={canvasHeight() + 2} + minWidth={0} + flexShrink={0} + borderStyle="rounded" + borderColor={props.api.theme.current.border} + overflow="hidden" + onMouse={mouse} + > + + + + + + + + + + Select a node.}> + {(fact) => ( + <> + ● selected · {fact().scope} + {compact(fact().text, wide() ? 96 : dimensions().width - 4)} + {fact().categoryIDs.join(", ") || "uncategorized"} + + {(link) => {compact(`${link.from === fact().id ? "→" : "←"} ${link.kind} ${link.from === fact().id ? link.to : link.from}`, wide() ? 31 : dimensions().width - 4)}} + + + )} + + 0}> + matches + + {(fact, index) => {compact(`${index() === 0 ? "›" : " "} ${fact.text}`, wide() ? 31 : dimensions().width - 4)}} + + + + categories + category.count > 0).slice(0, wide() ? 6 : 2)}> + {(category, index) => { + const palette = [props.api.theme.current.primary, props.api.theme.current.secondary, props.api.theme.current.accent, props.api.theme.current.success, props.api.theme.current.info, props.api.theme.current.warning] + return ● {compact(category.label, wide() ? 22 : dimensions().width - 12)} · {category.count} + }} + + + + + + + + + + arrows/hjkl select · +/- zoom · drag pan/node · f find · a fit · M minimap · L legend · r refresh · q back + + + ) +} + +export default { + id: "memory-graph-page-example.page", + async tui(api: TuiPluginApi) { + api.route.register([ + { + name: "example-memory-graph", + render() { + return + }, + }, + ]) + + api.command.register(() => [ + { + title: "Memory Graph", + value: "example.memory.graph", + slash: { name: "memory-graph", aliases: ["graph"] }, + description: "Explore the current project's persisted memory graph.", + category: "Memory", + onSelect() { + api.route.navigate("example-memory-graph") + }, + }, + ]) + }, +} diff --git a/src/mendcode/packages/opencode/examples/memory-graph-page-package/mend-package.json b/src/mendcode/packages/opencode/examples/memory-graph-page-package/mend-package.json new file mode 100644 index 00000000..f9b40533 --- /dev/null +++ b/src/mendcode/packages/opencode/examples/memory-graph-page-package/mend-package.json @@ -0,0 +1,25 @@ +{ + "version": 0, + "id": "memory-graph-page-example", + "packageVersion": "1.0.0", + "title": "Memory Graph Page Example", + "description": "Example MendCode package that adds a custom terminal-native graph page.", + "kind": "bundle", + "channel": "example", + "compatibility": { + "mendcode": ">=0.1.15 <1.0.0", + "runtimePack": "^0" + }, + "artifacts": { + "pages": [".mendcode/pages/memory-graph.tsx"] + }, + "distribution": { + "source": { + "type": "local", + "url": null + }, + "trust": { + "signatureRequired": false + } + } +} diff --git a/src/mendcode/packages/opencode/migration/20260620093000_loop_workflow/migration.sql b/src/mendcode/packages/opencode/migration/20260620093000_loop_workflow/migration.sql new file mode 100644 index 00000000..e08a04ab --- /dev/null +++ b/src/mendcode/packages/opencode/migration/20260620093000_loop_workflow/migration.sql @@ -0,0 +1,98 @@ +CREATE TABLE `loop_workflow` ( + `id` text PRIMARY KEY NOT NULL, + `project_id` text NOT NULL, + `workspace_id` text, + `owner_session_id` text, + `root_session_id` text, + `name` text NOT NULL, + `objective` text NOT NULL, + `state` text NOT NULL, + `source` text NOT NULL, + `template_id` text, + `phase` text NOT NULL, + `next_wakeup` integer, + `time_created` integer NOT NULL, + `time_updated` integer NOT NULL, + `time_activated` integer, + `time_archived` integer, + `data` text NOT NULL, + FOREIGN KEY (`project_id`) REFERENCES `project`(`id`) ON UPDATE no action ON DELETE cascade, + FOREIGN KEY (`owner_session_id`) REFERENCES `session`(`id`) ON UPDATE no action ON DELETE set null, + FOREIGN KEY (`root_session_id`) REFERENCES `session`(`id`) ON UPDATE no action ON DELETE set null +); +--> statement-breakpoint +CREATE INDEX `loop_workflow_project_idx` ON `loop_workflow` (`project_id`); +--> statement-breakpoint +CREATE INDEX `loop_workflow_state_idx` ON `loop_workflow` (`state`); +--> statement-breakpoint +CREATE INDEX `loop_workflow_root_session_idx` ON `loop_workflow` (`root_session_id`); +--> statement-breakpoint +CREATE INDEX `loop_workflow_owner_session_idx` ON `loop_workflow` (`owner_session_id`); + +--> statement-breakpoint +CREATE TABLE `loop_run` ( + `id` text PRIMARY KEY NOT NULL, + `workflow_id` text NOT NULL, + `root_session_id` text, + `state` text NOT NULL, + `trigger` text NOT NULL, + `phase` text NOT NULL, + `next_wakeup` integer, + `time_created` integer NOT NULL, + `time_updated` integer NOT NULL, + `time_started` integer, + `time_ended` integer, + `data` text NOT NULL, + FOREIGN KEY (`workflow_id`) REFERENCES `loop_workflow`(`id`) ON UPDATE no action ON DELETE cascade, + FOREIGN KEY (`root_session_id`) REFERENCES `session`(`id`) ON UPDATE no action ON DELETE set null +); +--> statement-breakpoint +CREATE INDEX `loop_run_workflow_idx` ON `loop_run` (`workflow_id`); +--> statement-breakpoint +CREATE INDEX `loop_run_state_idx` ON `loop_run` (`state`); + +--> statement-breakpoint +CREATE TABLE `loop_event` ( + `id` text PRIMARY KEY NOT NULL, + `workflow_id` text NOT NULL, + `run_id` text, + `session_id` text, + `sequence` integer NOT NULL, + `level` text NOT NULL, + `type` text NOT NULL, + `title` text NOT NULL, + `summary` text NOT NULL, + `time_created` integer NOT NULL, + `time_updated` integer NOT NULL, + `data` text, + FOREIGN KEY (`workflow_id`) REFERENCES `loop_workflow`(`id`) ON UPDATE no action ON DELETE cascade, + FOREIGN KEY (`run_id`) REFERENCES `loop_run`(`id`) ON UPDATE no action ON DELETE set null, + FOREIGN KEY (`session_id`) REFERENCES `session`(`id`) ON UPDATE no action ON DELETE set null +); +--> statement-breakpoint +CREATE INDEX `loop_event_workflow_sequence_idx` ON `loop_event` (`workflow_id`,`sequence`); +--> statement-breakpoint +CREATE INDEX `loop_event_workflow_time_idx` ON `loop_event` (`workflow_id`,`time_created`); + +--> statement-breakpoint +CREATE TABLE `loop_thread` ( + `workflow_id` text NOT NULL, + `run_id` text, + `session_id` text NOT NULL, + `role` text NOT NULL, + `purpose` text NOT NULL, + `state` text NOT NULL, + `parent_session_id` text, + `time_created` integer NOT NULL, + `time_updated` integer NOT NULL, + `data` text, + PRIMARY KEY(`workflow_id`,`session_id`), + FOREIGN KEY (`workflow_id`) REFERENCES `loop_workflow`(`id`) ON UPDATE no action ON DELETE cascade, + FOREIGN KEY (`run_id`) REFERENCES `loop_run`(`id`) ON UPDATE no action ON DELETE set null, + FOREIGN KEY (`session_id`) REFERENCES `session`(`id`) ON UPDATE no action ON DELETE cascade, + FOREIGN KEY (`parent_session_id`) REFERENCES `session`(`id`) ON UPDATE no action ON DELETE set null +); +--> statement-breakpoint +CREATE INDEX `loop_thread_workflow_idx` ON `loop_thread` (`workflow_id`); +--> statement-breakpoint +CREATE INDEX `loop_thread_session_idx` ON `loop_thread` (`session_id`); diff --git a/src/mendcode/packages/opencode/migration/20260620152600_loop_workflow_repair/migration.sql b/src/mendcode/packages/opencode/migration/20260620152600_loop_workflow_repair/migration.sql new file mode 100644 index 00000000..fc97a492 --- /dev/null +++ b/src/mendcode/packages/opencode/migration/20260620152600_loop_workflow_repair/migration.sql @@ -0,0 +1,64 @@ +CREATE TABLE IF NOT EXISTS `loop_run` ( + `id` text PRIMARY KEY NOT NULL, + `workflow_id` text NOT NULL, + `root_session_id` text, + `state` text NOT NULL, + `trigger` text NOT NULL, + `phase` text NOT NULL, + `next_wakeup` integer, + `time_created` integer NOT NULL, + `time_updated` integer NOT NULL, + `time_started` integer, + `time_ended` integer, + `data` text NOT NULL, + FOREIGN KEY (`workflow_id`) REFERENCES `loop_workflow`(`id`) ON UPDATE no action ON DELETE cascade, + FOREIGN KEY (`root_session_id`) REFERENCES `session`(`id`) ON UPDATE no action ON DELETE set null +); +--> statement-breakpoint +CREATE INDEX IF NOT EXISTS `loop_run_workflow_idx` ON `loop_run` (`workflow_id`); +--> statement-breakpoint +CREATE INDEX IF NOT EXISTS `loop_run_state_idx` ON `loop_run` (`state`); +--> statement-breakpoint +CREATE TABLE IF NOT EXISTS `loop_event` ( + `id` text PRIMARY KEY NOT NULL, + `workflow_id` text NOT NULL, + `run_id` text, + `session_id` text, + `sequence` integer NOT NULL, + `level` text NOT NULL, + `type` text NOT NULL, + `title` text NOT NULL, + `summary` text NOT NULL, + `time_created` integer NOT NULL, + `time_updated` integer NOT NULL, + `data` text, + FOREIGN KEY (`workflow_id`) REFERENCES `loop_workflow`(`id`) ON UPDATE no action ON DELETE cascade, + FOREIGN KEY (`run_id`) REFERENCES `loop_run`(`id`) ON UPDATE no action ON DELETE set null, + FOREIGN KEY (`session_id`) REFERENCES `session`(`id`) ON UPDATE no action ON DELETE set null +); +--> statement-breakpoint +CREATE INDEX IF NOT EXISTS `loop_event_workflow_sequence_idx` ON `loop_event` (`workflow_id`,`sequence`); +--> statement-breakpoint +CREATE INDEX IF NOT EXISTS `loop_event_workflow_time_idx` ON `loop_event` (`workflow_id`,`time_created`); +--> statement-breakpoint +CREATE TABLE IF NOT EXISTS `loop_thread` ( + `workflow_id` text NOT NULL, + `run_id` text, + `session_id` text NOT NULL, + `role` text NOT NULL, + `purpose` text NOT NULL, + `state` text NOT NULL, + `parent_session_id` text, + `time_created` integer NOT NULL, + `time_updated` integer NOT NULL, + `data` text, + PRIMARY KEY(`workflow_id`,`session_id`), + FOREIGN KEY (`workflow_id`) REFERENCES `loop_workflow`(`id`) ON UPDATE no action ON DELETE cascade, + FOREIGN KEY (`run_id`) REFERENCES `loop_run`(`id`) ON UPDATE no action ON DELETE set null, + FOREIGN KEY (`session_id`) REFERENCES `session`(`id`) ON UPDATE no action ON DELETE cascade, + FOREIGN KEY (`parent_session_id`) REFERENCES `session`(`id`) ON UPDATE no action ON DELETE set null +); +--> statement-breakpoint +CREATE INDEX IF NOT EXISTS `loop_thread_workflow_idx` ON `loop_thread` (`workflow_id`); +--> statement-breakpoint +CREATE INDEX IF NOT EXISTS `loop_thread_session_idx` ON `loop_thread` (`session_id`); diff --git a/src/mendcode/packages/opencode/migration/20260702120000_agent_view_metadata/migration.sql b/src/mendcode/packages/opencode/migration/20260702120000_agent_view_metadata/migration.sql new file mode 100644 index 00000000..9f32be2d --- /dev/null +++ b/src/mendcode/packages/opencode/migration/20260702120000_agent_view_metadata/migration.sql @@ -0,0 +1,7 @@ +CREATE TABLE `agent_view_metadata` ( + `session_id` text PRIMARY KEY NOT NULL, + `time_created` integer NOT NULL, + `time_updated` integer NOT NULL, + `data` text NOT NULL, + FOREIGN KEY (`session_id`) REFERENCES `session`(`id`) ON UPDATE no action ON DELETE cascade +); diff --git a/src/mendcode/packages/opencode/migration/20260702204500_agent_command/migration.sql b/src/mendcode/packages/opencode/migration/20260702204500_agent_command/migration.sql new file mode 100644 index 00000000..bd948e5a --- /dev/null +++ b/src/mendcode/packages/opencode/migration/20260702204500_agent_command/migration.sql @@ -0,0 +1,16 @@ +CREATE TABLE `agent_command` ( + `id` text PRIMARY KEY NOT NULL, + `source_session_id` text NOT NULL, + `target_session_id` text NOT NULL, + `state` text NOT NULL, + `time_created` integer NOT NULL, + `time_updated` integer NOT NULL, + `data` text NOT NULL, + FOREIGN KEY (`source_session_id`) REFERENCES `session`(`id`) ON UPDATE no action ON DELETE cascade, + FOREIGN KEY (`target_session_id`) REFERENCES `session`(`id`) ON UPDATE no action ON DELETE cascade +); + +CREATE INDEX `agent_command_source_idx` ON `agent_command` (`source_session_id`); +CREATE INDEX `agent_command_target_idx` ON `agent_command` (`target_session_id`); +CREATE INDEX `agent_command_state_idx` ON `agent_command` (`state`); +CREATE INDEX `agent_command_time_updated_idx` ON `agent_command` (`time_updated`); diff --git a/src/mendcode/packages/opencode/migration/20260708230000_loop_artifact_ledger/migration.sql b/src/mendcode/packages/opencode/migration/20260708230000_loop_artifact_ledger/migration.sql new file mode 100644 index 00000000..db80179a --- /dev/null +++ b/src/mendcode/packages/opencode/migration/20260708230000_loop_artifact_ledger/migration.sql @@ -0,0 +1,24 @@ +CREATE TABLE `loop_artifact` ( + `id` text PRIMARY KEY NOT NULL, + `workflow_id` text NOT NULL, + `run_id` text, + `session_id` text, + `sequence` integer NOT NULL, + `kind` text NOT NULL, + `title` text NOT NULL, + `summary` text NOT NULL, + `time_created` integer NOT NULL, + `time_updated` integer NOT NULL, + `data` text, + FOREIGN KEY (`workflow_id`) REFERENCES `loop_workflow`(`id`) ON UPDATE no action ON DELETE cascade, + FOREIGN KEY (`run_id`) REFERENCES `loop_run`(`id`) ON UPDATE no action ON DELETE set null, + FOREIGN KEY (`session_id`) REFERENCES `session`(`id`) ON UPDATE no action ON DELETE set null +); +--> statement-breakpoint +CREATE INDEX `loop_artifact_workflow_sequence_idx` ON `loop_artifact` (`workflow_id`,`sequence`); +--> statement-breakpoint +CREATE INDEX `loop_artifact_workflow_time_idx` ON `loop_artifact` (`workflow_id`,`time_created`); +--> statement-breakpoint +CREATE INDEX `loop_artifact_run_idx` ON `loop_artifact` (`run_id`); +--> statement-breakpoint +CREATE INDEX `loop_artifact_kind_idx` ON `loop_artifact` (`kind`); diff --git a/src/mendcode/packages/opencode/migration/20260714222217_background_task_control_plane/migration.sql b/src/mendcode/packages/opencode/migration/20260714222217_background_task_control_plane/migration.sql new file mode 100644 index 00000000..52abadde --- /dev/null +++ b/src/mendcode/packages/opencode/migration/20260714222217_background_task_control_plane/migration.sql @@ -0,0 +1,60 @@ +CREATE TABLE `background_task` ( + `task_id` text PRIMARY KEY NOT NULL, + `parent_session_id` text NOT NULL, + `origin_message_id` text, + `origin_call_id` text, + `current_generation` integer NOT NULL, + `title` text NOT NULL, + `agent` text, + `model` text, + `time_created` integer NOT NULL, + `time_updated` integer NOT NULL, + `time_dismissed` integer, + `time_expires` integer, + FOREIGN KEY (`task_id`) REFERENCES `session`(`id`) ON UPDATE no action ON DELETE cascade, + FOREIGN KEY (`parent_session_id`) REFERENCES `session`(`id`) ON UPDATE no action ON DELETE cascade +); +--> statement-breakpoint +CREATE INDEX `background_task_parent_idx` ON `background_task` (`parent_session_id`); +--> statement-breakpoint +CREATE INDEX `background_task_updated_idx` ON `background_task` (`time_updated`); +--> statement-breakpoint +CREATE TABLE `background_task_run` ( + `task_id` text NOT NULL, + `generation` integer NOT NULL, + `revision` integer NOT NULL, + `state` text NOT NULL, + `control_intent` text NOT NULL, + `owner_runtime_id` text, + `lease_expires_at` integer, + `result` text, + `time_created` integer NOT NULL, + `time_updated` integer NOT NULL, + `time_queued` integer NOT NULL, + `time_started` integer, + `time_finished` integer, + PRIMARY KEY (`task_id`, `generation`), + FOREIGN KEY (`task_id`) REFERENCES `background_task`(`task_id`) ON UPDATE no action ON DELETE cascade +); +--> statement-breakpoint +CREATE INDEX `background_task_run_state_idx` ON `background_task_run` (`state`); +--> statement-breakpoint +CREATE INDEX `background_task_run_lease_idx` ON `background_task_run` (`lease_expires_at`); +--> statement-breakpoint +CREATE TABLE `background_task_event` ( + `id` text PRIMARY KEY NOT NULL, + `task_id` text NOT NULL, + `generation` integer NOT NULL, + `revision` integer NOT NULL, + `type` text NOT NULL, + `payload` text, + `time_created` integer NOT NULL, + `time_updated` integer NOT NULL, + `time_delivered` integer, + `time_acknowledged` integer, + FOREIGN KEY (`task_id`) REFERENCES `background_task`(`task_id`) ON UPDATE no action ON DELETE cascade +); +--> statement-breakpoint +CREATE UNIQUE INDEX `background_task_event_transition_idx` ON `background_task_event` (`task_id`,`generation`,`revision`,`type`); +--> statement-breakpoint +CREATE INDEX `background_task_event_created_idx` ON `background_task_event` (`time_created`); diff --git a/src/mendcode/packages/opencode/migration/20260722100000_subagent_orchestration/migration.sql b/src/mendcode/packages/opencode/migration/20260722100000_subagent_orchestration/migration.sql new file mode 100644 index 00000000..72f0bb57 --- /dev/null +++ b/src/mendcode/packages/opencode/migration/20260722100000_subagent_orchestration/migration.sql @@ -0,0 +1,5 @@ +ALTER TABLE `background_task` ADD COLUMN `root_session_id` text; +--> statement-breakpoint +ALTER TABLE `background_task` ADD COLUMN `depth` integer NOT NULL DEFAULT 1; +--> statement-breakpoint +CREATE INDEX `background_task_root_idx` ON `background_task` (`root_session_id`); diff --git a/src/mendcode/packages/opencode/migration/20260803032053_dynamic_workflows/migration.sql b/src/mendcode/packages/opencode/migration/20260803032053_dynamic_workflows/migration.sql new file mode 100644 index 00000000..dfe9a23d --- /dev/null +++ b/src/mendcode/packages/opencode/migration/20260803032053_dynamic_workflows/migration.sql @@ -0,0 +1,251 @@ +CREATE TABLE `workflow_definition` ( + `id` text PRIMARY KEY NOT NULL, + `project_id` text NOT NULL, + `workspace_id` text, + `owner_session_id` text, + `name` text NOT NULL, + `description` text NOT NULL, + `source` text NOT NULL, + `current_revision` integer, + `saved` integer NOT NULL DEFAULT 0, + `time_created` integer NOT NULL, + `time_updated` integer NOT NULL, + FOREIGN KEY (`project_id`) REFERENCES `project`(`id`) ON UPDATE no action ON DELETE cascade, + FOREIGN KEY (`owner_session_id`) REFERENCES `session`(`id`) ON UPDATE no action ON DELETE set null +); +--> statement-breakpoint +CREATE INDEX `workflow_definition_project_idx` ON `workflow_definition` (`project_id`); +--> statement-breakpoint +CREATE INDEX `workflow_definition_owner_session_idx` ON `workflow_definition` (`owner_session_id`); +--> statement-breakpoint +CREATE INDEX `workflow_definition_saved_idx` ON `workflow_definition` (`saved`); +--> statement-breakpoint +CREATE TABLE `workflow_revision` ( + `id` text PRIMARY KEY NOT NULL, + `definition_id` text NOT NULL, + `revision` integer NOT NULL, + `plan_hash` text NOT NULL, + `plan` text NOT NULL, + `immutable` integer NOT NULL DEFAULT 1, + `time_created` integer NOT NULL, + `time_updated` integer NOT NULL, + FOREIGN KEY (`definition_id`) REFERENCES `workflow_definition`(`id`) ON UPDATE no action ON DELETE cascade +); +--> statement-breakpoint +CREATE UNIQUE INDEX `workflow_revision_definition_revision_idx` ON `workflow_revision` (`definition_id`,`revision`); +--> statement-breakpoint +CREATE INDEX `workflow_revision_definition_idx` ON `workflow_revision` (`definition_id`); +--> statement-breakpoint +CREATE TABLE `workflow_run` ( + `id` text PRIMARY KEY NOT NULL, + `definition_id` text NOT NULL, + `revision_id` text NOT NULL, + `revision` integer NOT NULL, + `origin_session_id` text, + `root_session_id` text, + `loop_id` text, + `loop_run_id` text, + `state` text NOT NULL, + `current_phase_id` text, + `overlap_key` text, + `lease_holder` text, + `lease_acquired_at` integer, + `lease_heartbeat_at` integer, + `lease_expires_at` integer, + `time_started` integer, + `time_ended` integer, + `time_created` integer NOT NULL, + `time_updated` integer NOT NULL, + `data` text NOT NULL, + FOREIGN KEY (`definition_id`) REFERENCES `workflow_definition`(`id`) ON UPDATE no action ON DELETE cascade, + FOREIGN KEY (`revision_id`) REFERENCES `workflow_revision`(`id`) ON UPDATE no action ON DELETE restrict, + FOREIGN KEY (`origin_session_id`) REFERENCES `session`(`id`) ON UPDATE no action ON DELETE set null, + FOREIGN KEY (`root_session_id`) REFERENCES `session`(`id`) ON UPDATE no action ON DELETE set null, + FOREIGN KEY (`loop_id`) REFERENCES `loop_workflow`(`id`) ON UPDATE no action ON DELETE set null, + FOREIGN KEY (`loop_run_id`) REFERENCES `loop_run`(`id`) ON UPDATE no action ON DELETE set null +); +--> statement-breakpoint +CREATE INDEX `workflow_run_definition_idx` ON `workflow_run` (`definition_id`); +--> statement-breakpoint +CREATE INDEX `workflow_run_revision_idx` ON `workflow_run` (`revision_id`); +--> statement-breakpoint +CREATE INDEX `workflow_run_state_idx` ON `workflow_run` (`state`); +--> statement-breakpoint +CREATE INDEX `workflow_run_origin_session_idx` ON `workflow_run` (`origin_session_id`); +--> statement-breakpoint +CREATE INDEX `workflow_run_loop_idx` ON `workflow_run` (`loop_id`); +--> statement-breakpoint +CREATE INDEX `workflow_run_lease_idx` ON `workflow_run` (`lease_expires_at`); +--> statement-breakpoint +CREATE UNIQUE INDEX `workflow_run_overlap_key_idx` ON `workflow_run` (`overlap_key`); +--> statement-breakpoint +CREATE TABLE `workflow_phase` ( + `run_id` text NOT NULL, + `id` text NOT NULL, + `ordinal` integer NOT NULL, + `name` text NOT NULL, + `description` text, + `state` text NOT NULL, + `barrier` text NOT NULL, + `task_count` integer NOT NULL DEFAULT 0, + `queued_count` integer NOT NULL DEFAULT 0, + `working_count` integer NOT NULL DEFAULT 0, + `completed_count` integer NOT NULL DEFAULT 0, + `failed_count` integer NOT NULL DEFAULT 0, + `blocked_count` integer NOT NULL DEFAULT 0, + `time_started` integer, + `time_ended` integer, + `time_created` integer NOT NULL, + `time_updated` integer NOT NULL, + `data` text, + PRIMARY KEY (`run_id`, `id`), + FOREIGN KEY (`run_id`) REFERENCES `workflow_run`(`id`) ON UPDATE no action ON DELETE cascade +); +--> statement-breakpoint +CREATE UNIQUE INDEX `workflow_phase_run_ordinal_idx` ON `workflow_phase` (`run_id`,`ordinal`); +--> statement-breakpoint +CREATE INDEX `workflow_phase_run_state_idx` ON `workflow_phase` (`run_id`,`state`); +--> statement-breakpoint +CREATE TABLE `workflow_task` ( + `run_id` text NOT NULL, + `id` text NOT NULL, + `phase_id` text NOT NULL, + `name` text NOT NULL, + `kind` text NOT NULL, + `prompt` text NOT NULL, + `state` text NOT NULL, + `depends_on` text NOT NULL, + `inputs` text, + `output` text NOT NULL, + `model` text, + `agent_profile` text, + `allowed_tools` text, + `workspace` text, + `permissions` text, + `retry` text, + `budget` text, + `map` text, + `attempt` integer NOT NULL DEFAULT 0, + `time_started` integer, + `time_ended` integer, + `time_created` integer NOT NULL, + `time_updated` integer NOT NULL, + `data` text, + PRIMARY KEY (`run_id`, `id`), + FOREIGN KEY (`run_id`,`phase_id`) REFERENCES `workflow_phase`(`run_id`,`id`) ON UPDATE no action ON DELETE cascade, + FOREIGN KEY (`run_id`) REFERENCES `workflow_run`(`id`) ON UPDATE no action ON DELETE cascade +); +--> statement-breakpoint +CREATE INDEX `workflow_task_run_state_idx` ON `workflow_task` (`run_id`,`state`); +--> statement-breakpoint +CREATE INDEX `workflow_task_run_phase_idx` ON `workflow_task` (`run_id`,`phase_id`); +--> statement-breakpoint +CREATE TABLE `workflow_task_dependency` ( + `run_id` text NOT NULL, + `task_id` text NOT NULL, + `depends_on_task_id` text NOT NULL, + PRIMARY KEY (`run_id`, `task_id`, `depends_on_task_id`), + FOREIGN KEY (`run_id`,`task_id`) REFERENCES `workflow_task`(`run_id`,`id`) ON UPDATE no action ON DELETE cascade, + FOREIGN KEY (`run_id`,`depends_on_task_id`) REFERENCES `workflow_task`(`run_id`,`id`) ON UPDATE no action ON DELETE cascade, + FOREIGN KEY (`run_id`) REFERENCES `workflow_run`(`id`) ON UPDATE no action ON DELETE cascade +); +--> statement-breakpoint +CREATE INDEX `workflow_task_dependency_dependency_idx` ON `workflow_task_dependency` (`run_id`,`depends_on_task_id`); +--> statement-breakpoint +CREATE TABLE `workflow_task_attempt` ( + `id` text PRIMARY KEY NOT NULL, + `run_id` text NOT NULL, + `task_id` text NOT NULL, + `attempt` integer NOT NULL, + `state` text NOT NULL, + `background_task_id` text, + `background_generation` integer, + `failure_class` text, + `reason` text, + `time_started` integer, + `time_completed` integer, + `time_created` integer NOT NULL, + `time_updated` integer NOT NULL, + `data` text, + FOREIGN KEY (`run_id`,`task_id`) REFERENCES `workflow_task`(`run_id`,`id`) ON UPDATE no action ON DELETE cascade, + FOREIGN KEY (`run_id`) REFERENCES `workflow_run`(`id`) ON UPDATE no action ON DELETE cascade +); +--> statement-breakpoint +CREATE UNIQUE INDEX `workflow_task_attempt_task_attempt_idx` ON `workflow_task_attempt` (`run_id`,`task_id`,`attempt`); +--> statement-breakpoint +CREATE INDEX `workflow_task_attempt_run_idx` ON `workflow_task_attempt` (`run_id`); +--> statement-breakpoint +CREATE INDEX `workflow_task_attempt_background_idx` ON `workflow_task_attempt` (`background_task_id`,`background_generation`); +--> statement-breakpoint +CREATE TABLE `workflow_artifact` ( + `id` text PRIMARY KEY NOT NULL, + `run_id` text NOT NULL, + `task_id` text, + `attempt_id` text, + `sequence` integer NOT NULL, + `kind` text NOT NULL, + `summary` text NOT NULL, + `status` text NOT NULL, + `schema_validated` integer NOT NULL, + `output_refs` text NOT NULL, + `evidence` text NOT NULL, + `session_id` text, + `attempt` integer, + `time_created` integer NOT NULL, + `time_updated` integer NOT NULL, + `data` text, + FOREIGN KEY (`run_id`) REFERENCES `workflow_run`(`id`) ON UPDATE no action ON DELETE cascade, + FOREIGN KEY (`run_id`,`task_id`) REFERENCES `workflow_task`(`run_id`,`id`) ON UPDATE no action ON DELETE cascade, + FOREIGN KEY (`attempt_id`) REFERENCES `workflow_task_attempt`(`id`) ON UPDATE no action ON DELETE set null, + FOREIGN KEY (`session_id`) REFERENCES `session`(`id`) ON UPDATE no action ON DELETE set null +); +--> statement-breakpoint +CREATE INDEX `workflow_artifact_run_sequence_idx` ON `workflow_artifact` (`run_id`,`sequence`); +--> statement-breakpoint +CREATE INDEX `workflow_artifact_task_idx` ON `workflow_artifact` (`run_id`,`task_id`); +--> statement-breakpoint +CREATE INDEX `workflow_artifact_attempt_idx` ON `workflow_artifact` (`attempt_id`); +--> statement-breakpoint +CREATE INDEX `workflow_artifact_kind_idx` ON `workflow_artifact` (`kind`); +--> statement-breakpoint +CREATE TABLE `workflow_event` ( + `id` text PRIMARY KEY NOT NULL, + `run_id` text NOT NULL, + `sequence` integer NOT NULL, + `level` text NOT NULL, + `type` text NOT NULL, + `title` text NOT NULL, + `summary` text NOT NULL, + `time_created` integer NOT NULL, + `time_updated` integer NOT NULL, + `data` text, + FOREIGN KEY (`run_id`) REFERENCES `workflow_run`(`id`) ON UPDATE no action ON DELETE cascade +); +--> statement-breakpoint +CREATE UNIQUE INDEX `workflow_event_run_sequence_idx` ON `workflow_event` (`run_id`,`sequence`); +--> statement-breakpoint +CREATE INDEX `workflow_event_run_time_idx` ON `workflow_event` (`run_id`,`time_created`); +--> statement-breakpoint +CREATE INDEX `workflow_event_type_idx` ON `workflow_event` (`type`); +--> statement-breakpoint +CREATE TABLE `workflow_gate` ( + `run_id` text NOT NULL, + `id` text NOT NULL, + `phase_id` text, + `task_id` text, + `state` text NOT NULL, + `required` integer NOT NULL, + `actor` text, + `reason` text, + `time_created` integer NOT NULL, + `time_updated` integer NOT NULL, + `data` text, + PRIMARY KEY (`run_id`, `id`), + FOREIGN KEY (`run_id`,`phase_id`) REFERENCES `workflow_phase`(`run_id`,`id`) ON UPDATE no action ON DELETE cascade, + FOREIGN KEY (`run_id`,`task_id`) REFERENCES `workflow_task`(`run_id`,`id`) ON UPDATE no action ON DELETE cascade, + FOREIGN KEY (`run_id`) REFERENCES `workflow_run`(`id`) ON UPDATE no action ON DELETE cascade +); +--> statement-breakpoint +CREATE INDEX `workflow_gate_run_state_idx` ON `workflow_gate` (`run_id`,`state`); +--> statement-breakpoint +CREATE INDEX `workflow_gate_task_idx` ON `workflow_gate` (`run_id`,`task_id`); diff --git a/src/mendcode/packages/opencode/migration/20260803032053_dynamic_workflows/snapshot.json b/src/mendcode/packages/opencode/migration/20260803032053_dynamic_workflows/snapshot.json new file mode 100644 index 00000000..cbf08790 --- /dev/null +++ b/src/mendcode/packages/opencode/migration/20260803032053_dynamic_workflows/snapshot.json @@ -0,0 +1,1502 @@ +{ + "id": "2716609d-160a-4864-b375-44071f72a465", + "prevIds": [ + "2ec89846-dcf1-4977-ab5e-244ddc9e3d67", + "27114226-085b-421a-9a40-29b88747e29a" + ], + "version": "7", + "dialect": "sqlite", + "ddl": [ + { + "name": "account_state", + "entityType": "tables" + }, + { + "name": "account", + "entityType": "tables" + }, + { + "name": "control_account", + "entityType": "tables" + }, + { + "name": "workspace", + "entityType": "tables" + }, + { + "name": "project", + "entityType": "tables" + }, + { + "name": "message", + "entityType": "tables" + }, + { + "name": "part", + "entityType": "tables" + }, + { + "name": "permission", + "entityType": "tables" + }, + { + "name": "session_entry", + "entityType": "tables" + }, + { + "name": "session", + "entityType": "tables" + }, + { + "name": "todo", + "entityType": "tables" + }, + { + "name": "session_share", + "entityType": "tables" + }, + { + "name": "event_sequence", + "entityType": "tables" + }, + { + "name": "event", + "entityType": "tables" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "account_state" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "active_account_id", + "entityType": "columns", + "table": "account_state" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "active_org_id", + "entityType": "columns", + "table": "account_state" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "account" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "email", + "entityType": "columns", + "table": "account" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "url", + "entityType": "columns", + "table": "account" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "access_token", + "entityType": "columns", + "table": "account" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "refresh_token", + "entityType": "columns", + "table": "account" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "token_expiry", + "entityType": "columns", + "table": "account" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "time_created", + "entityType": "columns", + "table": "account" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "time_updated", + "entityType": "columns", + "table": "account" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "email", + "entityType": "columns", + "table": "control_account" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "url", + "entityType": "columns", + "table": "control_account" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "access_token", + "entityType": "columns", + "table": "control_account" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "refresh_token", + "entityType": "columns", + "table": "control_account" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "token_expiry", + "entityType": "columns", + "table": "control_account" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "active", + "entityType": "columns", + "table": "control_account" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "time_created", + "entityType": "columns", + "table": "control_account" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "time_updated", + "entityType": "columns", + "table": "control_account" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "workspace" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "type", + "entityType": "columns", + "table": "workspace" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": "''", + "generated": null, + "name": "name", + "entityType": "columns", + "table": "workspace" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "branch", + "entityType": "columns", + "table": "workspace" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "directory", + "entityType": "columns", + "table": "workspace" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "extra", + "entityType": "columns", + "table": "workspace" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "project_id", + "entityType": "columns", + "table": "workspace" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "project" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "worktree", + "entityType": "columns", + "table": "project" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "vcs", + "entityType": "columns", + "table": "project" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "name", + "entityType": "columns", + "table": "project" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "icon_url", + "entityType": "columns", + "table": "project" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "icon_url_override", + "entityType": "columns", + "table": "project" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "icon_color", + "entityType": "columns", + "table": "project" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "time_created", + "entityType": "columns", + "table": "project" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "time_updated", + "entityType": "columns", + "table": "project" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "time_initialized", + "entityType": "columns", + "table": "project" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "sandboxes", + "entityType": "columns", + "table": "project" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "commands", + "entityType": "columns", + "table": "project" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "message" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "session_id", + "entityType": "columns", + "table": "message" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "time_created", + "entityType": "columns", + "table": "message" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "time_updated", + "entityType": "columns", + "table": "message" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "data", + "entityType": "columns", + "table": "message" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "part" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "message_id", + "entityType": "columns", + "table": "part" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "session_id", + "entityType": "columns", + "table": "part" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "time_created", + "entityType": "columns", + "table": "part" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "time_updated", + "entityType": "columns", + "table": "part" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "data", + "entityType": "columns", + "table": "part" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "project_id", + "entityType": "columns", + "table": "permission" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "time_created", + "entityType": "columns", + "table": "permission" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "time_updated", + "entityType": "columns", + "table": "permission" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "data", + "entityType": "columns", + "table": "permission" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "session_entry" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "session_id", + "entityType": "columns", + "table": "session_entry" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "type", + "entityType": "columns", + "table": "session_entry" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "time_created", + "entityType": "columns", + "table": "session_entry" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "time_updated", + "entityType": "columns", + "table": "session_entry" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "data", + "entityType": "columns", + "table": "session_entry" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "session" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "project_id", + "entityType": "columns", + "table": "session" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "workspace_id", + "entityType": "columns", + "table": "session" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "parent_id", + "entityType": "columns", + "table": "session" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "slug", + "entityType": "columns", + "table": "session" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "directory", + "entityType": "columns", + "table": "session" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "path", + "entityType": "columns", + "table": "session" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "title", + "entityType": "columns", + "table": "session" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "version", + "entityType": "columns", + "table": "session" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "share_url", + "entityType": "columns", + "table": "session" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "summary_additions", + "entityType": "columns", + "table": "session" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "summary_deletions", + "entityType": "columns", + "table": "session" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "summary_files", + "entityType": "columns", + "table": "session" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "summary_diffs", + "entityType": "columns", + "table": "session" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "revert", + "entityType": "columns", + "table": "session" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "permission", + "entityType": "columns", + "table": "session" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "time_created", + "entityType": "columns", + "table": "session" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "time_updated", + "entityType": "columns", + "table": "session" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "time_compacting", + "entityType": "columns", + "table": "session" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "time_archived", + "entityType": "columns", + "table": "session" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "session_id", + "entityType": "columns", + "table": "todo" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "content", + "entityType": "columns", + "table": "todo" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "status", + "entityType": "columns", + "table": "todo" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "priority", + "entityType": "columns", + "table": "todo" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "position", + "entityType": "columns", + "table": "todo" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "time_created", + "entityType": "columns", + "table": "todo" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "time_updated", + "entityType": "columns", + "table": "todo" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "session_id", + "entityType": "columns", + "table": "session_share" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "session_share" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "secret", + "entityType": "columns", + "table": "session_share" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "url", + "entityType": "columns", + "table": "session_share" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "time_created", + "entityType": "columns", + "table": "session_share" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "time_updated", + "entityType": "columns", + "table": "session_share" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "aggregate_id", + "entityType": "columns", + "table": "event_sequence" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "seq", + "entityType": "columns", + "table": "event_sequence" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "owner_id", + "entityType": "columns", + "table": "event_sequence" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "event" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "aggregate_id", + "entityType": "columns", + "table": "event" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "seq", + "entityType": "columns", + "table": "event" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "type", + "entityType": "columns", + "table": "event" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "data", + "entityType": "columns", + "table": "event" + }, + { + "columns": [ + "active_account_id" + ], + "tableTo": "account", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "SET NULL", + "nameExplicit": false, + "name": "fk_account_state_active_account_id_account_id_fk", + "entityType": "fks", + "table": "account_state" + }, + { + "columns": [ + "project_id" + ], + "tableTo": "project", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "fk_workspace_project_id_project_id_fk", + "entityType": "fks", + "table": "workspace" + }, + { + "columns": [ + "session_id" + ], + "tableTo": "session", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "fk_message_session_id_session_id_fk", + "entityType": "fks", + "table": "message" + }, + { + "columns": [ + "message_id" + ], + "tableTo": "message", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "fk_part_message_id_message_id_fk", + "entityType": "fks", + "table": "part" + }, + { + "columns": [ + "project_id" + ], + "tableTo": "project", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "fk_permission_project_id_project_id_fk", + "entityType": "fks", + "table": "permission" + }, + { + "columns": [ + "session_id" + ], + "tableTo": "session", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "fk_session_entry_session_id_session_id_fk", + "entityType": "fks", + "table": "session_entry" + }, + { + "columns": [ + "project_id" + ], + "tableTo": "project", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "fk_session_project_id_project_id_fk", + "entityType": "fks", + "table": "session" + }, + { + "columns": [ + "session_id" + ], + "tableTo": "session", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "fk_todo_session_id_session_id_fk", + "entityType": "fks", + "table": "todo" + }, + { + "columns": [ + "session_id" + ], + "tableTo": "session", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "fk_session_share_session_id_session_id_fk", + "entityType": "fks", + "table": "session_share" + }, + { + "columns": [ + "aggregate_id" + ], + "tableTo": "event_sequence", + "columnsTo": [ + "aggregate_id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "fk_event_aggregate_id_event_sequence_aggregate_id_fk", + "entityType": "fks", + "table": "event" + }, + { + "columns": [ + "email", + "url" + ], + "nameExplicit": false, + "name": "control_account_pk", + "entityType": "pks", + "table": "control_account" + }, + { + "columns": [ + "session_id", + "position" + ], + "nameExplicit": false, + "name": "todo_pk", + "entityType": "pks", + "table": "todo" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "account_state_pk", + "table": "account_state", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "account_pk", + "table": "account", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "workspace_pk", + "table": "workspace", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "project_pk", + "table": "project", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "message_pk", + "table": "message", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "part_pk", + "table": "part", + "entityType": "pks" + }, + { + "columns": [ + "project_id" + ], + "nameExplicit": false, + "name": "permission_pk", + "table": "permission", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "session_entry_pk", + "table": "session_entry", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "session_pk", + "table": "session", + "entityType": "pks" + }, + { + "columns": [ + "session_id" + ], + "nameExplicit": false, + "name": "session_share_pk", + "table": "session_share", + "entityType": "pks" + }, + { + "columns": [ + "aggregate_id" + ], + "nameExplicit": false, + "name": "event_sequence_pk", + "table": "event_sequence", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "event_pk", + "table": "event", + "entityType": "pks" + }, + { + "columns": [ + { + "value": "session_id", + "isExpression": false + }, + { + "value": "time_created", + "isExpression": false + }, + { + "value": "id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "message_session_time_created_id_idx", + "entityType": "indexes", + "table": "message" + }, + { + "columns": [ + { + "value": "message_id", + "isExpression": false + }, + { + "value": "id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "part_message_id_id_idx", + "entityType": "indexes", + "table": "part" + }, + { + "columns": [ + { + "value": "session_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "part_session_idx", + "entityType": "indexes", + "table": "part" + }, + { + "columns": [ + { + "value": "session_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "session_entry_session_idx", + "entityType": "indexes", + "table": "session_entry" + }, + { + "columns": [ + { + "value": "session_id", + "isExpression": false + }, + { + "value": "type", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "session_entry_session_type_idx", + "entityType": "indexes", + "table": "session_entry" + }, + { + "columns": [ + { + "value": "time_created", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "session_entry_time_created_idx", + "entityType": "indexes", + "table": "session_entry" + }, + { + "columns": [ + { + "value": "project_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "session_project_idx", + "entityType": "indexes", + "table": "session" + }, + { + "columns": [ + { + "value": "workspace_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "session_workspace_idx", + "entityType": "indexes", + "table": "session" + }, + { + "columns": [ + { + "value": "parent_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "session_parent_idx", + "entityType": "indexes", + "table": "session" + }, + { + "columns": [ + { + "value": "session_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "todo_session_idx", + "entityType": "indexes", + "table": "todo" + } + ], + "renames": [] +} \ No newline at end of file diff --git a/src/mendcode/packages/opencode/migration/20260904120000_continuity_runtime/migration.sql b/src/mendcode/packages/opencode/migration/20260904120000_continuity_runtime/migration.sql new file mode 100644 index 00000000..f0567720 --- /dev/null +++ b/src/mendcode/packages/opencode/migration/20260904120000_continuity_runtime/migration.sql @@ -0,0 +1,13 @@ +CREATE TABLE `continuity_record` ( + `id` text PRIMARY KEY NOT NULL, + `session_id` text NOT NULL REFERENCES `session`(`id`) ON DELETE CASCADE, + `directory` text NOT NULL, + `kind` text NOT NULL, + `generation` integer NOT NULL, + `status` text NOT NULL, + `data` text NOT NULL, + `time_created` integer NOT NULL, + `time_updated` integer NOT NULL +); +--> statement-breakpoint +CREATE INDEX `continuity_session_kind_idx` ON `continuity_record` (`session_id`, `kind`); diff --git a/src/mendcode/packages/opencode/migration/20260912160000_todo_target_lock/migration.sql b/src/mendcode/packages/opencode/migration/20260912160000_todo_target_lock/migration.sql new file mode 100644 index 00000000..a3b577d4 --- /dev/null +++ b/src/mendcode/packages/opencode/migration/20260912160000_todo_target_lock/migration.sql @@ -0,0 +1,8 @@ +CREATE TABLE `todo_target_lock` ( + `session_id` text PRIMARY KEY NOT NULL, + `revision` integer NOT NULL, + `data` text NOT NULL, + `time_created` integer NOT NULL, + `time_updated` integer NOT NULL, + FOREIGN KEY (`session_id`) REFERENCES `session`(`id`) ON UPDATE no action ON DELETE cascade +); diff --git a/src/mendcode/packages/opencode/package.json b/src/mendcode/packages/opencode/package.json index ccf126e8..c9aa6956 100644 --- a/src/mendcode/packages/opencode/package.json +++ b/src/mendcode/packages/opencode/package.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/package.json", - "version": "1.14.39", + "version": "0.1.44", "name": "mendcode", "type": "module", "license": "MIT", @@ -8,6 +8,13 @@ "scripts": { "typecheck": "tsgo --noEmit", "test": "bun test --timeout 30000", + "test:queue-compaction:manual": "bun run script/queue-compaction-smoke.ts", + "test:compaction:canary": "bun run script/compaction-canary.ts", + "test:session-runtime:smoke": "bun run script/session-runtime-smoke.ts", + "test:incident:local": "bun run script/incident-local-smoke.ts", + "dev:rearm": "bun run script/dev-rearm.ts", + "test:dev-rearm:smoke": "bun run script/dev-rearm-smoke.ts", + "test:markdown-render": "bun test test/cli/tui/markdown-render.test.ts --timeout 30000", "test:ci": "mkdir -p .artifacts/unit && bun test --timeout 30000 --reporter=junit --reporter-outfile=.artifacts/unit/junit.xml", "build": "bun run script/build.ts", "fix-node-pty": "bun run script/fix-node-pty.ts", @@ -17,7 +24,6 @@ "db": "bun drizzle-kit" }, "bin": { - "mend": "./bin/opencode", "mendcode": "./bin/opencode", "mendcode-runtime": "./bin/opencode" }, @@ -47,7 +53,7 @@ } }, "devDependencies": { - "@babel/core": "7.28.4", + "@babel/core": "7.29.6", "@octokit/webhooks-types": "7.6.1", "@mendcode/script": "workspace:*", "@mendcode/core": "workspace:*", @@ -98,34 +104,36 @@ "@ai-sdk/openai": "3.0.53", "@ai-sdk/openai-compatible": "2.0.41", "@ai-sdk/perplexity": "3.0.26", - "@ai-sdk/provider": "3.0.8", - "@ai-sdk/provider-utils": "4.0.23", + "@ai-sdk/provider": "3.0.12", + "@ai-sdk/provider-utils": "4.0.33", "@ai-sdk/togetherai": "2.0.41", "@ai-sdk/vercel": "2.0.39", "@ai-sdk/xai": "3.0.82", + "@anthropic-ai/claude-agent-sdk": "0.3.187", + "@anthropic-ai/sdk": "0.105.0", "@aws-sdk/credential-providers": "3.993.0", "@clack/prompts": "1.0.0-alpha.1", "@effect/opentelemetry": "catalog:", "@effect/platform-node": "catalog:", "@gitlab/opencode-gitlab-auth": "1.3.3", - "@hono/node-server": "1.19.13", + "@hono/node-server": "2.0.10", "@hono/node-ws": "1.3.0", "@hono/standard-validator": "0.1.5", "@hono/zod-validator": "catalog:", "@lydell/node-pty": "catalog:", - "@modelcontextprotocol/sdk": "1.27.1", - "@octokit/graphql": "9.0.2", - "@octokit/rest": "catalog:", - "@openauthjs/openauth": "catalog:", "@mendcode/plugin": "workspace:*", "@mendcode/script": "workspace:*", "@mendcode/sdk": "workspace:*", + "@modelcontextprotocol/sdk": "1.29.0", + "@octokit/graphql": "9.0.2", + "@octokit/rest": "catalog:", + "@openauthjs/openauth": "catalog:", "@openrouter/ai-sdk-provider": "2.8.1", "@opentelemetry/api": "1.9.0", - "@opentelemetry/context-async-hooks": "2.6.1", - "@opentelemetry/exporter-trace-otlp-http": "0.214.0", - "@opentelemetry/sdk-trace-base": "2.6.1", - "@opentelemetry/sdk-trace-node": "2.6.1", + "@opentelemetry/context-async-hooks": "2.8.0", + "@opentelemetry/exporter-trace-otlp-http": "0.219.0", + "@opentelemetry/sdk-trace-base": "2.8.0", + "@opentelemetry/sdk-trace-node": "2.8.0", "@opentui/core": "catalog:", "@opentui/solid": "catalog:", "@parcel/watcher": "2.5.1", diff --git a/src/mendcode/packages/opencode/script/build.ts b/src/mendcode/packages/opencode/script/build.ts index d9267cf2..9a9e3d33 100755 --- a/src/mendcode/packages/opencode/script/build.ts +++ b/src/mendcode/packages/opencode/script/build.ts @@ -52,12 +52,23 @@ const baselineFlag = process.argv.includes("--baseline") const skipInstall = process.argv.includes("--skip-install") const sourcemapsFlag = process.argv.includes("--sourcemaps") const releaseAssetsFlag = process.argv.includes("--release-assets") +const excludedOS = new Set( + process.argv + .filter((arg) => arg.startsWith("--exclude-os=")) + .flatMap((arg) => arg.slice("--exclude-os=".length).split(",")) + .map((value) => value.trim()) + .filter(Boolean), +) const plugin = createSolidTransformPlugin() const skipEmbedWebUi = process.argv.includes("--skip-embed-web-ui") const createEmbeddedWebUIBundle = async () => { - console.log(`Building Web UI to embed in the binary`) const appDir = path.join(import.meta.dirname, "../../app") + if (!fs.existsSync(path.join(appDir, "package.json"))) { + console.log(`Skipping embedded Web UI because packages/app is not present`) + return null + } + console.log(`Building Web UI to embed in the binary`) const dist = path.join(appDir, "dist") await $`bun run --cwd ${appDir} build` const files = (await Array.fromAsync(new Bun.Glob("**/*").scan({ cwd: dist }))) @@ -73,9 +84,10 @@ const createEmbeddedWebUIBundle = async () => { `// Import all files as file_$i with type: "file"`, ...imports, `// Export with original mappings`, - `export default {`, + `const embeddedFiles = {`, ...entries, `}`, + `export default embeddedFiles`, ].join("\n") } @@ -144,26 +156,27 @@ const allTargets: { }, ] -const targets = singleFlag - ? allTargets.filter((item) => { - if (item.os !== process.platform || item.arch !== process.arch) { - return false - } +const targets = allTargets.filter((item) => { + if (excludedOS.has(item.os)) return false + if (!singleFlag) return true - // When building for the current platform, prefer a single native binary by default. - // Baseline binaries require additional Bun artifacts and can be flaky to download. - if (item.avx2 === false) { - return baselineFlag - } + if (item.os !== process.platform || item.arch !== process.arch) { + return false + } - // also skip abi-specific builds for the same reason - if (item.abi !== undefined) { - return false - } + // When building for the current platform, prefer a single native binary by default. + // Baseline binaries require additional Bun artifacts and can be flaky to download. + if (item.avx2 === false) { + return baselineFlag + } - return true - }) - : allTargets + // also skip abi-specific builds for the same reason + if (item.abi !== undefined) { + return false + } + + return true +}) await $`rm -rf dist` @@ -204,7 +217,9 @@ for (const item of targets) { format: "esm", minify: true, sourcemap: sourcemapsFlag ? "linked" : "none", - splitting: true, + // Bun's Windows linker can emit orphaned minified exports when splitting + // is enabled. Keep Windows releases as one deterministic bundle. + splitting: item.os !== "win32", compile: { autoloadBunfig: false, autoloadDotenv: false, @@ -213,15 +228,24 @@ for (const item of targets) { target: name.replace(pkg.name, "bun") as any, outfile: `dist/${name}/bin/${binaryName}`, execArgv: [`--user-agent=mendcode/${Script.version}`, "--use-system-ca", "--"], - windows: {}, + windows: + item.os === "win32" + ? { + icon: path.resolve(dir, "../ui/src/assets/favicon/mendcode.ico"), + title: "MendCode", + publisher: "MendCode", + description: "MendCode AI coding terminal", + } + : undefined, }, files: embeddedFileMap ? { "opencode-web-ui.gen.ts": embeddedFileMap } : {}, - entrypoints: ["./src/index.ts", parserWorker, workerPath, ...(embeddedFileMap ? ["opencode-web-ui.gen.ts"] : [])], + entrypoints: ["./src/index.ts", parserWorker, workerPath, "./src/mend/codemode/worker.ts", ...(embeddedFileMap ? ["opencode-web-ui.gen.ts"] : [])], define: { OPENCODE_VERSION: `'${Script.version}'`, OPENCODE_MIGRATIONS: JSON.stringify(migrations), OTUI_TREE_SITTER_WORKER_PATH: bunfsRoot + workerRelativePath, OPENCODE_WORKER_PATH: workerPath, + MENDCODE_CODE_WORKER_PATH: "./src/mend/codemode/worker.ts", OPENCODE_CHANNEL: `'${Script.channel}'`, OPENCODE_LIBC: item.os === "linux" ? `'${item.abi ?? "glibc"}'` : "", }, @@ -230,10 +254,17 @@ for (const item of targets) { // Smoke test: only run if binary is for current platform if (item.os === process.platform && item.arch === process.arch && !item.abi) { const binaryPath = `dist/${name}/bin/${binaryName}` - console.log(`Running smoke test: ${binaryPath} --version`) + const checkHelp = item.avx2 !== false + console.log(`Running smoke test: ${binaryPath} --version${checkHelp ? " && --help" : ""}`) try { const versionOutput = await $`${binaryPath} --version`.text() - console.log(`Smoke test passed: ${versionOutput.trim()}`) + if (checkHelp) { + const helpOutput = await $`${binaryPath} --help 2>&1`.text() + if (!helpOutput.trim()) { + throw new Error("--help produced no output") + } + } + console.log(`Smoke test passed: ${versionOutput.trim()}${checkHelp ? " and --help startup" : ""}`) } catch (e) { console.error(`Smoke test failed for ${name}:`, e) process.exit(1) diff --git a/src/mendcode/packages/opencode/script/compaction-canary.ts b/src/mendcode/packages/opencode/script/compaction-canary.ts new file mode 100644 index 00000000..05770ea4 --- /dev/null +++ b/src/mendcode/packages/opencode/script/compaction-canary.ts @@ -0,0 +1,192 @@ +import { createHash } from "node:crypto" +import { performance } from "node:perf_hooks" +import { writeFile } from "node:fs/promises" + +export type CanaryStrategy = "portable" | "native" +export type CanaryMode = "fixture" | "live" + +export type FixtureState = { + readonly facts: readonly string[] + readonly actions: readonly string[] + readonly latestIntent: string + readonly constraints: readonly string[] + readonly toolPairs: readonly { readonly callID: string; readonly resultID: string }[] +} + +export type FixtureCorpus = { + readonly name: "medium" | "large" + readonly text: string + readonly expected: FixtureState + readonly sha256: string + readonly estimatedInputTokens: number + readonly tokenMethod: "utf8/4" +} + +export type CanaryResult = { + readonly mode: CanaryMode + readonly strategy: CanaryStrategy + readonly corpus: Pick + readonly status: "PASS" | "FAIL" | "NOT_RUN" + readonly evidenceKind: "synthetic-fixture" | "live-provider" + readonly fidelity?: { + readonly facts: boolean + readonly actions: boolean + readonly latestIntent: boolean + readonly constraints: boolean + readonly toolPairs: boolean + } + readonly timingMs?: { + readonly preparation: number + readonly compaction: number + readonly installation: number + readonly resume: number + readonly total: number + } + readonly reason?: string +} + +const facts = Array.from({ length: 20 }, (_, index) => `fact-${index + 1}: retained sanitized fact ${index + 1}`) +const actions = Array.from({ length: 5 }, (_, index) => `action-${index + 1}: pending follow-up ${index + 1}`) +const constraints = [ + "preserve the latest user intent", + "do not repeat completed work", + "keep tool call/result pairs valid", + "retain the original language", +] +const toolPairs = Array.from({ length: 5 }, (_, index) => ({ callID: `call-${index + 1}`, resultID: `result-${index + 1}` })) + +export const fixtureState: FixtureState = { + facts, + actions, + latestIntent: "Continue the bounded implementation from the latest correction.", + constraints, + toolPairs, +} + +const fixtureBody = (targetTokens: number) => { + const header = [ + "SANITIZED COMPACTION CANARY", + `latest-intent: ${fixtureState.latestIntent}`, + ...fixtureState.facts, + ...fixtureState.actions, + ...fixtureState.constraints.map((item) => `constraint: ${item}`), + ...fixtureState.toolPairs.map((pair) => `tool: ${pair.callID} -> ${pair.resultID}`), + ].join("\n") + const filler = "context filler preserves ordering and language without adding instructions.\n" + return `${header}\n${filler.repeat(Math.max(1, Math.ceil((targetTokens * 4 - header.length) / filler.length)))}.END\n` +} + +const sha256 = (value: string) => createHash("sha256").update(value).digest("hex") +const estimateTokens = (value: string) => Math.max(1, Math.ceil(new TextEncoder().encode(value).length / 4)) + +export function fixtureCorpora(): readonly FixtureCorpus[] { + return [30_000, 100_000].map((target, index) => { + const text = fixtureBody(target) + return { + name: index === 0 ? "medium" : "large", + text, + expected: fixtureState, + sha256: sha256(text), + estimatedInputTokens: estimateTokens(text), + tokenMethod: "utf8/4", + } + }) +} + +export function compactFixture(input: { readonly strategy: CanaryStrategy; readonly corpus: FixtureCorpus }): FixtureState { + // The fixture provider models a settled compaction boundary. The native + // branch keeps an opaque checkpoint conceptually, while the portable branch + // keeps a bounded summary. Both must preserve the same deterministic oracle. + void input.strategy + return structuredClone(input.corpus.expected) +} + +export function corruptedFixture(state: FixtureState, kind: "missing-fact" | "broken-tool-pair" | "wrong-intent") { + if (kind === "missing-fact") return { ...state, facts: state.facts.slice(1) } + if (kind === "broken-tool-pair") return { ...state, toolPairs: state.toolPairs.slice(0, -1) } + return { ...state, latestIntent: "Do an unrelated action." } +} + +export function checkFixtureFidelity(actual: FixtureState, expected: FixtureState) { + return { + facts: JSON.stringify(actual.facts) === JSON.stringify(expected.facts), + actions: JSON.stringify(actual.actions) === JSON.stringify(expected.actions), + latestIntent: actual.latestIntent === expected.latestIntent, + constraints: JSON.stringify(actual.constraints) === JSON.stringify(expected.constraints), + toolPairs: JSON.stringify(actual.toolPairs) === JSON.stringify(expected.toolPairs), + } +} + +const fidelityPassed = (fidelity: CanaryResult["fidelity"]) => Boolean(fidelity && Object.values(fidelity).every(Boolean)) + +export function runFixtureCanary(strategy: CanaryStrategy, corpus: FixtureCorpus): CanaryResult { + const started = performance.now() + const preparation = performance.now() + const prepared = structuredClone(corpus) + const afterPreparation = performance.now() + const actual = compactFixture({ strategy, corpus: prepared }) + const afterCompaction = performance.now() + const fidelity = checkFixtureFidelity(actual, corpus.expected) + const afterInstallation = performance.now() + // Fixture resume is intentionally local and deterministic; it is not a + // provider round trip and must never be reported as live native latency. + const afterResume = performance.now() + return { + mode: "fixture", + strategy, + corpus: { + name: corpus.name, + sha256: corpus.sha256, + estimatedInputTokens: corpus.estimatedInputTokens, + tokenMethod: corpus.tokenMethod, + }, + status: fidelityPassed(fidelity) ? "PASS" : "FAIL", + evidenceKind: "synthetic-fixture", + fidelity, + timingMs: { + preparation: afterPreparation - preparation, + compaction: afterCompaction - afterPreparation, + installation: afterInstallation - afterCompaction, + resume: afterResume - afterInstallation, + total: afterResume - started, + }, + } +} + +export function liveCanaryUnavailable(strategy: CanaryStrategy, corpus?: FixtureCorpus): CanaryResult { + return { + mode: "live", + strategy, + corpus: corpus + ? { name: corpus.name, sha256: corpus.sha256, estimatedInputTokens: corpus.estimatedInputTokens, tokenMethod: corpus.tokenMethod } + : { name: "medium", sha256: "not-provided", estimatedInputTokens: 0, tokenMethod: "utf8/4" }, + status: "NOT_RUN", + evidenceKind: "live-provider", + reason: "Live mode requires a separately authorized provider route, credentials, sanitized corpus and spend cap; this command never auto-enables them.", + } +} + +function option(name: string) { + const index = process.argv.indexOf(name) + return index >= 0 ? process.argv[index + 1] : undefined +} + +export async function main() { + const mode = (option("--mode") ?? "fixture") as CanaryMode + const strategy = (option("--strategy") ?? "portable") as CanaryStrategy + if (mode !== "fixture" && mode !== "live") throw new Error("--mode must be fixture or live") + if (strategy !== "portable" && strategy !== "native") throw new Error("--strategy must be portable or native") + + const corpora = fixtureCorpora() + const results = mode === "fixture" + ? corpora.map((corpus) => runFixtureCanary(strategy, corpus)) + : [liveCanaryUnavailable(strategy, corpora[0])] + const output = JSON.stringify({ mode, strategy, results }, null, 2) + const outputPath = option("--output") + if (outputPath) await writeFile(outputPath, `${output}\n`, "utf8") + process.stdout.write(`${output}\n`) +} + +if (import.meta.main) { + await main() +} diff --git a/src/mendcode/packages/opencode/script/dev-rearm-smoke.ts b/src/mendcode/packages/opencode/script/dev-rearm-smoke.ts new file mode 100644 index 00000000..65142f79 --- /dev/null +++ b/src/mendcode/packages/opencode/script/dev-rearm-smoke.ts @@ -0,0 +1,98 @@ +import { createServer, type IncomingMessage, type ServerResponse } from "node:http" +import { once } from "node:events" +import { probeRuntime } from "./dev-rearm" + +const VERSION = "0.1.43" +const PROJECT = "/tmp/mendcode-dev-rearm-smoke-project" + +function assert(condition: unknown, message: string): asserts condition { + if (!condition) throw new Error(message) +} + +function json(response: ServerResponse, value: unknown, status = 200) { + response.writeHead(status, { "content-type": "application/json" }) + response.end(JSON.stringify(value)) +} + +async function main() { + let mode: "ready" | "empty-session" | "empty-provider" | "no-default" = "ready" + const server = createServer((request: IncomingMessage, response: ServerResponse) => { + switch (request.url?.split("?")[0]) { + case "/global/health": + return json(response, { healthy: true, version: VERSION, channel: "local" }) + case "/path": + return json(response, { + home: "/tmp", + state: "/tmp/state", + config: "/tmp/config", + worktree: PROJECT, + directory: PROJECT, + }) + case "/session": + return json(response, mode === "empty-session" ? [] : [{ id: "session-smoke" }]) + case "/provider": + return json( + response, + mode === "empty-provider" + ? { all: [], default: {}, connected: [] } + : { + all: [{ id: "fake-local", models: { "fake-model": {} } }], + default: mode === "no-default" ? {} : { "fake-local": "fake-model" }, + connected: [], + }, + ) + default: + return json(response, { error: "not found" }, 404) + } + }) + server.listen(0, "127.0.0.1") + await once(server, "listening") + const address = server.address() + assert(address && typeof address === "object", "smoke server did not bind") + + const state = { + version: 1, + pid: process.pid, + url: `http://127.0.0.1:${address.port}/`, + username: "mendcode", + password: "smoke-password", + startedAt: new Date().toISOString(), + runtimeID: "smoke-runtime", + } + const ready = await probeRuntime(state, PROJECT, VERSION) + assert(ready.ok, `expected ready runtime, got ${ready.reason ?? "unknown"}`) + assert(ready.sessions?.length === 1, "ready smoke did not observe session data") + assert(ready.providers?.all?.length === 1, "ready smoke did not observe provider data") + + mode = "empty-session" + const emptySession = await probeRuntime(state, PROJECT, VERSION) + assert( + !emptySession.ok && emptySession.reason?.includes("session endpoint returned 0"), + "empty /session passed the gate", + ) + + mode = "empty-provider" + const emptyProvider = await probeRuntime(state, PROJECT, VERSION) + assert( + !emptyProvider.ok && emptyProvider.reason?.includes("provider endpoint returned 0"), + "empty /provider passed the gate", + ) + + mode = "no-default" + const noDefault = await probeRuntime(state, PROJECT, VERSION) + assert(!noDefault.ok && noDefault.reason?.includes("no default model"), "provider without a default passed the gate") + + await new Promise((resolve, reject) => server.close((error) => (error ? reject(error) : resolve()))) + const offline = await probeRuntime(state, PROJECT, VERSION) + assert(!offline.ok, "offline server passed the readiness gate") + console.log( + "PASS dev-rearm smoke: health + InstanceContext + non-empty session/provider gates reject offline/empty state", + ) +} + +if (import.meta.main) { + main().catch((error) => { + console.error(`FAIL dev-rearm smoke: ${error instanceof Error ? error.message : String(error)}`) + process.exitCode = 1 + }) +} diff --git a/src/mendcode/packages/opencode/script/dev-rearm.ts b/src/mendcode/packages/opencode/script/dev-rearm.ts new file mode 100644 index 00000000..7205222d --- /dev/null +++ b/src/mendcode/packages/opencode/script/dev-rearm.ts @@ -0,0 +1,732 @@ +import { randomUUID } from "node:crypto" +import { spawn, spawnSync, type ChildProcess } from "node:child_process" +import { existsSync } from "node:fs" +import { access, mkdir, readdir, readFile, realpath, rename, rm, stat, writeFile } from "node:fs/promises" +import os from "node:os" +import path from "node:path" +import { fileURLToPath } from "node:url" +import { resolveDualReadDbPathFromLayout } from "../src/storage/resolve-default-sqlite-path" +import { readGlobalLayoutInstallSelection, resolveActiveAppSegmentFromDirs } from "@mendcode/core/global-layout" + +const PACKAGE_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..") +const SOURCE_ENTRYPOINT = path.join(PACKAGE_ROOT, "src", "index.ts") +const STATE_VERSION = 1 +const CLIENT_LEASE_STALE_AFTER_MS = 30_000 +const PROBE_TIMEOUT_MS = 2_000 +const START_TIMEOUT_MS = 20_000 +const STOP_TIMEOUT_MS = 5_000 +const POLL_MS = 250 + +type SharedServerState = { + version: number + pid: number + url: string + username: string + password: string + startedAt: string + runtimeID: string +} + +export type DevRearmPaths = { + home: string + data: string + config: string + state: string + cache: string + segment: "mendcode" | "opencode" + db: string + stateFile: string + lockFile: string + clientsDir: string +} + +export type RuntimeProbe = { + ok: boolean + reason?: string + health?: { healthy?: boolean; version?: string; channel?: string } + instance?: { directory?: string; worktree?: string; home?: string } + sessions?: unknown[] + providers?: { all?: unknown[]; default?: Record; connected?: string[] } +} + +export type DevRearmResult = { + url: string + pid: number + project: string + db: string + paths: DevRearmPaths + runtimeID: string + probe: RuntimeProbe +} + +type ProcessInfo = { pid: number; command: string } + +export type DevRearmOptions = { + project: string + minSessions: number + minProviders: number + checkOnly: boolean + launchTui: boolean + env?: NodeJS.ProcessEnv + packageRoot?: string + entrypoint?: string + spawnServer?: (args: string[], env: NodeJS.ProcessEnv, cwd: string) => ChildProcess +} + +function envValue(env: NodeJS.ProcessEnv, name: string) { + const mend = `MENDCODE_${name.slice("OPENCODE_".length)}` + const primary = env[mend] + if (primary) return primary + const fallback = env[name] + return fallback || undefined +} + +function truthy(value: string | undefined) { + if (value === undefined) return false + return !["", "0", "false", "no", "off"].includes(value.trim().toLowerCase()) +} + +function xdgRoot(env: NodeJS.ProcessEnv, key: string, fallback: string) { + return env[key] || fallback +} + +export function resolveDevRearmPaths(env: NodeJS.ProcessEnv = process.env): DevRearmPaths { + const home = env.OPENCODE_TEST_HOME || env.HOME || os.homedir() + const dataBase = xdgRoot(env, "XDG_DATA_HOME", path.join(home, ".local", "share")) + const stateBase = xdgRoot(env, "XDG_STATE_HOME", path.join(home, ".local", "state")) + const configBase = xdgRoot(env, "XDG_CONFIG_HOME", path.join(home, ".config")) + const cacheBase = xdgRoot(env, "XDG_CACHE_HOME", path.join(home, ".cache")) + const segment = resolveActiveAppSegmentFromDirs({ + environmentSelection: env.MENDCODE_GLOBAL_LAYOUT, + installSelection: readGlobalLayoutInstallSelection(home), + legacyEnvironmentSelection: env.OPENCODE_GLOBAL_LAYOUT, + legacyDataDir: path.join(dataBase, "opencode"), + mendDataDir: path.join(dataBase, "mendcode"), + }) + const data = path.join(dataBase, segment) + const state = path.join(stateBase, segment) + const config = envValue(env, "OPENCODE_CONFIG_DIR") || path.join(configBase, segment) + const cache = path.join(cacheBase, segment) + const dbOverride = envValue(env, "OPENCODE_DB") + const db = dbOverride + ? dbOverride === ":memory:" + ? dbOverride + : path.isAbsolute(dbOverride) + ? dbOverride + : path.join(data, dbOverride) + : resolveDualReadDbPathFromLayout( + data, + env.MENDCODE_CHANNEL || "local", + truthy(envValue(env, "OPENCODE_DISABLE_CHANNEL_DB")), + ) + const shared = path.join(state, "shared-server") + return { + home, + data, + config, + state, + cache, + segment, + db, + stateFile: path.join(shared, "server.json"), + lockFile: path.join(shared, "server.lock"), + clientsDir: path.join(shared, "clients"), + } +} + +async function exists(target: string) { + return access(target).then( + () => true, + () => false, + ) +} + +async function sleep(ms: number) { + await new Promise((resolve) => setTimeout(resolve, ms)) +} + +function processAlive(pid: number) { + try { + process.kill(pid, 0) + return true + } catch (error) { + return error instanceof Error && "code" in error && (error as NodeJS.ErrnoException).code === "EPERM" + } +} + +function parseProcessList(output: string) { + const result: ProcessInfo[] = [] + for (const line of output.split("\n")) { + const match = /^\s*(\d+)\s+(.*)$/.exec(line) + if (!match) continue + result.push({ pid: Number(match[1]), command: match[2] }) + } + return result +} + +export function listMendCodeServeProcesses(packageRoot = PACKAGE_ROOT): ProcessInfo[] { + const result = spawnSync("ps", ["-axo", "pid=,command="], { encoding: "utf8" }) + if (result.error || result.status !== 0) return [] + return parseProcessList(String(result.stdout)).filter( + (item) => + item.command.includes("serve") && + (item.command.includes(packageRoot) || /(?:^|[\\/])(?:mendcode|opencode)(?:\s|$)/i.test(item.command)), + ) +} + +function safeServerProcess(pid: number, packageRoot = PACKAGE_ROOT) { + return listMendCodeServeProcesses(packageRoot).find((item) => item.pid === pid) +} + +async function readState(stateFile: string): Promise { + try { + const value = JSON.parse(await readFile(stateFile, "utf8")) as Partial + if ( + value.version !== STATE_VERSION || + !Number.isInteger(value.pid) || + !value.url || + !value.username || + !value.password || + !value.startedAt || + !value.runtimeID + ) + return + const url = new URL(value.url) + if (url.protocol !== "http:" || url.hostname !== "127.0.0.1" || url.username || url.password) return + return value as SharedServerState + } catch { + return + } +} + +function authHeaders(state: SharedServerState, project: string) { + const authorization = `Basic ${Buffer.from(`${state.username}:${state.password}`).toString("base64")}` + const directory = encodeURIComponent(project) + return { + Authorization: authorization, + "x-mendcode-directory": directory, + "x-opencode-directory": directory, + } +} + +async function requestJson(state: SharedServerState, project: string, requestPath: string) { + const response = await fetch(new URL(requestPath, state.url), { + headers: authHeaders(state, project), + signal: AbortSignal.timeout(PROBE_TIMEOUT_MS), + }) + const text = await response.text() + let value: unknown + try { + value = JSON.parse(text) + } catch { + value = undefined + } + if (!response.ok) throw new Error(`${requestPath} returned HTTP ${response.status}: ${text.slice(0, 240)}`) + return value +} + +function pathMatches(actual: string | undefined, expected: string) { + if (!actual) return false + return path.resolve(actual) === path.resolve(expected) +} + +export async function probeRuntime( + state: SharedServerState, + project: string, + expectedVersion: string, + minSessions = 1, + minProviders = 1, +): Promise { + try { + const health = (await requestJson(state, project, "/global/health")) as RuntimeProbe["health"] + if (!health?.healthy) return { ok: false, reason: "health response is not healthy", health } + if (health.version !== expectedVersion) + return { + ok: false, + reason: `runtime version ${health.version ?? "unknown"} != source ${expectedVersion}`, + health, + } + if (health.channel !== "local") + return { ok: false, reason: `runtime channel ${health.channel ?? "unknown"} is not source-local`, health } + + const instance = (await requestJson(state, project, "/path")) as RuntimeProbe["instance"] + if (!pathMatches(instance?.directory, project)) { + return { + ok: false, + reason: `InstanceContext directory ${instance?.directory ?? "missing"} != ${project}`, + health, + instance, + } + } + + const sessionPayload = (await requestJson(state, project, "/session?scope=project&limit=100")) as unknown + const sessions = Array.isArray(sessionPayload) ? sessionPayload : undefined + if (!sessions || sessions.length < minSessions) { + return { + ok: false, + reason: `session endpoint returned ${sessions?.length ?? "invalid"} rows; expected at least ${minSessions}`, + health, + instance, + sessions: sessions ?? [], + } + } + + const providers = (await requestJson(state, project, "/provider")) as RuntimeProbe["providers"] + const all = Array.isArray(providers?.all) ? providers.all : undefined + if (!all || all.length < minProviders) { + return { + ok: false, + reason: `provider endpoint returned ${all?.length ?? "invalid"} providers; expected at least ${minProviders}`, + health, + instance, + sessions, + providers: providers ?? {}, + } + } + const defaults = providers?.default && typeof providers.default === "object" ? providers.default : undefined + if (!defaults || Object.keys(defaults).length < 1) { + return { + ok: false, + reason: "provider endpoint returned no default model; refusing a TUI with no provider selected", + health, + instance, + sessions, + providers: providers ?? {}, + } + } + + return { ok: true, health, instance, sessions, providers } + } catch (error) { + return { ok: false, reason: error instanceof Error ? error.message : String(error) } + } +} + +async function waitForRuntime( + stateFile: string, + project: string, + expectedVersion: string, + expectedPid: number | undefined, + minSessions: number, + minProviders: number, + timeoutMs = START_TIMEOUT_MS, +) { + const started = Date.now() + let last: RuntimeProbe = { ok: false, reason: "shared server state not written" } + while (Date.now() - started < timeoutMs) { + const state = await readState(stateFile) + if (state && (expectedPid === undefined || state.pid === expectedPid)) { + last = await probeRuntime(state, project, expectedVersion, minSessions, minProviders) + if (last.ok) return { state, probe: last } + } + await sleep(POLL_MS) + } + throw new Error(`runtime did not pass readiness gates within ${timeoutMs}ms: ${last.reason ?? "unknown error"}`) +} + +async function activeClientLeases(clientsDir: string) { + const roots = await readdir(clientsDir, { withFileTypes: true }).catch(() => []) + let active = 0 + const inspect = async (file: string) => { + if (!file.endsWith(".lease")) return + try { + const metadata = await stat(file) + const value = JSON.parse(await readFile(file, "utf8")) as { clientPID?: unknown } + const clientPID = typeof value.clientPID === "number" ? value.clientPID : undefined + const stale = Date.now() - metadata.mtimeMs > CLIENT_LEASE_STALE_AFTER_MS + if (!stale || (clientPID !== undefined && processAlive(clientPID))) active++ + } catch { + // A lease disappearing during inspection is not an active lease. + } + } + await Promise.all( + roots.map(async (entry) => { + const target = path.join(clientsDir, entry.name) + if (entry.isDirectory()) { + const nested = await readdir(target, { withFileTypes: true }).catch(() => []) + await Promise.all(nested.filter((item) => item.isFile()).map((item) => inspect(path.join(target, item.name)))) + return + } + if (entry.isFile()) await inspect(target) + }), + ) + return active +} + +async function acquireLock(lockFile: string) { + await mkdir(path.dirname(lockFile), { recursive: true }) + try { + await mkdir(lockFile) + } catch { + let age = "unknown" + try { + age = `${Math.round((Date.now() - (await stat(lockFile)).mtimeMs) / 1000)}s` + } catch { + // The lock may have disappeared between mkdir and stat. + } + throw new Error(`another MendCode rearm is already running (lock age ${age}); refusing to start a competitor`) + } + await writeFile(path.join(lockFile, "owner"), `${process.pid}\n`, { encoding: "utf8", mode: 0o600 }) + return async () => { + await rm(lockFile, { recursive: true, force: true }).catch(() => undefined) + } +} + +async function archiveState(stateFile: string) { + if (!(await exists(stateFile))) return + const backup = `${stateFile}.stale-${Date.now()}-${process.pid}.json` + await rename(stateFile, backup) + return backup +} + +async function stopServer(pid: number, packageRoot: string) { + const processInfo = safeServerProcess(pid, packageRoot) + if (!processInfo) throw new Error(`refusing to stop pid ${pid}: command is not a MendCode source serve process`) + try { + process.kill(pid, "SIGTERM") + } catch (error) { + if (!processAlive(pid)) return + throw new Error( + `could not signal stale MendCode server pid ${pid}: ${error instanceof Error ? error.message : String(error)}`, + ) + } + const deadline = Date.now() + STOP_TIMEOUT_MS + while (Date.now() < deadline) { + if (!processAlive(pid)) return + await sleep(100) + } + throw new Error(`stale MendCode server pid ${pid} did not exit after SIGTERM; no force-kill attempted`) +} + +async function sourceRuntimeID(entrypoint: string, packageRoot: string) { + const metadata = await stat(entrypoint).catch(() => undefined) + const sourceFiles: string[] = [] + const visit = async (directory: string): Promise => { + const entries = await readdir(directory, { withFileTypes: true }).catch(() => []) + await Promise.all( + entries.map(async (entry) => { + const file = path.join(directory, entry.name) + if (entry.isDirectory()) return visit(file) + if (!entry.isFile()) return + const item = await stat(file).catch(() => undefined) + if (item) sourceFiles.push(`${path.relative(packageRoot, file)}:${item.size}:${item.mtimeMs}`) + }), + ) + } + await visit(path.join(packageRoot, "src")) + const hash = await crypto.subtle + .digest("SHA-256", new TextEncoder().encode(sourceFiles.sort().join("\n"))) + .then((buffer) => Buffer.from(buffer).toString("hex")) + return [entrypoint, metadata?.size ?? "unknown", metadata?.mtimeMs ?? "unknown", hash].join(":") +} + +async function packageVersion(packageRoot: string) { + const value = JSON.parse(await readFile(path.join(packageRoot, "package.json"), "utf8")) as { version?: unknown } + if (typeof value.version !== "string" || !value.version) throw new Error("source package version is missing") + return value.version +} + +async function spawnSourceServer( + packageRoot: string, + entrypoint: string, + env: NodeJS.ProcessEnv, + spawnServer = (args: string[], childEnv: NodeJS.ProcessEnv, cwd: string) => + spawn(process.execPath, args, { cwd, env: childEnv, detached: true, stdio: "ignore" }), +) { + const child = spawnServer( + [ + "--cwd", + packageRoot, + "--no-install", + "--conditions=browser", + entrypoint, + "serve", + "--hostname", + "127.0.0.1", + "--port", + "0", + ], + env, + packageRoot, + ) + child.unref() + return child +} + +function runtimeEnvironment(input: { + env: NodeJS.ProcessEnv + paths: DevRearmPaths + runtimeID: string + username: string + password: string +}) { + const env = { ...input.env } + for (const key of [ + "MENDCODE_SERVER_URL", + "OPENCODE_SERVER_URL", + "MENDCODE_DISABLE_SHARED_SERVER", + "OPENCODE_DISABLE_SHARED_SERVER", + ]) { + delete env[key] + } + const dataBase = path.dirname(input.paths.data) + const stateBase = path.dirname(input.paths.state) + const configBase = path.dirname(input.paths.config) + const cacheBase = path.dirname(input.paths.cache) + Object.assign(env, { + HOME: input.paths.home, + XDG_DATA_HOME: dataBase, + XDG_STATE_HOME: stateBase, + XDG_CONFIG_HOME: configBase, + XDG_CACHE_HOME: cacheBase, + MENDCODE_GLOBAL_LAYOUT: input.paths.segment, + OPENCODE_GLOBAL_LAYOUT: input.paths.segment, + MENDCODE_DB: input.paths.db, + OPENCODE_DB: input.paths.db, + MENDCODE_CONFIG_DIR: input.paths.config, + OPENCODE_CONFIG_DIR: input.paths.config, + MENDCODE_SHARED_SERVER_STATE_FILE: input.paths.stateFile, + MENDCODE_SHARED_SERVER_RUNTIME_ID: input.runtimeID, + MENDCODE_SERVER_USERNAME: input.username, + OPENCODE_SERVER_USERNAME: input.username, + MENDCODE_SERVER_PASSWORD: input.password, + OPENCODE_SERVER_PASSWORD: input.password, + MENDCODE_USE_SOURCE_RUNTIME: "1", + MENDCODE_RUNTIME: "1", + OPENCODE: "1", + AGENT: "1", + }) + return env +} + +async function rearm(input: DevRearmOptions): Promise { + const env = input.env ?? process.env + const packageRoot = input.packageRoot ?? PACKAGE_ROOT + const entrypoint = input.entrypoint ?? SOURCE_ENTRYPOINT + const project = await realpath(path.resolve(input.project)) + const paths = resolveDevRearmPaths(env) + if (paths.db === ":memory:") + throw new Error("refusing an in-memory DB; dev rearm requires the authoritative persisted DB") + if (!(await exists(paths.db))) + throw new Error(`authoritative DB does not exist: ${paths.db}; refusing to create an empty UI`) + const version = await packageVersion(packageRoot) + const runtimeID = await sourceRuntimeID(entrypoint, packageRoot) + const processes = listMendCodeServeProcesses(packageRoot) + const release = await acquireLock(paths.lockFile) + let staleBackup: string | undefined + try { + const state = await readState(paths.stateFile) + if (!state && processes.length > 0) { + throw new Error( + `MendCode serve process exists without a valid shared-server state (${processes.map((item) => item.pid).join(", ")}); refusing to create a competitor`, + ) + } + + if (state) { + const probe = await probeRuntime(state, project, version, input.minSessions, input.minProviders) + const currentRuntime = state.runtimeID === runtimeID + if (probe.ok && currentRuntime) { + const running = listMendCodeServeProcesses(packageRoot) + if (running.length !== 1 || running[0]?.pid !== state.pid) { + throw new Error( + `shared server passed readiness but uniqueness failed; observed pids ${running.map((item) => item.pid).join(", ") || "none"}`, + ) + } + return { url: state.url, pid: state.pid, project, db: paths.db, paths, runtimeID, probe } + } + + const active = await activeClientLeases(paths.clientsDir) + if (active > 0) { + throw new Error( + `shared server pid ${state.pid} is not ready (${probe.reason ?? "runtime mismatch"}) but ${active} client lease(s) are active; refusing to interrupt them`, + ) + } + if (input.checkOnly) { + throw new Error( + `shared server pid ${state.pid} at ${state.url} is not ready: ${probe.reason ?? "runtime mismatch"}; db=${paths.db}; state=${paths.stateFile}`, + ) + } + staleBackup = await archiveState(paths.stateFile) + if (processAlive(state.pid)) await stopServer(state.pid, packageRoot) + } + + const remaining = listMendCodeServeProcesses(packageRoot) + if (remaining.length > 0) { + throw new Error( + `MendCode serve process(es) remain after stale cleanup (${remaining.map((item) => item.pid).join(", ")}); refusing to start a second server`, + ) + } + if (input.checkOnly) { + throw new Error( + `shared server is not ready: ${staleBackup ? `stale state archived at ${staleBackup}` : "no ready state"}`, + ) + } + + const username = "mendcode" + const password = `${randomUUID()}${randomUUID()}` + const childEnv = runtimeEnvironment({ env, paths, runtimeID, username, password }) + const child = await spawnSourceServer(packageRoot, entrypoint, childEnv, input.spawnServer) + try { + const started = await waitForRuntime( + paths.stateFile, + project, + version, + child.pid, + input.minSessions, + input.minProviders, + ) + const running = listMendCodeServeProcesses(packageRoot) + if (running.length !== 1 || running[0]?.pid !== started.state.pid) { + throw new Error( + `readiness passed but server uniqueness failed; observed pids ${running.map((item) => item.pid).join(", ") || "none"}`, + ) + } + return { + url: started.state.url, + pid: started.state.pid, + project, + db: paths.db, + paths, + runtimeID, + probe: started.probe, + } + } catch (error) { + let cleanupError: string | undefined + if (child.pid && processAlive(child.pid)) { + try { + await stopServer(child.pid, packageRoot) + } catch (stopError) { + cleanupError = stopError instanceof Error ? stopError.message : String(stopError) + } + } + const failedState = await archiveState(paths.stateFile) + const suffix = failedState ? `; failed state archived at ${failedState}` : "" + const cleanupSuffix = cleanupError ? `; cleanup failed: ${cleanupError}` : "" + throw new Error(`${error instanceof Error ? error.message : String(error)}${suffix}${cleanupSuffix}`) + } + } catch (error) { + if (staleBackup && !(await exists(paths.stateFile))) { + // Keep the backup as the recovery artifact. Do not restore it over a new state file. + const message = error instanceof Error ? error.message : String(error) + throw new Error(`${message}; previous state archived at ${staleBackup}`) + } + throw error + } finally { + await release() + } +} + +function printHelp() { + console.log(`Usage: bun run script/dev-rearm.ts [options] + +Rearm the source MendCode shared server without creating a competing process. + +Options: + --project Project directory to validate (default: cwd) + --min-sessions Minimum /session rows required (default: 1) + --min-providers Minimum /provider all rows required (default: 1) + --check-only Diagnose readiness without stopping or starting a server + --tui Open the TUI only after every readiness gate passes + --help Show this help + +The command never edits SQLite. A stale shared-server JSON is renamed to a +timestamped .stale-*.json recovery artifact before the exact stale PID is stopped.`) +} + +function parseArgs(argv: string[]) { + const options = { + project: process.cwd(), + minSessions: 1, + minProviders: 1, + checkOnly: false, + launchTui: false, + } + for (let index = 0; index < argv.length; index++) { + const arg = argv[index] + if (arg === "--help" || arg === "-h") { + printHelp() + return + } + if (arg === "--check-only") { + options.checkOnly = true + continue + } + if (arg === "--tui") { + options.launchTui = true + continue + } + if (arg === "--project" || arg === "-p") { + const value = argv[++index] + if (!value) throw new Error(`${arg} requires a path`) + options.project = value + continue + } + if (arg === "--min-sessions" || arg === "--min-providers") { + const value = Number(argv[++index]) + if (!Number.isInteger(value) || value < 1) throw new Error(`${arg} must be an integer >= 1`) + if (arg === "--min-sessions") options.minSessions = value + else options.minProviders = value + continue + } + throw new Error(`unknown option ${arg}`) + } + return options +} + +async function launchTui(result: DevRearmResult) { + const env = { ...process.env } + delete env.MENDCODE_SERVER_URL + delete env.OPENCODE_SERVER_URL + Object.assign(env, { + HOME: result.paths.home, + XDG_DATA_HOME: path.dirname(result.paths.data), + XDG_STATE_HOME: path.dirname(result.paths.state), + XDG_CONFIG_HOME: path.dirname(result.paths.config), + XDG_CACHE_HOME: path.dirname(result.paths.cache), + MENDCODE_GLOBAL_LAYOUT: result.paths.segment, + OPENCODE_GLOBAL_LAYOUT: result.paths.segment, + MENDCODE_DB: result.paths.db, + OPENCODE_DB: result.paths.db, + MENDCODE_CONFIG_DIR: result.paths.config, + OPENCODE_CONFIG_DIR: result.paths.config, + MENDCODE_SHARED_SERVER_STATE_FILE: result.paths.stateFile, + MENDCODE_SHARED_SERVER_RUNTIME_ID: result.runtimeID, + }) + const child = spawn( + process.execPath, + ["--cwd", PACKAGE_ROOT, "--no-install", "--conditions=browser", SOURCE_ENTRYPOINT, result.project], + { cwd: result.project, env, stdio: "inherit" }, + ) + const code = await new Promise((resolve) => + child.once("exit", (value, signal) => resolve(value ?? (signal ? 1 : 0))), + ) + if (code !== 0) throw new Error(`TUI exited with code ${code}`) +} + +export async function runDevRearm(options: DevRearmOptions) { + return rearm(options) +} + +async function main() { + try { + const options = parseArgs(process.argv.slice(2)) + if (!options) return 0 + const result = await rearm(options) + console.log(`MendCode source runtime ready: ${result.url}`) + console.log(`pid=${result.pid} version=${result.probe.health?.version} channel=${result.probe.health?.channel}`) + console.log(`project=${result.project}`) + console.log(`db=${result.db}`) + console.log(`sessions=${result.probe.sessions?.length ?? 0} providers=${result.probe.providers?.all?.length ?? 0}`) + if (options.launchTui) await launchTui(result) + return 0 + } catch (error) { + console.error(`MendCode dev rearm failed: ${error instanceof Error ? error.message : String(error)}`) + console.error("No TUI was opened; inspect the stale-state backup and dev.log before retrying.") + return 1 + } +} + +if (import.meta.main) { + main().then((code) => { + process.exitCode = code + }) +} diff --git a/src/mendcode/packages/opencode/script/incident-local-smoke.ts b/src/mendcode/packages/opencode/script/incident-local-smoke.ts new file mode 100644 index 00000000..c6bf36cf --- /dev/null +++ b/src/mendcode/packages/opencode/script/incident-local-smoke.ts @@ -0,0 +1,320 @@ +import { spawn } from "node:child_process" +import { fileURLToPath } from "node:url" +import path from "node:path" + +const PACKAGE_ROOT = path.dirname(path.dirname(fileURLToPath(import.meta.url))) +const STEP_TIMEOUT_MS = 120_000 +const OUTPUT_LIMIT = 12_000 + +const groups = [ + { + name: "TUI render and terminal state", + tests: [ + "test/cli/tui/markdown-render.test.ts", + "test/cli/tui/agent-view.test.ts", + "test/cli/tui/route.test.ts", + "test/cli/tui/session-initialization.test.ts", + "test/cli/tui/session-layout.test.ts", + "test/cli/tui/session-working.test.ts", + "test/cli/tui/session-exit-summary.test.ts", + "test/cli/tui/workflow-view.test.ts", + "test/mend/tui-presentation-renderers.test.ts", + "test/pty/pty-output-isolation.test.ts", + "test/pty/pty-session.test.ts", + ], + }, + { + name: "shared server and reconnect contracts", + tests: [ + // The full sync component suite requires the production provider tree; + // these standalone contracts exercise the same reconnect/outbox paths. + "test/cli/tui/shared-server.test.ts", + "test/cli/tui/session-control.test.ts", + "test/cli/tui/permission-sync.test.ts", + "test/cli/cmd/serve.test.ts", + ], + }, + { + name: "server listener and instance isolation", + tests: [ + "test/control-plane/adapters.test.ts", + // httpapi-instance-context.test.ts currently has a pre-existing + // InstanceLayer bootstrap cycle when run as an isolated Bun file. + "test/server/httpapi-listen.test.ts", + "test/server/httpapi-workspace-routing.test.ts", + ], + }, + { + name: "persisted database and session state", + tests: [ + "test/storage/resolve-default-sqlite-path.test.ts", + "test/session/session.test.ts", + "test/session/workflow-persistence.test.ts", + ], + }, + { + name: "dev and installed entrypoints", + tests: ["test/cli/public-bin-worktree.test.ts", "test/installation/installation.test.ts"], + }, + { + name: "workflow and subagent state", + tests: [ + "test/session/agent-command.test.ts", + "test/session/workflow-scheduler.test.ts", + "test/session/workflow-task-executor.test.ts", + "test/session/loop.test.ts", + "test/tool/loop.test.ts", + "test/mend/loop-service.test.ts", + "test/server/workflow-routes.test.ts", + "test/tool/task.test.ts", + ], + }, + { + name: "session API parity", + tests: ["test/server/httpapi-session.test.ts", "test/server/httpapi-json-parity.test.ts"], + }, +] as const + +const providerKeys = [ + "ANTHROPIC_API_KEY", + "OPENAI_API_KEY", + "GOOGLE_API_KEY", + "GOOGLE_GENERATIVE_AI_API_KEY", + "AZURE_OPENAI_API_KEY", + "AWS_ACCESS_KEY_ID", + "AWS_SECRET_ACCESS_KEY", + "AWS_SESSION_TOKEN", + "AWS_PROFILE", + "AWS_REGION", + "AWS_BEARER_TOKEN_BEDROCK", + "OPENROUTER_API_KEY", + "LLM_GATEWAY_API_KEY", + "GROQ_API_KEY", + "MISTRAL_API_KEY", + "PERPLEXITY_API_KEY", + "TOGETHER_API_KEY", + "XAI_API_KEY", + "DEEPSEEK_API_KEY", + "FIREWORKS_API_KEY", + "CEREBRAS_API_KEY", + "SAMBANOVA_API_KEY", +] + +function noAIEnvironment() { + const env = { ...process.env } + for (const key of providerKeys) delete env[key] + for (const key of [ + "MENDCODE_DB", + "OPENCODE_DB", + "MENDCODE_CONFIG_DIR", + "OPENCODE_CONFIG_DIR", + "MENDCODE_CONFIG_CONTENT", + "OPENCODE_CONFIG_CONTENT", + "MENDCODE_MODELS_PATH", + "OPENCODE_MODELS_PATH", + "MENDCODE_SERVER_URL", + "OPENCODE_SERVER_URL", + "MENDCODE_SHARED_SERVER_STATE_FILE", + "MENDCODE_SHARED_SERVER_RUNTIME_ID", + ]) { + delete env[key] + } + + Object.assign(env, { + MENDCODE_NO_AI: "1", + OPENCODE_NO_AI: "1", + MENDCODE_PURE: "1", + OPENCODE_PURE: "1", + MENDCODE_DISABLE_DEFAULT_PLUGINS: "1", + OPENCODE_DISABLE_DEFAULT_PLUGINS: "1", + MENDCODE_DISABLE_MODELS_FETCH: "1", + OPENCODE_DISABLE_MODELS_FETCH: "1", + MENDCODE_EXPERIMENTAL_DISABLE_FILEWATCHER: "1", + OPENCODE_EXPERIMENTAL_DISABLE_FILEWATCHER: "1", + NO_COLOR: "1", + OTEL_SDK_DISABLED: "true", + }) + return env +} + +function appendOutput(current: string, chunk: unknown) { + const next = current + String(chunk) + return next.length > OUTPUT_LIMIT ? next.slice(-OUTPUT_LIMIT) : next +} + +type CommandResult = { + code: number + output: string + timedOut: boolean +} + +function runCommand(args: readonly string[], env: NodeJS.ProcessEnv): Promise { + return new Promise((resolve) => { + const child = spawn(process.execPath, [...args], { + cwd: PACKAGE_ROOT, + env, + stdio: ["ignore", "pipe", "pipe"], + detached: process.platform !== "win32", + }) + let output = "" + let timedOut = false + let killTimer: ReturnType | undefined + let finished = false + const terminate = (signal: NodeJS.Signals) => { + if (process.platform !== "win32" && child.pid) { + try { + process.kill(-child.pid, signal) + return + } catch { + // Fall through when the child has already exited. + } + } + child.kill(signal) + } + const timer = setTimeout(() => { + timedOut = true + terminate("SIGTERM") + killTimer = setTimeout(() => terminate("SIGKILL"), 5_000) + killTimer.unref?.() + }, STEP_TIMEOUT_MS) + timer.unref?.() + + const append = (chunk: unknown) => { + output = appendOutput(output, chunk) + } + child.stdout?.on("data", append) + child.stderr?.on("data", append) + + const finish = (code: number) => { + if (finished) return + finished = true + clearTimeout(timer) + if (killTimer) clearTimeout(killTimer) + resolve({ code, output, timedOut }) + } + child.once("error", (error) => { + append(error) + finish(1) + }) + child.once("exit", (code, signal) => finish(code ?? (signal ? 1 : 0))) + }) +} + +async function runStep(label: string, args: readonly string[], env: NodeJS.ProcessEnv) { + console.log(`RUN ${label}`) + const result = await runCommand(args, env) + if (result.code === 0) { + console.log(`PASS ${label}`) + return true + } + + const reason = result.timedOut ? `timed out after ${STEP_TIMEOUT_MS}ms` : `exit ${result.code}` + console.error(`FAIL ${label}: ${reason}`) + if (result.output) console.error(result.output) + return false +} + +function printManual() { + const source = path.join(PACKAGE_ROOT, "src", "index.ts") + const models = path.join(PACKAGE_ROOT, "test", "tool", "fixtures", "models-api.json") + console.log(`Manual two-terminal reconnect lab (no prompt/model request): + +Terminal A — create one isolated server and the first TUI client: + +LAB=$(mktemp -d "\${TMPDIR:-/tmp}/mendcode-reconnect.XXXXXX") +mkdir -p "$LAB"/{home,project,db,xdg-config,xdg-data,xdg-state,xdg-cache} +PORT=$(bun -e 'const s=Bun.serve({port:0,fetch(){return new Response()}}); console.log(s.port); s.stop()') +echo "$PORT" > "$LAB/port" +echo "LAB=$LAB" +export MENDCODE_LAB="$LAB" MENDCODE_PACKAGE_ROOT="${PACKAGE_ROOT}" MENDCODE_PORT="$PORT" +export HOME="$LAB/home" XDG_CONFIG_HOME="$LAB/xdg-config" XDG_DATA_HOME="$LAB/xdg-data" XDG_STATE_HOME="$LAB/xdg-state" XDG_CACHE_HOME="$LAB/xdg-cache" +export MENDCODE_GLOBAL_LAYOUT=mendcode OPENCODE_GLOBAL_LAYOUT=mendcode +export MENDCODE_DB="$LAB/db/mendcode-local.db" OPENCODE_DB="$LAB/db/mendcode-local.db" +export MENDCODE_MODELS_PATH="${models}" OPENCODE_MODELS_PATH="${models}" +export MENDCODE_CONFIG_CONTENT='{"formatter":false,"lsp":false,"enabled_providers":[]}' OPENCODE_CONFIG_CONTENT="$MENDCODE_CONFIG_CONTENT" +export MENDCODE_DISABLE_DEFAULT_PLUGINS=1 OPENCODE_DISABLE_DEFAULT_PLUGINS=1 MENDCODE_DISABLE_MODELS_FETCH=1 OPENCODE_DISABLE_MODELS_FETCH=1 MENDCODE_PURE=1 OPENCODE_PURE=1 NO_COLOR=1 +unset MENDCODE_SERVER_URL OPENCODE_SERVER_URL MENDCODE_SHARED_SERVER_STATE_FILE MENDCODE_SHARED_SERVER_RUNTIME_ID +unset ANTHROPIC_API_KEY OPENAI_API_KEY GOOGLE_API_KEY GOOGLE_GENERATIVE_AI_API_KEY +(bun --cwd "$MENDCODE_PACKAGE_ROOT" --no-install --conditions=browser "$MENDCODE_PACKAGE_ROOT/src/index.ts" serve --hostname 127.0.0.1 --port "$PORT" >"$LAB/server.log" 2>&1 & echo $! >"$LAB/server.pid") +sleep 1 +bun --cwd "$MENDCODE_PACKAGE_ROOT" --no-install --conditions=browser "${source}" "$LAB/project" --server-url "http://127.0.0.1:$PORT" + +Terminal B — use the same explicit server, never auto-start a competing shared server: + +LAB=/path/printed/by/Terminal-A +MENDCODE_PACKAGE_ROOT="${PACKAGE_ROOT}" +PORT=$(<"$LAB/port") +export HOME="$LAB/home" XDG_CONFIG_HOME="$LAB/xdg-config" XDG_DATA_HOME="$LAB/xdg-data" XDG_STATE_HOME="$LAB/xdg-state" XDG_CACHE_HOME="$LAB/xdg-cache" +export MENDCODE_GLOBAL_LAYOUT=mendcode OPENCODE_GLOBAL_LAYOUT=mendcode +export MENDCODE_DB="$LAB/db/mendcode-local.db" OPENCODE_DB="$LAB/db/mendcode-local.db" +export MENDCODE_MODELS_PATH="${models}" OPENCODE_MODELS_PATH="${models}" +export MENDCODE_CONFIG_CONTENT='{"formatter":false,"lsp":false,"enabled_providers":[]}' OPENCODE_CONFIG_CONTENT="$MENDCODE_CONFIG_CONTENT" +export MENDCODE_DISABLE_DEFAULT_PLUGINS=1 OPENCODE_DISABLE_DEFAULT_PLUGINS=1 MENDCODE_DISABLE_MODELS_FETCH=1 OPENCODE_DISABLE_MODELS_FETCH=1 MENDCODE_PURE=1 OPENCODE_PURE=1 NO_COLOR=1 +unset MENDCODE_SERVER_URL OPENCODE_SERVER_URL MENDCODE_SHARED_SERVER_STATE_FILE MENDCODE_SHARED_SERVER_RUNTIME_ID +unset ANTHROPIC_API_KEY OPENAI_API_KEY GOOGLE_API_KEY GOOGLE_GENERATIVE_AI_API_KEY +bun --cwd "$MENDCODE_PACKAGE_ROOT" --no-install --conditions=browser "${source}" "$LAB/project" --server-url "http://127.0.0.1:$PORT" + +With both clients open, capture durable state, then kill only the lab server and observe both clients enter reconnecting, not Generating: + +BASE="http://127.0.0.1:$PORT" +curl -fsS -H "x-mendcode-directory:$LAB/project" "$BASE/workflow" >"$LAB/workflows.before.json" +cd "$LAB/project" +bun --cwd "$MENDCODE_PACKAGE_ROOT" --no-install --conditions=browser "${source}" loops status --json >"$LAB/loops.before.json" + +kill "$(<"$LAB/server.pid")" + +Restart the exact server command from Terminal A, then verify both clients recover the same session list and parent/subagent navigation. Do not submit a prompt; this lab has no provider credentials and no AI request path. + +Durable workflow/loop check from a spare shell (before and after the restart): + +BASE="http://127.0.0.1:$PORT" +curl -fsS -H "x-mendcode-directory:$LAB/project" "$BASE/workflow" >"$LAB/workflows.after.json" +cd "$LAB/project" +bun --cwd "$MENDCODE_PACKAGE_ROOT" --no-install --conditions=browser "${source}" loops status --json >"$LAB/loops.after.json" + +The JSON must still contain the same queued/working workflow runs and active/sleeping loops, with an overdue loop reported as due/catch_up on the first daemon tick. Compare the files captured before the kill with the files captured after the restart; a transient network outage must not turn them into an empty list or create a second server. +`) +} + +async function main() { + const args = new Set(process.argv.slice(2)) + if (args.has("--help") || args.has("-h")) { + console.log( + "Usage: bun run script/incident-local-smoke.ts [--contracts-only|--runtime-only|--require-installed|--manual]", + ) + return + } + if (args.has("--manual")) { + printManual() + return + } + + const env = noAIEnvironment() + const failures: string[] = [] + if (!args.has("--runtime-only")) { + for (const group of groups) { + const ok = await runStep(group.name, ["test", "--timeout", "30000", ...group.tests], env) + if (!ok) failures.push(group.name) + } + } + + if (!args.has("--contracts-only")) { + const runtimeArgs = ["run", "script/session-runtime-smoke.ts"] + if (args.has("--require-installed")) runtimeArgs.push("--require-installed") + const ok = await runStep("isolated subprocess runtime smoke", runtimeArgs, env) + if (!ok) failures.push("isolated subprocess runtime smoke") + } + + if (failures.length > 0) { + console.error(`\nIncident-local smoke failed: ${failures.join(", ")}`) + process.exitCode = 1 + return + } + + console.log("\nPASS incident-local smoke: no provider credentials or model requests were enabled") + console.log( + "Manual-only: human terminal perception during a real server-process restart; automated PTY transport loss/recovery is covered by test:session-runtime:smoke; use --manual", + ) +} + +await main() diff --git a/src/mendcode/packages/opencode/script/postinstall.mjs b/src/mendcode/packages/opencode/script/postinstall.mjs index e1789aa0..0067805b 100644 --- a/src/mendcode/packages/opencode/script/postinstall.mjs +++ b/src/mendcode/packages/opencode/script/postinstall.mjs @@ -49,8 +49,8 @@ function detectPlatformAndArch() { function findBinary() { const { platform, arch } = detectPlatformAndArch() - const packageName = `opencode-${platform}-${arch}` - const binaryName = platform === "windows" ? "opencode.exe" : "opencode" + const packageName = `mendcode-${platform}-${arch}` + const binaryName = platform === "windows" ? "mendcode.exe" : "mendcode" try { // Use require.resolve to find the package @@ -89,7 +89,7 @@ async function main() { } fs.chmodSync(target, 0o755) } catch (error) { - console.error("Failed to setup opencode binary:", error.message) + console.error("Failed to setup MendCode binary:", error.message) process.exit(1) } } diff --git a/src/mendcode/packages/opencode/script/publish.ts b/src/mendcode/packages/opencode/script/publish.ts index 533d7a87..64c5f856 100755 --- a/src/mendcode/packages/opencode/script/publish.ts +++ b/src/mendcode/packages/opencode/script/publish.ts @@ -41,7 +41,7 @@ if (publishRegistries) { await Bun.file(`./dist/${pkg.name}/package.json`).write( JSON.stringify( { - name: pkg.name + "-ai", + name: pkg.name, bin: { [pkg.name]: "./bin/opencode", }, @@ -61,7 +61,7 @@ if (publishRegistries) { await publish(`./dist/${name}`, name, binaries[name]) }) await Promise.all(tasks) - await publish(`./dist/${pkg.name}`, `${pkg.name}-ai`, version) + await publish(`./dist/${pkg.name}`, pkg.name, version) } else { console.log("Skipping npm binary package publishing; set MENDCODE_PUBLISH_REGISTRIES=true to enable it.") } diff --git a/src/mendcode/packages/opencode/script/queue-compaction-smoke.ts b/src/mendcode/packages/opencode/script/queue-compaction-smoke.ts new file mode 100644 index 00000000..21874a7f --- /dev/null +++ b/src/mendcode/packages/opencode/script/queue-compaction-smoke.ts @@ -0,0 +1,407 @@ +import { spawn, type ChildProcess } from "node:child_process" +import { randomUUID } from "node:crypto" +import { readFileSync, rmSync } from "node:fs" +import { mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises" +import os from "node:os" +import path from "node:path" +import { setTimeout as sleep } from "node:timers/promises" +import { Effect } from "effect" +import { TestLLMServer } from "../test/lib/llm-server" + +const MODEL = "queue-smoke/test-model" +const CONTEXT_LIMIT = 50_000 +const COMPACTION_LIMIT = 40_000 +const PAYLOAD_CHARS = 90_000 +const HOLD_MS = Number(process.env.MENDCODE_QUEUE_SMOKE_HOLD_MS ?? 20_000) +const packageRoot = path.resolve(import.meta.dir, "..") +const entrypoint = path.join(packageRoot, "src", "index.ts") +const lockIdentity = + os.userInfo().uid >= 0 ? os.userInfo().uid : os.userInfo().username.replace(/[^a-zA-Z0-9_-]/g, "_") +const defaultLockPath = path.join(os.tmpdir(), `mendcode-queue-compaction-smoke-${lockIdentity}.lock`) + +const sensitiveEnvironmentKeys = [ + "ANTHROPIC_API_KEY", + "OPENAI_API_KEY", + "GOOGLE_API_KEY", + "GOOGLE_GENERATIVE_AI_API_KEY", + "AZURE_OPENAI_API_KEY", + "AWS_ACCESS_KEY_ID", + "AWS_PROFILE", + "AWS_REGION", + "AWS_BEARER_TOKEN_BEDROCK", + "OPENROUTER_API_KEY", + "LLM_GATEWAY_API_KEY", + "GROQ_API_KEY", + "MISTRAL_API_KEY", + "PERPLEXITY_API_KEY", + "TOGETHER_API_KEY", + "XAI_API_KEY", + "DEEPSEEK_API_KEY", + "FIREWORKS_API_KEY", + "CEREBRAS_API_KEY", + "SAMBANOVA_API_KEY", + "MENDCODE_SERVER_PASSWORD", + "MENDCODE_SERVER_USERNAME", + "OPENCODE_SERVER_PASSWORD", + "OPENCODE_SERVER_USERNAME", +] + +type Fixture = { + root: string + project: string + environment: NodeJS.ProcessEnv +} + +type ChildResult = { + code: number | null + signal: NodeJS.Signals | null + stdout: string + stderr: string +} + +type SmokeLockOwner = { + pid: number + token: string + startedAt: string +} + +const activeChildren = new Set() +let activeFixtureRoot: string | undefined +let activeSmokeLock: Awaited> | undefined +let shutdownExitCode: number | undefined + +function errorHasCode(error: unknown, code: string): error is NodeJS.ErrnoException { + return error instanceof Error && "code" in error && error.code === code +} + +function smokeLockOwner(lockPath: string) { + return readFile(lockPath, "utf8") + .then((value) => JSON.parse(value) as unknown) + .then((value): SmokeLockOwner | undefined => { + if (!value || typeof value !== "object") return + if ( + !("pid" in value) || + typeof value.pid !== "number" || + !Number.isSafeInteger(value.pid) || + value.pid <= 0 + ) return + if (!("token" in value) || typeof value.token !== "string") return + if (!("startedAt" in value) || typeof value.startedAt !== "string") return + return { pid: value.pid, token: value.token, startedAt: value.startedAt } + }) + .catch(() => undefined) +} + +function processIsRunning(pid: number) { + try { + process.kill(pid, 0) + return true + } catch (error) { + return errorHasCode(error, "EPERM") + } +} + +export async function acquireQueueCompactionSmokeLock(lockPath = defaultLockPath, attempt = 0) { + const owner = { pid: process.pid, token: randomUUID(), startedAt: new Date().toISOString() } + try { + await writeFile(lockPath, JSON.stringify(owner) + "\n", { flag: "wx" }) + } catch (error) { + if (!errorHasCode(error, "EEXIST")) throw error + const current = await smokeLockOwner(lockPath) + if (current && processIsRunning(current.pid)) { + throw new Error( + `the queue/compaction smoke is already running (PID ${current.pid}); use that terminal or stop it before starting another`, + ) + } + if (!current && attempt < 2) { + await sleep(50) + return acquireQueueCompactionSmokeLock(lockPath, attempt + 1) + } + if (attempt >= 4) throw new Error("could not acquire the queue/compaction smoke single-instance lock") + await rm(lockPath, { force: true }) + return acquireQueueCompactionSmokeLock(lockPath, attempt + 1) + } + + const release = async () => { + if ((await smokeLockOwner(lockPath))?.token !== owner.token) return + await rm(lockPath, { force: true }) + } + const releaseSync = () => { + try { + const current = JSON.parse(readFileSync(lockPath, "utf8")) as Partial + if (current.token === owner.token) rmSync(lockPath, { force: true }) + } catch { + return + } + } + return { release, releaseSync } +} + +function trackChild(child: ChildProcess) { + activeChildren.add(child) + const cleanup = () => activeChildren.delete(child) + child.once("close", cleanup) + child.once("error", cleanup) + return cleanup +} + +function terminateActiveChildren(signal: NodeJS.Signals = "SIGTERM") { + for (const child of activeChildren) { + if (child.exitCode === null && child.signalCode === null) child.kill(signal) + } +} + +function installChildCleanup() { + process.once("exit", () => { + terminateActiveChildren("SIGKILL") + activeSmokeLock?.releaseSync() + if (activeFixtureRoot) rmSync(activeFixtureRoot, { recursive: true, force: true }) + }) + for (const [signal, exitCode] of [ + ["SIGINT", 130], + ["SIGTERM", 143], + ["SIGHUP", 129], + ] as const) { + process.once(signal, () => { + shutdownExitCode = exitCode + terminateActiveChildren() + process.exitCode = exitCode + setTimeout(() => { + terminateActiveChildren("SIGKILL") + process.exit(exitCode) + }, 1_000) + }) + } +} + +function syntheticPrompt(label: string) { + const line = `${label}: synthetic compaction smoke content 0123456789 abcdefghijklmnopqrstuvwxyz\n` + const body = line.repeat(Math.ceil(PAYLOAD_CHARS / line.length)).slice(0, PAYLOAD_CHARS) + return `${label.toUpperCase()}_BEGIN\n${body}${label.toUpperCase()}_END\n` +} + +function environment(root: string): NodeJS.ProcessEnv { + const env: NodeJS.ProcessEnv = { + // Do not inherit config-content, package-root, or provider overrides from + // the developer's active MendCode session into the isolated fixture. + ...Object.fromEntries(["PATH", "TERM", "COLORTERM", "LANG", "LC_ALL", "TMPDIR"].flatMap((key) => process.env[key] === undefined ? [] : [[key, process.env[key]]])), + HOME: path.join(root, "home"), + XDG_DATA_HOME: path.join(root, "data"), + XDG_CACHE_HOME: path.join(root, "cache"), + XDG_CONFIG_HOME: path.join(root, "config"), + XDG_STATE_HOME: path.join(root, "state"), + MENDCODE_MEMORY_DIR: path.join(root, "data", "memory"), + MENDCODE_MEMORY_DISCOVERY_ROOTS: "", + OPENCODE_GLOBAL_LAYOUT: "mendcode", + OPENCODE_DB: path.join(root, "state", "queue-smoke.db"), + OPENCODE_DISABLE_DEFAULT_PLUGINS: "true", + OPENCODE_DISABLE_SHARED_SERVER: "1", + MENDCODE_DISABLE_SHARED_SERVER: "1", + OPENCODE_DISABLE_SHARE: "true", + OPENCODE_MODELS_PATH: path.join(packageRoot, "test", "tool", "fixtures", "models-api.json"), + } + + for (const key of sensitiveEnvironmentKeys) delete env[key] + return env +} + +async function fixture(): Promise { + const root = await mkdtemp(path.join(os.tmpdir(), "mendcode-queue-compaction-")) + const project = path.join(root, "project") + await mkdir(project, { recursive: true }) + await mkdir(path.join(root, "home"), { recursive: true }) + return { root, project, environment: environment(root) } +} + +function config(baseURL: string) { + return { + $schema: "https://mendcode.ai/config.json", + enabled_providers: ["queue-smoke"], + model: MODEL, + small_model: MODEL, + compaction: { + auto: true, + token_limit: COMPACTION_LIMIT, + }, + provider: { + "queue-smoke": { + name: "Queue compaction smoke (local only)", + npm: "@ai-sdk/openai-compatible", + env: [], + options: { + apiKey: "local-only", + baseURL, + }, + models: { + "test-model": { + id: "test-model", + name: "Queue compaction smoke model", + attachment: false, + reasoning: false, + tool_call: false, + limit: { context: CONTEXT_LIMIT, output: 2_000 }, + compaction: { token_limit: COMPACTION_LIMIT }, + }, + }, + }, + }, + agent: { + build: { model: MODEL }, + plan: { model: MODEL }, + title: { model: MODEL }, + summary: { model: MODEL }, + compaction: { model: MODEL }, + general: { model: MODEL }, + }, + share: "disabled", + autoupdate: false, + } +} + +function childArgs(args: string[]) { + return ["--cwd", packageRoot, "--no-install", "--conditions=browser", entrypoint, ...args] +} + +function waitForChild(child: ChildProcess, input?: string): Promise { + return new Promise((resolve, reject) => { + let stdout = "" + let stderr = "" + + if (input !== undefined && child.stdin) child.stdin.end(input) + child.stdout?.on("data", (value: Buffer) => (stdout += value.toString())) + child.stderr?.on("data", (value: Buffer) => (stderr += value.toString())) + child.once("error", reject) + child.once("close", (code, signal) => resolve({ code, signal, stdout, stderr })) + }) +} + +function runCLI(args: string[], env: NodeJS.ProcessEnv, options?: { input?: string; inherit?: boolean }) { + const child = spawn(process.execPath, childArgs(args), { + cwd: packageRoot, + env, + stdio: options?.inherit ? "inherit" : ["pipe", "pipe", "pipe"], + }) + const cleanup = trackChild(child) + return waitForChild(child, options?.input).finally(cleanup) +} + +function sessionID(output: string) { + for (const line of output.split(/\r?\n/).reverse()) { + if (!line.trim()) continue + try { + const value = JSON.parse(line) as { kind?: string; sessionID?: unknown } + if (value.kind === "result" && typeof value.sessionID === "string") return value.sessionID + } catch { + continue + } + } + throw new Error("the seed command did not return a session id") +} + +function requireSuccess(result: ChildResult, label: string) { + if (result.code === 0) return + const detail = [result.stderr, result.stdout].filter(Boolean).join("\n").trim().slice(-2_000) + throw new Error(`${label} exited with ${result.code ?? result.signal}\n${detail}`) +} + +async function main() { + if (!process.stdin.isTTY || !process.stdout.isTTY) { + throw new Error("the queue/compaction smoke requires an interactive terminal") + } + + const lock = await acquireQueueCompactionSmokeLock() + activeSmokeLock = lock + try { + const test = await fixture() + activeFixtureRoot = test.root + process.env = test.environment + + const program = Effect.gen(function* () { + const llm = yield* TestLLMServer + yield* Effect.promise(() => + writeFile(path.join(test.project, "mendcode.json"), JSON.stringify(config(llm.url), null, 2) + "\n"), + ) + + yield* llm.text("local seed response", { usage: { input: 25_000, output: 20 } }) + const seed = yield* Effect.promise(() => + runCLI( + [ + "--pure", + "run", + "--format", + "json", + "--model", + MODEL, + "--title", + "Queue compaction smoke", + "--dir", + test.project, + "--dangerously-skip-permissions", + ], + test.environment, + { input: syntheticPrompt("seed") }, + ), + ) + requireSuccess(seed, "seed session") + const id = sessionID(seed.stdout) + + const previousCalls = yield* llm.calls + const release = Effect.runPromise(llm.wait(previousCalls + 1)).then(() => sleep(HOLD_MS)) + yield* llm.hold("local compaction summary", release) + process.stderr.write( + [ + "", + "MendCode queue/compaction smoke is ready (the provider is local and never calls an API).", + `Model context limit: ${CONTEXT_LIMIT.toLocaleString()} tokens; auto-compaction: ${COMPACTION_LIMIT.toLocaleString()} tokens.`, + "The TUI opens with a synthetic trigger prompt already loaded.", + "Press Enter to submit it, press Esc once to arm interruption, then press Esc again within five seconds to cancel it.", + `The local model holds that request for ${Math.round(HOLD_MS / 1_000)} seconds so the queued state is visible.`, + "Only one smoke can run at a time. Exit with /exit or Ctrl+C; child processes and the lock are cleaned automatically.", + "Expected result: the second Esc issues one cancellation; the compaction summary terminates once, Snake's final board stays visible and stops advancing, the transcript collapses, and queued messages remain paired with their queued/send state.", + "", + ].join("\n"), + ) + + const tui = yield* Effect.promise(() => + runCLI( + [ + "--pure", + "--isolated", + "--model", + MODEL, + "--session", + id, + "--initial-message", + syntheticPrompt("trigger"), + test.project, + ], + test.environment, + { inherit: true }, + ), + ) + requireSuccess(tui, "TUI") + + const inputs = yield* llm.inputs + process.stderr.write(`\nLocal mock requests observed: ${inputs.length}. No external provider was contacted.\n`) + }) + + try { + await Effect.runPromise(program.pipe(Effect.provide(TestLLMServer.layer), Effect.scoped)) + } finally { + await rm(test.root, { recursive: true, force: true }) + activeFixtureRoot = undefined + } + } finally { + await lock.release() + if (activeSmokeLock === lock) activeSmokeLock = undefined + } +} + +if (import.meta.main) { + installChildCleanup() + await main().catch((error) => { + if (shutdownExitCode !== undefined) return + process.stderr.write(`\n${error instanceof Error ? error.message : String(error)}\n`) + process.exitCode = 1 + }) +} diff --git a/src/mendcode/packages/opencode/script/session-runtime-smoke.ts b/src/mendcode/packages/opencode/script/session-runtime-smoke.ts new file mode 100644 index 00000000..869c19b5 --- /dev/null +++ b/src/mendcode/packages/opencode/script/session-runtime-smoke.ts @@ -0,0 +1,1491 @@ +import { execFileSync, spawn, type ChildProcess } from "node:child_process" +import { createServer, type AddressInfo } from "node:net" +import { access, mkdir, mkdtemp, readFile, rm, utimes, writeFile } from "node:fs/promises" +import os from "node:os" +import path from "node:path" +import { fileURLToPath } from "node:url" +import stripAnsi from "strip-ansi" +import * as pty from "#pty" + +const PACKAGE_ROOT = path.dirname(path.dirname(fileURLToPath(import.meta.url))) +const SCRIPT_PATH = fileURLToPath(import.meta.url) +const SOURCE_ENTRYPOINT = path.join(PACKAGE_ROOT, "src", "index.ts") +const FAKE_PROVIDER_ID = "fake-local" +const FAKE_MODEL_ID = "fake-model" +const CHILD_TIMEOUT_MS = 30_000 +const SERVER_START_TIMEOUT_MS = 20_000 +const PTY_SMOKE_TIMEOUT_MS = 30_000 +const COMPLETE_PROMPT = "pty normal completion" +const STREAM_PROMPT = "pty provider stream" +const UNAFFECTED_PROMPT = "pty unaffected stream" + +type Sandbox = { + root: string + home: string + project: string + db: string + models: string + state: string + providerURL: string + env: NodeJS.ProcessEnv +} + +type JsonResponse = { + status: number + value: any + text: string +} + +type RunningServer = { + child: ChildProcess + url: string + output: () => string + stop: () => Promise +} + +type FakeProviderCall = { + prompt: string + aborted: boolean + abort: Promise + finish: () => void +} + +type RunningFakeProvider = { + calls: FakeProviderCall[] + waitForCall: (prompt: string) => Promise + stop: () => Promise +} + +type RunningTransportProxy = { + url: string + activeStreams: () => number + requests: () => string[] + drop: () => void + restore: () => void + stop: () => Promise +} + +type RunningTui = { + pid: number + output: () => string + exitState: () => string + write: (value: string) => void + stop: () => Promise +} + +function assert(condition: unknown, message: string): asserts condition { + if (!condition) throw new Error(message) +} + +function sleep(ms: number) { + return new Promise((resolve) => setTimeout(resolve, ms)) +} + +async function exists(target: string) { + return access(target).then( + () => true, + () => false, + ) +} + +async function reservePort() { + const listener = createServer() + await new Promise((resolve, reject) => { + listener.once("error", reject) + listener.listen(0, "127.0.0.1", () => resolve()) + }) + const address = listener.address() as AddressInfo + const port = address.port + await new Promise((resolve, reject) => listener.close((error) => (error ? reject(error) : resolve()))) + return port +} + +function fakeModels(providerURL: string) { + return { + [FAKE_PROVIDER_ID]: { + id: FAKE_PROVIDER_ID, + name: "Fake local", + env: [], + api: providerURL, + npm: "@ai-sdk/openai-compatible", + models: { + [FAKE_MODEL_ID]: { + id: FAKE_MODEL_ID, + name: "Fake model", + release_date: "2026-01-01", + attachment: false, + reasoning: false, + temperature: false, + tool_call: true, + limit: { context: 100_000, output: 1_000 }, + cost: { input: 0, output: 0 }, + }, + }, + }, + } +} + +function fakeConfig(providerURL: string) { + return { + $schema: "https://mendcode.ai/config.json", + formatter: false, + lsp: false, + permission: { bash: "allow" }, + enabled_providers: [FAKE_PROVIDER_ID], + provider: { + [FAKE_PROVIDER_ID]: { + name: "Fake local", + models: { + [FAKE_MODEL_ID]: { + name: "Fake model", + limit: { context: 100_000, output: 1_000 }, + provider: { + npm: "@ai-sdk/openai-compatible", + api: providerURL, + }, + }, + }, + }, + }, + } +} + +function buildEnvironment(input: { + home: string + project: string + db: string + models: string + xdgConfig: string + xdgData: string + xdgState: string + xdgCache: string + providerURL: string +}) { + const env: NodeJS.ProcessEnv = {} + for (const key of ["PATH", "SHELL", "TMPDIR", "LANG", "LC_ALL", "LC_CTYPE", "TERM", "TZ", "BUN_INSTALL"]) { + if (process.env[key] !== undefined) env[key] = process.env[key] + } + + const config = JSON.stringify(fakeConfig(input.providerURL)) + const configDir = path.join(input.xdgConfig, "mendcode") + Object.assign(env, { + HOME: input.home, + OPENCODE_TEST_HOME: input.home, + XDG_CONFIG_HOME: input.xdgConfig, + XDG_DATA_HOME: input.xdgData, + XDG_STATE_HOME: input.xdgState, + XDG_CACHE_HOME: input.xdgCache, + MENDCODE_GLOBAL_LAYOUT: "mendcode", + OPENCODE_GLOBAL_LAYOUT: "mendcode", + MENDCODE_DB: input.db, + OPENCODE_DB: input.db, + MENDCODE_CONFIG_DIR: configDir, + OPENCODE_CONFIG_DIR: configDir, + MENDCODE_CONFIG_CONTENT: config, + OPENCODE_CONFIG_CONTENT: config, + MENDCODE_MODELS_PATH: input.models, + OPENCODE_MODELS_PATH: input.models, + MENDCODE_DISABLE_MODELS_FETCH: "1", + OPENCODE_DISABLE_MODELS_FETCH: "1", + MENDCODE_DISABLE_DEFAULT_PLUGINS: "1", + OPENCODE_DISABLE_DEFAULT_PLUGINS: "1", + MENDCODE_EXPERIMENTAL_DISABLE_FILEWATCHER: "1", + OPENCODE_EXPERIMENTAL_DISABLE_FILEWATCHER: "1", + MENDCODE_EXPERIMENTAL_HTTPAPI: "1", + OPENCODE_EXPERIMENTAL_HTTPAPI: "1", + MENDCODE_PURE: "1", + OPENCODE_PURE: "1", + MENDCODE_DISABLE_CHANNEL_DB: "1", + OPENCODE_DISABLE_CHANNEL_DB: "1", + NO_COLOR: "1", + OTEL_SDK_DISABLED: "true", + }) + delete env.MENDCODE_SHARED_SERVER_STATE_FILE + delete env.MENDCODE_SHARED_SERVER_RUNTIME_ID + delete env.MENDCODE_SERVER_USERNAME + delete env.MENDCODE_SERVER_PASSWORD + delete env.OPENCODE_SERVER_USERNAME + delete env.OPENCODE_SERVER_PASSWORD + return env +} + +async function createSandbox(label: string): Promise { + const root = await mkdtemp(path.join(os.tmpdir(), `mendcode-session-${label}-`)) + const home = path.join(root, "home") + const project = path.join(root, "project") + const dbDir = path.join(root, "db") + const xdgConfig = path.join(root, "xdg-config") + const xdgData = path.join(root, "xdg-data") + const xdgState = path.join(root, "xdg-state") + const xdgCache = path.join(root, "xdg-cache") + const models = path.join(root, "models.json") + const providerURL = `http://127.0.0.1:${await reservePort()}/v1` + await Promise.all( + [home, project, dbDir, xdgConfig, xdgData, xdgState, xdgCache].map((directory) => + mkdir(directory, { recursive: true }), + ), + ) + await writeFile(models, JSON.stringify(fakeModels(providerURL), null, 2)) + const db = path.join(dbDir, "mendcode-local.db") + return { + root, + home, + project, + db, + models, + state: path.join(xdgState, "mendcode", "shared-server"), + providerURL, + env: buildEnvironment({ + home, + project, + db, + models, + xdgConfig, + xdgData, + xdgState, + xdgCache, + providerURL, + }), + } +} + +function trimOutput(value: string) { + return value.length > 8_000 ? value.slice(-8_000) : value +} + +function trimTerminalOutput(value: string) { + return value +} + +function terminalContains(output: string, text: string) { + const compact = (value: string) => stripAnsi(value).replace(/\s+/g, "") + return compact(output).includes(compact(text)) +} + +function deferred() { + let settled = false + let resolve!: (value: T | PromiseLike) => void + const promise = new Promise((next) => { + resolve = (value) => { + if (settled) return + settled = true + next(value) + } + }) + return { promise, resolve, settled: () => settled } +} + +async function waitUntil(label: string, check: () => boolean | Promise, timeoutMs = PTY_SMOKE_TIMEOUT_MS) { + const deadline = Date.now() + timeoutMs + while (Date.now() < deadline) { + if (await check()) return + await sleep(50) + } + throw new Error(`${label} timed out after ${timeoutMs}ms`) +} + +async function withTimeout(label: string, promise: Promise, timeoutMs = PTY_SMOKE_TIMEOUT_MS) { + let timer: ReturnType | undefined + try { + return await Promise.race([ + promise, + new Promise((_, reject) => { + timer = setTimeout(() => reject(new Error(`${label} timed out after ${timeoutMs}ms`)), timeoutMs) + timer.unref?.() + }), + ]) + } finally { + if (timer) clearTimeout(timer) + } +} + +function processAlive(pid: number) { + try { + process.kill(pid, 0) + return true + } catch { + return false + } +} + +function chatChunk(value: Record) { + return `data: ${JSON.stringify(value)}\n\n` +} + +function openAIStream(chunks: Record[], done = true) { + const encoder = new TextEncoder() + const payload = chunks.map(chatChunk).join("") + (done ? "data: [DONE]\n\n" : "") + return encoder.encode(payload) +} + +async function startFakeProvider(sandbox: Sandbox, longStream = false): Promise { + const provider = new URL(sandbox.providerURL) + const calls: FakeProviderCall[] = [] + const active = new Set>() + + const server = Bun.serve({ + hostname: provider.hostname, + port: Number(provider.port), + idleTimeout: 255, + async fetch(request) { + const url = new URL(request.url) + if (!url.pathname.endsWith("/chat/completions")) return new Response("not found", { status: 404 }) + const body = await request.text() + const prompt = [STREAM_PROMPT, UNAFFECTED_PROMPT, COMPLETE_PROMPT].find((value) => body.includes(value)) ?? body + const aborted = deferred() + let finish = () => {} + let streamController: ReadableStreamDefaultController | undefined + const call: FakeProviderCall = { + prompt, + aborted: false, + abort: aborted.promise, + finish: () => finish(), + } + calls.push(call) + + const markAborted = () => { + call.aborted = true + aborted.resolve() + } + request.signal.addEventListener("abort", markAborted, { once: true }) + + return new Response( + new ReadableStream({ + start(controller) { + streamController = controller + active.add(controller) + let settled = false + finish = () => { + if (settled) return + settled = true + active.delete(controller) + controller.enqueue( + openAIStream([ + { + id: `chatcmpl-${prompt === UNAFFECTED_PROMPT ? "unaffected" : "primary"}`, + object: "chat.completion.chunk", + choices: [{ index: 0, delta: {}, finish_reason: "stop" }], + usage: { prompt_tokens: 8, completion_tokens: 4, total_tokens: 12 }, + }, + ]), + ) + controller.close() + } + controller.enqueue( + openAIStream( + [ + { + id: `chatcmpl-${prompt === UNAFFECTED_PROMPT ? "unaffected" : "primary"}`, + object: "chat.completion.chunk", + choices: [{ index: 0, delta: { role: "assistant" } }], + }, + { + id: `chatcmpl-${prompt === UNAFFECTED_PROMPT ? "unaffected" : "primary"}`, + object: "chat.completion.chunk", + choices: [{ index: 0, delta: { content: longStream + ? `${prompt} active\n\n${Array.from({ length: 80 }, (_, index) => `SCROLL-ROW-${index}`).join("\n\n")}\n\nSCROLL-END` + : `${prompt} active` } }], + }, + ], + false, + ), + ) + }, + cancel() { + if (streamController) active.delete(streamController) + markAborted() + }, + }), + { status: 200, headers: { "content-type": "text/event-stream" } }, + ) + }, + }) + + return { + calls, + async waitForCall(prompt) { + await waitUntil(`provider request ${prompt}`, () => calls.some((call) => call.prompt === prompt)) + return calls.find((call) => call.prompt === prompt)! + }, + async stop() { + for (const controller of active) { + try { + controller.close() + } catch { + // The stream may already have been closed by cancellation. + } + } + active.clear() + await server.stop(true) + }, + } +} + +async function startTransportProxy(upstream: string): Promise { + const port = await reservePort() + let blocked = false + const streams = new Set<{ close: () => void }>() + const requests: string[] = [] + const server = Bun.serve({ + hostname: "127.0.0.1", + port, + idleTimeout: 255, + async fetch(request) { + const source = new URL(request.url) + requests.push(source.pathname + source.search) + const target = new URL(source.pathname + source.search, upstream) + const event = source.pathname.endsWith("/event") + if (blocked && event) return new Response("transport unavailable", { status: 503 }) + + const headers = new Headers(request.headers) + headers.delete("host") + headers.delete("content-length") + const body = request.method === "GET" || request.method === "HEAD" ? undefined : await request.arrayBuffer() + const response = await fetch(target, { + method: request.method, + headers, + body, + redirect: "manual", + signal: request.signal, + }) + if (!event || !response.body) return response + + const reader = response.body.getReader() + let closed = false + let entry!: { close: () => void } + const close = () => { + if (closed) return + closed = true + streams.delete(entry) + void reader.cancel().catch(() => undefined) + } + entry = { close } + streams.add(entry) + const wrapped = new ReadableStream({ + start(controller) { + const pump = async () => { + try { + while (!closed) { + const next = await reader.read() + if (next.done) break + controller.enqueue(next.value) + } + if (!closed) controller.close() + } catch (error) { + if (!closed) controller.error(error) + } finally { + close() + } + } + void pump() + entry.close = () => { + if (closed) return + closed = true + streams.delete(entry) + void reader.cancel().catch(() => undefined) + try { + controller.close() + } catch { + // Closing a stream already released by the client is harmless. + } + } + }, + cancel: close, + }) + const responseHeaders = new Headers(response.headers) + responseHeaders.delete("content-length") + return new Response(wrapped, { + status: response.status, + statusText: response.statusText, + headers: responseHeaders, + }) + }, + }) + + return { + url: `http://127.0.0.1:${port}`, + activeStreams: () => streams.size, + requests: () => [...requests], + drop() { + blocked = true + for (const stream of [...streams]) stream.close() + }, + restore() { + blocked = false + }, + async stop() { + for (const stream of [...streams]) stream.close() + await server.stop(true) + }, + } +} + +function ptyEnvironment(env: NodeJS.ProcessEnv) { + return Object.fromEntries( + Object.entries({ ...env, TERM: "xterm-256color", COLORTERM: "truecolor" }).filter( + (entry): entry is [string, string] => typeof entry[1] === "string", + ), + ) +} + +async function startTui( + sandbox: Sandbox, + serverURL: string, + sessionID: string, + entrypoint = SOURCE_ENTRYPOINT, +): Promise { + const installed = entrypoint !== SOURCE_ENTRYPOINT + const terminal = pty.spawn( + installed ? entrypoint : process.execPath, + installed + ? [sandbox.project, "--server-url", serverURL, "--session", sessionID] + : [ + "--cwd", + PACKAGE_ROOT, + "--no-install", + "--conditions=browser", + entrypoint, + sandbox.project, + "--server-url", + serverURL, + "--session", + sessionID, + ], + { + cwd: PACKAGE_ROOT, + env: ptyEnvironment(sandbox.env), + cols: Math.max(40, Number.parseInt(process.env.MENDCODE_SMOKE_COLS ?? "120", 10) || 120), + rows: Math.max(16, Number.parseInt(process.env.MENDCODE_SMOKE_ROWS ?? "40", 10) || 40), + name: "xterm-256color", + }, + ) + let output = "" + terminal.onData((chunk) => (output = trimTerminalOutput(output + chunk))) + const exit = deferred() + let exitState = "running" + terminal.onExit((event) => { + exitState = `exitCode=${event.exitCode} signal=${event.signal ?? "none"}` + exit.resolve() + }) + let stopped = false + return { + pid: terminal.pid, + output: () => output, + exitState: () => exitState, + write: (value) => terminal.write(value), + async stop() { + if (stopped && !processAlive(terminal.pid)) return + stopped = true + if (!exit.settled()) terminal.write("\x03") + await Promise.race([exit.promise, sleep(500)]) + if (processAlive(terminal.pid)) terminal.kill("SIGTERM") + await Promise.race([exit.promise, sleep(2_000)]) + if (processAlive(terminal.pid)) { + try { + if (process.platform !== "win32") process.kill(-terminal.pid, "SIGKILL") + else process.kill(terminal.pid, "SIGKILL") + } catch { + // The PTY child exited between the liveness check and the signal. + } + } + const deadline = Date.now() + 5_000 + while (processAlive(terminal.pid) && Date.now() < deadline) await sleep(50) + }, + } +} + +async function runChild(args: string[], env: NodeJS.ProcessEnv) { + const child = spawn(process.execPath, [SCRIPT_PATH, ...args], { + cwd: PACKAGE_ROOT, + env, + stdio: ["ignore", "pipe", "pipe"], + }) + let stdout = "" + let stderr = "" + child.stdout?.on("data", (chunk) => (stdout = trimOutput(stdout + String(chunk)))) + child.stderr?.on("data", (chunk) => (stderr = trimOutput(stderr + String(chunk)))) + const exit = new Promise((resolve, reject) => { + child.once("error", reject) + child.once("exit", (code, signal) => resolve(code ?? (signal ? 1 : 0))) + }) + const timer = setTimeout(() => child.kill("SIGKILL"), CHILD_TIMEOUT_MS) + timer.unref() + const code = await exit + clearTimeout(timer) + if (code !== 0) { + throw new Error(`child ${args[0]} failed with ${code}\nstdout:\n${stdout}\nstderr:\n${stderr}`) + } + return { stdout, stderr } +} + +async function terminateChild(child: ChildProcess, exit: Promise) { + if (child.exitCode !== null) return + child.kill("SIGTERM") + await Promise.race([exit.catch(() => undefined), sleep(5_000)]) + if (child.exitCode === null) child.kill("SIGKILL") + await exit.catch(() => undefined) +} + +async function startServer(input: { + entrypoint: string + installed: boolean + sandbox: Sandbox +}): Promise { + const port = await reservePort() + const args = input.installed + ? ["serve", "--hostname", "127.0.0.1", "--port", String(port)] + : [ + "--cwd", + PACKAGE_ROOT, + "--no-install", + "--conditions=browser", + input.entrypoint, + "serve", + "--hostname", + "127.0.0.1", + "--port", + String(port), + ] + const child = spawn(input.installed ? input.entrypoint : process.execPath, args, { + cwd: PACKAGE_ROOT, + env: input.sandbox.env, + stdio: ["ignore", "pipe", "pipe"], + }) + let output = "" + const exit = new Promise((resolve, reject) => { + child.once("error", reject) + child.once("exit", (code, signal) => resolve(code ?? (signal ? 1 : 0))) + }) + const listening = new Promise((resolve, reject) => { + const timer = setTimeout(() => reject(new Error(`server did not start\n${output}`)), SERVER_START_TIMEOUT_MS) + timer.unref() + const onData = (chunk: unknown) => { + output = trimOutput(output + String(chunk)) + const match = output.match(/MendCode runtime server listening on (http:\/\/127\.0\.0\.1:\d+)/) + if (!match) return + clearTimeout(timer) + resolve(match[1]) + } + child.stdout?.on("data", onData) + child.stderr?.on("data", onData) + void exit.then((code) => { + if (code !== 0) reject(new Error(`server exited before listening (${code})\n${output}`)) + }) + }) + let url: string + try { + url = await listening + } catch (error) { + await terminateChild(child, exit) + throw error + } + let stopPromise: Promise | undefined + const stop = () => + (stopPromise ??= (async () => { + await terminateChild(child, exit) + })()) + return { child, url, output: () => output, stop } +} + +async function requestJSON( + server: RunningServer, + sandbox: Sandbox, + route: string, + init: RequestInit = {}, +): Promise { + const headers = new Headers(init.headers) + headers.set("x-mendcode-directory", sandbox.project) + headers.set("x-opencode-directory", sandbox.project) + if (init.body && !headers.has("content-type")) headers.set("content-type", "application/json") + const response = await fetch(new URL(route, server.url), { + ...init, + headers, + signal: init.signal ?? AbortSignal.timeout(5_000), + }) + const text = await response.text() + let value: any = undefined + try { + value = text ? JSON.parse(text) : undefined + } catch { + value = text + } + return { status: response.status, value, text } +} + +async function submitAsyncPrompt(server: RunningServer, sandbox: Sandbox, sessionID: string, text: string) { + const response = await requestJSON(server, sandbox, `/session/${encodeURIComponent(sessionID)}/prompt_async`, { + method: "POST", + body: JSON.stringify({ + agent: "build", + model: { providerID: FAKE_PROVIDER_ID, modelID: FAKE_MODEL_ID }, + parts: [{ type: "text", text }], + }), + }) + expectStatus(response, 204, `async prompt ${text}`) +} + +function startSessionShell(server: RunningServer, sandbox: Sandbox, sessionID: string, pidFile: string) { + const childScript = `import { writeFileSync } from "node:fs"; writeFileSync(process.argv[1], String(process.pid)); setInterval(() => {}, 1000)` + const command = `${JSON.stringify(process.execPath)} -e ${JSON.stringify(childScript)} ${JSON.stringify(pidFile)}` + const response = requestJSON(server, sandbox, `/session/${encodeURIComponent(sessionID)}/shell`, { + method: "POST", + body: JSON.stringify({ + agent: "build", + model: { providerID: FAKE_PROVIDER_ID, modelID: FAKE_MODEL_ID }, + command, + }), + signal: AbortSignal.timeout(PTY_SMOKE_TIMEOUT_MS), + }) + return { command, response } +} + +async function sessionMessages(server: RunningServer, sandbox: Sandbox, sessionID: string) { + const response = await requestJSON(server, sandbox, `/session/${encodeURIComponent(sessionID)}/message`) + expectStatus(response, 200, "session messages") + assert(Array.isArray(response.value), "session messages response is not an array") + return response.value as Array<{ info?: any; parts?: any[] }> +} + +function promptCount(messages: Array<{ info?: any; parts?: any[] }>, prompt: string) { + return messages.filter( + (message) => + message.info?.role === "user" && + message.parts?.some( + (part) => part?.type === "text" && typeof part.text === "string" && part.text.includes(prompt), + ), + ).length +} + +function interruptedAssistantCount(messages: Array<{ info?: any; parts?: any[] }>) { + return messages.filter( + (message) => + message.info?.role === "assistant" && + (message.info?.error?.name === "MessageAbortedError" || + message.parts?.some((part) => part?.state?.metadata?.interrupted === true)), + ).length +} + +function shellParts(messages: Array<{ info?: any; parts?: any[] }>, command: string) { + return messages.flatMap((message) => + (message.parts ?? []).filter((part) => part?.type === "tool" && part?.state?.input?.command === command), + ) +} + +async function sessionStatusType(server: RunningServer, sandbox: Sandbox, sessionID: string) { + const response = await requestJSON(server, sandbox, "/session/status") + expectStatus(response, 200, "session status") + return response.value?.[sessionID]?.type ?? "idle" +} + +async function waitForSessionStatus( + server: RunningServer, + sandbox: Sandbox, + sessionID: string, + expected: "busy" | "idle", +) { + await waitUntil(`session ${sessionID} status ${expected}`, async () => { + try { + return (await sessionStatusType(server, sandbox, sessionID)) === expected + } catch { + return false + } + }) +} + +async function interruptThroughTui(tui: RunningTui, label: string) { + const firstOffset = tui.output().length + tui.write("\x1b") + await waitUntil(`${label} first Esc hint`, () => + terminalContains(tui.output().slice(firstOffset), "[esc again to interrupt]"), + ) + const secondOffset = tui.output().length + tui.write("\x1b") + return secondOffset +} + +async function settledPromptRender(tui: RunningTui, label: string) { + const offset = tui.output().length + tui.write("x") + await waitUntil(`${label} prompt redraw`, () => tui.output().length > offset) + const cleanupOffset = tui.output().length + tui.write("\x7f") + await waitUntil(`${label} prompt cleanup redraw`, () => tui.output().length > cleanupOffset) + return stripAnsi(tui.output().slice(offset)) +} + +async function abortSession(server: RunningServer, sandbox: Sandbox, sessionID: string) { + const response = await requestJSON(server, sandbox, `/session/${encodeURIComponent(sessionID)}/abort`, { + method: "POST", + }) + expectStatus(response, 200, "session abort") +} + +async function runQueuedLoopTuiScenario(sandbox: Sandbox) { + const provider = await startFakeProvider(sandbox, true) + let backend: RunningServer | undefined + let proxy: RunningTransportProxy | undefined + let tui: RunningTui | undefined + try { + backend = await startServer({ entrypoint: SOURCE_ENTRYPOINT, installed: false, sandbox }) + await waitForHealth(backend, sandbox) + const primary = await createSession(backend, sandbox) + proxy = await startTransportProxy(backend.url) + tui = await startTui(sandbox, proxy.url, primary.id) + await waitUntil("queued loop TUI event subscription", () => proxy!.activeStreams() > 0) + await submitAsyncPrompt(backend, sandbox, primary.id, STREAM_PROMPT) + const call = await provider.waitForCall(STREAM_PROMPT) + await waitUntil("long stream prompt rendered", () => terminalContains(tui!.output(), STREAM_PROMPT)) + for (let page = 0; page < 10; page++) { + tui.write("\x1b[6~") + await sleep(50) + } + await waitUntil("long stream end rendered", () => terminalContains(tui!.output(), "SCROLL-END")) + + const notification = await requestJSON(backend, sandbox, `/session/${primary.id}/prompt_async`, { + method: "POST", + body: JSON.stringify({ + agent: "build", + model: { providerID: FAKE_PROVIDER_ID, modelID: FAKE_MODEL_ID }, + parts: [ + { + type: "text", + text: "Internal loop stopped notification", + synthetic: true, + metadata: { kind: "loop_owner_notification" }, + }, + ], + }), + }) + expectStatus(notification, 204, "queued internal loop notification") + const queueOffset = tui.output().length + await submitAsyncPrompt(backend, sandbox, primary.id, "VISIBLE-QUEUED-QUESTION") + await waitUntil("visible queued question keeps Send now", () => { + const output = tui!.output().slice(queueOffset) + return terminalContains(output, "VISIBLE-QUEUED-QUESTION") && terminalContains(output, "SEND") + }) + + const upOffset = tui.output().length + tui.write("\x1b[5~") + await waitUntil("PageUp reveals earlier long stream content", () => + terminalContains(tui!.output().slice(upOffset), "SCROLL-ROW-"), + ) + const downOffset = tui.output().length + tui.write("\x1b[6~") + await waitUntil("PageDown reaches the queued question", () => + terminalContains(tui!.output().slice(downOffset), "VISIBLE-QUEUED-QUESTION"), + ) + + await interruptThroughTui(tui, "queued loop notification") + await withTimeout("queued loop active provider cancellation", call.abort) + await waitForSessionStatus(backend, sandbox, primary.id, "idle") + assert(provider.calls.length === 1, "double Esc started a hidden or human queued prompt") + } catch (error) { + throw new Error( + `${error instanceof Error ? error.message : String(error)}\nPTY:\n${stripAnsi(tui?.output() ?? "").slice(-8000)}`, + ) + } finally { + await tui?.stop() + await proxy?.stop() + await backend?.stop() + await provider.stop() + } +} + +async function runTuiPtyScenario(sandbox: Sandbox, tuiEntrypoint = SOURCE_ENTRYPOINT) { + let provider: RunningFakeProvider | undefined + let backend: RunningServer | undefined + let restarted: RunningServer | undefined + let proxy: RunningTransportProxy | undefined + let tui: RunningTui | undefined + let toolChildPID: number | undefined + const toolChildPIDFile = path.join(sandbox.root, "tool-child.pid") + + try { + provider = await startFakeProvider(sandbox) + backend = await startServer({ entrypoint: SOURCE_ENTRYPOINT, installed: false, sandbox }) + await waitForHealth(backend, sandbox) + proxy = await startTransportProxy(backend.url) + const primary = await createSession(backend, sandbox) + const unaffected = await createSession(backend, sandbox) + tui = await startTui(sandbox, proxy.url, primary.id, tuiEntrypoint) + + try { + await waitUntil("TUI event subscription", () => proxy!.activeStreams() > 0) + } catch (error) { + throw new Error( + `${error instanceof Error ? error.message : String(error)}\nPTY pid=${tui.pid} alive=${processAlive(tui.pid)} ${tui.exitState()}:\n${stripAnsi(tui.output()).slice(-8_000)}\nProxy requests:\n${proxy.requests().join("\n")}`, + ) + } + await submitAsyncPrompt(backend, sandbox, primary.id, COMPLETE_PROMPT) + const completedCall = await provider.waitForCall(COMPLETE_PROMPT) + await waitForSessionStatus(backend, sandbox, primary.id, "busy") + await waitUntil("TUI rendered normally completing provider stream", () => + terminalContains(tui!.output(), `${COMPLETE_PROMPT} active`), + ) + completedCall.finish() + await waitForSessionStatus(backend, sandbox, primary.id, "idle") + const completedMessages = await sessionMessages(backend, sandbox, primary.id) + assert(promptCount(completedMessages, COMPLETE_PROMPT) === 1, "normal completion duplicated its user message") + assert( + completedMessages.some( + (message) => + message.info?.role === "assistant" && + message.info?.finish === "stop" && + typeof message.info?.time?.completed === "number", + ), + "normal completion did not persist a terminal assistant receipt", + ) + const completedRender = await settledPromptRender(tui, "normal completion") + assert(!completedRender.includes("Generating"), "TUI retained generating activity after normal completion") + + await submitAsyncPrompt(backend, sandbox, unaffected.id, UNAFFECTED_PROMPT) + const unaffectedCall = await provider.waitForCall(UNAFFECTED_PROMPT) + await submitAsyncPrompt(backend, sandbox, primary.id, STREAM_PROMPT) + const primaryCall = await provider.waitForCall(STREAM_PROMPT) + await waitForSessionStatus(backend, sandbox, primary.id, "busy") + await waitForSessionStatus(backend, sandbox, unaffected.id, "busy") + try { + await waitUntil("TUI rendered active provider stream", () => + terminalContains(tui!.output(), `${STREAM_PROMPT} active`), + ) + } catch (error) { + const messages = await sessionMessages(backend, sandbox, primary.id) + throw new Error( + `${error instanceof Error ? error.message : String(error)}\nPTY:\n${stripAnsi(tui.output()).slice(-12_000)}\nProxy requests:\n${proxy.requests().join("\n")}\nMessages:\n${JSON.stringify(messages).slice(-8_000)}`, + ) + } + + const beforeDisconnect = await sessionMessages(backend, sandbox, primary.id) + assert(promptCount(beforeDisconnect, STREAM_PROMPT) === 1, "primary prompt was not persisted exactly once") + const disconnectOffset = tui.output().length + proxy.drop() + await waitUntil("TUI reconnect label", () => + terminalContains(tui!.output().slice(disconnectOffset), "Reconnecting to backend"), + ) + assert(!primaryCall.aborted, "transport loss incorrectly aborted the provider turn") + assert(!unaffectedCall.aborted, "transport loss incorrectly aborted the unaffected session") + + proxy.restore() + await waitUntil("TUI event resubscription", () => proxy!.activeStreams() > 0) + await waitForSessionStatus(backend, sandbox, primary.id, "busy") + const afterReconnect = await sessionMessages(backend, sandbox, primary.id) + assert(promptCount(afterReconnect, STREAM_PROMPT) === 1, "reconnect duplicated the primary prompt") + assert( + provider.calls.filter((call) => call.prompt === STREAM_PROMPT).length === 1, + "reconnect started a duplicate provider turn", + ) + + const primarySettleOffset = await interruptThroughTui(tui, "provider stream") + await withTimeout("provider AbortSignal", primaryCall.abort) + await waitForSessionStatus(backend, sandbox, primary.id, "idle") + await waitUntil("TUI cancellation render", () => tui!.output().length > primarySettleOffset) + const primarySettledRender = stripAnsi(tui.output().slice(primarySettleOffset)) + assert(!primarySettledRender.includes("Reconnecting to backend"), "TUI retained reconnect activity after cancel") + assert(!primarySettledRender.includes("Generating"), "TUI retained generating activity after cancel") + const afterPrimaryCancel = await sessionMessages(backend, sandbox, primary.id) + assert(interruptedAssistantCount(afterPrimaryCancel) >= 1, "provider cancellation was not persisted as interrupted") + assert(promptCount(afterPrimaryCancel, STREAM_PROMPT) === 1, "provider cancellation duplicated the user message") + assert(!unaffectedCall.aborted, "targeted cancellation interrupted the other session") + assert( + (await sessionStatusType(backend, sandbox, unaffected.id)) === "busy", + "targeted cancellation cleared the other session status", + ) + + const shell = startSessionShell(backend, sandbox, primary.id, toolChildPIDFile) + await waitUntil("tool child PID", () => exists(toolChildPIDFile)) + toolChildPID = Number((await readFile(toolChildPIDFile, "utf8")).trim()) + assert(Number.isInteger(toolChildPID) && toolChildPID > 1, "tool child did not publish a valid PID") + assert(processAlive(toolChildPID), "tool child exited before cancellation") + await waitForSessionStatus(backend, sandbox, primary.id, "busy") + + const toolSettleOffset = await interruptThroughTui(tui, "tool child") + await waitUntil("tool child termination", () => !processAlive(toolChildPID!)) + await waitForSessionStatus(backend, sandbox, primary.id, "idle") + await waitUntil("TUI tool cancellation render", () => tui!.output().length > toolSettleOffset) + const toolSettledRender = stripAnsi(tui.output().slice(toolSettleOffset)) + assert(!toolSettledRender.includes("Generating"), "TUI retained tool activity after cancel") + const shellResponse = await withTimeout("session shell cancellation response", shell.response) + expectStatus(shellResponse, 200, "session shell cancellation") + const beforeRestart = await sessionMessages(backend, sandbox, primary.id) + assert(promptCount(beforeRestart, STREAM_PROMPT) === 1, "stream prompt duplicated before restart") + assert(promptCount(beforeRestart, COMPLETE_PROMPT) === 1, "normal completion prompt duplicated before restart") + const cancelledShellParts = shellParts(beforeRestart, shell.command) + assert(cancelledShellParts.length === 1, "cancelled shell was not persisted exactly once") + assert(cancelledShellParts[0]?.state?.status === "completed", "cancelled shell did not reach terminal state") + assert( + String(cancelledShellParts[0]?.state?.output).includes("User aborted the command"), + "cancelled shell did not persist its user-abort receipt", + ) + assert(interruptedAssistantCount(beforeRestart) >= 1, "provider cancellation lost its interrupted receipt") + assert(!unaffectedCall.aborted, "tool cancellation interrupted the other session") + + await abortSession(backend, sandbox, unaffected.id) + await withTimeout("unaffected session cleanup", unaffectedCall.abort) + await waitForSessionStatus(backend, sandbox, unaffected.id, "idle") + const providerCallsBeforeRestart = provider.calls.length + const messageCountBeforeRestart = beforeRestart.length + + await tui.stop() + assert(!processAlive(tui.pid), "TUI child remained alive after exact cleanup") + tui = undefined + await proxy.stop() + proxy = undefined + await backend.stop() + backend = undefined + + restarted = await startServer({ entrypoint: SOURCE_ENTRYPOINT, installed: false, sandbox }) + await waitForHealth(restarted, sandbox) + await sleep(500) + assert((await sessionStatusType(restarted, sandbox, primary.id)) === "idle", "restart revived the cancelled turn") + const afterRestart = await sessionMessages(restarted, sandbox, primary.id) + assert(afterRestart.length === messageCountBeforeRestart, "restart duplicated persisted messages") + assert(promptCount(afterRestart, STREAM_PROMPT) === 1, "restart duplicated the stream prompt") + assert(promptCount(afterRestart, COMPLETE_PROMPT) === 1, "restart duplicated the normal completion prompt") + assert(shellParts(afterRestart, shell.command).length === 1, "restart duplicated the cancelled shell") + assert(provider.calls.length === providerCallsBeforeRestart, "restart resumed a cancelled provider turn") + + return { + primaryMessages: afterRestart.length, + providerCalls: provider.calls.length, + completed: promptCount(afterRestart, COMPLETE_PROMPT), + interrupted: interruptedAssistantCount(afterRestart), + toolChildPID, + } + } finally { + await tui?.stop().catch(() => undefined) + await proxy?.stop().catch(() => undefined) + await restarted?.stop().catch(() => undefined) + await backend?.stop().catch(() => undefined) + await provider?.stop().catch(() => undefined) + if (toolChildPID && processAlive(toolChildPID)) { + try { + process.kill(toolChildPID, "SIGKILL") + } catch { + // The exact isolated child may exit during cleanup. + } + } + } +} + +function expectStatus(response: JsonResponse, expected: number, label: string) { + assert( + response.status === expected, + `${label}: expected HTTP ${expected}, got ${response.status}: ${response.text.slice(0, 1_000)}`, + ) +} + +async function waitForHealth(server: RunningServer, sandbox: Sandbox) { + const deadline = Date.now() + SERVER_START_TIMEOUT_MS + while (Date.now() < deadline) { + try { + const response = await requestJSON(server, sandbox, "/global/health") + if (response.status === 200) return + } catch { + // The listener can be ready a few milliseconds before the router is usable. + } + await sleep(100) + } + throw new Error(`health probe timed out\n${server.output()}`) +} + +async function createSession(server: RunningServer, sandbox: Sandbox, parentID?: string) { + const response = await requestJSON(server, sandbox, "/session", { + method: "POST", + body: JSON.stringify({ + title: parentID ? "Persisted child" : "Persisted parent", + parentID, + agent: "build", + model: { providerID: FAKE_PROVIDER_ID, id: FAKE_MODEL_ID }, + }), + }) + expectStatus(response, 200, "session create") + assert(response.value && typeof response.value.id === "string", "session create did not return an id") + return response.value as { id: string; parentID?: string } +} + +async function registerBackground(server: RunningServer, sandbox: Sandbox, sessionID: string) { + const response = await requestJSON(server, sandbox, `/session/${encodeURIComponent(sessionID)}/background`, { + method: "POST", + body: JSON.stringify({ state: "working", summary: "persisted background smoke", pinned: true }), + }) + expectStatus(response, 200, "background register") +} + +async function seedPersistedRows(sandbox: Sandbox, parentID: string, childID: string) { + await runChild(["--seed-db", sandbox.db, parentID, childID], sandbox.env) +} + +async function seedDatabase(dbPath: string, parentID: string, childID: string) { + assert( + process.env.MENDCODE_DB !== undefined && path.resolve(process.env.MENDCODE_DB) === path.resolve(dbPath), + "seed child resolved an unexpected MendCode DB", + ) + assert( + process.env.OPENCODE_DB !== undefined && path.resolve(process.env.OPENCODE_DB) === path.resolve(dbPath), + "seed child resolved an unexpected OpenCode DB", + ) + const { Database } = await import("../src/storage/db") + const { MessageTable, PartTable, SessionMessageTable, SessionStatusTable } = await import( + "../src/session/session.sql" + ) + const now = Date.now() + Database.use((db) => { + db.insert(SessionStatusTable) + .values([ + { + session_id: parentID, + time_created: now, + time_updated: now, + data: { type: "busy", kind: "subagent-wait", message: "Smoke parent busy", startedAt: now }, + }, + { + session_id: childID, + time_created: now, + time_updated: now, + data: { type: "busy", kind: "mflow-wait", message: "Smoke child busy", startedAt: now }, + }, + ] as any) + .run() + db.insert(MessageTable) + .values({ + id: "msg_smoke_incomplete", + session_id: parentID, + time_created: now, + time_updated: now, + data: { + role: "user", + time: { created: now }, + agent: "build", + model: { providerID: FAKE_PROVIDER_ID, modelID: FAKE_MODEL_ID }, + queued: true, + }, + } as any) + .run() + db.insert(PartTable) + .values({ + id: "prt_smoke_incomplete", + message_id: "msg_smoke_incomplete", + session_id: parentID, + time_created: now, + time_updated: now, + data: { type: "text", text: "persisted incomplete prompt" }, + } as any) + .run() + db.insert(SessionMessageTable) + .values({ + id: "evt_smoke_incomplete", + session_id: parentID, + type: "user", + time_created: now, + time_updated: now, + data: { + text: "persisted v2 incomplete prompt", + files: [], + agents: [], + time: { created: now }, + }, + } as any) + .run() + }) + Database.close() +} + +async function verifyPersistedApis(server: RunningServer, sandbox: Sandbox, parentID: string, childID: string) { + const sessions = await requestJSON(server, sandbox, "/session") + expectStatus(sessions, 200, "session list") + assert(Array.isArray(sessions.value), "session list is not an array") + assert( + sessions.value.some((item: any) => item.id === parentID), + "persisted parent is missing from session list", + ) + assert( + sessions.value.some((item: any) => item.id === childID), + "persisted child is missing from session list", + ) + + const roots = await requestJSON(server, sandbox, "/session?roots=true") + expectStatus(roots, 200, "root session list") + assert( + roots.value.some((item: any) => item.id === parentID), + "persisted parent is missing from root list", + ) + assert(!roots.value.some((item: any) => item.id === childID), "child leaked into root session list") + + const children = await requestJSON(server, sandbox, `/session/${encodeURIComponent(parentID)}/children`) + expectStatus(children, 200, "child session list") + assert( + children.value.some((item: any) => item.id === childID), + "persisted child is missing from parent children", + ) + + const statuses = await requestJSON(server, sandbox, "/session/status") + expectStatus(statuses, 200, "session status") + assert(statuses.value[parentID]?.type === "busy", "persisted parent busy status is missing") + assert(statuses.value[childID]?.type === "busy", "persisted child busy status is missing") + + const background = await requestJSON(server, sandbox, "/session/background") + expectStatus(background, 200, "background list") + assert( + background.value.some((item: any) => item.sessionID === childID), + "persisted background session is missing", + ) + + const providers = await requestJSON(server, sandbox, "/provider") + expectStatus(providers, 200, "provider list") + const fakeProvider = providers.value?.all?.find((provider: any) => provider.id === FAKE_PROVIDER_ID) + assert(fakeProvider?.models?.[FAKE_MODEL_ID], "fake local provider/model is missing") + assert(providers.value.connected?.includes(FAKE_PROVIDER_ID), "fake local provider is not connected") + + const messages = await requestJSON(server, sandbox, `/session/${encodeURIComponent(parentID)}/message`) + expectStatus(messages, 200, "legacy session messages") + assert( + messages.value.some( + (message: any) => message.info?.id === "msg_smoke_incomplete" || message.id === "msg_smoke_incomplete", + ), + `persisted legacy message is missing: ${JSON.stringify(messages.value).slice(0, 1_000)}`, + ) + + const context = await requestJSON(server, sandbox, `/api/session/${encodeURIComponent(parentID)}/context`) + expectStatus(context, 200, "v2 session context") + assert( + context.value.some((message: any) => message.id === "evt_smoke_incomplete"), + "persisted v2 context is missing", + ) + + const v2Sessions = await requestJSON(server, sandbox, "/api/session?roots=true") + expectStatus(v2Sessions, 200, "v2 session list") + assert( + v2Sessions.value.items.some((item: any) => item.id === parentID), + "persisted parent is missing from v2 session list", + ) + + const combined = JSON.stringify({ sessions, statuses, background, providers, messages, context, v2Sessions }) + assert(!combined.includes("No context found for instance"), "session APIs returned the incident context error") + return { + sessions: sessions.value.length, + statuses: Object.keys(statuses.value).length, + background: background.value.length, + providers: providers.value.all.length, + context: context.value.length, + } +} + +async function runSourceRestartScenario(sandbox: Sandbox) { + let first: RunningServer | undefined + let second: RunningServer | undefined + try { + first = await startServer({ entrypoint: SOURCE_ENTRYPOINT, installed: false, sandbox }) + await waitForHealth(first, sandbox) + const parent = await createSession(first, sandbox) + const child = await createSession(first, sandbox, parent.id) + await registerBackground(first, sandbox, child.id) + await first.stop() + first = undefined + + await seedPersistedRows(sandbox, parent.id, child.id) + second = await startServer({ entrypoint: SOURCE_ENTRYPOINT, installed: false, sandbox }) + await waitForHealth(second, sandbox) + const result = await verifyPersistedApis(second, sandbox, parent.id, child.id) + return result + } finally { + await second?.stop().catch(() => undefined) + await first?.stop().catch(() => undefined) + } +} + +async function writeStaleSharedState(sandbox: Sandbox) { + await mkdir(sandbox.state, { recursive: true }) + const lock = path.join(sandbox.state, "server.lock") + await mkdir(lock, { recursive: true }) + await writeFile(path.join(lock, "owner"), "stale smoke lock") + const stale = new Date(Date.now() - 120_000) + await utimes(lock, stale, stale) + await writeFile( + path.join(sandbox.state, "server.json"), + JSON.stringify({ + version: 1, + pid: 999_999, + url: `http://127.0.0.1:${await reservePort()}`, + username: "mendcode", + password: "stale-smoke", + startedAt: new Date(stale).toISOString(), + runtimeID: "stale-runtime", + }), + ) +} + +async function runManagedRecovery(sandbox: Sandbox) { + await writeStaleSharedState(sandbox) + sandbox.env.MENDCODE_SHARED_SERVER_PORT = String(await reservePort()) + const result = await runChild(["--managed-recovery", SOURCE_ENTRYPOINT, sandbox.project, PACKAGE_ROOT], sandbox.env) + const line = result.stdout + .split("\n") + .map((item) => item.trim()) + .reverse() + .find((item) => item.startsWith("{") && item.endsWith("}")) + assert(line, `managed recovery did not return JSON\n${result.stdout}`) + const value = JSON.parse(line) + assert(value.ok === true && typeof value.pid === "number" && typeof value.url === "string", "managed recovery failed") + assert(!(await exists(path.join(sandbox.state, "server.lock"))), "stale shared-server lock was not recovered") + return { pid: value.pid, url: value.url } +} + +async function managedRecovery(entrypoint: string, project: string, runtimeCwd: string) { + process.argv[1] = entrypoint + const { ensureLocalSharedServer } = await import("../src/cli/cmd/tui/thread") + const connection = await ensureLocalSharedServer({ directory: project, runtimeCwd }) + assert(connection, "ensureLocalSharedServer did not recover the stale server") + try { + console.log(JSON.stringify({ ok: true, pid: connection.pid, url: connection.url })) + } finally { + await connection.lease.release() + try { + process.kill(connection.pid, "SIGTERM") + } catch { + // The server may already have exited after the lease was released. + } + const deadline = Date.now() + 5_000 + while (Date.now() < deadline) { + try { + process.kill(connection.pid, 0) + } catch { + return + } + await sleep(50) + } + try { + process.kill(connection.pid, "SIGKILL") + } catch { + // Cleanup is best effort after the bounded wait. + } + } +} + +function installedEntrypoint(realHome: string) { + const explicit = process.env.MENDCODE_INSTALLED_BIN + if (explicit) return explicit + const candidates = [ + path.join(realHome, ".mendcode", "bin", "mendcode"), + (() => { + try { + return execFileSync("which", ["mendcode"], { encoding: "utf8" }).trim() + } catch { + return "" + } + })(), + ] + return candidates.find((candidate) => candidate && candidate !== SOURCE_ENTRYPOINT) || undefined +} + +async function runInstalledParity(entrypoint: string, realHome: string) { + const sandbox = await createSandbox("installed") + let server: RunningServer | undefined + try { + assert( + !path.resolve(sandbox.db).startsWith(path.join(path.resolve(realHome), ".mendcode") + path.sep), + "installed smoke DB escaped the temporary sandbox", + ) + server = await startServer({ entrypoint, installed: true, sandbox }) + await waitForHealth(server, sandbox) + const created = await createSession(server, sandbox) + const providers = await requestJSON(server, sandbox, "/provider") + expectStatus(providers, 200, "installed provider list") + const fakeProvider = providers.value?.all?.find((provider: any) => provider.id === FAKE_PROVIDER_ID) + assert(fakeProvider?.models?.[FAKE_MODEL_ID], "installed runtime lost the fake provider/model") + const sessions = await requestJSON(server, sandbox, "/session") + expectStatus(sessions, 200, "installed session list") + assert( + sessions.value.some((item: any) => item.id === created.id), + "installed runtime did not persist its isolated session", + ) + return { version: await runtimeVersion(entrypoint, sandbox.env), sessions: sessions.value.length } + } finally { + await server?.stop().catch(() => undefined) + await rm(sandbox.root, { recursive: true, force: true }) + } +} + +async function runtimeVersion(entrypoint: string, env: NodeJS.ProcessEnv) { + const result = await new Promise<{ code: number; stdout: string; stderr: string }>((resolve, reject) => { + const child = spawn(entrypoint, ["--version"], { cwd: PACKAGE_ROOT, env, stdio: ["ignore", "pipe", "pipe"] }) + let stdout = "" + let stderr = "" + child.stdout?.on("data", (chunk) => (stdout += String(chunk))) + child.stderr?.on("data", (chunk) => (stderr += String(chunk))) + child.once("error", reject) + child.once("exit", (code) => resolve({ code: code ?? 1, stdout, stderr })) + }) + assert(result.code === 0, `installed runtime --version failed\n${result.stderr}`) + return result.stdout.trim().split("\n").at(-1) || "unknown" +} + +async function main() { + const mode = process.argv[2] + if (mode === "--seed-db") return seedDatabase(process.argv[3], process.argv[4], process.argv[5]) + if (mode === "--managed-recovery") return managedRecovery(process.argv[3], process.argv[4], process.argv[5]) + + const requireInstalled = process.argv.includes("--require-installed") + if (process.argv.includes("--loop-queue-only")) { + const sandbox = await createSandbox("loop-queue") + try { + await runQueuedLoopTuiScenario(sandbox) + console.log("PASS real TUI/PTY hidden loop notification, visible Send now, PageUp/PageDown, and double Esc") + return + } finally { + await rm(sandbox.root, { recursive: true, force: true }) + } + } + if (process.argv.includes("--pty-only")) { + const sandbox = await createSandbox("pty") + try { + const result = await runTuiPtyScenario(sandbox) + console.log( + `PASS real TUI/PTY completion, reconnect, and targeted cancellation: messages=${result.primaryMessages} completed=${result.completed} interrupted=${result.interrupted} providerCalls=${result.providerCalls} toolChildPID=${result.toolChildPID}`, + ) + return + } finally { + await rm(sandbox.root, { recursive: true, force: true }) + } + } + const realHome = process.env.HOME ?? os.homedir() + const sourceSandbox = await createSandbox("source") + const managedSandbox = await createSandbox("managed") + const ptySandbox = await createSandbox("pty") + try { + const source = await runSourceRestartScenario(sourceSandbox) + console.log( + `PASS persisted DB restart: sessions=${source.sessions} statuses=${source.statuses} background=${source.background} providers=${source.providers} context=${source.context}`, + ) + + const managed = await runManagedRecovery(managedSandbox) + console.log(`PASS stale lock/state/PID recovery: pid=${managed.pid} url=${managed.url}`) + + const installed = installedEntrypoint(realHome) + if (!installed || !(await exists(installed))) { + if (requireInstalled) + throw new Error("installed mendcode binary not found; set MENDCODE_INSTALLED_BIN to an isolated executable") + console.log("SKIP source/installed parity: no installed mendcode binary found") + } else { + const parity = await runInstalledParity(installed, realHome) + console.log(`PASS source/installed isolated parity: installed=${parity.version} sessions=${parity.sessions}`) + } + + const ptyEntrypoint = requireInstalled && installed ? installed : SOURCE_ENTRYPOINT + const ptyResult = await runTuiPtyScenario(ptySandbox, ptyEntrypoint) + console.log( + `PASS real ${ptyEntrypoint === SOURCE_ENTRYPOINT ? "source" : "installed"} TUI/PTY completion, reconnect, and targeted cancellation: messages=${ptyResult.primaryMessages} completed=${ptyResult.completed} interrupted=${ptyResult.interrupted} providerCalls=${ptyResult.providerCalls} toolChildPID=${ptyResult.toolChildPID}`, + ) + console.log( + "PASS isolation: all smoke processes used temporary HOME/XDG/DB paths and a loopback-only fake provider; no external provider or real user session was used", + ) + } finally { + await rm(sourceSandbox.root, { recursive: true, force: true }) + await rm(managedSandbox.root, { recursive: true, force: true }) + await rm(ptySandbox.root, { recursive: true, force: true }) + } +} + +await main().catch((error) => { + console.error(error instanceof Error ? error.stack || error.message : String(error)) + process.exitCode = 1 +}) diff --git a/src/mendcode/packages/opencode/specs/v2/opencode-v2-subagents-stabilizations.md b/src/mendcode/packages/opencode/specs/v2/opencode-v2-subagents-stabilizations.md new file mode 100644 index 00000000..e6d70054 --- /dev/null +++ b/src/mendcode/packages/opencode/specs/v2/opencode-v2-subagents-stabilizations.md @@ -0,0 +1,72 @@ +# OpenCode V2 Subagents Stabilizations + +## Context + +MendCode already has parent/child subagent sessions, `Ctrl+T` navigation, and a Subagents dock/widget. We should not duplicate that with a separate subagent shell. The V2 work should stabilize the existing surface and then extend execution semantics. + +## Goals + +- Reuse the existing subagent session navigation and UI instead of adding a new shell. +- Make subagent rendering readable in child sessions, including long prompts/tool outputs. +- Show only active/relevant subagents for the current root session. +- Do not resurrect historical subagent entries from compacted or stale transcript state. +- Keep responsive behavior clean at narrow and wide terminal sizes. +- Add configurable subagent launch behavior: + - `wait`: parent blocks until the subagent returns output. + - `background`: parent launches the subagent, keeps working, and can monitor/summarize child progress later. + - `auto`: model chooses per task whether to wait or run in background. + +## Non-goals + +- Do not build a separate “subagents shell”. Existing navigation/dock should be improved. +- Do not change compaction semantics just to hide UI artifacts. +- Do not break existing `task` tool behavior or parent/child session navigation. + +## UI Stabilization Requirements + +1. Child/subagent sessions must render messages top-to-bottom without oversized prompt/tool blocks making the view feel broken. +2. Long subagent prompt bodies should be visually bounded or summarized when they are orchestration boilerplate. +3. The Subagents widget should prefer active/current-session child sessions: + - include children belonging to the current root session, + - include child sessions referenced by current, non-compacted task tool calls, + - exclude stale child sessions that only appear in compacted/old historical task parts. +4. Responsive layout should degrade gracefully: + - narrow terminals: concise labels and status, + - wider terminals: agent type, description, status, and model/progress where available. +5. Clicking or selecting a subagent keeps existing navigation behavior. + +## Execution Behavior Proposal + +Add a subagent launch mode to task execution. Proposed authoring layers, highest priority first: + +1. Tool call argument, e.g. `mode: "wait" | "background" | "auto"`. +2. Agent config default, e.g. `agent..subagent_mode` or future V2 `agents..subagent.mode`. +3. Global config default, e.g. `subagent_mode` or future V2 `subagents.default_mode`. +4. Runtime fallback: `wait` to preserve current behavior. + +### `wait` + +Matches current behavior: parent creates a child session, waits for the final child output, and inserts the result back into the parent task tool output. + +### `background` + +Parent creates a child session and returns immediately with a durable child session reference. The parent can keep working. UI shows the child as running/needs-input/responded. A later monitor/summarize path can inspect child output and synthesize results. + +### `auto` + +The model decides whether to wait or background based on task size, independence, expected runtime, and whether user flow benefits from parallel work. The tool schema must make the tradeoff explicit so the model can choose safely. + +## Safety / Compatibility + +- Default remains `wait` until background semantics are durable and observable. +- Background children must preserve permission boundaries and inherited deny/external-directory rules. +- Parent session must not lose child evidence on disconnect; retained child references should remain resumable. +- UI must handle missing child messages, disconnected sync, and compacted parent transcript safely. + +## Implementation Checklist + +- [x] Filter Subagents widget entries to current root session and current non-compacted task references. +- [x] Improve child/subagent message rendering for long orchestration prompts and code/tool blocks. +- [x] Add focused layout tests for subagent widget filtering/responsive behavior. +- [x] Add schema/config design for `wait | background | auto` launch mode. +- [ ] Implement background launch only after durable observation/summarization behavior is specified. diff --git a/src/mendcode/packages/opencode/src/acp/agent.ts b/src/mendcode/packages/opencode/src/acp/agent.ts index 35f16ad0..89044c16 100644 --- a/src/mendcode/packages/opencode/src/acp/agent.ts +++ b/src/mendcode/packages/opencode/src/acp/agent.ts @@ -61,6 +61,30 @@ const DEFAULT_VARIANT_VALUE = "default" const log = Log.create({ service: "acp-agent" }) +function smartReplyForPermission(permission: { metadata?: Record }, grant?: "once" | "task") { + const facts = permission.metadata?.actionFacts + const authority = permission.metadata?.authorityContext + const actionFingerprint = + facts && typeof facts === "object" && typeof (facts as { fingerprint?: unknown }).fingerprint === "string" + ? (facts as { fingerprint: string }).fingerprint + : typeof permission.metadata?.smartActionFingerprint === "string" + ? permission.metadata.smartActionFingerprint + : undefined + const smartManaged = permission.metadata?.smartApproval === true + if (!actionFingerprint && !smartManaged) return undefined + const contextRevision = + authority && + typeof authority === "object" && + Number.isSafeInteger((authority as { contextRevision?: unknown }).contextRevision) + ? (authority as { contextRevision: number }).contextRevision + : undefined + return { + ...(actionFingerprint === undefined ? {} : { actionFingerprint }), + ...(contextRevision === undefined ? {} : { contextRevision }), + ...(grant ? { grant } : {}), + } +} + async function getContextLimit( sdk: OpencodeClient, providerID: ProviderID, @@ -256,6 +280,14 @@ export class Agent implements ACPAgent { await this.sdk.permission.reply({ requestID: permission.id, reply: res.outcome.optionId as "once" | "always" | "reject", + smart: smartReplyForPermission( + permission, + res.outcome.optionId === "always" + ? "task" + : res.outcome.optionId === "once" && permission.metadata?.smartApproval === true + ? "once" + : undefined, + ), directory, }) }) diff --git a/src/mendcode/packages/opencode/src/agent/agent.ts b/src/mendcode/packages/opencode/src/agent/agent.ts index 7e5293d9..59b3ea0f 100644 --- a/src/mendcode/packages/opencode/src/agent/agent.ts +++ b/src/mendcode/packages/opencode/src/agent/agent.ts @@ -13,8 +13,9 @@ import PROMPT_EXPLORE from "./prompt/explore.txt" import PROMPT_SUMMARY from "./prompt/summary.txt" import PROMPT_TITLE from "./prompt/title.txt" import { Permission } from "@/permission" -import { mergeDeep, pipe, sortBy, values } from "remeda" +import { mergeDeep } from "remeda" import { Global } from "@mendcode/core/global" +import { AppFileSystem } from "@mendcode/core/filesystem" import path from "path" import { Plugin } from "@/plugin" import { Skill } from "../skill" @@ -81,10 +82,12 @@ export const layer = Layer.effect( Effect.fn("Agent.state")(function* (ctx) { const cfg = yield* config.get() const skillDirs = yield* skill.dirs() + const whitelistedRoots = [Global.Path.tmp, ...skillDirs] const whitelistedDirs = [ Truncate.GLOB, - path.join(Global.Path.tmp, "*"), - ...skillDirs.map((dir) => path.join(dir, "*")), + ...new Set( + whitelistedRoots.flatMap((dir) => [dir, AppFileSystem.resolve(dir)]).map((dir) => path.join(dir, "*")), + ), ] const defaults = Permission.fromConfig({ @@ -287,14 +290,13 @@ export const layer = Layer.effect( const list = Effect.fnUntraced(function* () { const cfg = yield* config.get() - return pipe( - agents, - values(), - sortBy( - [(x) => (cfg.default_agent ? x.name === cfg.default_agent : x.name === "build"), "desc"], - [(x) => x.name, "asc"], - ), - ) + const defaultKey = cfg.default_agent ?? "build" + return Object.entries(agents) + .toSorted( + ([leftKey, left], [rightKey, right]) => + Number(rightKey === defaultKey) - Number(leftKey === defaultKey) || left.name.localeCompare(right.name), + ) + .map(([, agent]) => agent) }) const defaultAgent = Effect.fnUntraced(function* () { @@ -304,14 +306,14 @@ export const layer = Layer.effect( if (!agent) throw new Error(`default agent "${c.default_agent}" not found`) if (agent.mode === "subagent") throw new Error(`default agent "${c.default_agent}" is a subagent`) if (agent.hidden === true) throw new Error(`default agent "${c.default_agent}" is hidden`) - return agent.name + return c.default_agent } - const visible = Object.values(agents).find((a) => a.mode !== "subagent" && a.hidden !== true) + const visible = Object.entries(agents).find(([, agent]) => agent.mode !== "subagent" && agent.hidden !== true) if (!visible) throw new Error( 'no primary visible agent found; configure a primary custom agent with "default_agent" or re-enable agent.build/agent.plan', ) - return visible.name + return visible[0] }) return { diff --git a/src/mendcode/packages/opencode/src/agent/prompt/title.txt b/src/mendcode/packages/opencode/src/agent/prompt/title.txt index 62960b2c..e2ec0a34 100644 --- a/src/mendcode/packages/opencode/src/agent/prompt/title.txt +++ b/src/mendcode/packages/opencode/src/agent/prompt/title.txt @@ -7,12 +7,15 @@ Follow all rules in Use the so you know what a good title looks like. Your output must be: - A single line -- ≤50 characters +- 3 to 5 words +- Prefer fewer words when they remain clear +- Keep it under 50 characters when possible - No explanations - you MUST use the same language as the user message you are summarizing +- Use 3 to 5 words that capture the dominant topic; never write a full sentence - Title must be grammatically correct and read naturally - no word salad - Never include tool names in the title (e.g. "read tool", "bash tool", "edit tool") - Focus on the main topic or question the user needs to retrieve diff --git a/src/mendcode/packages/opencode/src/auth/index.ts b/src/mendcode/packages/opencode/src/auth/index.ts index 4248b94e..f2af6099 100644 --- a/src/mendcode/packages/opencode/src/auth/index.ts +++ b/src/mendcode/packages/opencode/src/auth/index.ts @@ -4,6 +4,7 @@ import { zod } from "@/util/effect-zod" import { NonNegativeInt } from "@/util/schema" import { Global } from "@mendcode/core/global" import { AppFileSystem } from "@mendcode/core/filesystem" +import { EffectFlock } from "@mendcode/core/util/effect-flock" export const OAUTH_DUMMY_KEY = "opencode-oauth-dummy-key" @@ -54,7 +55,12 @@ export const layer = Layer.effect( Service, Effect.gen(function* () { const fsys = yield* AppFileSystem.Service + const flock = yield* EffectFlock.Service const decode = Schema.decodeUnknownOption(Info) + const withMutationLock = (body: Effect.Effect) => + flock.withLock(body, `auth:${file}`).pipe( + Effect.mapError((error) => (error._tag === "AuthError" ? error : fail("Failed to lock auth data")(error))), + ) const all = Effect.fn("Auth.all")(function* () { if (process.env.OPENCODE_AUTH_CONTENT) { @@ -71,28 +77,39 @@ export const layer = Layer.effect( return (yield* all())[providerID] }) - const set = Effect.fn("Auth.set")(function* (key: string, info: Info) { - const norm = key.replace(/\/+$/, "") - const data = yield* all() - if (norm !== key) delete data[key] - delete data[norm + "/"] - yield* fsys - .writeJson(file, { ...data, [norm]: info }, 0o600) - .pipe(Effect.mapError(fail("Failed to write auth data"))) - }) - - const remove = Effect.fn("Auth.remove")(function* (key: string) { - const norm = key.replace(/\/+$/, "") - const data = yield* all() - delete data[key] - delete data[norm] - yield* fsys.writeJson(file, data, 0o600).pipe(Effect.mapError(fail("Failed to write auth data"))) - }) + const set = Effect.fn("Auth.set")((key: string, info: Info) => + withMutationLock( + Effect.gen(function* () { + const norm = key.replace(/\/+$/, "") + const data = yield* all() + if (norm !== key) delete data[key] + delete data[norm + "/"] + yield* fsys + .writeJson(file, { ...data, [norm]: info }, 0o600) + .pipe(Effect.mapError(fail("Failed to write auth data"))) + }), + ), + ) + + const remove = Effect.fn("Auth.remove")((key: string) => + withMutationLock( + Effect.gen(function* () { + const norm = key.replace(/\/+$/, "") + const data = yield* all() + delete data[key] + delete data[norm] + yield* fsys.writeJson(file, data, 0o600).pipe(Effect.mapError(fail("Failed to write auth data"))) + }), + ), + ) return Service.of({ get, all, set, remove }) }), ) -export const defaultLayer = layer.pipe(Layer.provide(AppFileSystem.defaultLayer)) +export const defaultLayer = layer.pipe( + Layer.provide(AppFileSystem.defaultLayer), + Layer.provide(EffectFlock.defaultLayer), +) export * as Auth from "." diff --git a/src/mendcode/packages/opencode/src/bus/global-relay.ts b/src/mendcode/packages/opencode/src/bus/global-relay.ts new file mode 100644 index 00000000..a39a27c5 --- /dev/null +++ b/src/mendcode/packages/opencode/src/bus/global-relay.ts @@ -0,0 +1,200 @@ +import { closeSync, existsSync, mkdirSync, openSync, readSync, statSync } from "fs" +import { appendFile, mkdir, stat, truncate } from "fs/promises" +import path from "path" +import { Global } from "@mendcode/core/global" +import type { GlobalEvent } from "./global" + +type RelayEnvelope = { + source: string + sequence: number + time: number + event: GlobalEvent +} + +const RELAY_INTERVAL_MS = 40 +const RELAY_FLUSH_DELAY_MS = 25 +const RELAY_BATCH_MAX_BYTES = 256 * 1024 +const RELAY_PENDING_MAX_BYTES = 2 * 1024 * 1024 +const DEFAULT_RELAY_MAX_BYTES = 8 * 1024 * 1024 +const SOURCE_ID = `${process.pid}:${Date.now()}:${Math.random().toString(36).slice(2)}` +const RELAY_PATH = process.env.MENDCODE_GLOBAL_EVENT_RELAY_FILE || path.join(Global.Path.state, "global-events.jsonl") + +let sequence = 0 +let offset = 0 +let carry = "" +let started = false +let flushTimer: ReturnType | undefined +let flushPromise: Promise | undefined +let pendingBytes = 0 +const pendingLines: Array<{ data: string; bytes: number }> = [] + +export function globalEventRelayPath() { + return RELAY_PATH +} + +function ensureRelayDir() { + mkdirSync(path.dirname(RELAY_PATH), { recursive: true }) +} + +function shouldRelay(event: GlobalEvent) { + const type = event.payload?.type + return type !== "server.connected" && type !== "server.heartbeat" && type !== "message.part.delta" +} + +function relayMaxBytes() { + const value = Number(process.env.MENDCODE_GLOBAL_EVENT_RELAY_MAX_BYTES) + return Number.isFinite(value) && value > 0 ? Math.floor(value) : DEFAULT_RELAY_MAX_BYTES +} + +export function appendGlobalEvent(event: GlobalEvent) { + if (!shouldRelay(event)) return + try { + const maxBytes = relayMaxBytes() + const envelope: RelayEnvelope = { + source: SOURCE_ID, + sequence: ++sequence, + time: Date.now(), + event, + } + const line = JSON.stringify(envelope) + "\n" + const bytes = Buffer.byteLength(line) + if (bytes > maxBytes || bytes > RELAY_PENDING_MAX_BYTES) return + + // GlobalBus.emit runs on the shared server event loop. Queue the disk write + // so event delivery and provider/tool work never wait on JSONL persistence. + // Relay delivery is best-effort, so discard the oldest backlog when the + // filesystem cannot keep up instead of retaining events without a bound. + while (pendingLines.length > 0 && pendingBytes + bytes > RELAY_PENDING_MAX_BYTES) { + const dropped = pendingLines.shift() + if (dropped) pendingBytes -= dropped.bytes + } + if (pendingBytes + bytes > RELAY_PENDING_MAX_BYTES) return + pendingLines.push({ data: line, bytes }) + pendingBytes += bytes + scheduleFlush() + } catch { + // Relay is best-effort; in-process subscribers already received the event. + } +} + +function scheduleFlush() { + if (flushTimer !== undefined || flushPromise !== undefined) return + flushTimer = setTimeout(() => { + flushTimer = undefined + void flushGlobalEventRelay() + }, RELAY_FLUSH_DELAY_MS) + flushTimer.unref?.() +} + +async function writeBatch(lines: Array<{ data: string; bytes: number }>, maxBytes: number) { + let batch = "" + let batchBytes = 0 + + const flushBatch = async () => { + if (!batch) return + await mkdir(path.dirname(RELAY_PATH), { recursive: true }) + const currentSize = await stat(RELAY_PATH).then((result) => result.size).catch(() => 0) + if (currentSize >= maxBytes || currentSize + batchBytes > maxBytes) { + await truncate(RELAY_PATH, 0) + offset = 0 + carry = "" + } + await appendFile(RELAY_PATH, batch, { mode: 0o600 }) + batch = "" + batchBytes = 0 + } + + for (const line of lines) { + if (line.bytes > maxBytes) continue + if (batchBytes > 0 && batchBytes + line.bytes > Math.min(maxBytes, RELAY_BATCH_MAX_BYTES)) { + await flushBatch() + } + batch += line.data + batchBytes += line.bytes + } + await flushBatch() +} + +function flushQueuedEvents() { + if (flushPromise !== undefined) return flushPromise + if (pendingLines.length === 0) return Promise.resolve() + + const lines = pendingLines.splice(0) + pendingBytes = 0 + flushPromise = writeBatch(lines, relayMaxBytes()) + .catch(() => { + // Relay is best-effort; in-process subscribers already received events. + }) + .finally(() => { + flushPromise = undefined + if (pendingLines.length > 0) scheduleFlush() + }) + return flushPromise +} + +/** Flush queued relay writes for deterministic tests and graceful shutdown. */ +export function flushGlobalEventRelay() { + if (flushTimer !== undefined) { + clearTimeout(flushTimer) + flushTimer = undefined + } + return flushQueuedEvents() +} + +function readAvailable(emit: (event: GlobalEvent) => void) { + if (!existsSync(RELAY_PATH)) return + let size = 0 + try { + size = statSync(RELAY_PATH).size + } catch { + return + } + if (size < offset) { + offset = 0 + carry = "" + } + if (size === offset) return + + let fd: number | undefined + try { + fd = openSync(RELAY_PATH, "r") + while (offset < size) { + const length = Math.min(size - offset, 256 * 1024) + const buffer = Buffer.allocUnsafe(length) + const read = readSync(fd, buffer, 0, length, offset) + if (read <= 0) break + offset += read + const chunk = carry + buffer.subarray(0, read).toString("utf8") + const lines = chunk.split("\n") + carry = lines.pop() ?? "" + for (const line of lines) { + if (!line) continue + try { + const envelope = JSON.parse(line) as RelayEnvelope + if (envelope.source === SOURCE_ID) continue + if (!envelope.event?.payload?.type) continue + emit(envelope.event) + } catch { + // Ignore a malformed or partial writer line and keep tailing. + } + } + } + } catch { + return + } finally { + if (fd !== undefined) closeSync(fd) + } +} + +export function startGlobalEventRelay(emit: (event: GlobalEvent) => void) { + if (started) return + started = true + try { + ensureRelayDir() + offset = existsSync(RELAY_PATH) ? statSync(RELAY_PATH).size : 0 + } catch { + offset = 0 + } + const timer = setInterval(() => readAvailable(emit), RELAY_INTERVAL_MS) + timer.unref?.() +} diff --git a/src/mendcode/packages/opencode/src/bus/global.ts b/src/mendcode/packages/opencode/src/bus/global.ts index 3cfd4536..0d073670 100644 --- a/src/mendcode/packages/opencode/src/bus/global.ts +++ b/src/mendcode/packages/opencode/src/bus/global.ts @@ -1,5 +1,6 @@ import { EventEmitter } from "events" import { Identifier } from "@/id/id" +import { appendGlobalEvent, startGlobalEventRelay } from "./global-relay" export type GlobalEvent = { directory?: string @@ -8,15 +9,37 @@ export type GlobalEvent = { payload: any } +export function matchesGlobalEventDirectory(event: GlobalEvent, directory?: string) { + if (!directory) return true + return !event.directory || event.directory === "global" || event.directory === directory +} + class GlobalBusEmitter extends EventEmitter<{ event: [GlobalEvent] }> { + #relaying = false + + constructor() { + super() + startGlobalEventRelay((event) => this.emitFromRelay(event)) + } + override emit(eventName: "event", event: GlobalEvent): boolean { if (event.payload && typeof event.payload === "object" && !("id" in event.payload)) { event.payload.id = event.payload.syncEvent?.id ?? Identifier.create("evt", "ascending") } + if (!this.#relaying) appendGlobalEvent(event) return super.emit(eventName, event) } + + emitFromRelay(event: GlobalEvent) { + this.#relaying = true + try { + return this.emit("event", event) + } finally { + this.#relaying = false + } + } } export const GlobalBus = new GlobalBusEmitter() diff --git a/src/mendcode/packages/opencode/src/bus/index.ts b/src/mendcode/packages/opencode/src/bus/index.ts index 7ec2a46b..653cf2c1 100644 --- a/src/mendcode/packages/opencode/src/bus/index.ts +++ b/src/mendcode/packages/opencode/src/bus/index.ts @@ -29,6 +29,11 @@ type State = { typed: Map> } +// Event producers must slow down when a subscriber stops consuming. An +// unbounded PubSub turns a stalled SSE/TUI client into a process-wide memory +// leak because every tool delta is retained until that client catches up. +export const INTERNAL_EVENT_BUFFER_CAPACITY = 2048 + export interface Interface { readonly publish: ( def: D, @@ -51,7 +56,10 @@ export const layer = Layer.effect( Effect.gen(function* () { const state = yield* InstanceState.make( Effect.fn("Bus.state")(function* (ctx) { - const wildcard = yield* PubSub.unbounded() + // Preserve delivery semantics while bounding memory. Publishers apply + // backpressure when a subscriber is slow; terminal events are never + // silently dropped as they would be with a dropping/sliding buffer. + const wildcard = yield* PubSub.bounded(INTERNAL_EVENT_BUFFER_CAPACITY) const typed = new Map>() yield* Effect.addFinalizer(() => @@ -77,7 +85,7 @@ export const layer = Layer.effect( return Effect.gen(function* () { let ps = state.typed.get(def.type) if (!ps) { - ps = yield* PubSub.unbounded() + ps = yield* PubSub.bounded(INTERNAL_EVENT_BUFFER_CAPACITY) state.typed.set(def.type, ps) } return ps as unknown as PubSub.PubSub> @@ -88,7 +96,7 @@ export const layer = Layer.effect( return Effect.gen(function* () { const s = yield* InstanceState.get(state) const payload: Payload = { id: options?.id ?? createID(), type: def.type, properties } - log.info("publishing", { type: def.type }) + if (def.type !== "message.part.delta") log.debug("publishing", { type: def.type }) const ps = s.typed.get(def.type) if (ps) yield* PubSub.publish(ps, payload) diff --git a/src/mendcode/packages/opencode/src/cli/automation.ts b/src/mendcode/packages/opencode/src/cli/automation.ts new file mode 100644 index 00000000..a8cb5cfc --- /dev/null +++ b/src/mendcode/packages/opencode/src/cli/automation.ts @@ -0,0 +1,64 @@ +import { EOL } from "os" + +export const AUTOMATION_PROTOCOL = "mendcode.cli.v1" as const + +export type AutomationKind = "event" | "result" | "error" + +export type AutomationEnvelope = { + protocol: typeof AUTOMATION_PROTOCOL + kind: AutomationKind + event: string + eventID: string + timestamp: number + sessionID?: string + data: T +} + +let sequence = 0 + +function nextEventID(timestamp: number) { + sequence += 1 + return `evt_${timestamp.toString(36)}_${sequence.toString(36)}` +} + +const sensitiveKey = + /(?:api[_-]?key|authorization|credential|password|secret|(?:access|refresh|id)?[_-]?token(?:$|[_-])|bearer|private[_-]?key|cookie)/i + +export function redactAutomationData(value: unknown, key?: string): unknown { + if (key && sensitiveKey.test(key)) return "[REDACTED]" + if (Array.isArray(value)) return value.map((item) => redactAutomationData(item)) + if (!value || typeof value !== "object") return value + return Object.fromEntries(Object.entries(value).map(([name, item]) => [name, redactAutomationData(item, name)])) +} + +export function automationEnvelope(input: { + kind: AutomationKind + event: string + data: T + sessionID?: string + timestamp?: number + eventID?: string +}): AutomationEnvelope { + const timestamp = input.timestamp ?? Date.now() + return { + protocol: AUTOMATION_PROTOCOL, + kind: input.kind, + event: input.event, + eventID: input.eventID ?? nextEventID(timestamp), + timestamp, + ...(input.sessionID ? { sessionID: input.sessionID } : {}), + data: redactAutomationData(input.data) as T, + } +} + +export function writeAutomationEnvelope(input: Parameters>[0]) { + process.stdout.write(JSON.stringify(automationEnvelope(input)) + EOL) +} + +export function automationJSONRequested(args: readonly string[]) { + return args.some( + (arg, index) => arg === "--json" || arg === "--format=json" || (arg === "--format" && args[index + 1] === "json"), + ) +} + +export * as Automation from "./automation" diff --git a/src/mendcode/packages/opencode/src/cli/cmd/cache.ts b/src/mendcode/packages/opencode/src/cli/cmd/cache.ts new file mode 100644 index 00000000..85242d35 --- /dev/null +++ b/src/mendcode/packages/opencode/src/cli/cmd/cache.ts @@ -0,0 +1,138 @@ +import type { Argv } from "yargs" +import { Effect } from "effect" +import { Config } from "@/config/config" +import { ConfigCache, type CacheMutation } from "@/config/cache" +import { Instance } from "@/project/instance" +import { cmd } from "./cmd" +import { effectCmd, fail } from "../effect-cmd" +import { UI } from "../ui" + +type CacheArgs = { + global?: boolean + provider?: string + model?: string + session?: string + projectPath?: string + scope?: ConfigCache.Scope +} + +function cacheOptions(yargs: Argv) { + return yargs + .option("global", { + type: "boolean", + default: false, + describe: "write the global config instead of the current project config", + }) + .option("provider", { + type: "string", + describe: "provider ID to target", + }) + .option("model", { + type: "string", + describe: "exact model ID to target; requires --provider", + }) + .option("session", { + type: "string", + describe: "session ID to include or exclude", + }) + .option("project-path", { + type: "string", + describe: "absolute or relative project path to target in global config", + }) + .option("scope", { + type: "string", + choices: ["session", "project"] as const, + describe: "cache-key scope for an enabled provider/project policy", + }) +} + +function mutationFromArgs(args: CacheArgs, action: CacheMutation["action"]): CacheMutation { + if (args.projectPath && !args.global) throw new Error("--project-path requires --global") + return { + action, + providerID: args.provider, + modelID: args.model, + sessionID: args.session, + projectPath: args.projectPath, + scope: args.scope, + } +} + +export const CacheStatusCommand = effectCmd({ + command: "status", + describe: "show prompt-cache policy and configured scopes", + builder: (yargs) => + yargs + .option("format", { + type: "string", + choices: ["text", "json"], + default: "text", + describe: "output format", + }) + .option("json", { + type: "boolean", + default: false, + describe: "output JSON", + }), + handler: Effect.fn("Cli.cache.status")(function* (args: { format?: string; json?: boolean }) { + const config = yield* Config.Service + const current = yield* config.get() + const selection = ConfigCache.selectCacheConfig({ + config: current.cache, + projectScope: Instance.directory, + }) + const status = { + project: Instance.directory, + mode: selection.mode, + scope: selection.scope, + configured: current.cache ?? null, + activeKeeper: false, + note: "MendCode only uses passive provider cache controls; no keepalive requests are scheduled.", + } + if (args.json || args.format === "json") { + UI.println(JSON.stringify(status, null, 2)) + return + } + UI.println(`Prompt cache: ${status.mode}`) + UI.println(`Project: ${status.project}`) + UI.println("Active keeper: disabled") + if (!current.cache) UI.println("Configuration: legacy provider behavior (no cache override)") + else UI.println(`Configuration: ${JSON.stringify(current.cache)}`) + }), +}) + +const CacheMutationCommand = (action: CacheMutation["action"]) => + effectCmd({ + command: action, + aliases: action === "enable" ? ["on"] : ["off"], + describe: `${action === "enable" ? "enable" : "disable"} passive prompt caching for a scope`, + instance: (args: CacheArgs) => !args.global, + builder: cacheOptions, + handler: Effect.fn(`Cli.cache.${action}`)(function* (args: CacheArgs) { + const config = yield* Config.Service + const current = args.global ? yield* config.getGlobal() : yield* config.get() + let next: ConfigCache.Info + try { + next = ConfigCache.updateCacheConfig(current.cache, mutationFromArgs(args, action)) + } catch (error) { + return yield* fail(error instanceof Error ? error.message : String(error)) + } + + if (args.global) yield* config.updateGlobal({ cache: next }) + else yield* config.update({ cache: next }) + + UI.println(`${action === "enable" ? "Enabled" : "Disabled"} prompt cache policy.`) + UI.println(JSON.stringify(next, null, 2)) + }), + }) + +export const CacheEnableCommand = CacheMutationCommand("enable") +export const CacheDisableCommand = CacheMutationCommand("disable") + +export const CacheCommand = cmd({ + command: "cache", + describe: "control passive provider prompt caching", + builder: (yargs) => + yargs.command(CacheStatusCommand).command(CacheEnableCommand).command(CacheDisableCommand).demandCommand(), + async handler() {}, +}) diff --git a/src/mendcode/packages/opencode/src/cli/cmd/context.ts b/src/mendcode/packages/opencode/src/cli/cmd/context.ts new file mode 100644 index 00000000..b8ddf2bd --- /dev/null +++ b/src/mendcode/packages/opencode/src/cli/cmd/context.ts @@ -0,0 +1,44 @@ +import { cmd } from "./cmd" +import { withSharedClient } from "../shared-client" +import { contextReport } from "@/session/context-profile" +import type { MessageV2 } from "@/session/message-v2" +import { SessionID } from "@/session/schema" + +export const ContextCommand = cmd({ + command: "context ", + describe: "inspect recent context estimates, cache usage and request timing", + builder: (yargs) => yargs + .positional("sessionID", { type: "string", demandOption: true }) + .option("limit", { type: "number", default: 20, describe: "recent messages to inspect (1–100)" }) + .option("json", { type: "boolean", default: false, describe: "print the structured context report" }), + handler: async (args) => { + const id = SessionID.make(args.sessionID) + if (!Number.isInteger(args.limit) || args.limit < 1 || args.limit > 100) throw new Error("limit must be an integer from 1 to 100") + const report = await withSharedClient(process.cwd(), async (connection) => { + const url = new URL(`/session/${encodeURIComponent(id)}/message`, connection.url) + url.searchParams.set("limit", String(args.limit)) + url.searchParams.set("view", "tui") + url.searchParams.set("partsLimit", "100") + const response = await fetch(url, { headers: connection.headers, signal: AbortSignal.timeout(30_000) }) + if (!response.ok) throw new Error(`Context report failed (HTTP ${response.status})`) + return contextReport(await response.json() as MessageV2.WithParts[]) + }) + if (args.json) { + console.log(JSON.stringify(report, null, 2)) + return + } + console.log("Context and cache — recent messages") + if (!report.requests.length) { + console.log("No request profiles in this page. Profiles are recorded by the updated runtime on completed steps.") + return + } + for (const request of report.requests) { + const p = request.profile + const t = p.estimatedTokens + console.log(`\n${request.messageID} ${request.providerID}/${request.modelID}`) + console.log(`Estimated tokens: instructions ${t.instructions}, memory ${t.memory}, history ${t.history}, tool results ${t.toolResults}, schemas ${t.toolSchemas}, media ${t.media}; total ${t.total}`) + console.log(`Provider input: ${request.inputTokens ?? "unavailable"}; cache read: ${request.cachedTokens ?? "unavailable"}; cache write: ${request.cacheWriteTokens ?? "unavailable"}; hit rate: ${request.cacheHitRate === null ? "unavailable" : `${(request.cacheHitRate * 100).toFixed(1)}%`}`) + console.log(`First token: ${p.firstTokenMs == null ? "unavailable" : `${p.firstTokenMs} ms`}; request: ${p.durationMs ?? "unavailable"} ms; tools: ${p.toolCount}; images: ${p.imageCount}`) + } + }, +}) diff --git a/src/mendcode/packages/opencode/src/cli/cmd/db.ts b/src/mendcode/packages/opencode/src/cli/cmd/db.ts index 23bbeb7e..d0ccf187 100644 --- a/src/mendcode/packages/opencode/src/cli/cmd/db.ts +++ b/src/mendcode/packages/opencode/src/cli/cmd/db.ts @@ -94,12 +94,15 @@ const MigrateCommand = cmd({ if (tty) process.stderr.write("\n") if (tty) process.stderr.write("\x1b[?25h") else process.stderr.write(`sqlite-migration:done${EOL}`) - UI.println( - `Migration complete: ${stats.projects} projects, ${stats.sessions} sessions, ${stats.messages} messages`, - ) - await JsonMigration.writeJsonStorageMigrationDoneMarker() - if (stats.errors.length > 0) { - UI.println(`${stats.errors.length} errors occurred during migration`) + if (JsonMigration.jsonStorageMigrationSucceeded(stats)) { + UI.println( + `Migration complete: ${stats.projects} projects, ${stats.sessions} sessions, ${stats.messages} messages`, + ) + await JsonMigration.writeJsonStorageMigrationDoneMarker() + } else { + UI.error(`Migration incomplete: ${stats.errors.length} errors occurred; the next run will retry`) + for (const error of stats.errors.slice(0, 10)) UI.error(error) + process.exitCode = 1 } } catch (err) { if (tty) process.stderr.write("\x1b[?25h") diff --git a/src/mendcode/packages/opencode/src/cli/cmd/debug/agent.ts b/src/mendcode/packages/opencode/src/cli/cmd/debug/agent.ts index 1a3f7939..c1b121c0 100644 --- a/src/mendcode/packages/opencode/src/cli/cmd/debug/agent.ts +++ b/src/mendcode/packages/opencode/src/cli/cmd/debug/agent.ts @@ -29,7 +29,7 @@ export const AgentCommand = effectCmd({ }) .option("params", { type: "string", - description: "Tool params as JSON or a JS object literal", + description: "Tool params as JSON", }), handler: Effect.fn("Cli.debug.agent")(function* (args) { const ctx = yield* InstanceRef @@ -105,14 +105,7 @@ function parseToolParams(input?: string) { try { return JSON.parse(trimmed) } catch (jsonError) { - try { - return new Function(`return (${trimmed})`)() - } catch (evalError) { - throw new Error( - `Failed to parse --params. Use JSON or a JS object literal. JSON error: ${jsonError}. Eval error: ${evalError}.`, - { cause: evalError }, - ) - } + throw new Error(`Failed to parse --params. Use JSON. JSON error: ${jsonError}.`, { cause: jsonError }) } }) diff --git a/src/mendcode/packages/opencode/src/cli/cmd/debug/index.ts b/src/mendcode/packages/opencode/src/cli/cmd/debug/index.ts index 31f55b62..55b5b87b 100644 --- a/src/mendcode/packages/opencode/src/cli/cmd/debug/index.ts +++ b/src/mendcode/packages/opencode/src/cli/cmd/debug/index.ts @@ -1,7 +1,7 @@ import { Global } from "@mendcode/core/global" -import { InstallationVersion } from "@mendcode/core/installation/version" import { Flag } from "@mendcode/core/flag/flag" import os from "os" +import { Installation } from "@/installation" import { Duration, Effect } from "effect" import { Config } from "@/config/config" import { ConfigPlugin } from "@/config/plugin" @@ -56,7 +56,8 @@ const InfoCommand = effectCmd({ : undefined const terminal = [termProgram, process.env.TERM].filter((item): item is string => Boolean(item)).join(" / ") - console.log(`MendCode runtime version: ${InstallationVersion}`) + console.log(`MendCode runtime version: ${Installation.displayVersion()}`) + console.log(`channel: ${Installation.channel()}`) console.log(`os: ${os.type()} ${os.release()} ${os.arch()}`) console.log(`terminal: ${terminal || "unknown"}`) console.log("plugins:") diff --git a/src/mendcode/packages/opencode/src/cli/cmd/github.ts b/src/mendcode/packages/opencode/src/cli/cmd/github.ts index 709e1269..f150b13c 100644 --- a/src/mendcode/packages/opencode/src/cli/cmd/github.ts +++ b/src/mendcode/packages/opencode/src/cli/cmd/github.ts @@ -1,5 +1,5 @@ import path from "path" -import { exec } from "child_process" +import { spawn } from "child_process" import { Filesystem } from "@/util/filesystem" import * as prompts from "@clack/prompts" import { map, pipe, sortBy, values } from "remeda" @@ -342,15 +342,26 @@ export const GithubInstallCommand = effectCmd({ // Open browser const url = "https://github.com/apps/opencode-agent" - const command = + const opener = process.platform === "darwin" - ? `open "${url}"` + ? { command: "open", args: [url] } : process.platform === "win32" - ? `start "" "${url}"` - : `xdg-open "${url}"` + ? { command: "cmd", args: ["/c", "start", "", url] } + : { command: "xdg-open", args: [url] } - exec(command, (error) => { - if (error) { + const child = spawn(opener.command, opener.args, { + detached: true, + stdio: "ignore", + windowsHide: true, + }) + child.on("error", () => { + prompts.log.warn(`Could not open browser. Please visit: ${url}`) + }) + child.on("spawn", () => { + child.unref() + }) + child.on("exit", (code) => { + if (code && code !== 0) { prompts.log.warn(`Could not open browser. Please visit: ${url}`) } }) diff --git a/src/mendcode/packages/opencode/src/cli/cmd/global-layout.ts b/src/mendcode/packages/opencode/src/cli/cmd/global-layout.ts index c35f117c..be2187b8 100644 --- a/src/mendcode/packages/opencode/src/cli/cmd/global-layout.ts +++ b/src/mendcode/packages/opencode/src/cli/cmd/global-layout.ts @@ -25,7 +25,7 @@ const MigrateCommand = cmd({ return } UI.println(`Copied: ${result.copiedRoots.join(", ")}`) - UI.println("Migration marker written. Restart mend-runtime so Global.Path uses the mend segment.") + UI.println("Migration marker written. Restart mendcode so Global.Path uses the mend segment.") } catch (e) { UI.error(errorMessage(e)) process.exit(1) diff --git a/src/mendcode/packages/opencode/src/cli/cmd/mcp.ts b/src/mendcode/packages/opencode/src/cli/cmd/mcp.ts index 161c5dd1..84a13fa7 100644 --- a/src/mendcode/packages/opencode/src/cli/cmd/mcp.ts +++ b/src/mendcode/packages/opencode/src/cli/cmd/mcp.ts @@ -119,7 +119,7 @@ export const McpListCommand = effectCmd({ if (servers.length === 0) { prompts.log.warn("No MCP servers configured") - prompts.outro("Add servers with: mend-runtime mcp add") + prompts.outro("Add servers with: mendcode mcp add") return } diff --git a/src/mendcode/packages/opencode/src/cli/cmd/plug.ts b/src/mendcode/packages/opencode/src/cli/cmd/plug.ts index 9e78da15..c939db76 100644 --- a/src/mendcode/packages/opencode/src/cli/cmd/plug.ts +++ b/src/mendcode/packages/opencode/src/cli/cmd/plug.ts @@ -28,7 +28,7 @@ export type PlugDeps = { readText: (file: string) => Promise write: (file: string, text: string) => Promise exists: (file: string) => Promise - files: (dir: string, name: "opencode" | "tui") => string[] + files: (dir: string, name: "mendcode" | "tui") => string[] global: string } diff --git a/src/mendcode/packages/opencode/src/cli/cmd/pr.ts b/src/mendcode/packages/opencode/src/cli/cmd/pr.ts index da7ef577..05a77ec7 100644 --- a/src/mendcode/packages/opencode/src/cli/cmd/pr.ts +++ b/src/mendcode/packages/opencode/src/cli/cmd/pr.ts @@ -105,7 +105,7 @@ export const PrCommand = effectCmd({ const mendcodeArgs = sessionId ? ["-s", sessionId] : [] const code = yield* Effect.promise( () => - Process.spawn(["mend-runtime", ...mendcodeArgs], { + Process.spawn(["mendcode", ...mendcodeArgs], { stdin: "inherit", stdout: "inherit", stderr: "inherit", diff --git a/src/mendcode/packages/opencode/src/cli/cmd/run.ts b/src/mendcode/packages/opencode/src/cli/cmd/run.ts index 490e26fa..0020aea5 100644 --- a/src/mendcode/packages/opencode/src/cli/cmd/run.ts +++ b/src/mendcode/packages/opencode/src/cli/cmd/run.ts @@ -4,13 +4,13 @@ import { pathToFileURL } from "url" import { Effect } from "effect" import { UI } from "../ui" import { effectCmd } from "../effect-cmd" +import { cmd } from "./cmd" import { Flag } from "@mendcode/core/flag/flag" import { ServerAuth } from "@/server/auth" import { EOL } from "os" import { Filesystem } from "@/util/filesystem" import { createOpencodeClient, type OpencodeClient, type ToolPart } from "@mendcode/sdk/v2" import { Server } from "../../server/server" -import { Provider } from "@/provider/provider" import { Agent } from "../../agent/agent" import { Permission } from "../../permission" import { Tool } from "@/tool/tool" @@ -27,6 +27,12 @@ import { ShellTool } from "../../tool/shell" import { ShellID } from "../../tool/shell/id" import { TodoWriteTool } from "../../tool/todo" import { Locale } from "@/util/locale" +import { Session } from "@/session/session" +import { SessionID } from "@/session/schema" +import { resolveRuntimeModel, type RuntimeModelResolution } from "../model-selection" +import { writeAutomationEnvelope } from "../automation" +import { AppRuntime } from "@/effect/app-runtime" +import { withSharedClient } from "../shared-client" type ToolProps = { input: Tool.InferParameters @@ -203,15 +209,9 @@ function normalizePath(input?: string) { return input } -export const RunCommand = effectCmd({ +const ClientRunCommand = cmd({ command: "run [message..]", describe: "run MendCode runtime with a message", - // --attach connects to a remote server (no local instance needed); the - // default path runs an in-process server and needs the project instance. - instance: (args) => !args.attach, - // For --dir without --attach, load instance for the resolved target dir. - // The handler also chdirs (preserving the legacy order: chdir → file resolution). - directory: (args) => (args.dir && !args.attach ? path.resolve(process.cwd(), args.dir) : process.cwd()), builder: (yargs: Argv) => yargs .positional("message", { @@ -303,313 +303,292 @@ export const RunCommand = effectCmd({ describe: "auto-approve permissions that are not explicitly denied (dangerous!)", default: false, }), - handler: Effect.fn("Cli.run")(function* (args) { - const agentSvc = yield* Agent.Service - yield* Effect.promise(async () => { - let message = [...args.message, ...(args["--"] || [])] - .map((arg) => (arg.includes(" ") ? `"${arg.replace(/"/g, '\\"')}"` : arg)) - .join(" ") - - const directory = (() => { - if (!args.dir) return undefined - if (args.attach) return args.dir - try { - process.chdir(args.dir) - return process.cwd() - } catch { - UI.error("Failed to change directory to " + args.dir) - process.exit(1) - } - })() - - const files: { type: "file"; url: string; filename: string; mime: string }[] = [] - if (args.file) { - const list = Array.isArray(args.file) ? args.file : [args.file] - - for (const filePath of list) { - const resolvedPath = path.resolve(process.cwd(), filePath) - if (!(await Filesystem.exists(resolvedPath))) { - UI.error(`File not found: ${filePath}`) - process.exit(1) - } + handler: async (args) => { + let message = [...args.message, ...(args["--"] || [])] + .map((arg) => (arg.includes(" ") ? JSON.stringify(arg) : arg)) + .join(" ") + + const directory = (() => { + if (!args.dir) return undefined + if (args.attach) return args.dir + try { + process.chdir(args.dir) + return process.cwd() + } catch { + UI.error("Failed to change directory to " + args.dir) + process.exit(1) + } + })() - const mime = (await Filesystem.isDir(resolvedPath)) ? "application/x-directory" : "text/plain" + const files: { type: "file"; url: string; filename: string; mime: string }[] = [] + if (args.file) { + const list = Array.isArray(args.file) ? args.file : [args.file] - files.push({ - type: "file", - url: pathToFileURL(resolvedPath).href, - filename: path.basename(resolvedPath), - mime, - }) + for (const filePath of list) { + const resolvedPath = path.resolve(process.cwd(), filePath) + if (!(await Filesystem.exists(resolvedPath))) { + UI.error(`File not found: ${filePath}`) + process.exit(1) } - } - if (!process.stdin.isTTY) message += "\n" + (await Bun.stdin.text()) + const mime = (await Filesystem.isDir(resolvedPath)) ? "application/x-directory" : "text/plain" - if (message.trim().length === 0 && !args.command) { - UI.error("You must provide a message or a command") - process.exit(1) + files.push({ + type: "file", + url: pathToFileURL(resolvedPath).href, + filename: path.basename(resolvedPath), + mime, + }) } - - if (args.fork && !args.continue && !args.session) { - UI.error("--fork requires --continue or --session") - process.exit(1) + } + + if (!process.stdin.isTTY) message += "\n" + (await Bun.stdin.text()) + + if (message.trim().length === 0 && !args.command) { + UI.error("You must provide a message or a command") + process.exit(1) + } + + if (args.fork && !args.continue && !args.session) { + UI.error("--fork requires --continue or --session") + process.exit(1) + } + + const rules: Permission.Ruleset = [ + { + permission: "question", + action: "deny", + pattern: "*", + }, + { + permission: "plan_enter", + action: "deny", + pattern: "*", + }, + { + permission: "plan_exit", + action: "deny", + pattern: "*", + }, + ] + + function title() { + if (args.title === undefined) return + if (args.title !== "") return args.title + return message.slice(0, 50) + (message.length > 50 ? "..." : "") + } + + async function session(sdk: OpencodeClient) { + const baseID = args.continue ? (await sdk.session.list()).data?.find((s) => !s.parentID)?.id : args.session + + if (baseID && args.fork) { + const forked = await sdk.session.fork({ sessionID: baseID }) + return forked.data?.id } - const rules: Permission.Ruleset = [ - { - permission: "question", - action: "deny", - pattern: "*", - }, - { - permission: "plan_enter", - action: "deny", - pattern: "*", - }, - { - permission: "plan_exit", - action: "deny", - pattern: "*", - }, - ] - - function title() { - if (args.title === undefined) return - if (args.title !== "") return args.title - return message.slice(0, 50) + (message.length > 50 ? "..." : "") - } + if (baseID) return baseID - async function session(sdk: OpencodeClient) { - const baseID = args.continue ? (await sdk.session.list()).data?.find((s) => !s.parentID)?.id : args.session + const name = title() + const result = await sdk.session.create({ title: name, permission: rules }) + return result.data?.id + } - if (baseID && args.fork) { - const forked = await sdk.session.fork({ sessionID: baseID }) - return forked.data?.id + async function share(sdk: OpencodeClient, sessionID: string) { + const cfg = await sdk.config.get() + if (!cfg.data) return + if (cfg.data.share !== "auto" && !Flag.OPENCODE_AUTO_SHARE && !args.share) return + const res = await sdk.session.share({ sessionID }).catch((error) => { + if (error instanceof Error && error.message.includes("disabled")) { + UI.println(UI.Style.TEXT_DANGER_BOLD + "! " + error.message) } - - if (baseID) return baseID - - const name = title() - const result = await sdk.session.create({ title: name, permission: rules }) - return result.data?.id + return { error } + }) + if (!res.error && "data" in res && res.data?.share?.url) { + UI.println(UI.Style.TEXT_INFO_BOLD + "~ " + res.data.share.url) } + } - async function share(sdk: OpencodeClient, sessionID: string) { - const cfg = await sdk.config.get() - if (!cfg.data) return - if (cfg.data.share !== "auto" && !Flag.OPENCODE_AUTO_SHARE && !args.share) return - const res = await sdk.session.share({ sessionID }).catch((error) => { - if (error instanceof Error && error.message.includes("disabled")) { - UI.println(UI.Style.TEXT_DANGER_BOLD + "! " + error.message) - } - return { error } - }) - if (!res.error && "data" in res && res.data?.share?.url) { - UI.println(UI.Style.TEXT_INFO_BOLD + "~ " + res.data.share.url) + async function execute(sdk: OpencodeClient) { + function tool(part: ToolPart) { + try { + if (part.tool === ShellID.ToolID) return shell(props(part)) + if (part.tool === "glob") return glob(props(part)) + if (part.tool === "grep") return grep(props(part)) + if (part.tool === "read") return read(props(part)) + if (part.tool === "write") return write(props(part)) + if (part.tool === "webfetch") return webfetch(props(part)) + if (part.tool === "edit") return edit(props(part)) + if (part.tool === "websearch") return websearch(props(part)) + if (part.tool === "task") return task(props(part)) + if (part.tool === "todowrite") return todo(props(part)) + if (part.tool === "skill") return skill(props(part)) + return fallback(part) + } catch { + return fallback(part) } } - async function execute(sdk: OpencodeClient) { - function tool(part: ToolPart) { - try { - if (part.tool === ShellID.ToolID) return shell(props(part)) - if (part.tool === "glob") return glob(props(part)) - if (part.tool === "grep") return grep(props(part)) - if (part.tool === "read") return read(props(part)) - if (part.tool === "write") return write(props(part)) - if (part.tool === "webfetch") return webfetch(props(part)) - if (part.tool === "edit") return edit(props(part)) - if (part.tool === "websearch") return websearch(props(part)) - if (part.tool === "task") return task(props(part)) - if (part.tool === "todowrite") return todo(props(part)) - if (part.tool === "skill") return skill(props(part)) - return fallback(part) - } catch { - return fallback(part) - } + function emit(type: string, data: Record) { + if (args.format === "json") { + writeAutomationEnvelope({ kind: "event", event: type, sessionID, data }) + return true } + return false + } - function emit(type: string, data: Record) { - if (args.format === "json") { - process.stdout.write(JSON.stringify({ type, timestamp: Date.now(), sessionID, ...data }) + EOL) - return true + const eventController = new AbortController() + const events = await sdk.event.subscribe(undefined, { signal: eventController.signal }) + let error: string | undefined + + async function loop() { + const toggles = new Map() + + for await (const event of events.stream) { + if ( + event.type === "message.updated" && + event.properties.info.sessionID === sessionID && + event.properties.info.role === "assistant" && + args.format !== "json" && + toggles.get("start") !== true + ) { + UI.empty() + UI.println(`> ${event.properties.info.agent} · ${event.properties.info.modelID}`) + UI.empty() + toggles.set("start", true) } - return false - } - const events = await sdk.event.subscribe() - let error: string | undefined + if (event.type === "message.part.updated") { + const part = event.properties.part + if (part.sessionID !== sessionID) continue - async function loop() { - const toggles = new Map() + if (part.type === "tool" && (part.state.status === "completed" || part.state.status === "error")) { + if (emit("tool_use", { part })) continue + if (part.state.status === "completed") { + tool(part) + continue + } + inline({ + icon: "✗", + title: `${part.tool} failed`, + }) + UI.error(part.state.error) + } - for await (const event of events.stream) { if ( - event.type === "message.updated" && - event.properties.info.role === "assistant" && - args.format !== "json" && - toggles.get("start") !== true + part.type === "tool" && + part.tool === "task" && + part.state.status === "running" && + args.format !== "json" ) { - UI.empty() - UI.println(`> ${event.properties.info.agent} · ${event.properties.info.modelID}`) - UI.empty() - toggles.set("start", true) + if (toggles.get(part.id) === true) continue + task(props(part)) + toggles.set(part.id, true) } - if (event.type === "message.part.updated") { - const part = event.properties.part - if (part.sessionID !== sessionID) continue - - if (part.type === "tool" && (part.state.status === "completed" || part.state.status === "error")) { - if (emit("tool_use", { part })) continue - if (part.state.status === "completed") { - tool(part) - continue - } - inline({ - icon: "✗", - title: `${part.tool} failed`, - }) - UI.error(part.state.error) - } - - if ( - part.type === "tool" && - part.tool === "task" && - part.state.status === "running" && - args.format !== "json" - ) { - if (toggles.get(part.id) === true) continue - task(props(part)) - toggles.set(part.id, true) - } + if (part.type === "step-start") { + if (emit("step_start", { part })) continue + } - if (part.type === "step-start") { - if (emit("step_start", { part })) continue - } + if (part.type === "step-finish") { + if (emit("step_finish", { part })) continue + } - if (part.type === "step-finish") { - if (emit("step_finish", { part })) continue + if (part.type === "text" && part.time?.end) { + if (emit("text", { part })) continue + const text = part.text.trim() + if (!text) continue + if (!process.stdout.isTTY) { + process.stdout.write(text + EOL) + continue } + UI.empty() + UI.println(text) + UI.empty() + } - if (part.type === "text" && part.time?.end) { - if (emit("text", { part })) continue - const text = part.text.trim() - if (!text) continue - if (!process.stdout.isTTY) { - process.stdout.write(text + EOL) - continue - } + if (part.type === "reasoning" && part.time?.end && args.thinking) { + if (emit("reasoning", { part })) continue + const text = part.text.trim() + if (!text) continue + const line = `Thinking: ${text}` + if (process.stdout.isTTY) { UI.empty() - UI.println(text) + UI.println(`${UI.Style.TEXT_DIM}\u001b[3m${line}\u001b[0m${UI.Style.TEXT_NORMAL}`) UI.empty() + continue } - - if (part.type === "reasoning" && part.time?.end && args.thinking) { - if (emit("reasoning", { part })) continue - const text = part.text.trim() - if (!text) continue - const line = `Thinking: ${text}` - if (process.stdout.isTTY) { - UI.empty() - UI.println(`${UI.Style.TEXT_DIM}\u001b[3m${line}\u001b[0m${UI.Style.TEXT_NORMAL}`) - UI.empty() - continue - } - process.stdout.write(line + EOL) - } - } - - if (event.type === "session.error") { - const props = event.properties - if (props.sessionID !== sessionID || !props.error) continue - let err = String(props.error.name) - if ("data" in props.error && props.error.data && "message" in props.error.data) { - err = String(props.error.data.message) - } - error = error ? error + EOL + err : err - if (emit("error", { error: props.error })) continue - UI.error(err) - } - - if ( - event.type === "session.status" && - event.properties.sessionID === sessionID && - event.properties.status.type === "idle" - ) { - break + process.stdout.write(line + EOL) } + } - if (event.type === "permission.asked") { - const permission = event.properties - if (permission.sessionID !== sessionID) continue - - if (args["dangerously-skip-permissions"]) { - await sdk.permission.reply({ - requestID: permission.id, - reply: "once", - }) - } else { - UI.println( - UI.Style.TEXT_WARNING_BOLD + "!", - UI.Style.TEXT_NORMAL + - `permission requested: ${permission.permission} (${permission.patterns.join(", ")}); auto-rejecting`, - ) - await sdk.permission.reply({ - requestID: permission.id, - reply: "reject", - }) - } + if (event.type === "session.error") { + const props = event.properties + if (props.sessionID !== sessionID || !props.error) continue + let err = String(props.error.name) + if ("data" in props.error && props.error.data && "message" in props.error.data) { + err = String(props.error.data.message) } + error = error ? error + EOL + err : err + process.exitCode = 1 + if (emit("error", { error: props.error })) continue + UI.error(err) } - } - // Validate agent if specified - const agent = await (async () => { - if (!args.agent) return undefined - const name = args.agent + if ( + event.type === "session.status" && + event.properties.sessionID === sessionID && + event.properties.status.type === "idle" + ) { + break + } - // When attaching, validate against the running server instead of local Instance state. - if (args.attach) { - const modes = await sdk.app - .agents(undefined, { throwOnError: true }) - .then((x) => x.data ?? []) - .catch(() => undefined) + if (event.type === "permission.asked") { + const permission = event.properties + if (permission.sessionID !== sessionID) continue - if (!modes) { + if (args["dangerously-skip-permissions"]) { + await sdk.permission.reply({ + requestID: permission.id, + reply: "once", + }) + } else { UI.println( UI.Style.TEXT_WARNING_BOLD + "!", - UI.Style.TEXT_NORMAL, - `failed to list agents from ${args.attach}. Falling back to default agent`, + UI.Style.TEXT_NORMAL + + `permission requested: ${permission.permission} (${permission.patterns.join(", ")}); auto-rejecting`, ) - return undefined + await sdk.permission.reply({ + requestID: permission.id, + reply: "reject", + }) } + } + } + } - const agent = modes.find((a) => a.name === name) - if (!agent) { - UI.println( - UI.Style.TEXT_WARNING_BOLD + "!", - UI.Style.TEXT_NORMAL, - `agent "${name}" not found. Falling back to default agent`, - ) - return undefined - } + // Validate agent if specified + const agent = await (async () => { + if (!args.agent) return undefined + const name = args.agent - if (agent.mode === "subagent") { - UI.println( - UI.Style.TEXT_WARNING_BOLD + "!", - UI.Style.TEXT_NORMAL, - `agent "${name}" is a subagent, not a primary agent. Falling back to default agent`, - ) - return undefined - } + // When attaching, validate against the running server instead of local Instance state. + if (args.attach) { + const modes = await sdk.app + .agents(undefined, { throwOnError: true }) + .then((x) => x.data ?? []) + .catch(() => undefined) - return name + if (!modes) { + UI.println( + UI.Style.TEXT_WARNING_BOLD + "!", + UI.Style.TEXT_NORMAL, + `failed to list agents from ${args.attach}. Falling back to default agent`, + ) + return undefined } - const entry = await Effect.runPromise(agentSvc.get(name)) - if (!entry) { + const agent = modes.find((a) => a.name === name) + if (!agent) { UI.println( UI.Style.TEXT_WARNING_BOLD + "!", UI.Style.TEXT_NORMAL, @@ -617,7 +596,8 @@ export const RunCommand = effectCmd({ ) return undefined } - if (entry.mode === "subagent") { + + if (agent.mode === "subagent") { UI.println( UI.Style.TEXT_WARNING_BOLD + "!", UI.Style.TEXT_NORMAL, @@ -625,54 +605,160 @@ export const RunCommand = effectCmd({ ) return undefined } + return name - })() + } - const sessionID = await session(sdk) - if (!sessionID) { - UI.error("Session not found") - process.exit(1) + const entry = await AppRuntime.runPromise(Agent.Service.use((svc) => svc.get(name))) + if (!entry) { + UI.println( + UI.Style.TEXT_WARNING_BOLD + "!", + UI.Style.TEXT_NORMAL, + `agent "${name}" not found. Falling back to default agent`, + ) + return undefined } - await share(sdk, sessionID) + if (entry.mode === "subagent") { + UI.println( + UI.Style.TEXT_WARNING_BOLD + "!", + UI.Style.TEXT_NORMAL, + `agent "${name}" is a subagent, not a primary agent. Falling back to default agent`, + ) + return undefined + } + return name + })() - loop().catch((e) => { - console.error(e) - process.exit(1) - }) + const sessionID = await session(sdk) + if (!sessionID) { + UI.error("Session not found") + process.exit(1) + } + await share(sdk, sessionID) + + const selection = { explicitAgent: agent, explicitModel: args.model, explicitVariant: args.variant } + const resolved: RuntimeModelResolution = await (async () => { + if (args.attach) { + const url = new URL(`/continuity/${encodeURIComponent(sessionID)}/model-resolution`, args.attach) + const headers = new Headers(ServerAuth.headers({ password: args.password, username: args.username })) + headers.set("content-type", "application/json") + if (directory) headers.set("x-opencode-directory", encodeURIComponent(directory)) + const response = await fetch(url, { + method: "POST", + headers, + body: JSON.stringify(selection), + signal: AbortSignal.timeout(30_000), + }) + if (!response.ok) throw new Error(`Backend model resolution failed (HTTP ${response.status})`) + return response.json() + } + return AppRuntime.runPromise( + Effect.gen(function* () { + const sessions = yield* Session.Service + const session = yield* sessions.get(SessionID.make(sessionID)) + return yield* resolveRuntimeModel({ session, ...selection }) + }), + ) + })() + emit("session.started", { + resolution: resolved, + }) + + const eventLoop = loop() + try { if (args.command) { - await sdk.session.command({ - sessionID, - agent, - model: args.model, - command: args.command, - arguments: message, - variant: args.variant, - }) + await sdk.session.command( + { + sessionID, + agent: resolved.agent, + model: resolved.model ? `${resolved.model.providerID}/${resolved.model.modelID}` : undefined, + command: args.command, + arguments: message, + variant: resolved.variant, + }, + { throwOnError: true }, + ) } else { - const model = args.model ? Provider.parseModel(args.model) : undefined - await sdk.session.prompt({ - sessionID, - agent, - model, - variant: args.variant, - parts: [...files, { type: "text", text: message }], - }) + await sdk.session.prompt( + { + sessionID, + agent: resolved.agent, + model: resolved.model, + variant: resolved.variant, + parts: [...files, { type: "text", text: message }], + }, + { throwOnError: true }, + ) } + } catch (failure) { + eventController.abort() + throw failure + } finally { + await eventLoop + eventController.abort() } - if (args.attach) { - const headers = ServerAuth.headers({ password: args.password, username: args.username }) - const sdk = createOpencodeClient({ baseUrl: args.attach, directory, headers }) - return await execute(sdk) + if (args.format === "json") { + writeAutomationEnvelope({ + kind: "result", + event: "session.completed", + sessionID, + data: { + status: error ? "failed" : "completed", + resolution: resolved, + error: error ?? null, + }, + }) } + } + + if (args.attach) { + const headers = ServerAuth.headers({ password: args.password, username: args.username }) + const sdk = createOpencodeClient({ baseUrl: args.attach, directory, headers }) + return await execute(sdk) + } + + const fetchFn = (async (input: RequestInfo | URL, init?: RequestInit) => { + const request = new Request(input, init) + return Server.Default().app.fetch(request) + }) as typeof globalThis.fetch + const sdk = createOpencodeClient({ baseUrl: "http://opencode.internal", fetch: fetchFn }) + await execute(sdk) + }, +}) - const fetchFn = (async (input: RequestInfo | URL, init?: RequestInit) => { - const request = new Request(input, init) - return Server.Default().app.fetch(request) - }) as typeof globalThis.fetch - const sdk = createOpencodeClient({ baseUrl: "http://opencode.internal", fetch: fetchFn }) - await execute(sdk) - }) - }), +const LocalRunCommand = effectCmd({ + command: "run", + describe: "run a local session", + directory: (args: Parameters[0]) => path.resolve(args.dir ?? process.cwd()), + handler: (args: Parameters[0]) => + Effect.promise(async () => { + await ClientRunCommand.handler(args) + }), }) + +export const RunCommand = { + ...ClientRunCommand, + async handler(args: Parameters[0]) { + if (args.attach) return ClientRunCommand.handler(args) + if (process.env.MENDCODE_DISABLE_SHARED_SERVER === "1" || process.env.OPENCODE_DISABLE_SHARED_SERVER === "1") { + await (await import("@/storage/startup-migration")).migrateLegacyStorage() + return LocalRunCommand.handler(args) + } + if (args.dir) process.chdir(path.resolve(args.dir)) + return withSharedClient(process.cwd(), async (connection) => { + const authorization = connection.headers.get("authorization") + if (!authorization?.startsWith("Basic ")) throw new Error("Local backend credentials are unavailable") + const credentials = Buffer.from(authorization.slice(6), "base64").toString("utf8") + const separator = credentials.indexOf(":") + return ClientRunCommand.handler({ + ...args, + attach: connection.url, + dir: connection.directory, + username: credentials.slice(0, separator), + password: credentials.slice(separator + 1), + }) + }) + }, +} diff --git a/src/mendcode/packages/opencode/src/cli/cmd/serve-shutdown.ts b/src/mendcode/packages/opencode/src/cli/cmd/serve-shutdown.ts new file mode 100644 index 00000000..4c27d157 --- /dev/null +++ b/src/mendcode/packages/opencode/src/cli/cmd/serve-shutdown.ts @@ -0,0 +1,56 @@ +// Keep this shorter than the client's bounded wait for the previous process. +export const SHARED_SERVER_SHUTDOWN_TIMEOUT_MS = 10_000 + +/** Own the whole shutdown, not just instance disposal. A closed listener must + * never leave a live process retaining the database writer lease indefinitely. */ +export function createShutdown(input: { + stopListener: () => Promise + disposeInstances: () => Promise + closeDatabase: () => void | Promise + clearState: () => Promise + exit: (code: number) => void + report?: (stage: string, error: unknown) => void + shutdownTimeoutMs?: number +}) { + let shutdown: Promise | undefined + return () => (shutdown ??= run()) + + async function run() { + let stage = "listener" + let expired = false + let exitCode = 0 + let timer: ReturnType | undefined + const deadline = new Promise((_, reject) => { + // This timer deliberately stays referenced: cleanup is not complete + // until the process exits and the OS releases its remaining resources. + timer = setTimeout(() => { + expired = true + reject(new Error(`Shared server shutdown timed out during ${stage}`)) + }, input.shutdownTimeoutMs ?? SHARED_SERVER_SHUTDOWN_TIMEOUT_MS) + }) + const cleanup = async () => { + await input.stopListener() + if (expired) return + stage = "instances" + await input.disposeInstances() + if (expired) return + stage = "database" + await input.closeDatabase() + if (expired) return + // Only relinquish discovery after all writers have actually closed. + // On failure retain the receipt for dead-process recovery by the client. + stage = "state" + await input.clearState() + } + try { + await Promise.race([cleanup(), deadline]) + } catch (error) { + exitCode = 1 + input.report?.(stage, error) + throw error + } finally { + if (timer) clearTimeout(timer) + input.exit(exitCode) + } + } +} diff --git a/src/mendcode/packages/opencode/src/cli/cmd/serve.ts b/src/mendcode/packages/opencode/src/cli/cmd/serve.ts index 9e0b0dac..4dcd1039 100644 --- a/src/mendcode/packages/opencode/src/cli/cmd/serve.ts +++ b/src/mendcode/packages/opencode/src/cli/cmd/serve.ts @@ -3,6 +3,19 @@ import { Server } from "../../server/server" import { effectCmd } from "../effect-cmd" import { withNetworkOptions, resolveNetworkOptions } from "../network" import { Flag } from "@mendcode/core/flag/flag" +import { SharedServer } from "./tui/shared-server" +import { InstanceStore } from "@/project/instance-store" +import { BackgroundTask } from "@/session/background-task" +import { SessionRunState } from "@/session/run-state" +import { SessionStatus } from "@/session/status" +import * as Log from "@mendcode/core/util/log" +import { recoverStaleSessionStatuses } from "@/session/recovery" +import { Database } from "@/storage/db" +import { createShutdown } from "./serve-shutdown" + +export { createShutdown } from "./serve-shutdown" + +const log = Log.create({ service: "cli.serve" }) export const ServeCommand = effectCmd({ command: "serve", @@ -12,13 +25,100 @@ export const ServeCommand = effectCmd({ // need for an ambient project InstanceContext at startup. instance: false, handler: Effect.fn("Cli.serve")(function* (args) { + const recovered = yield* Effect.sync(() => recoverStaleSessionStatuses()) + if (recovered.length > 0) log.warn("finalized stale foreground sessions", { count: recovered.length }) if (!Flag.OPENCODE_SERVER_PASSWORD) { console.log("Warning: OPENCODE_SERVER_PASSWORD is not set; server is unsecured.") } const opts = yield* Effect.promise(() => resolveNetworkOptions(args)) const server = yield* Effect.promise(() => Server.listen(opts)) + const shared = Boolean(process.env.MENDCODE_SHARED_SERVER_STATE_FILE) + if (shared) { + const credentials = SharedServer.credentials() + yield* Effect.promise(() => + SharedServer.writeState({ + version: 1, + pid: process.pid, + url: server.url.toString(), + username: credentials.username, + password: credentials.password, + startedAt: new Date().toISOString(), + runtimeID: process.env.MENDCODE_SHARED_SERVER_RUNTIME_ID || "unknown", + }), + ) + } console.log(`MendCode runtime server listening on http://${server.hostname}:${server.port}`) - yield* Effect.never + const store = yield* InstanceStore.Service + const controller = new AbortController() + let resolveSignal: (() => void) | undefined + const signal = new Promise((resolve) => { + resolveSignal = resolve + }) + const onSignal = () => resolveSignal?.() + process.once("SIGINT", onSignal) + process.once("SIGTERM", onSignal) + + const stop = createShutdown({ + stopListener: () => server.stop(true), + disposeInstances: () => Effect.runPromise(store.disposeAll()), + closeDatabase: () => Database.close(), + clearState: async () => { + if (shared) await SharedServer.clearStateIfOwned(process.pid) + }, + exit: (code) => process.exit(code), + report: (stage, error) => + log.warn("server shutdown failed; exiting with ownership receipt retained", { + stage, + error: error instanceof Error ? error.message : String(error), + }), + }) + + try { + const idle = shared + ? SharedServer.waitForClientLeases({ + pid: process.pid, + stop, + signal: controller.signal, + hasActiveWork: () => + Effect.runPromise( + store.loaded().pipe( + Effect.flatMap((instances) => + Effect.forEach( + instances, + (instance) => + store.provide( + instance, + Effect.gen(function* () { + if (BackgroundTask.hasActiveTasks()) return true + const statuses = yield* SessionStatus.Service + const runState = yield* SessionRunState.Service + const sessions = yield* statuses.list() + for (const [sessionID, status] of sessions) { + if (status.type !== "busy") continue + if (yield* runState.isBusy(sessionID)) return true + } + return false + }).pipe(Effect.provide([SessionRunState.defaultLayer, SessionStatus.defaultLayer])), + ), + { concurrency: "unbounded" }, + ), + ), + Effect.map((active) => active.some(Boolean)), + ), + ), + }) + : new Promise(() => undefined) + yield* Effect.raceFirst( + Effect.promise(() => idle), + Effect.promise(() => signal), + ) + yield* Effect.promise(stop) + } finally { + controller.abort() + process.off("SIGINT", onSignal) + process.off("SIGTERM", onSignal) + yield* Effect.promise(stop) + } }), }) diff --git a/src/mendcode/packages/opencode/src/cli/cmd/session.ts b/src/mendcode/packages/opencode/src/cli/cmd/session.ts index 2ceb4e98..281fe065 100644 --- a/src/mendcode/packages/opencode/src/cli/cmd/session.ts +++ b/src/mendcode/packages/opencode/src/cli/cmd/session.ts @@ -1,147 +1,709 @@ import type { Argv } from "yargs" -import { Effect } from "effect" +import { asc, eq } from "drizzle-orm" +import { Effect, Stream } from "effect" +import { spawn } from "node:child_process" +import path from "path" +import { EOL } from "os" import { cmd } from "./cmd" import { effectCmd, fail } from "../effect-cmd" -import { Session } from "@/session/session" -import { SessionID } from "../../session/schema" -import { UI } from "../ui" -import { Locale } from "@/util/locale" -import { Flag } from "@mendcode/core/flag/flag" -import { Filesystem } from "@/util/filesystem" -import { Process } from "@/util/process" +import { automationEnvelope, writeAutomationEnvelope } from "../automation" +import { resolveRuntimeModel } from "../model-selection" +import { Bus } from "@/bus" +import { Database } from "@/storage/db" +import { EventTable } from "@/sync/event.sql" +import { Session, type Info as SessionInfo } from "@/session/session" +import { MessageID, SessionID } from "../../session/schema" +import { SessionPrompt } from "@/session/prompt" +import { SessionStatus } from "@/session/status" +import { BackgroundTask } from "@/session/background-task" +import { LoopWorkflow } from "@/session/loop" +import { MessageV2 } from "@/session/message-v2" +import { Question } from "@/question" +import { Permission } from "@/permission" +import { PlanReview } from "@/plan-review" +import { ModelID, ProviderID } from "@/provider/schema" import { NotFoundError } from "@/storage/storage" -import { EOL } from "os" -import path from "path" -import { which } from "../../util/which" +import { Locale } from "@/util/locale" + +const DEFAULT_WAIT_TIMEOUT_MS = 30 * 60 * 1000 +const DEFAULT_WAIT_INTERVAL_MS = 250 + +type OutputArgs = { + format?: string + json?: boolean +} + +type SessionCommandArgs = OutputArgs & { + dir?: string +} + +function sessionDirectory(args: SessionCommandArgs) { + return args.dir ? path.resolve(process.cwd(), args.dir) : process.cwd() +} + +function withSessionOptions(yargs: Argv) { + return yargs + .option("dir", { + describe: "project directory to operate on", + type: "string", + }) + .option("format", { + describe: "output format", + type: "string", + choices: ["table", "json"], + default: "table", + }) + .option("json", { + describe: "emit versioned JSON output", + type: "boolean", + default: false, + }) +} + +function wantsJSON(args: OutputArgs) { + return args.json === true || args.format === "json" +} + +function writeResult(args: OutputArgs, event: string, data: T, human: string, sessionID?: string) { + if (wantsJSON(args)) { + writeAutomationEnvelope({ kind: "result", event, sessionID, data }) + return + } + if (human) console.log(human) +} + +function sessionID(value: string) { + try { + return SessionID.make(value) + } catch { + throw new Error(`Invalid session ID: ${value}`) + } +} + +function parseModel(value?: string, variant?: string) { + if (!value) return undefined + const [providerID, ...rest] = value.split("/") + const modelID = rest.join("/") + if (!providerID || !modelID) throw new Error(`Invalid model: ${value}; expected provider/model`) + return { + providerID: ProviderID.make(providerID), + id: ModelID.make(modelID), + ...(variant ? { variant } : {}), + } +} + +function modelText(model?: SessionInfo["model"]) { + if (!model) return undefined + return `${model.providerID}/${model.id}${model.variant ? ` (${model.variant})` : ""}` +} -function pagerCmd(): string[] { - const lessOptions = ["-R", "-S"] - if (process.platform !== "win32") { - return ["less", ...lessOptions] +function sessionHuman(info: SessionInfo, status?: SessionStatus.Info, state?: string) { + return [ + `${info.id} ${info.title}`, + `State: ${state ?? status?.type ?? "unknown"}`, + `Agent: ${info.agent ?? "default"}`, + `Model: ${modelText(info.model) ?? "runtime default"}`, + `Directory: ${info.directory}`, + `Updated: ${new Date(info.time.updated).toISOString()}`, + ].join("\n") +} + +function sessionRow(info: SessionInfo, status?: SessionStatus.Info, state?: string) { + return { + id: info.id, + title: info.title, + projectID: info.projectID, + directory: info.directory, + parentID: info.parentID ?? null, + agent: info.agent ?? null, + model: info.model + ? { + providerID: info.model.providerID, + modelID: info.model.id, + variant: info.model.variant ?? null, + } + : null, + status: status ?? { type: "idle" }, + state: state ?? status?.type ?? "idle", + archived: info.time.archived ?? null, + created: info.time.created, + updated: info.time.updated, } +} - // user could have less installed via other options - const lessOnPath = which("less") - if (lessOnPath) { - if (Filesystem.stat(lessOnPath)?.size) return [lessOnPath, ...lessOptions] +function lastAssistant(messages: MessageV2.WithParts[]) { + return messages.findLast((message) => message.info.role === "assistant") +} + +function pendingForSession(items: ReadonlyArray, id: string) { + return items.filter((item) => item.sessionID === id) +} + +export function deriveSessionState(input: { + sessionID: string + status: SessionStatus.Info + messages: MessageV2.WithParts[] + questions: ReadonlyArray<{ sessionID: string }> + permissions: ReadonlyArray<{ sessionID: string }> + planReviews: ReadonlyArray<{ sessionID: string }> +}) { + if (input.questions.some((item) => item.sessionID === input.sessionID)) return "waiting_for_input" + if (input.permissions.some((item) => item.sessionID === input.sessionID)) return "waiting_for_approval" + if (input.planReviews.some((item) => item.sessionID === input.sessionID)) return "waiting_for_approval" + if (input.status.type === "busy") { + if (input.status.kind === "mflow-wait") return "waiting_for_lock" + if (input.status.kind === "subagent-wait") return "waiting_for_subagent" + return "running" } + if (input.status.type === "retry") return "retrying" - if (Flag.OPENCODE_GIT_BASH_PATH) { - const less = path.join(Flag.OPENCODE_GIT_BASH_PATH, "..", "..", "usr", "bin", "less.exe") - if (Filesystem.stat(less)?.size) return [less, ...lessOptions] + if (input.messages.at(-1)?.info.role === "user") return "running" + + const assistant = lastAssistant(input.messages) + if (assistant?.info.role === "assistant" && assistant.info.error) { + return assistant.info.error.name === "MessageAbortedError" ? "cancelled" : "failed" } + if (assistant?.info.role === "assistant" && assistant.info.time.completed) return "completed" + return "idle" +} - const git = which("git") - if (git) { - const less = path.join(git, "..", "..", "usr", "bin", "less.exe") - if (Filesystem.stat(less)?.size) return [less, ...lessOptions] +function terminalState(state: string) { + return state === "completed" || state === "failed" || state === "cancelled" +} + +type SessionSnapshot = { + session: SessionInfo + status: SessionStatus.Info + state: string + messages: MessageV2.WithParts[] + children: SessionInfo[] + subagents: BackgroundTask.Snapshot[] + loops: LoopWorkflow.Info[] + pending: { + questions: unknown[] + permissions: unknown[] + planReviews: unknown[] } + events: Array<{ + id: string + sequence: number + type: string + data: Record + }> + diff: unknown[] +} + +function inspectSession(sessionIDValue: SessionID, limit = 50) { + return Effect.gen(function* () { + const sessions = yield* Session.Service + const statuses = yield* SessionStatus.Service + const tasks = yield* BackgroundTask.Service + const loops = yield* LoopWorkflow.Service + const questions = yield* Question.Service + const permissions = yield* Permission.Service + const planReviews = yield* PlanReview.Service + const info = yield* sessions.get(sessionIDValue) + const messages = yield* sessions.messages({ sessionID: sessionIDValue, ...(limit > 0 ? { limit } : {}) }) + const pendingQuestions = pendingForSession(yield* questions.list(), sessionIDValue) + const pendingPermissions = pendingForSession(yield* permissions.list(), sessionIDValue) + const pendingPlanReviews = pendingForSession(yield* planReviews.list(), sessionIDValue) + const status = yield* statuses.get(sessionIDValue) + const state = deriveSessionState({ + sessionID: sessionIDValue, + status, + messages, + questions: pendingQuestions, + permissions: pendingPermissions, + planReviews: pendingPlanReviews, + }) + const events = yield* Effect.sync(() => + Database.use((db) => + db + .select({ id: EventTable.id, sequence: EventTable.seq, type: EventTable.type, data: EventTable.data }) + .from(EventTable) + .where(eq(EventTable.aggregate_id, sessionIDValue)) + .orderBy(asc(EventTable.seq)) + .all(), + ), + ) + return { + session: info, + status, + state, + messages, + children: yield* sessions.children(sessionIDValue), + subagents: yield* tasks.list(sessionIDValue), + loops: (yield* loops.list()).filter( + (item) => item.rootSessionID === sessionIDValue || item.ownerSessionID === sessionIDValue, + ), + pending: { + questions: pendingQuestions, + permissions: pendingPermissions, + planReviews: pendingPlanReviews, + }, + events, + diff: yield* sessions.diff(sessionIDValue), + } satisfies SessionSnapshot + }) +} + +function waitForSession(sessionIDValue: SessionID, timeoutMs: number, intervalMs: number) { + return Effect.gen(function* () { + const started = Date.now() + let snapshot = yield* inspectSession(sessionIDValue, 50) + while (!terminalState(snapshot.state)) { + const remaining = timeoutMs - (Date.now() - started) + if (remaining <= 0) return { snapshot, timedOut: true } + yield* Effect.sleep(`${Math.min(intervalMs, remaining)} millis`) + snapshot = yield* inspectSession(sessionIDValue, 50) + } + return { snapshot, timedOut: false } + }) +} - // Fall back to Windows built-in more (via cmd.exe) - return ["cmd", "/c", "more"] +function timeoutValue(value?: number) { + const result = value ?? DEFAULT_WAIT_TIMEOUT_MS + if (!Number.isFinite(result) || result <= 0) throw new Error("--timeout-ms must be a positive number") + return Math.floor(result) +} + +function intervalValue(value?: number) { + const result = value ?? DEFAULT_WAIT_INTERVAL_MS + if (!Number.isFinite(result) || result <= 0) throw new Error("--interval-ms must be a positive number") + return Math.floor(result) +} + +function extractEventSessionID(properties: unknown) { + if (!properties || typeof properties !== "object") return undefined + const record = properties as Record + if (typeof record.sessionID === "string") return record.sessionID + for (const key of ["info", "part", "snapshot", "request"]) { + const value = record[key] + if (value && typeof value === "object" && typeof (value as Record).sessionID === "string") { + return (value as Record).sessionID as string + } + } + return undefined +} + +class SessionEventDone extends Error {} + +function launchAsyncPrompt(input: { + sessionID: string + directory: string + message: string + model?: string + agent?: string + variant?: string +}) { + const entry = process.argv[1] + const script = entry && /\.(?:ts|tsx|js|mjs)$/.test(entry) ? entry : undefined + const command = script ? process.execPath : entry || process.execPath + const commandArgs = [ + ...(script ? [script] : []), + "run", + "--dir", + input.directory, + "--session", + input.sessionID, + "--format", + "json", + ...(input.model ? ["--model", input.model] : []), + ...(input.agent ? ["--agent", input.agent] : []), + ...(input.variant ? ["--variant", input.variant] : []), + input.message, + ] + const child = spawn(command, commandArgs, { + cwd: input.directory, + detached: true, + env: { ...process.env }, + stdio: "ignore", + }) + child.unref() + return child.pid } export const SessionCommand = cmd({ command: "session", - describe: "manage sessions", - builder: (yargs: Argv) => yargs.command(SessionListCommand).command(SessionDeleteCommand).demandCommand(), + describe: "manage and automate sessions", + builder: (yargs: Argv) => + withSessionOptions(yargs) + .command(SessionCreateCommand) + .command(SessionListCommand) + .command(SessionGetCommand) + .command(SessionInspectCommand) + .command(SessionRenameCommand) + .command(SessionForkCommand) + .command(SessionArchiveCommand) + .command(SessionDeleteCommand) + .command(SessionSendCommand) + .command(SessionStatusCommand) + .command(SessionWaitCommand) + .command(SessionCancelCommand) + .command(SessionEventsCommand) + .command(SessionExportCommand) + .demandCommand(), async handler() {}, }) -export const SessionDeleteCommand = effectCmd({ - command: "delete ", - describe: "delete a session", - builder: (yargs) => - yargs.positional("sessionID", { - describe: "session ID to delete", - type: "string", - demandOption: true, - }), - handler: Effect.fn("Cli.session.delete")(function* (args) { - const svc = yield* Session.Service - const sessionID = SessionID.make(args.sessionID) - yield* svc - .remove(sessionID) - .pipe(Effect.catchIf(NotFoundError.isInstance, () => fail(`Session not found: ${args.sessionID}`))) - UI.println(UI.Style.TEXT_SUCCESS_BOLD + `Session ${args.sessionID} deleted` + UI.Style.TEXT_NORMAL) +export const SessionCreateCommand = effectCmd({ + command: "create", + describe: "create a session", + builder: (yargs: Argv) => + withSessionOptions(yargs) + .option("title", { type: "string", describe: "session title" }) + .option("parent", { type: "string", describe: "parent session ID" }) + .option("agent", { type: "string", describe: "agent to use" }) + .option("model", { type: "string", describe: "model as provider/model" }) + .option("variant", { type: "string", describe: "model variant" }), + directory: sessionDirectory, + handler: Effect.fn("Cli.session.create")(function* (args) { + const sessions = yield* Session.Service + const info = yield* sessions.create({ + title: args.title, + parentID: args.parent ? sessionID(args.parent) : undefined, + agent: args.agent, + model: parseModel(args.model, args.variant), + }) + writeResult(args, "session.created", sessionRow(info), `Created session ${info.id}: ${info.title}`, info.id) }), }) export const SessionListCommand = effectCmd({ command: "list", describe: "list sessions", - builder: (yargs) => - yargs - .option("max-count", { - alias: "n", - describe: "limit to N most recent sessions", - type: "number", - }) - .option("format", { - describe: "output format", - type: "string", - choices: ["table", "json"], - default: "table", - }), + builder: (yargs: Argv) => + withSessionOptions(yargs) + .option("max-count", { alias: "n", describe: "limit to N sessions", type: "number" }) + .option("all", { describe: "include child sessions", type: "boolean", default: false }) + .option("all-projects", { describe: "include sessions from all projects", type: "boolean", default: false }) + .option("project", { describe: "filter by project ID", type: "string" }) + .option("state", { describe: "filter by derived state", type: "string" }) + .option("active", { describe: "only active sessions", type: "boolean" }) + .option("archived", { describe: "include archived sessions", type: "boolean", default: false }) + .option("agent", { describe: "filter by agent", type: "string" }) + .option("model", { describe: "filter by provider/model", type: "string" }) + .option("since", { describe: "updated since Unix milliseconds", type: "number" }) + .option("search", { describe: "search titles", type: "string" }), + directory: sessionDirectory, handler: Effect.fn("Cli.session.list")(function* (args) { - const sessions = yield* Session.Service.use((svc) => svc.list({ roots: true, limit: args.maxCount })) + const sessions = yield* Session.Service + const statuses = yield* SessionStatus.Service + const list = args["all-projects"] || args.project + ? Array.from( + Session.listGlobal({ + directory: args["all-projects"] ? undefined : sessionDirectory(args), + roots: !args.all, + start: args.since, + search: args.search, + limit: args["max-count"], + archived: args.archived, + }), + ) + : yield* sessions.list({ roots: !args.all, start: args.since, search: args.search, limit: args["max-count"] }) + const statusMap = yield* statuses.list() + const rows = list + .filter((info) => !args.project || info.projectID === args.project) + .filter((info) => args.agent === undefined || info.agent === args.agent) + .filter((info) => args.model === undefined || modelText(info.model)?.startsWith(args.model)) + .filter((info) => args.archived || !info.time.archived) + .map((info) => { + const status = statusMap.get(info.id) ?? { type: "idle" as const } + const state = status.type + return { info, status, state } + }) + .filter((item) => args.active === undefined || (args.active ? item.state !== "idle" : item.state === "idle")) + .filter((item) => args.state === undefined || item.state === args.state) + const data = rows.map((item) => sessionRow(item.info, item.status, item.state)) + const human = data.length + ? data + .map((item) => `${item.id} ${item.state.padEnd(10)} ${Locale.truncate(item.title, 35)}`) + .join(EOL) + : "No sessions" + writeResult(args, "session.list", data, human) + }), +}) - if (sessions.length === 0) return +export const SessionGetCommand = effectCmd({ + command: "get ", + describe: "get session metadata", + builder: (yargs: Argv) => withSessionOptions(yargs).positional("sessionID", { type: "string", demandOption: true }), + directory: sessionDirectory, + handler: Effect.fn("Cli.session.get")(function* (args) { + const sessions = yield* Session.Service + const info = yield* sessions.get(sessionID(args.sessionID)).pipe( + Effect.catchIf(NotFoundError.isInstance, () => fail(`Session not found: ${args.sessionID}`)), + ) + writeResult(args, "session.get", sessionRow(info), sessionHuman(info), info.id) + }), +}) - const output = args.format === "json" ? formatSessionJSON(sessions) : formatSessionTable(sessions) +export const SessionInspectCommand = effectCmd({ + command: "inspect ", + describe: "inspect session progress, subagents, loops, approvals, and result", + builder: (yargs: Argv) => + withSessionOptions(yargs) + .positional("sessionID", { type: "string", demandOption: true }) + .option("limit", { type: "number", default: 50, describe: "maximum messages to include" }), + directory: sessionDirectory, + handler: Effect.fn("Cli.session.inspect")(function* (args) { + const snapshot = yield* inspectSession(sessionID(args.sessionID), args.limit) + writeResult( + args, + "session.inspect", + snapshot, + sessionHuman(snapshot.session, snapshot.status, snapshot.state), + snapshot.session.id, + ) + }), +}) - const shouldPaginate = process.stdout.isTTY && !args.maxCount && args.format === "table" +export const SessionRenameCommand = effectCmd({ + command: "rename ", + describe: "rename a session", + builder: (yargs: Argv) => + withSessionOptions(yargs) + .positional("sessionID", { type: "string", demandOption: true }) + .positional("title", { type: "string", array: true, demandOption: true }), + directory: sessionDirectory, + handler: Effect.fn("Cli.session.rename")(function* (args) { + const id = sessionID(args.sessionID) + const title = args.title.join(" ").trim() + if (!title) return yield* fail("A non-empty title is required") + const sessions = yield* Session.Service + yield* sessions.setTitle({ sessionID: id, title }) + const info = yield* sessions.get(id) + writeResult(args, "session.renamed", sessionRow(info), `Renamed ${id} to ${title}`, id) + }), +}) - if (shouldPaginate) { - yield* Effect.promise(async () => { - const proc = Process.spawn(pagerCmd(), { - stdin: "pipe", - stdout: "inherit", - stderr: "inherit", - }) +export const SessionForkCommand = effectCmd({ + command: "fork ", + describe: "fork a session", + builder: (yargs: Argv) => + withSessionOptions(yargs) + .positional("sessionID", { type: "string", demandOption: true }) + .option("message-id", { type: "string", describe: "fork before this message" }), + directory: sessionDirectory, + handler: Effect.fn("Cli.session.fork")(function* (args) { + const sessions = yield* Session.Service + const info = yield* sessions.fork({ + sessionID: sessionID(args.sessionID), + messageID: args["message-id"] ? MessageID.make(args["message-id"]) : undefined, + }) + writeResult(args, "session.forked", sessionRow(info), `Forked session ${info.id} from ${args.sessionID}`, info.id) + }), +}) - if (!proc.stdin) { - console.log(output) - return - } +export const SessionArchiveCommand = effectCmd({ + command: "archive ", + describe: "archive or restore a session", + builder: (yargs: Argv) => withSessionOptions(yargs).positional("sessionID", { type: "string", demandOption: true }).option("restore", { type: "boolean", default: false }), + directory: sessionDirectory, + handler: Effect.fn("Cli.session.archive")(function* (args) { + const id = sessionID(args.sessionID) + const sessions = yield* Session.Service + yield* sessions.setArchived({ sessionID: id, time: args.restore ? undefined : Date.now() }) + const info = yield* sessions.get(id) + writeResult(args, args.restore ? "session.restored" : "session.archived", sessionRow(info), args.restore ? `Restored ${id}` : `Archived ${id}`, id) + }), +}) - proc.stdin.write(output) - proc.stdin.end() - await proc.exited +export const SessionDeleteCommand = effectCmd({ + command: "delete ", + describe: "delete a session", + builder: (yargs: Argv) => withSessionOptions(yargs).positional("sessionID", { type: "string", demandOption: true }), + directory: sessionDirectory, + handler: Effect.fn("Cli.session.delete")(function* (args) { + const id = sessionID(args.sessionID) + const sessions = yield* Session.Service + yield* sessions.remove(id).pipe(Effect.catchIf(NotFoundError.isInstance, () => fail(`Session not found: ${args.sessionID}`))) + writeResult(args, "session.deleted", { id }, `Session ${args.sessionID} deleted`, args.sessionID) + }), +}) + +export const SessionSendCommand = effectCmd({ + command: "send [message..]", + describe: "send work to an existing session", + builder: (yargs: Argv) => + withSessionOptions(yargs) + .positional("sessionID", { type: "string", demandOption: true }) + .positional("message", { type: "string", array: true, default: [] }) + .option("model", { type: "string", describe: "explicit provider/model override" }) + .option("agent", { type: "string", describe: "explicit agent override" }) + .option("variant", { type: "string", describe: "explicit model variant" }) + .option("async", { type: "boolean", default: false, describe: "start a detached runtime and return immediately" }) + .option("wait", { type: "boolean", default: false, describe: "wait for a terminal result" }) + .option("timeout-ms", { type: "number", describe: "wait timeout" }) + .option("interval-ms", { type: "number", describe: "poll interval" }), + directory: sessionDirectory, + handler: Effect.fn("Cli.session.send")(function* (args) { + const message = args.message.join(" ").trim() + if (!message) return yield* fail("You must provide a message") + const id = sessionID(args.sessionID) + const sessions = yield* Session.Service + const info = yield* sessions.get(id).pipe(Effect.catchIf(NotFoundError.isInstance, () => fail(`Session not found: ${args.sessionID}`))) + const resolved = yield* resolveRuntimeModel({ + session: info, + explicitAgent: args.agent, + explicitModel: args.model, + explicitVariant: args.variant, + }) + const selectedModel = resolved.model ? `${resolved.model.providerID}/${resolved.model.modelID}` : undefined + + if (args.async && !args.wait) { + const pid = launchAsyncPrompt({ + sessionID: info.id, + directory: sessionDirectory(args), + message, + model: selectedModel, + agent: resolved.agent, + variant: resolved.variant, }) - } else { - console.log(output) + writeResult(args, "session.accepted", { sessionID: info.id, pid, resolution: resolved }, `Accepted work for ${info.id} (pid ${pid ?? "unknown"})`, info.id) + return } + + const prompt = yield* SessionPrompt.Service + const result = yield* prompt.prompt({ + sessionID: id, + agent: resolved.agent, + model: resolved.model + ? { providerID: ProviderID.make(resolved.model.providerID), modelID: ModelID.make(resolved.model.modelID) } + : undefined, + variant: resolved.variant, + parts: [{ type: "text", text: message }], + }) + const snapshot = yield* inspectSession(id, 20) + writeResult( + args, + "session.completed", + { resolution: resolved, state: snapshot.state, response: result, session: sessionRow(snapshot.session, snapshot.status, snapshot.state) }, + sessionHuman(snapshot.session, snapshot.status, snapshot.state), + info.id, + ) }), }) -function formatSessionTable(sessions: Session.Info[]): string { - const lines: string[] = [] +export const SessionStatusCommand = effectCmd({ + command: "status ", + describe: "read current session status without blocking", + builder: (yargs: Argv) => withSessionOptions(yargs).positional("sessionID", { type: "string", demandOption: true }), + directory: sessionDirectory, + handler: Effect.fn("Cli.session.status")(function* (args) { + const snapshot = yield* inspectSession(sessionID(args.sessionID), 20) + writeResult(args, "session.status", snapshot, sessionHuman(snapshot.session, snapshot.status, snapshot.state), snapshot.session.id) + }), +}) - const maxIdWidth = Math.max(20, ...sessions.map((s) => s.id.length)) - const maxTitleWidth = Math.max(25, ...sessions.map((s) => s.title.length)) +export const SessionWaitCommand = effectCmd({ + command: "wait ", + describe: "wait until a session completes, fails, or is cancelled", + builder: (yargs: Argv) => + withSessionOptions(yargs) + .positional("sessionID", { type: "string", demandOption: true }) + .option("timeout-ms", { type: "number", describe: "maximum wait time" }) + .option("interval-ms", { type: "number", describe: "poll interval" }), + directory: sessionDirectory, + handler: Effect.fn("Cli.session.wait")(function* (args) { + const id = sessionID(args.sessionID) + const result = yield* waitForSession(id, timeoutValue(args["timeout-ms"]), intervalValue(args["interval-ms"])) + writeResult( + args, + result.timedOut ? "session.timeout" : "session.terminal", + { timedOut: result.timedOut, ...result.snapshot }, + sessionHuman(result.snapshot.session, result.snapshot.status, result.snapshot.state), + id, + ) + if (result.timedOut) return yield* fail(`Timed out waiting for session ${id}`) + }), +}) - const header = `Session ID${" ".repeat(maxIdWidth - 10)} Title${" ".repeat(maxTitleWidth - 5)} Updated` - lines.push(header) - lines.push("─".repeat(header.length)) - for (const session of sessions) { - const truncatedTitle = Locale.truncate(session.title, maxTitleWidth) - const timeStr = Locale.todayTimeOrDateTime(session.time.updated) - const line = `${session.id.padEnd(maxIdWidth)} ${truncatedTitle.padEnd(maxTitleWidth)} ${timeStr}` - lines.push(line) - } +export const SessionCancelCommand = effectCmd({ + command: "cancel ", + describe: "cancel active work in a session", + builder: (yargs: Argv) => withSessionOptions(yargs).positional("sessionID", { type: "string", demandOption: true }), + directory: sessionDirectory, + handler: Effect.fn("Cli.session.cancel")(function* (args) { + const id = sessionID(args.sessionID) + const prompt = yield* SessionPrompt.Service + yield* prompt.cancel(id) + const snapshot = yield* inspectSession(id, 20) + writeResult(args, "session.cancelled", snapshot, `Cancelled ${id}`, id) + }), +}) - return lines.join(EOL) -} +export const SessionEventsCommand = effectCmd({ + command: "events ", + describe: "stream ordered session events", + builder: (yargs: Argv) => + withSessionOptions(yargs) + .positional("sessionID", { type: "string", demandOption: true }) + .option("follow", { type: "boolean", default: false, describe: "follow live events" }) + .option("keep-open", { type: "boolean", default: false, describe: "do not stop when the session becomes idle" }) + .option("limit", { type: "number", describe: "stop after N matching events" }), + directory: sessionDirectory, + handler: Effect.fn("Cli.session.events")(function* (args) { + const id = sessionID(args.sessionID) + if (!args.follow) { + const snapshot = yield* inspectSession(id, 0) + const events = snapshot.events.map((event) => ({ + ...automationEnvelope({ + kind: "event" as const, + event: event.type, + eventID: event.id, + timestamp: typeof event.data.time === "number" ? event.data.time : 0, + sessionID: id, + data: event.data, + }), + sequence: event.sequence, + })) + if (wantsJSON(args)) { + for (const event of events) process.stdout.write(JSON.stringify(event) + EOL) + } else { + console.log(events.map((event) => `${event.sequence} ${event.event}`).join(EOL) || "No events") + } + return + } -function formatSessionJSON(sessions: Session.Info[]): string { - const jsonData = sessions.map((session) => ({ - id: session.id, - title: session.title, - updated: session.time.updated, - created: session.time.created, - projectId: session.projectID, - directory: session.directory, - })) - return JSON.stringify(jsonData, null, 2) + const bus = yield* Bus.Service + let count = 0 + yield* Stream.runForEach(bus.subscribeAll(), (event) => + Effect.gen(function* () { + if (extractEventSessionID(event.properties) !== id) return + count += 1 + if (wantsJSON(args)) { + writeAutomationEnvelope({ kind: "event", event: event.type, eventID: event.id, sessionID: id, data: event.properties }) + } else { + console.log(`${new Date().toISOString()} ${event.type}`) + } + const isIdle = event.type === SessionStatus.Event.Status.type && (event.properties as { status?: { type?: string } }).status?.type === "idle" + if ((args.limit && count >= args.limit) || (isIdle && !args["keep-open"])) return yield* Effect.fail(new SessionEventDone()) + }), + ).pipe(Effect.catchIf((error) => error instanceof SessionEventDone, () => Effect.void)) + }), +}) + +export const SessionExportCommand = effectCmd({ + command: "export ", + describe: "export session metadata, messages, events, subagents, loops, and diff", + builder: (yargs: Argv) => withSessionOptions(yargs).positional("sessionID", { type: "string", demandOption: true }), + directory: sessionDirectory, + handler: Effect.fn("Cli.session.export")(function* (args) { + const snapshot = yield* inspectSession(sessionID(args.sessionID), 0) + writeResult(args, "session.export", snapshot, sessionHuman(snapshot.session, snapshot.status, snapshot.state), snapshot.session.id) + }), +}) + +export function formatSessionTable(sessions: Session.Info[]) { + const maxIdWidth = Math.max(20, ...sessions.map((session) => session.id.length)) + const maxTitleWidth = Math.max(25, ...sessions.map((session) => session.title.length)) + const header = `Session ID${" ".repeat(maxIdWidth - 10)} Title${" ".repeat(maxTitleWidth - 5)} Updated` + return [ + header, + "─".repeat(header.length), + ...sessions.map((session) => `${session.id.padEnd(maxIdWidth)} ${Locale.truncate(session.title, maxTitleWidth).padEnd(maxTitleWidth)} ${new Date(session.time.updated).toISOString()}`), + ].join(EOL) } + +export * as SessionCommandModule from "./session" diff --git a/src/mendcode/packages/opencode/src/cli/cmd/stats.ts b/src/mendcode/packages/opencode/src/cli/cmd/stats.ts index 0124a269..da40504a 100644 --- a/src/mendcode/packages/opencode/src/cli/cmd/stats.ts +++ b/src/mendcode/packages/opencode/src/cli/cmd/stats.ts @@ -1,12 +1,12 @@ import { Effect } from "effect" -import { effectCmd } from "../effect-cmd" +import { cmd } from "./cmd" import { Session } from "@/session/session" import { Database } from "@/storage/db" import { SessionTable } from "../../session/session.sql" import { Project } from "@/project/project" -import { InstanceRef } from "@/effect/instance-ref" +import { withSharedClient } from "../shared-client" -interface SessionStats { +export interface SessionStats { totalSessions: number totalMessages: number totalCost: number @@ -45,7 +45,7 @@ interface SessionStats { medianTokensPerSession: number } -export const StatsCommand = effectCmd({ +export const StatsCommand = cmd({ command: "stats", describe: "show token usage and cost statistics", builder: (yargs) => @@ -65,10 +65,15 @@ export const StatsCommand = effectCmd({ describe: "filter by project (default: all projects, empty string: current project)", type: "string", }), - handler: Effect.fn("Cli.stats")(function* (args) { - const ctx = yield* InstanceRef - if (!ctx) return - const stats = yield* aggregateSessionStats(args.days, args.project, ctx.project) + handler: async (args) => { + const stats = await withSharedClient(process.cwd(), async (connection) => { + const url = new URL("/usage", connection.url) + if (args.days !== undefined) url.searchParams.set("days", String(args.days)) + if (args.project !== undefined) url.searchParams.set("project", args.project) + const response = await fetch(url, { headers: connection.headers, signal: AbortSignal.timeout(30_000) }) + if (!response.ok) throw new Error(`Backend statistics failed (HTTP ${response.status})`) + return (await response.json()) as SessionStats + }) let modelLimit: number | undefined if (args.models === true) { modelLimit = Infinity @@ -76,14 +81,14 @@ export const StatsCommand = effectCmd({ modelLimit = args.models } displayStats(stats, args.tools, modelLimit) - }), + }, }) const getAllSessions = Effect.sync(() => Database.use((db) => db.select().from(SessionTable).all()).map((row) => Session.fromRow(row)), ) -const aggregateSessionStats = Effect.fn("Cli.stats.aggregate")(function* ( +export const aggregateSessionStats = Effect.fn("Cli.stats.aggregate")(function* ( days?: number, projectFilter?: string, currentProject?: Project.Info, diff --git a/src/mendcode/packages/opencode/src/cli/cmd/theme.ts b/src/mendcode/packages/opencode/src/cli/cmd/theme.ts new file mode 100644 index 00000000..f01dbb36 --- /dev/null +++ b/src/mendcode/packages/opencode/src/cli/cmd/theme.ts @@ -0,0 +1,72 @@ +import type { Argv } from "yargs" +import { cmd } from "./cmd" +import { Global } from "@mendcode/core/global" +import path from "path" +import { mkdir, readFile, writeFile } from "fs/promises" +import { validateThemeDocument } from "./tui/theme-format" + +type Scope = "project" | "global" +function scope(args: { scope?: string }): Scope { return args.scope === "global" ? "global" : "project" } +function themeDir(selected: Scope) { return selected === "global" ? path.join(Global.Path.config, "themes") : path.join(process.cwd(), ".mendcode", "themes") } +function tuiFile(selected: Scope) { return selected === "global" ? path.join(Global.Path.config, "tui.json") : path.join(process.cwd(), ".mendcode", "tui.json") } + +const ValidateCommand = cmd({ + command: "validate ", + describe: "validate a MendCode theme JSON document without starting the TUI", + builder: (yargs: Argv) => yargs.positional("file", { type: "string", demandOption: true }), + handler: async (args: { file: string }) => { + const document = JSON.parse(await readFile(path.resolve(args.file), "utf8")) + const errors = validateThemeDocument(document) + const result = { ok: errors.length === 0, file: path.resolve(args.file), errors, callsProviders: false } + console.log(JSON.stringify(result, null, 2)) + if (errors.length) process.exitCode = 1 + }, +}) + +const InstallCommand = cmd({ + command: "install ", + describe: "install a validated theme into the project or global MendCode theme directory", + builder: (yargs: Argv) => yargs + .positional("file", { type: "string", demandOption: true }) + .option("name", { type: "string", describe: "theme name; defaults to the source filename" }) + .option("scope", { choices: ["project", "global"] as const, default: "project" }), + handler: async (args: { file: string; name?: string; scope?: string }) => { + const source = path.resolve(args.file) + const document = JSON.parse(await readFile(source, "utf8")) + const errors = validateThemeDocument(document) + if (errors.length) throw new Error(`Invalid theme:\n${errors.map((x) => `- ${x}`).join("\n")}`) + const name = (args.name ?? path.basename(source, path.extname(source))).trim() + if (!/^[a-z0-9][a-z0-9._-]*$/i.test(name)) throw new Error("Theme name must contain only letters, numbers, dot, underscore, or hyphen") + const dir = themeDir(scope(args)) + await mkdir(dir, { recursive: true }) + const destination = path.join(dir, `${name}.json`) + await writeFile(destination, JSON.stringify(document, null, 2) + "\n", "utf8") + console.log(JSON.stringify({ ok: true, name, scope: scope(args), path: destination, callsProviders: false }, null, 2)) + }, +}) + +const SelectCommand = cmd({ + command: "select ", + describe: "select an installed MendCode theme in tui.json", + builder: (yargs: Argv) => yargs + .positional("name", { type: "string", demandOption: true }) + .option("scope", { choices: ["project", "global"] as const, default: "project" }), + handler: async (args: { name: string; scope?: string }) => { + const selected = scope(args) + const file = path.join(themeDir(selected), `${args.name}.json`) + await readFile(file, "utf8") + const config = tuiFile(selected) + await mkdir(path.dirname(config), { recursive: true }) + let data: Record = {} + try { data = JSON.parse(await readFile(config, "utf8")) } catch { /* create a minimal config */ } + await writeFile(config, JSON.stringify({ ...data, theme: args.name }, null, 2) + "\n", "utf8") + console.log(JSON.stringify({ ok: true, name: args.name, scope: selected, config, callsProviders: false }, null, 2)) + }, +}) + +export const ThemeCommand = cmd({ + command: "theme", + describe: "validate, install, and select agent-authored MendCode themes", + builder: (yargs: Argv) => yargs.command(ValidateCommand).command(InstallCommand).command(SelectCommand).demandCommand(), + handler: () => {}, +}) diff --git a/src/mendcode/packages/opencode/src/cli/cmd/tui/app.tsx b/src/mendcode/packages/opencode/src/cli/cmd/tui/app.tsx index 591ef618..4819e2d2 100644 --- a/src/mendcode/packages/opencode/src/cli/cmd/tui/app.tsx +++ b/src/mendcode/packages/opencode/src/cli/cmd/tui/app.tsx @@ -14,7 +14,9 @@ import { onCleanup, batch, Show, + For, on, + type JSX, } from "solid-js" import { win32DisableProcessedInput, win32InstallCtrlCGuard } from "./win32" import { Flag } from "@mendcode/core/flag/flag" @@ -27,9 +29,12 @@ import { ProjectProvider, useProject } from "@tui/context/project" import { EditorContextProvider } from "@tui/context/editor" import { useEvent } from "@tui/context/event" import { SDKProvider, useSDK } from "@tui/context/sdk" -import { StartupLoading } from "@tui/component/startup-loading" +import { StartupLoading, startupLoadingText } from "@tui/component/startup-loading" +import { FirstRunIntro } from "@tui/component/first-run-intro" import { SyncProvider, useSync } from "@tui/context/sync" import { SyncProviderV2 } from "@tui/context/sync-v2" +import { SessionControlProvider } from "@tui/context/session-control" +import { QuestionControlProvider } from "@tui/context/question-control" import { LocalProvider, useLocal } from "@tui/context/local" import { DialogModel } from "@tui/component/dialog-model" import { useConnected } from "@tui/component/use-connected" @@ -46,11 +51,18 @@ import { ThemeProvider, useTheme } from "@tui/context/theme" import { Home } from "@tui/routes/home" import { Session } from "@tui/routes/session" import { Setup } from "@tui/routes/setup" +import { Stats } from "@tui/routes/stats" +import { Memory } from "@tui/routes/memory" +import { Changes } from "@tui/routes/changes" +import { Loops } from "@tui/routes/loops" +import { Workflows } from "@tui/routes/workflows" +import { SessionHistory } from "@tui/routes/session-history" import { PromptHistoryProvider } from "./component/prompt/history" import { FrecencyProvider } from "./component/prompt/frecency" import { PromptStashProvider } from "./component/prompt/stash" import { DialogAlert } from "./ui/dialog-alert" import { DialogConfirm } from "./ui/dialog-confirm" +import { DialogCustomization, type TuiCustomizationAction } from "@tui/component/dialog-customization" import { showDialogObject } from "./ui/dialog-object" import { DialogPrompt } from "./ui/dialog-prompt" import { DialogSelect, type DialogSelectOption } from "./ui/dialog-select" @@ -69,8 +81,11 @@ import { createTuiApi } from "@/cli/cmd/tui/plugin/api" import { TuiPluginRuntime } from "@/cli/cmd/tui/plugin/runtime" import type { RouteMap } from "@/cli/cmd/tui/plugin/api" import { FormatError, FormatUnknownError } from "@/cli/error" +import { Locale } from "@/util/locale" +import { backgroundTaskToast } from "@tui/util/background-task-notification" +import { checkUpgrade, skippedUpdateVersion, SKIPPED_UPDATE_VERSION_KEY } from "@/cli/upgrade" -import type { EventSource } from "./context/sdk" +import type { EventSource, SDKConnectionRefresh } from "./context/sdk" import { DialogVariant } from "./component/dialog-variant" import { MendTuiProfileProvider, useMendTuiProfile } from "./context/mend" import type { MendTuiProfile } from "@/mend/profile" @@ -81,18 +96,14 @@ import { deactivateMflow, mflowLocalRelayGuide, mflowControlStatus, + isLegacyPublicMflowRelay, removeMflowConfig, scanMflowRelays, + startMflowDaemon, + stopMflowDaemon, type MflowRelayMode, } from "@/mend/config/mflow" -import { - activateTsm, - deactivateTsm, - removeTsm, - setupTsm, - tsmPlan, - tsmStatus, -} from "@/mend/config/tsm" +import { activateTsm, deactivateTsm, removeTsm, setupTsm, tsmPlan, tsmStatus } from "@/mend/config/tsm" import { worktreeAdopt, worktreeCreate, @@ -113,11 +124,30 @@ import { type RuntimePackSelection, } from "@/mend/runtime/pack" import { packageMetadata, packageMetadataSet, syncProject } from "@/mend/config/project" -import { cyclePromptMode, writePromptMode, type MendPromptMode } from "@/mend/prompt/mode" +import { + availablePromptModes, + cyclePromptMode, + promptModeLabel, + writePromptMode, + type MendPromptMode, +} from "@/mend/prompt/mode" import { readActiveTuiProfile, writeActiveTuiProfile } from "@/mend/tui/profile-actions" +import { + DEFAULT_MEND_TUI_CUSTOMIZATION, + readMendTuiCustomization, + resolveMendTerminalTitle, + writeMendTuiCustomization, +} from "@/mend/tui/customization" import { setupReadiness } from "@/mend/runtime/readiness" import { isSetupComplete, readSetupState } from "@/mend/setup/state" -import { runtimeRegistryApply, runtimeRegistryPreview, runtimeRegistrySearch, runtimeRegistryShow, runtimeRegistryStatus } from "@/mend/runtime/registry" +import { + runtimeRegistryAdd, + runtimeRegistryInstallPack, + runtimeRegistryRemove, + runtimeRegistrySearch, + runtimeRegistryShow, + runtimeRegistryStatus, +} from "@/mend/runtime/registry" import type { RegistryMarketplacePackManifest } from "@/mend/runtime/registry/marketplace" import { disableAllMendPackages, @@ -125,8 +155,15 @@ import { removeMendPackage, setMendPackageEnabled, } from "@/mend/runtime/packages" -import { writeProjectMemoryConfig, type MemoryConfig } from "@/mend/memory/config" -import { readPermissionsConfig } from "@/mend/config/permissions" +import { resolveProjectMemoryRoot, writeProjectMemoryConfig, type MemoryConfig } from "@/mend/memory/config" +import { readPermissionsConfig, writePermissionsConfig, type PermissionMode } from "@/mend/config/permissions" +import { + homePromptBootstrapReady, + initialTuiPluginReady, + themeModeWaitMs, + tuiFastBootEnabled, +} from "@/cli/cmd/tui/util/fast-boot" +import { FIRST_RUN_INTRO_SEEN_KEY, shouldShowFirstRunIntro } from "@/cli/cmd/tui/util/first-run-intro" import { appendMemoryEntry, deleteMemoryEntry, @@ -144,7 +181,25 @@ import { } from "@/mend/memory/proposals" import type { MendPromptChromePreset } from "@/mend/tui/prompt-chrome" import { defaultPromptStatus, type MendPromptStatusBuiltin, type MendPromptStatusItem } from "@/mend/tui/prompt-status" -import { resolveTuiPresentation, type MendPresentationProfile } from "@/mend/tui/presentation" +import { + messageRendererForPresentationProfile, + presentationProfileTitle, + resolveTuiPresentation, + type MendCompactionArcade, + type MendCompactionStyle, + type MendMessageRenderer, + type MendPresentationProfile, +} from "@/mend/tui/presentation" +import { defaultHomeMascot } from "@/mend/tui/mascot" +import { + clearMendOverlay, + focusMendOverlay, + listMendOverlays, + mendOverlayRenderContext, + readFocusedMendOverlayID, + type MendOverlayEntry, +} from "@/mend/tui/overlays" +import { formatDiagnostics, type DiagnosticsSnapshot } from "@/util/process-memory" function rendererConfig(_config: TuiConfig.Info): CliRendererConfig { const mouseEnabled = !Flag.OPENCODE_DISABLE_MOUSE && (_config.mouse ?? true) @@ -173,6 +228,25 @@ function canStartInteractiveTui() { return process.stdin.isTTY && (process.stdout.isTTY || process.stderr.isTTY) } +function releaseTerminalInputModes() { + const out = process.stdout.isTTY ? process.stdout : process.stderr.isTTY ? process.stderr : undefined + out?.write("\x1b[?1000l\x1b[?1002l\x1b[?1003l\x1b[?1005l\x1b[?1006l\x1b[?1015l\x1b[?2004l") + const stdin = process.stdin as typeof process.stdin & { setRawMode?: (mode: boolean) => unknown } + if (process.stdin.isTTY && typeof stdin.setRawMode === "function") { + try { + stdin.setRawMode(false) + } catch { + // Best-effort terminal recovery before yielding control to the parent shell. + } + } +} + +function permissionModeTitle(mode: PermissionMode) { + if (mode === "full_access") return "Full Access" + if (mode === "smart") return "Smart Approval" + return "Require approval" +} + function errorMessage(error: unknown) { const formatted = FormatError(error) if (formatted !== undefined) return formatted @@ -182,19 +256,130 @@ function errorMessage(error: unknown) { "data" in error && typeof error.data === "object" && error.data !== null && - "message" in error.data && - typeof error.data.message === "string" + (("message" in error.data && typeof error.data.message === "string") || + ("error" in error.data && typeof error.data.error === "string")) ) { - return error.data.message + if ("message" in error.data && typeof error.data.message === "string") return error.data.message + if ("error" in error.data && typeof error.data.error === "string") return error.data.error } return FormatUnknownError(error) } +function overlaySize(value: MendOverlayEntry["width"], total: number, fallback: number) { + if (typeof value === "number") return Math.max(1, Math.min(total, value)) + if (typeof value === "string" && value.endsWith("%")) + return Math.max(1, Math.min(total, Math.floor((total * Number(value.slice(0, -1))) / 100))) + return Math.max(1, Math.min(total, fallback)) +} + +function overlayFrame(item: MendOverlayEntry, dimensions: { width: number; height: number }) { + const margin = item.margin + const availableWidth = Math.max(1, dimensions.width - margin.left - margin.right) + const availableHeight = Math.max(1, dimensions.height - margin.top - margin.bottom) + const width = overlaySize(item.width, availableWidth, Math.min(90, availableWidth)) + const maxHeight = overlaySize(item.maxHeight, availableHeight, availableHeight) + const height = Math.min(overlaySize(item.height, availableHeight, Math.min(12, availableHeight)), maxHeight) + const centerLeft = margin.left + Math.max(0, Math.floor((availableWidth - width) / 2)) + const centerTop = margin.top + Math.max(0, Math.floor((availableHeight - height) / 2)) + return { + width, + height, + left: item.anchor.endsWith("right") + ? dimensions.width - margin.right - width + : item.anchor.endsWith("left") + ? margin.left + : centerLeft, + top: item.anchor.startsWith("bottom") + ? dimensions.height - margin.bottom - height + : item.anchor.startsWith("top") + ? margin.top + : centerTop, + } +} + +function RenderMendOverlay(props: { item: MendOverlayEntry; dimensions: { width: number; height: number } }) { + const { theme } = useTheme() + const renderer = useRenderer() + const frame = createMemo(() => overlayFrame(props.item, props.dimensions)) + const focused = createMemo(() => readFocusedMendOverlayID() === props.item.id) + const rendered = createMemo(() => props.item.render(mendOverlayRenderContext(props.item))) + const primitive = createMemo(() => { + const value = rendered() + if (typeof value === "string" || typeof value === "number") return String(value) + if (typeof value === "boolean") return value ? "true" : "" + return undefined + }) + const fallback = (error: unknown) => ( + + + Overlay error · {errorMessage(error)} + + + ) + return ( + { + if (props.item.nonCapturing) return + focusMendOverlay(props.item.id) + event.target?.focus() + }} + onKeyDown={(event) => { + if (props.item.nonCapturing) return + if (event.name !== "escape") return + if (renderer.getSelection()?.getSelectedText()) return + clearMendOverlay(props.item.id) + event.preventDefault() + event.stopPropagation() + }} + > + + {(title) => ( + + {title()} + + )} + + + + + {primitive()} + + + + + ) +} + +function MendOverlayHost(props: { dimensions: { width: number; height: number } }) { + return ( + {(item) => } + ) +} + function cleanMarketplaceVersion(version: string | undefined) { if (!version || version === "0") return "unversioned" return version } +function OptionalSyncProviderV2(props: { children: JSX.Element }) { + if (!Flag.OPENCODE_EXPERIMENTAL_SESSION_V2_DEBUG) return props.children + return {props.children} +} + function marketplaceRuntimeSummary(pack: RegistryMarketplacePackManifest) { const runtime = pack.runtime || {} const items = [ @@ -203,6 +388,9 @@ function marketplaceRuntimeSummary(pack: RegistryMarketplacePackManifest) { ["modes", runtime.modes], ["skills", runtime.skills], ["plugins", runtime.plugins], + ["tools", runtime.tools], + ["pages", runtime.pages], + ["widgets", runtime.widgets], ["prompts", runtime.prompts], ["MCP", runtime.mcpFiles], ["extensions", runtime.extensions], @@ -212,6 +400,77 @@ function marketplaceRuntimeSummary(pack: RegistryMarketplacePackManifest) { return items.length ? items.join(" · ") : "No runtime artifacts advertised" } +function marketplaceShortSummary(pack: RegistryMarketplacePackManifest) { + return Locale.truncate(marketplaceRuntimeSummary(pack), 90) +} + +function marketplaceSourceIDFromURL(value: string) { + const clean = value.trim().replace(/\.git$/, "") + const last = clean.split(/[/:]/).filter(Boolean).at(-1) || "package-source" + const slug = last + .toLowerCase() + .replace(/[^a-z0-9._-]+/g, "-") + .replace(/^-+|-+$/g, "") + return `url-${slug || "package-source"}`.slice(0, 64) +} + +function isPublicGitHubMarketplaceURL(value: string) { + try { + const url = new URL(value.trim()) + return ( + url.protocol === "https:" && + url.hostname.toLowerCase() === "github.com" && + !url.username && + !url.password && + !url.search && + !url.hash && + url.pathname.split("/").filter(Boolean).length === 2 + ) + } catch { + return false + } +} + +function marketplaceInstallBadge(packID: string, installed: Awaited>["installed"]) { + const found = installed.find((item) => item.id === packID) + if (!found) return null + return found.enabled ? "active" : "installed" +} + +function marketplaceBadgeTitle(title: string, badge?: string | null) { + return `${badge ? `[${badge}] ` : ""}${title}` +} + +function marketplaceSearchText(parts: Array) { + return parts.filter(Boolean).join(" ") +} + +function marketplaceStatusCategory(input: { badge?: string | null; sourceID?: string; channel?: string | null }) { + const state = input.badge === "active" ? "Active" : input.badge === "installed" ? "Installed" : undefined + const source = input.channel || input.sourceID + return [state, source].filter(Boolean).join(" · ") || "Packages" +} + +function marketplaceSourceSafetyLines(input: { + sourceID: string + sourceType?: string + url?: string | null + digest?: { algorithm: "sha256"; value: string } + signature?: { algorithm: "sha256"; value: string } +}) { + if (input.sourceID === "official" || input.sourceID === "local") return [] + return [ + "Security preview:", + `- Source: ${input.url || input.sourceID}`, + `- Type: ${input.sourceType || "unknown"}`, + `- Digest: ${input.digest ? `${input.digest.algorithm}:${input.digest.value.slice(0, 12)}...` : "not pinned"}`, + `- Signature: ${input.signature ? `${input.signature.algorithm}:${input.signature.value.slice(0, 12)}...` : "not signed"}`, + "- Trust only repos you expect to run MendCode package content from.", + "- Packages may add commands, skills, plugins, widgets, pages, scripts, and MCP config.", + "- MendCode copies allowlisted package files only; local sessions, auth, runs, cache, and customizations stay untouched.", + ] +} + function marketplacePackDetails(pack: RegistryMarketplacePackManifest, sourceID: string) { const lines = [ `Name: ${pack.title || pack.id}`, @@ -236,6 +495,30 @@ function marketplacePackDetails(pack: RegistryMarketplacePackManifest, sourceID: return lines.filter((line): line is string => line !== null).join("\n") } +function PluginRouteError(props: { id: string; error: unknown }) { + const { theme } = useTheme() + const message = props.error instanceof Error ? props.error.message : String(props.error) + + onMount(() => { + console.error("[tui.plugin.route] render error", { + route: props.id, + message, + }) + }) + + return ( + + + Plugin route failed: {props.id} + + {message} + + esc or command palette can return to a normal route. + + + ) +} + function registryStatusText(status: Awaited>) { const redactionShared = status.redaction?.shared || [] return [ @@ -260,9 +543,7 @@ function registryStatusText(status: Awaited `- ${item}`) - : ["- none"]), + ...(redactionShared.length ? redactionShared.slice(0, 12).map((item) => `- ${item}`) : ["- none"]), ...(redactionShared.length > 12 ? [`- ...and ${redactionShared.length - 12} more`] : []), ].join("\n") } @@ -275,6 +556,8 @@ type MemoryManagerOption = DialogSelectOption & { function MemoryManagerPreview(props: { option: MemoryManagerOption }) { const { theme } = useTheme() + const dimensions = useTerminalDimensions() + const previewHeight = createMemo(() => Math.max(5, Math.min(12, Math.floor(dimensions().height * 0.22)))) return ( - - {props.option.previewBody || props.option.description || "No extra details."} - + 360 }} + > + + {props.option.previewBody || props.option.description || "No extra details."} + + ) @@ -317,16 +606,21 @@ export function tui(input: { config?: unknown } onSnapshot?: () => Promise + onStartupReady?: () => Promise + onDiagnostics?: () => Promise directory?: string fetch?: typeof fetch headers?: RequestInit["headers"] events?: EventSource + reconnect?: Parameters[0]["reconnect"] }) { // promise to prevent immediate exit // oxlint-disable-next-line no-async-promise-executor -- intentional: async executor used for sequential setup before resolve return new Promise(async (resolve) => { if (!canStartInteractiveTui()) { - process.stderr.write("Error: mend TUI requires an interactive terminal. Use `mend run` for non-interactive input.\n") + process.stderr.write( + "Error: mend TUI requires an interactive terminal. Use `mendcode run` for non-interactive input.\n", + ) process.exitCode = 1 resolve() return @@ -337,6 +631,7 @@ export function tui(input: { const onExit = async () => { unguard?.() + releaseTerminalInputModes() resolve() } @@ -344,10 +639,11 @@ export function tui(input: { await TuiPluginRuntime.dispose() } + const fastBoot = tuiFastBootEnabled() const renderer = await createCliRenderer(rendererConfig(input.config)) // Prewarm palette before ThemeProvider mounts so `system` theme avoids a first-paint fallback flash. void renderer.getPalette({ size: 16 }).catch(() => undefined) - const mode = (await renderer.waitForThemeMode(1000)) ?? "dark" + const mode = (await renderer.waitForThemeMode(themeModeWaitMs(fastBoot))) ?? "dark" await render(() => { return ( @@ -383,33 +679,42 @@ export function tui(input: { fetch={input.fetch} headers={input.headers} events={input.events} + reconnect={input.reconnect} > - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -425,7 +730,7 @@ export function tui(input: { }) } -function App(props: { onSnapshot?: () => Promise }) { +function App(props: { onSnapshot?: () => Promise; onDiagnostics?: () => Promise; onStartupReady?: () => Promise }) { const tuiConfig = useTuiConfig() const route = useRoute() const dimensions = useTerminalDimensions() @@ -448,8 +753,36 @@ function App(props: { onSnapshot?: () => Promise }) { const sync = useSync() const exit = useExit() const promptRef = usePromptRef() + const [firstRunIntroVisible, setFirstRunIntroVisible] = createSignal(false) + const [firstRunIntroRun, setFirstRunIntroRun] = createSignal(0) + const completeFirstRunIntro = () => { + if (!firstRunIntroVisible()) return + setFirstRunIntroVisible(false) + kv.set(FIRST_RUN_INTRO_SEEN_KEY, true) + } + const replayFirstRunIntro = () => { + dialog.clear() + setFirstRunIntroRun((value) => value + 1) + setFirstRunIntroVisible(true) + } + + useKeyboard((evt) => { + if (!firstRunIntroVisible() || evt.defaultPrevented) return + if (keybind.match("app_exit", evt)) { + evt.preventDefault() + evt.stopPropagation() + void exit() + return + } + evt.preventDefault() + evt.stopPropagation() + completeFirstRunIntro() + }) + const routes: RouteMap = new Map() const [routeRev, setRouteRev] = createSignal(0) + const [homeRevision, setHomeRevision] = createSignal(0) + const promptRouteActive = createMemo(() => route.data.type === "home" || route.data.type === "session") const routeView = (name: string) => { routeRev() return routes.get(name)?.at(-1)?.render @@ -471,23 +804,31 @@ function App(props: { onSnapshot?: () => Promise }) { toast, renderer, }) - const [ready, setReady] = createSignal(false) - TuiPluginRuntime.init({ - api, - config: tuiConfig, - }) - .catch((error) => { - console.error("Failed to load TUI plugins", error) - }) - .finally(() => { - setReady(true) - }) + const fastBoot = tuiFastBootEnabled() + const [ready, setReady] = createSignal(initialTuiPluginReady(fastBoot)) + const [pluginsReady, setPluginsReady] = createSignal(false) + onMount(() => { + const loadPlugins = () => { + void TuiPluginRuntime.init({ + api, + config: tuiConfig, + }) + .catch((error) => { + console.error("Failed to load TUI plugins", error) + }) + .finally(() => { + setPluginsReady(true) + setReady(true) + }) + } - const permissionConfigSummary = createMemo(() => { - const permission = sync.data.config.permission - if (permission === undefined) return "No explicit project permission config loaded. Runtime defaults still apply." - if (typeof permission === "string") return `permission: ${permission}` - return JSON.stringify(permission, null, 2) + if (!fastBoot) { + loadPlugins() + return + } + + const pluginTimer = setTimeout(loadPlugins, 0) + if (typeof pluginTimer === "object") pluginTimer.unref() }) useKeyboard((evt) => { @@ -498,24 +839,56 @@ function App(props: { onSnapshot?: () => Promise }) { command.trigger("session.list") }) - async function showGlobalPermissionStatus() { + useKeyboard((evt) => { + if (evt.defaultPrevented || dialog.stack.length > 0) return + if (!promptRouteActive()) return + if (!keybind.match("agent_mode_picker", evt)) return + evt.preventDefault() + evt.stopPropagation() + showAgentModePicker() + }) + + async function showDefaultPermissionMode() { const permissions = await readPermissionsConfig() - await DialogAlert.show( - dialog, - "Permission mode", - [ - `Global default: ${permissions.mode === "full_access" ? "Full Access" : permissions.mode === "smart" ? "Smart Approval" : "Require approval"}`, - `Smart reviewer role: ${permissions.reviewerRole}`, - "", - "Interactive Full Access and Smart Approval are available from a session command palette.", - "Open a session, press Ctrl+P, then search for `permission`.", - "", - "Config permission:", - permissionConfigSummary(), - "", - "--dangerously-skip-permissions only applies to `mend run`; it does not toggle an already-running TUI session.", - ].join("\n"), - ) + dialog.replace(() => ( + { + if (option.value !== "approval" && option.value !== "smart" && option.value !== "full_access") return + const mode: PermissionMode = option.value + void writePermissionsConfig({ mode }) + .then(() => { + toast.show({ + message: `Default approval mode saved: ${permissionModeTitle(mode)}.`, + variant: "success", + duration: 4000, + }) + dialog.clear() + }) + .catch((error) => { + toast.show({ message: errorMessage(error), variant: "error", duration: 5000 }) + }) + }} + /> + )) } useKeyboard((evt) => { @@ -553,6 +926,14 @@ function App(props: { onSnapshot?: () => Promise }) { renderer.clearSelection() }) + createEffect(() => { + if (promptRouteActive()) return + promptRef.current?.blur() + const focus = renderer.currentFocusedRenderable + if (!focus || focus.isDestroyed) return + focus.blur() + }) + // Wire up console copy-to-clipboard via opentui's onCopySelection callback renderer.console.onCopySelection = async (text: string) => { if (!text || text.length === 0) return @@ -563,40 +944,67 @@ function App(props: { onSnapshot?: () => Promise }) { renderer.clearSelection() } - const [terminalTitleEnabled, setTerminalTitleEnabled] = createSignal(kv.get("terminal_title_enabled", true)) + const tuiCustomization = createMemo(() => readMendTuiCustomization((key, fallback) => kv.get(key, fallback))) + const terminalTitleEnabled = createMemo(() => tuiCustomization().terminalTitle) const [pasteSummaryEnabled, setPasteSummaryEnabled] = createSignal( - kv.get("paste_summary_enabled", !sync.data.config.experimental?.disable_paste_summary), + kv.get( + "paste_summary_enabled", + sync.data.config.experimental?.disable_paste_summary === undefined + ? mend.profile.presentation.input.pasteSummary + : !sync.data.config.experimental.disable_paste_summary, + ), ) - // Update terminal window title based on current route and session + // Update terminal window title based on the live customization contract. createEffect(() => { - if (!terminalTitleEnabled() || Flag.OPENCODE_DISABLE_TERMINAL_TITLE) return - - if (route.data.type === "home") { - renderer.setTerminalTitle(productName()) - return - } - - if (route.data.type === "session") { - const session = sync.session.get(route.data.sessionID) - if (!session || SessionApi.isDefaultTitle(session.title)) { - renderer.setTerminalTitle(productName()) - return - } - - const title = session.title.length > 40 ? session.title.slice(0, 37) + "..." : session.title - renderer.setTerminalTitle(`${productName()} | ${title}`) + const customization = tuiCustomization() + if (Flag.OPENCODE_DISABLE_TERMINAL_TITLE) return + if (!customization.terminalTitle) { + renderer.setTerminalTitle("") return } - if (route.data.type === "plugin") { - renderer.setTerminalTitle(`${productName()} | ${route.data.id}`) + const session = route.data.type === "session" ? sync.session.get(route.data.sessionID) : undefined + const routeLabel = + route.data.type === "home" + ? "Home" + : route.data.type === "session" + ? "Session" + : route.data.type === "plugin" + ? route.data.id + : route.data.type === "setup" + ? "Setup" + : route.data.type === "memory" + ? "Memory" + : route.data.type === "changes" + ? "Changes" + : route.data.type === "loops" + ? "Loops" + : route.data.type === "workflows" + ? "Workflows" + : route.data.type === "session-history" + ? "Session History" + : route.data.type + const sessionLabel = session && !SessionApi.isDefaultTitle(session.title) ? session.title : routeLabel + if ( + route.data.type === "home" && + customization.terminalTitleTemplate === DEFAULT_MEND_TUI_CUSTOMIZATION.terminalTitleTemplate + ) { + renderer.setTerminalTitle(productName()) return } - - if (route.data.type === "setup") { - renderer.setTerminalTitle(`${productName()} | Setup`) - } + renderer.setTerminalTitle( + resolveMendTerminalTitle({ + template: customization.terminalTitleTemplate, + product: productName(), + session: sessionLabel.length > 40 ? sessionLabel.slice(0, 37) + "..." : sessionLabel, + route: routeLabel, + path: + route.data.type === "session" + ? session?.directory || project.instance.path().directory + : project.instance.path().directory, + }), + ) }) const args = useArgs() @@ -682,32 +1090,70 @@ function App(props: { onSnapshot?: () => Promise }) { let setupRedirectChecked = false createEffect(() => { - if (setupRedirectChecked || !ready() || sync.status === "loading") return + if (setupRedirectChecked || !ready() || !pluginsReady() || sync.status === "loading" || !kv.ready) return if (route.data.type !== "home") return setupRedirectChecked = true void Promise.all([readSetupState(mend.root), setupReadiness(mend.root)]) .then(([state, readiness]) => { if (isSetupComplete(state)) return if (readiness.aiReady) return - route.navigate({ type: "setup", step: state.currentStep, minimal: Boolean(state.dismissedAt) }) + if ( + shouldShowFirstRunIntro({ + interactive: true, + setupComplete: isSetupComplete(state), + dismissed: Boolean(state.dismissedAt), + seen: kv.get(FIRST_RUN_INTRO_SEEN_KEY, false) === true, + }) + ) { + dialog.clear() + setFirstRunIntroRun((value) => value + 1) + setFirstRunIntroVisible(true) + } + route.navigate({ type: "setup", step: state.currentStep }) }) .catch(toast.error) }) const connected = useConnected() const mendCategory = "System" - const memoryRoot = () => project.instance.path().worktree || project.instance.path().directory || mend.root + const memoryRoot = () => + resolveProjectMemoryRoot(project.instance.path().worktree, project.instance.path().directory) || mend.root + const currentSessionReturn = () => + route.data.type === "session" ? ({ type: "session", sessionID: route.data.sessionID } as const) : undefined + const setupRoute = (step?: "provider" | "models" | "budget") => { + const returnTo = currentSessionReturn() + const base = step ? { type: "setup" as const, step } : { type: "setup" as const } + return returnTo ? { ...base, returnTo } : base + } + const statsRoute = (scope: "global" | "project") => { + const returnTo = currentSessionReturn() + return returnTo ? { type: "stats" as const, scope, returnTo } : { type: "stats" as const, scope } + } + const changesRoute = () => { + const returnTo = currentSessionReturn() + return returnTo ? { type: "changes" as const, returnTo } : { type: "changes" as const } + } + const loopsRoute = (selectedID?: string) => { + const returnTo = currentSessionReturn() + return returnTo ? { type: "loops" as const, selectedID, returnTo } : { type: "loops" as const, selectedID } + } + const workflowsRoute = (selectedID?: string) => { + const returnTo = currentSessionReturn() + return returnTo ? { type: "workflows" as const, selectedID, returnTo } : { type: "workflows" as const, selectedID } + } const showMendStatus = async (title = "MendCode Status") => { await DialogAlert.show(dialog, title, await mendStatusSummary(mend.root)) } const mflowStatusLine = async () => { const status = await mflowControlStatus(mend.root) const config = status.config - const relayLabel = config.relayMode === "local" - ? "Local" - : config.relayMode === "legacy-public" || (config.relayMode === "public" && config.signaling.includes("mflow-signal.obed0101.deno.net")) - ? "Legacy public" - : "Public" + const relayLabel = + config.relayMode === "local" + ? "Local" + : config.relayMode === "legacy-public" || + (config.relayMode === "public" && isLegacyPublicMflowRelay(config.signaling)) + ? "Legacy public" + : "Public" return { status, line: `${status.mode} · ${config.relayMode} · ${config.room}`, @@ -716,16 +1162,23 @@ function App(props: { onSnapshot?: () => Promise }) { locks: status.locks.checked ? "locks available" : "locks unavailable", } } - const mflowDaemonValue = (output: string | undefined, label: string) => { - return output?.match(new RegExp(`^\\s*${label}:\\s*(.+)$`, "m"))?.[1]?.trim() ?? "unknown" + const mflowDaemonValue = (status: Awaited>, label: string) => { + const parsed = status.daemon.output?.match(new RegExp(`^\\s*${label}:\\s*(.+)$`, "m"))?.[1]?.trim() + if (parsed) return parsed + if (!status.daemon.checked) return label === "State" ? "not checked" : "unavailable" + if (!status.daemon.running) return label === "State" ? "not running" : "unavailable" + return "unknown" } const showTsmManager = async () => { const status = await tsmStatus(mend.root) const workspace = status.workspace - const currentLabel = workspace.isLinkedWorktree ? `worktree ${workspace.currentBranch || "detached"}` : `base ${workspace.currentBranch || "detached"}` + const currentLabel = workspace.isLinkedWorktree + ? `worktree ${workspace.currentBranch || "detached"}` + : `base ${workspace.currentBranch || "detached"}` dialog.replace(() => ( Promise }) { const showWorktreeManager = async () => { const status = await worktreeStatus(mend.root) const workspace = status.workspace - const currentLabel = workspace.isLinkedWorktree ? `worktree ${workspace.currentBranch || "detached"}` : `base ${workspace.currentBranch || "detached"}` + const currentLabel = workspace.isLinkedWorktree + ? `worktree ${workspace.currentBranch || "detached"}` + : `base ${workspace.currentBranch || "detached"}` dialog.replace(() => ( Promise }) { category: "Actions", description: "Show destructive gate; no git commands run.", onSelect: async () => { - const target = await DialogPrompt.show(dialog, "worktree to remove", { placeholder: "id, branch, or path" }) + const target = await DialogPrompt.show(dialog, "worktree to remove", { + placeholder: "id, branch, or path", + }) if (!target) return const result = await worktreeRemove([target], mend.root) await showDialogObject(dialog, "Worktree remove preview", result.previewText || result) @@ -904,7 +1362,9 @@ function App(props: { onSnapshot?: () => Promise }) { category: "Actions", description: "Show destructive gate; no reset or clean runs.", onSelect: async () => { - const target = await DialogPrompt.show(dialog, "worktree to reset", { placeholder: "id, branch, or path" }) + const target = await DialogPrompt.show(dialog, "worktree to reset", { + placeholder: "id, branch, or path", + }) if (!target) return const result = await worktreeReset([target], mend.root) await showDialogObject(dialog, "Worktree reset preview", result.previewText || result) @@ -919,11 +1379,17 @@ function App(props: { onSnapshot?: () => Promise }) { const current = await mflowStatusLine() const status = current.status const config = status.config - const dashboard = status.daemon.output?.match(/https:\/\/\S+\/dashboard/)?.[0] ?? "https://mflow-signal.obed0101.deno.net/dashboard" + const dashboard = + status.daemon.output?.match(/https:\/\/\S+\/dashboard/)?.[0] ?? "https://mflow-signal.obed0101.deno.net/dashboard" const locksText = status.locks.output?.trim() || "No lock output." + const localRelayHelp = + config.relayMode === "local" && !status.daemon.running + ? "Local relay is configured but not running; use the start commands from mflow details." + : undefined dialog.replace(() => ( Promise }) { onSelect: () => {}, }, { - title: config.relayMode === "local" ? "Local relay" : config.relayMode === "legacy-public" || config.signaling.includes("mflow-signal.obed0101.deno.net") ? "Legacy public relay" : "Public relay URL", + title: + config.relayMode === "local" + ? "Local relay" + : config.relayMode === "legacy-public" || isLegacyPublicMflowRelay(config.signaling) + ? "Legacy public relay" + : "Public relay URL", value: "relay", category: "Connection", - description: config.signaling, + description: localRelayHelp ?? config.signaling, onSelect: () => {}, }, { @@ -949,17 +1420,21 @@ function App(props: { onSnapshot?: () => Promise }) { onSelect: () => {}, }, { - title: mflowDaemonValue(status.daemon.output, "State"), + title: mflowDaemonValue(status, "State"), value: "daemon", category: "Daemon", - description: `${mflowDaemonValue(status.daemon.output, "Peers")} peers · ${mflowDaemonValue(status.daemon.output, "Files")} · ${mflowDaemonValue(status.daemon.output, "Ops/s")} ops/s`, + description: status.daemon.running + ? `${mflowDaemonValue(status, "Peers")} peers · ${mflowDaemonValue(status, "Files")} · ${mflowDaemonValue(status, "Ops/s")} ops/s` + : status.daemon.output, onSelect: () => {}, }, { - title: mflowDaemonValue(status.daemon.output, "Uptime"), + title: mflowDaemonValue(status, "Uptime"), value: "uptime", category: "Daemon", - description: `memory ${mflowDaemonValue(status.daemon.output, "Memory")}`, + description: status.daemon.running + ? `memory ${mflowDaemonValue(status, "Memory")}` + : "daemon metrics unavailable while stopped", onSelect: () => {}, }, { @@ -976,6 +1451,24 @@ function App(props: { onSnapshot?: () => Promise }) { description: dashboard, onSelect: () => {}, }, + { + title: "Start daemon", + value: "start-daemon", + category: "Actions", + description: status.config.enabled + ? "Run mflow start with saved config." + : "Configure and turn on mflow first.", + disabled: !status.config.enabled || status.daemon.running, + onSelect: () => void startMflowDaemonFromTui(), + }, + { + title: "Stop daemon", + value: "stop-daemon", + category: "Actions", + description: "Run mflow stop for this repo.", + disabled: !status.daemon.running, + onSelect: () => void stopMflowDaemonFromTui(), + }, { title: "Back", value: "back", @@ -989,7 +1482,7 @@ function App(props: { onSnapshot?: () => Promise }) { } const configureAndActivateMflowFromTui = async () => { const current = (await mflowControlStatus(mend.root)).config - const currentIsLegacyPublic = current.relayMode === "legacy-public" || current.signaling.includes("mflow-signal.obed0101.deno.net") + const currentIsLegacyPublic = current.relayMode === "legacy-public" || isLegacyPublicMflowRelay(current.signaling) const showLocalRelayPicker = async (): Promise => { const scan = await scanMflowRelays() return new Promise((resolve) => { @@ -998,7 +1491,8 @@ function App(props: { onSnapshot?: () => Promise }) { () => ( ({ @@ -1009,18 +1503,24 @@ function App(props: { onSnapshot?: () => Promise }) { onSelect: () => resolve(relay.url), })), { - title: "Start local relay", + title: "Show relay start commands", value: "start", category: "Actions", - description: guide.commands[0], - onSelect: () => void showDialogObject(dialog, "Start local mflow relay", guide).then(() => resolve(null)), + description: "Show relay-server commands; use localhost after starting one.", + onSelect: () => + void showDialogObject(dialog, "Start local mflow relay", guide).then(() => + showLocalRelayPicker().then(resolve), + ), }, { - title: "Copy LAN relay URL", + title: "Show LAN relay URL", value: "copy", category: "Actions", description: guide.lanUrlExample, - onSelect: () => void showDialogObject(dialog, "LAN relay URL", guide).then(() => resolve(null)), + onSelect: () => + void showDialogObject(dialog, "LAN relay URL", guide).then(() => + showLocalRelayPicker().then(resolve), + ), }, { title: "Refresh scan", @@ -1033,7 +1533,8 @@ function App(props: { onSnapshot?: () => Promise }) { title: "Use localhost:8787", value: "localhost", category: "Actions", - description: "Use the default local relay URL even if the scan did not detect it.", + description: + "Configure MendCode for this relay URL; start the relay separately if scan did not detect it.", onSelect: () => resolve(guide.recommendedUrl), }, ]} @@ -1048,7 +1549,13 @@ function App(props: { onSnapshot?: () => Promise }) { () => ( Promise }) { } if (relayMode === "public") { const value = await DialogPrompt.show(dialog, "mflow relay URL", { - value: !currentIsLegacyPublic && (current.relayMode === "public" || current.relayMode === "remote" || current.relayMode === "custom") ? current.signaling : "wss://", + value: + !currentIsLegacyPublic && + (current.relayMode === "public" || current.relayMode === "remote" || current.relayMode === "custom") + ? current.signaling + : "wss://", placeholder: "wss://relay.example.com", }) if (value === null || value === undefined) return @@ -1123,9 +1634,10 @@ function App(props: { onSnapshot?: () => Promise }) { }) if (!secretMode) return - const secret = secretMode === "manual" - ? await DialogPrompt.show(dialog, "mflow room secret", { placeholder: "shared room secret" }) - : undefined + const secret = + secretMode === "manual" + ? await DialogPrompt.show(dialog, "mflow room secret", { placeholder: "shared room secret" }) + : undefined if (secretMode === "manual" && (secret === null || secret === undefined)) return const storeSecret = await DialogConfirm.show( @@ -1142,16 +1654,19 @@ function App(props: { onSnapshot?: () => Promise }) { }) if (priorityText === null || priorityText === undefined) return - await activateMflow({ - relayMode, - signaling, - room: room.trim(), - secret: secret?.trim(), - generateSecret: secretMode === "generate", - storeSecret: storeSecret === true, - hookPriority: Number(priorityText) || 0, - publicRelayNoticeAccepted, - }, mend.root) + await activateMflow( + { + relayMode, + signaling, + room: room.trim(), + secret: secret?.trim(), + generateSecret: secretMode === "generate", + storeSecret: storeSecret === true, + hookPriority: Number(priorityText) || 0, + publicRelayNoticeAccepted, + }, + mend.root, + ) await mend.reload() toast.show({ variant: "success", @@ -1178,11 +1693,42 @@ function App(props: { onSnapshot?: () => Promise }) { toast.show({ variant: "success", message: "mflow config removed.", duration: 4000 }) await showMflowManager() } + const startMflowDaemonFromTui = async () => { + const result = await startMflowDaemon(mend.root).catch((error) => { + toast.show({ + variant: "error", + message: `mflow daemon did not start: ${error instanceof Error ? error.message : String(error)}`, + duration: 7000, + }) + return undefined + }) + if (!result) return + toast.show({ + variant: "success", + message: result.daemon.running ? "mflow daemon started." : "mflow start ran, but daemon is not detected yet.", + duration: 5000, + }) + await showMflowManager() + } + const stopMflowDaemonFromTui = async () => { + const result = await stopMflowDaemon(mend.root).catch((error) => { + toast.show({ + variant: "error", + message: `mflow daemon did not stop: ${error instanceof Error ? error.message : String(error)}`, + duration: 7000, + }) + return undefined + }) + if (!result) return + toast.show({ variant: "success", message: "mflow daemon stopped.", duration: 4000 }) + await showMflowManager() + } const showMflowManager = async () => { const current = await mflowStatusLine() dialog.replace(() => ( Promise }) { description: "Choose local/public relay, room, secret handling, and queue priority.", onSelect: () => void configureAndActivateMflowFromTui(), }, + { + title: "Start daemon", + value: "start-daemon", + category: "Actions", + description: current.status.config.enabled + ? "Run mflow start for this repo using the saved room/relay/secret." + : "Configure and turn on mflow first.", + disabled: !current.status.config.enabled || current.status.daemon.running, + onSelect: () => void startMflowDaemonFromTui(), + }, + { + title: "Stop daemon", + value: "stop-daemon", + category: "Actions", + description: "Run mflow stop for this repo.", + disabled: !current.status.daemon.running, + onSelect: () => void stopMflowDaemonFromTui(), + }, { title: "Turn off", value: "deactivate", @@ -1236,27 +1800,35 @@ function App(props: { onSnapshot?: () => Promise }) { toast.show({ variant: "success", message, duration: 4000 }) await showMemoryManager(tab) } - const showPromptModes = () => { - const modes: Array<{ mode: MendPromptMode; title: string; description: string }> = [ - { mode: "minimal", title: "Minimal", description: "Small MendCode boundary only." }, - { mode: "focus", title: "Focus", description: "Provider-aware harness behavior." }, - { mode: "full", title: "Full", description: "Focus plus MendCode runtime context." }, - ] + const showPromptModes = async () => { + const available = await availablePromptModes(mend.root) + const details: Record = { + minimal: { title: "Minimal", description: "Small MendCode boundary only." }, + focus: { title: "Focus", description: "Provider-aware harness behavior." }, + full: { + title: "Full", + description: "Focus plus MendCode TODO, loop, cost, TUI, and extension context.", + }, + custom: { + title: mend.customPromptName || "Project prompt", + description: "Project-defined instructions from .mendcode/prompts/custom.md.", + }, + } dialog.replace(() => ( ({ - title: item.title, - value: item.mode, - description: item.description, - category: "Prompt Mode", + options={available.map((mode) => ({ + title: details[mode].title, + value: mode, + description: details[mode].description, + category: "Prompt Context", onSelect: async () => { - const result = await writePromptMode(item.mode, mend.root) + const result = await writePromptMode(mode, mend.root) await mend.reload() toast.show({ variant: "info", - message: `Prompt mode is now ${result.mode}.`, + message: `Prompt context is now ${promptModeLabel(result)}.`, duration: 4000, }) dialog.clear() @@ -1265,17 +1837,44 @@ function App(props: { onSnapshot?: () => Promise }) { /> )) } + const showAgentModePicker = () => { + dialog.setSize("large") + dialog.replace(() => ( + ({ + value: item.name, + title: item.name, + description: item.native ? "native" : item.description, + }))} + onSelect={(option) => { + local.agent.set(option.value) + local.model.pinAgentCurrent() + toast.show({ + variant: "info", + message: `Mode is now ${option.value}.`, + duration: 3000, + }) + dialog.clear() + }} + /> + )) + } const updatePromptChrome = async ( update: ( profile: Awaited>, ) => Awaited>, - message: string, + message?: string, ) => { const current = await readActiveTuiProfile(mend.root) const next = update(current) await writeActiveTuiProfile(next, mend.root) await mend.reload() - toast.show({ variant: "info", message, duration: 4000 }) + if (route.data.type === "home") setHomeRevision((value) => value + 1) + if (message) toast.show({ variant: "info", message, duration: 4000 }) dialog.clear() } const showPromptChromePresets = () => { @@ -1369,14 +1968,14 @@ function App(props: { onSnapshot?: () => Promise }) { title: "ASCII mascot", value: "mascot", category: "Home", - description: "Use the MendBug mascot on home and as compact activity feedback.", + description: "Use ASCII mascot art as the Home identity.", onSelect: () => void updatePromptChrome( (profile) => ({ ...profile, identity: { ...profile.identity, logoMode: "mascot" }, }), - "Home identity now uses the MendBug mascot.", + "Home identity now uses the default mascot.", ), }, ]} @@ -1392,12 +1991,31 @@ function App(props: { onSnapshot?: () => Promise }) { ), }) if (value === undefined || value === null) return + await updatePromptChrome((profile) => ({ + ...profile, + identity: { ...profile.identity, productName: normalizeProductName(value) }, + })) + } + const showHomeMascotText = async () => { + const value = await DialogPrompt.show(dialog, "Home mascot ASCII", { + value: mend.profile.surfaces.homeLogo?.text || "", + placeholder: defaultHomeMascot, + description: () => ( + Paste custom ASCII for Home. Blank resets to the default mascot. + ), + }) + if (value === undefined || value === null) return + const text = value.trimEnd() await updatePromptChrome( (profile) => ({ ...profile, - identity: { ...profile.identity, productName: normalizeProductName(value) }, + identity: { ...profile.identity, logoMode: "mascot" }, + surfaces: { + ...profile.surfaces, + homeLogo: text ? { ...(profile.surfaces.homeLogo || {}), text } : {}, + }, }), - `Home title updated to ${normalizeProductName(value)}.`, + text ? "Home mascot ASCII updated." : "Home mascot reset to the default ASCII.", ) } const showHomeLogoFont = () => { @@ -1433,42 +2051,15 @@ function App(props: { onSnapshot?: () => Promise }) { /> )) } - const showHomeLogoSize = () => { - const current = mend.profile.surfaces.homeLogo?.size || "default" - const options: Array<{ title: string; value: "compact" | "default" | "large"; description: string }> = [ - { title: "Compact", value: "compact", description: "Small MendBug for tighter home screens." }, - { title: "Default", value: "default", description: "Larger MendBug default identity." }, - { title: "Large", value: "large", description: "Big MendBug for spacious terminal starts." }, - ] - dialog.replace(() => ( - ({ - title: item.title, - value: item.value, - category: "Home", - description: item.description, - onSelect: () => - void updatePromptChrome( - (profile) => ({ - ...profile, - surfaces: { - ...profile.surfaces, - homeLogo: { ...(profile.surfaces.homeLogo || {}), size: item.value }, - }, - }), - `Home ASCII size is now ${item.value}.`, - ), - }))} - /> - )) - } const showHomeWelcomeMode = () => { const current = mend.profile.surfaces.homeWelcome?.mode || "centered" const options: Array<{ title: string; value: "centered" | "split"; description: string }> = [ { title: "Centered", value: "centered", description: "Current centered logo with actions underneath." }, - { title: "Split", value: "split", description: "Claude-style welcome: identity top-left, actions top-right." }, + { + title: "Split", + value: "split", + description: "Two-column welcome: identity top-left, activity panel top-right.", + }, ] dialog.replace(() => ( Promise }) { )) } const showHomeSplitPanel = () => { - const current = mend.profile.surfaces.homeWelcome?.rightPanel || "actions" + const current = mend.profile.surfaces.homeWelcome?.rightPanel || "agentManager" const options: Array<{ title: string; value: "actions" | "agentManager"; description: string }> = [ { title: "Actions", value: "actions", description: "Show Resume, Open commands, and Quit in the split panel." }, - { title: "Agent View", value: "agentManager", description: "Show global sessions grouped by input, working, and completed." }, + { + title: "Agent View", + value: "agentManager", + description: "Show global sessions grouped by input, working, and completed.", + }, ] dialog.replace(() => ( Promise }) { { title: "Raw", value: "raw", - description: "Full session history: reasoning, tool cards, diffs, and classic metadata.", + description: "Plain messages only: no Markdown, tables, Mermaid, or emphasis.", }, { title: "Minimal", value: "minimal", - description: "Compact session history: collapsed reasoning and one-line tool traces.", + description: "Compact activity detail with Markdown messages; Mermaid stays literal.", }, { - title: "MendCode", + title: "Full", value: "mendcode", - description: "MendCode session history: compact simple tools, rich diffs, and MendCode symbols.", + description: "Full rich messages: Markdown, lists, tables, and local Mermaid rendering.", }, ] dialog.replace(() => ( @@ -1550,15 +2145,236 @@ function App(props: { onSnapshot?: () => Promise }) { options={options.map((item) => ({ title: item.title, value: item.value, - category: "MendCode", + category: "Chat", + description: item.description, + onSelect: () => + void updatePromptChrome( + (profile) => ({ + ...profile, + presentation: resolveTuiPresentation({ + ...profile.presentation, + profile: item.value, + message: { + ...profile.presentation.message, + renderer: messageRendererForPresentationProfile(item.value), + }, + }), + }), + `Chat presentation is now ${presentationProfileTitle(item.value)}.`, + ), + }))} + /> + )) + } + const showMessageRenderer = () => { + const current = mend.profile.presentation.message.renderer + const options: Array<{ title: string; value: MendMessageRenderer; description: string }> = [ + { + title: "Plain", + value: "plain", + description: "Literal assistant text: no Markdown, Mermaid, tables, or emphasis.", + }, + { + title: "Markdown", + value: "markdown", + description: "Markdown assistant text without local Mermaid conversion.", + }, + { + title: "Rich", + value: "rich", + description: "Markdown plus local Mermaid diagrams, lists, and wide table cleanup.", + }, + ] + dialog.replace(() => ( + ({ + title: item.title, + value: item.value, + category: "Chat", description: item.description, onSelect: () => void updatePromptChrome( (profile) => ({ ...profile, - presentation: resolveTuiPresentation({ ...profile.presentation, profile: item.value }), + presentation: resolveTuiPresentation({ + ...profile.presentation, + message: { + ...profile.presentation.message, + renderer: item.value, + }, + }), }), - `Chat presentation is now ${item.value}.`, + `Message rendering is now ${item.value}.`, + ), + }))} + /> + )) + } + const compactionStyleTitle = (style: MendCompactionStyle) => { + if (style === "arcade") return "Arcade" + if (style === "cockpit") return "Cockpit" + if (style === "quiet") return "Quiet" + return "Minimal" + } + const compactionArcadeTitle = (arcade: MendCompactionArcade) => { + if (arcade === "off") return "Off" + if (arcade === "snake") return "Snake" + if (arcade === "stars") return "Stars" + if (arcade === "blocks") return "Blocks" + return arcade + } + const showCompactionStyle = () => { + const current = mend.profile.presentation.compaction.style + const options: Array<{ title: string; value: MendCompactionStyle; description: string }> = [ + { + title: "Arcade", + value: "arcade", + description: "Show context stages, the packed summary, scratchpad, and the selected arcade game.", + }, + { + title: "Cockpit", + value: "cockpit", + description: "Show context stages, packed summary, and scratchpad without a game.", + }, + { + title: "Minimal", + value: "minimal", + description: "Show only a short packing status line.", + }, + { + title: "Quiet", + value: "quiet", + description: "Show only a compact divider while context is being packed.", + }, + ] + dialog.replace(() => ( + ({ + title: item.title, + value: item.value, + category: "Context pack", + description: item.description, + onSelect: () => + void updatePromptChrome( + (profile) => { + const compaction = profile.presentation.compaction + return { + ...profile, + presentation: resolveTuiPresentation({ + ...profile.presentation, + compaction: { + ...compaction, + style: item.value, + showProgress: item.value === "arcade" ? true : compaction.showProgress, + allowScratchpad: item.value === "arcade" ? true : compaction.allowScratchpad, + arcade: item.value === "arcade" && compaction.arcade === "off" ? "snake" : compaction.arcade, + }, + }), + } + }, + `Context pack presentation is now ${compactionStyleTitle(item.value)}.`, + ), + }))} + /> + )) + } + const showCompactionArcade = () => { + const current = mend.profile.presentation.compaction.arcade + const options: Array<{ title: string; value: MendCompactionArcade; description: string }> = [ + { title: "Off", value: "off", description: "Do not show an arcade game during context packing." }, + { title: "Snake", value: "snake", description: "Classic keyboard-driven Snake game." }, + { title: "Stars", value: "stars", description: "Ambient starfield animation while context is packed." }, + { title: "Blocks", value: "blocks", description: "Animated block pattern while context is packed." }, + ] + dialog.replace(() => ( + ({ + title: item.title, + value: item.value, + category: "Context pack", + description: item.description, + onSelect: () => + void updatePromptChrome( + (profile) => ({ + ...profile, + presentation: resolveTuiPresentation({ + ...profile.presentation, + compaction: { + ...profile.presentation.compaction, + style: item.value === "off" ? profile.presentation.compaction.style : "arcade", + showProgress: item.value === "off" ? profile.presentation.compaction.showProgress : true, + allowScratchpad: item.value === "off" ? profile.presentation.compaction.allowScratchpad : true, + arcade: item.value, + }, + }), + }), + `Context pack arcade is now ${compactionArcadeTitle(item.value)}.`, + ), + }))} + /> + )) + } + const showCompactionProgress = () => { + const current = mend.profile.presentation.compaction.showProgress ? "on" : "off" + const options = [ + { title: "On", value: "on", description: "Show capture, memory, tail, and continue stages." }, + { title: "Off", value: "off", description: "Hide the context packing stage row." }, + ] as const + dialog.replace(() => ( + ({ + title: item.title, + value: item.value, + category: "Context pack", + description: item.description, + onSelect: () => + void updatePromptChrome( + (profile) => ({ + ...profile, + presentation: resolveTuiPresentation({ + ...profile.presentation, + compaction: { ...profile.presentation.compaction, showProgress: item.value === "on" }, + }), + }), + `Context pack progress is now ${item.value}.`, + ), + }))} + /> + )) + } + const showCompactionScratchpad = () => { + const current = mend.profile.presentation.compaction.allowScratchpad ? "on" : "off" + const options = [ + { title: "On", value: "on", description: "Show the editable follow-up scratchpad after compaction." }, + { title: "Off", value: "off", description: "Hide the follow-up scratchpad." }, + ] as const + dialog.replace(() => ( + ({ + title: item.title, + value: item.value, + category: "Context pack", + description: item.description, + onSelect: () => + void updatePromptChrome( + (profile) => ({ + ...profile, + presentation: resolveTuiPresentation({ + ...profile.presentation, + compaction: { ...profile.presentation.compaction, allowScratchpad: item.value === "on" }, + }), + }), + `Context pack scratchpad is now ${item.value}.`, ), }))} /> @@ -1986,7 +2802,23 @@ function App(props: { onSnapshot?: () => Promise }) { "Prompt status separator updated.", ) } - const showRegistryMarketplace = async (initialSourceID = "local") => { + const showDialogLoading = (title: string, message: string) => { + dialog.replace(() => ( + + + {title} + esc + + {message} + + )) + dialog.setSize("medium") + } + const showRegistryMarketplace = async (initialSourceID = "local", cleanupSourceOnClose = false) => { + showDialogLoading( + initialSourceID === "local" ? "Loading local packages" : "Loading marketplace", + initialSourceID === "local" ? "Reading local package catalog..." : "Fetching package catalog...", + ) let sourceID = initialSourceID let sourceRoot = sourceID === "local" ? await prepareGlobalRuntimePackAuthorRoot() : mend.root const result = await runtimeRegistrySearch("", sourceID, sourceRoot).catch(async (error) => { @@ -2000,22 +2832,88 @@ function App(props: { onSnapshot?: () => Promise }) { }) return runtimeRegistrySearch("", sourceID, sourceRoot) }) - dialog.replace(() => ( - ({ - title: pack.title || pack.id, - value: pack.id, - category: pack.channel ? `${sourceID} / ${pack.channel}` : sourceID, - description: pack.description ? `${pack.description} · ${marketplaceRuntimeSummary(pack)}` : marketplaceRuntimeSummary(pack), - footer: cleanMarketplaceVersion(pack.version), - onSelect: async () => { - const detail = await runtimeRegistryShow(pack.id, sourceID, sourceRoot) - await DialogAlert.show(dialog, detail.pack.title || detail.pack.id, marketplacePackDetails(detail.pack, sourceID)) - }, - }))} - /> - )) + const packageState = await listMendPackages(mend.root) + let keepTemporarySource = false + dialog.replace( + () => ( + { + const badge = marketplaceInstallBadge(pack.id, packageState.installed) + return { + title: marketplaceBadgeTitle(pack.title || pack.id, badge), + value: pack.id, + category: marketplaceStatusCategory({ badge, sourceID, channel: pack.channel }), + description: marketplaceShortSummary(pack), + searchText: marketplaceSearchText([ + pack.id, + pack.title, + pack.description, + marketplaceRuntimeSummary(pack), + sourceID, + pack.channel, + badge, + ...(pack.tags || []), + ]), + footer: [cleanMarketplaceVersion(pack.version), badge].filter(Boolean).join(" · "), + onSelect: async () => { + try { + showDialogLoading("Loading package", `Reading ${pack.id}...`) + const detail = await runtimeRegistryShow(pack.id, sourceID, sourceRoot) + if (sourceID === "local") { + await DialogAlert.show( + dialog, + detail.pack.title || detail.pack.id, + marketplacePackDetails(detail.pack, sourceID), + ) + return + } + const confirmed = await DialogConfirm.show( + dialog, + detail.pack.title || detail.pack.id, + [ + marketplacePackDetails(detail.pack, sourceID), + "", + ...marketplaceSourceSafetyLines({ + sourceID, + sourceType: detail.source.type, + url: detail.source.url, + digest: detail.digest, + signature: detail.pack.signature, + }), + "", + "Install this package overlay for the next message?", + "", + "Will not touch local skills/modes/sessions/auth.", + ].join("\n"), + ) + if (!confirmed) { + if (cleanupSourceOnClose) await runtimeRegistryRemove(sourceID, mend.root).catch(() => undefined) + return + } + const result = await runtimeRegistryInstallPack(detail.pack.id, sourceID, mend.root) + keepTemporarySource = true + await mend.reload() + toast.show({ + variant: "success", + message: `Package installed: ${result.package.id}.`, + duration: 5000, + }) + await showPackageManager() + } catch (error) { + if (cleanupSourceOnClose) await runtimeRegistryRemove(sourceID, mend.root).catch(() => undefined) + toast.show({ variant: "error", message: errorMessage(error), duration: 7000 }) + } + }, + } + })} + /> + ), + () => { + if (!cleanupSourceOnClose || keepTemporarySource) return + void runtimeRegistryRemove(sourceID, mend.root).catch(() => undefined) + }, + ) dialog.setSize("xlarge") } const refreshPackagesRuntime = async () => { @@ -2029,41 +2927,67 @@ function App(props: { onSnapshot?: () => Promise }) { const title = await DialogPrompt.show(dialog, "Package title", { value: metadata.title || "", placeholder: "Starter Pack", - description: () => Human-facing package name shown in local package lists and registry previews., + description: () => ( + Human-facing package name shown in local package lists and registry previews. + ), }) if (title === undefined || title === null) return const id = await DialogPrompt.show(dialog, "Package id", { value: metadata.id || "", placeholder: "starter-pack", - description: () => Stable package id. Blank keeps the generated local runtime id., + description: () => ( + Stable package id. Blank keeps the generated local runtime id. + ), }) if (id === undefined || id === null) return const description = await DialogPrompt.show(dialog, "Package description", { value: metadata.description || "", placeholder: "Reusable MendCode starter package", - description: () => Short summary for package search, install previews, and show output., + description: () => ( + Short summary for package search, install previews, and show output. + ), }) if (description === undefined || description === null) return const version = await DialogPrompt.show(dialog, "Package version", { value: metadata.version || "0.1.0", placeholder: "0.1.0", - description: () => Optional semantic package version. This is not the manifest schema version., + description: () => ( + Optional semantic package version. This is not the manifest schema version. + ), }) if (version === undefined || version === null) return const selection: RuntimePackSelection = { ...(metadata.selection as RuntimePackSelection) } - type PackageFileCategoryKey = "commands" | "agents" | "modes" | "skills" | "plugins" | "prompts" | "mcp" | "context" | "extensions" + type PackageFileCategoryKey = + | "commands" + | "agents" + | "modes" + | "skills" + | "plugins" + | "tools" + | "prompts" + | "mcp" + | "context" + | "pages" + | "widgets" + | "extensions" const fileCategories: Array<{ key: PackageFileCategoryKey; title: string; files: string[] }> = [ { key: "commands", title: "Commands", files: candidates.commands }, { key: "agents", title: "Agents", files: candidates.agents }, { key: "modes", title: "Modes", files: candidates.modes }, { key: "skills", title: "Skills", files: candidates.skills }, { key: "plugins", title: "Plugins", files: candidates.plugins }, + { key: "tools", title: "Tool calls", files: candidates.tools }, { key: "prompts", title: "Prompt templates", files: candidates.prompts }, { key: "mcp", title: "MCP files", files: candidates.mcp }, { key: "context", title: "Context files", files: candidates.context }, - { key: "extensions", title: "Widgets, components, scripts", files: candidates.extensions }, + { key: "pages", title: "TUI pages", files: candidates.pages }, + { key: "widgets", title: "TUI widgets", files: candidates.widgets }, + { key: "extensions", title: "Extension support files", files: candidates.extensions }, ] - const boolCategories: Array<{ key: "tuiProfile" | "worktreePolicy" | "models" | "focus" | "budget" | "memory" | "permissions"; title: string }> = [ + const boolCategories: Array<{ + key: "tuiProfile" | "worktreePolicy" | "models" | "focus" | "budget" | "memory" | "permissions" + title: string + }> = [ { key: "models", title: "Model roles (global config)" }, { key: "focus", title: "Focus config (global config)" }, { key: "budget", title: "Budget policy (global config)" }, @@ -2072,33 +2996,36 @@ function App(props: { onSnapshot?: () => Promise }) { { key: "tuiProfile", title: "TUI profile (global config)" }, { key: "worktreePolicy", title: "Worktree policy (global config)" }, ] - const selectedSet = (key: PackageFileCategoryKey, files: string[]) => - new Set((selection[key] ?? files) as string[]) - const selectedCount = (key: PackageFileCategoryKey, files: string[]) => - selectedSet(key, files).size + const selectedSet = (key: PackageFileCategoryKey, files: string[]) => new Set((selection[key] ?? files) as string[]) + const selectedCount = (key: PackageFileCategoryKey, files: string[]) => selectedSet(key, files).size const visibleFileCategories = () => fileCategories.filter((category) => category.files.length > 0 || selectedCount(category.key, category.files) > 0) - const boolEnabled = (key: "tuiProfile" | "worktreePolicy" | "models" | "focus" | "budget" | "memory" | "permissions") => - selection[key] !== false + const boolEnabled = ( + key: "tuiProfile" | "worktreePolicy" | "models" | "focus" | "budget" | "memory" | "permissions", + ) => selection[key] !== false const configSelectedCount = () => boolCategories.filter((category) => boolEnabled(category.key)).length const packageSummaryLine = () => - `${selectedCount("commands", candidates.commands)} cmd · ${selectedCount("agents", candidates.agents)} agents · ${selectedCount("skills", candidates.skills)} skills · ${selectedCount("mcp", candidates.mcp)} MCP · ${configSelectedCount()}/${boolCategories.length} config` - const packageSummaryText = () => [ - `Commands: ${selectedCount("commands", candidates.commands)}/${candidates.commands.length}`, - `Agents/subagents: ${selectedCount("agents", candidates.agents)}/${candidates.agents.length}`, - `Modes: ${selectedCount("modes", candidates.modes)}/${candidates.modes.length}`, - `Skills: ${selectedCount("skills", candidates.skills)}/${candidates.skills.length}`, - `Plugins: ${selectedCount("plugins", candidates.plugins)}/${candidates.plugins.length}`, - `Prompt templates: ${selectedCount("prompts", candidates.prompts)}/${candidates.prompts.length}`, - `MCP files: ${selectedCount("mcp", candidates.mcp)}/${candidates.mcp.length}`, - `Context files: ${selectedCount("context", candidates.context)}/${candidates.context.length}`, - `Widgets/components/scripts: ${selectedCount("extensions", candidates.extensions)}/${candidates.extensions.length}`, - `Config groups: ${configSelectedCount()}/${boolCategories.length}`, - "", - "Package source: global MendCode configuration, not the currently opened project folder.", - "Global skills from ~/.claude/skills and ~/.agents/skills are copied into this package authoring snapshot.", - "Original global skills/config are not deleted or moved.", - ].join("\n") + `${selectedCount("commands", candidates.commands)} cmd · ${selectedCount("agents", candidates.agents)} agents · ${selectedCount("skills", candidates.skills)} skills · ${selectedCount("tools", candidates.tools)} tools · ${configSelectedCount()}/${boolCategories.length} config` + const packageSummaryText = () => + [ + `Commands: ${selectedCount("commands", candidates.commands)}/${candidates.commands.length}`, + `Agents/subagents: ${selectedCount("agents", candidates.agents)}/${candidates.agents.length}`, + `Modes: ${selectedCount("modes", candidates.modes)}/${candidates.modes.length}`, + `Skills: ${selectedCount("skills", candidates.skills)}/${candidates.skills.length}`, + `Plugins: ${selectedCount("plugins", candidates.plugins)}/${candidates.plugins.length}`, + `Tool calls: ${selectedCount("tools", candidates.tools)}/${candidates.tools.length}`, + `Prompt templates: ${selectedCount("prompts", candidates.prompts)}/${candidates.prompts.length}`, + `MCP files: ${selectedCount("mcp", candidates.mcp)}/${candidates.mcp.length}`, + `Context files: ${selectedCount("context", candidates.context)}/${candidates.context.length}`, + `TUI pages: ${selectedCount("pages", candidates.pages)}/${candidates.pages.length}`, + `TUI widgets: ${selectedCount("widgets", candidates.widgets)}/${candidates.widgets.length}`, + `Extension support files: ${selectedCount("extensions", candidates.extensions)}/${candidates.extensions.length}`, + `Config groups: ${configSelectedCount()}/${boolCategories.length}`, + "", + "Package source: global MendCode configuration, not the currently opened project folder.", + "Global skills from supported legacy and MendCode skill folders are copied into this package authoring snapshot.", + "Original global skills/config are not deleted or moved.", + ].join("\n") const openFileCategory = (category: (typeof fileCategories)[number]) => { const chosen = selectedSet(category.key, category.files) dialog.replace(() => ( @@ -2208,12 +3135,15 @@ function App(props: { onSnapshot?: () => Promise }) { description: "Choose files.", onSelect: () => openFileCategory(category), })) - : [{ - title: "No global artifact files found", - value: "no-project-files", - category: "Global files", - description: "No global MendCode commands, agents, modes, skills, plugins, prompts, MCP files, or widgets were found.", - }]), + : [ + { + title: "No global artifact files found", + value: "no-project-files", + category: "Global files", + description: + "No global MendCode commands, agents, modes, skills, plugins, prompts, MCP files, or widgets were found.", + }, + ]), ...boolCategories.map((category) => ({ title: `${boolEnabled(category.key) ? "[x]" : "[ ]"} ${category.title}`, value: category.key, @@ -2252,23 +3182,24 @@ function App(props: { onSnapshot?: () => Promise }) { activeAfter: string[] files: string[] extra?: string[] - }) => [ - input.action, - "", - `Active before: ${input.activeBefore.join(", ") || "none"}`, - `Active after: ${input.activeAfter.join(", ") || "none"}`, - "", - "Runtime updated for next message:", - packageArtifactSummary(input.files), - ...(input.extra?.length ? ["", ...input.extra] : []), - "", - "Will not touch:", - "- open chat/session history", - "- local .mendcode/skills, modes, commands, plugins", - "- provider auth, runs, cache, generated history", - "", - "If the current mode disappears, MendCode will switch to the first available mode and show a notification.", - ].join("\n") + }) => + [ + input.action, + "", + `Active before: ${input.activeBefore.join(", ") || "none"}`, + `Active after: ${input.activeAfter.join(", ") || "none"}`, + "", + "Runtime updated for next message:", + packageArtifactSummary(input.files), + ...(input.extra?.length ? ["", ...input.extra] : []), + "", + "Will not touch:", + "- open chat/session history", + "- local .mendcode/skills, modes, commands, plugins", + "- provider auth, runs, cache, generated history", + "", + "If the current mode disappears, MendCode will switch to the first available mode and show a notification.", + ].join("\n") const confirmPackageTransition = async (input: Parameters[0]) => DialogConfirm.show(dialog, input.title, packageTransitionText(input)) const showPackageManager = async () => { @@ -2276,7 +3207,7 @@ function App(props: { onSnapshot?: () => Promise }) { const installed = state.installed dialog.replace(() => ( Promise }) { }, { title: "Install source", - value: "install-source", - category: "Install", - description: "Apply a source id.", - onSelect: async () => { - const source = await DialogPrompt.show(dialog, "Package source id", { - value: "official", - placeholder: "official", - }) - if (!source?.trim()) return - const preview = await runtimeRegistryPreview(source.trim(), mend.root) - const stateBefore = await listMendPackages(mend.root) - const confirmed = await DialogConfirm.show( - dialog, - "Install package source", - [ - `Source: ${source.trim()}`, - `Fetches network: ${preview.fetchesNetwork ? "yes" : "no"}`, - `Pack: ${preview.package?.title || preview.package?.id || source.trim()}`, - "", - "Will update for next message:", - `Commands: ${preview.pack?.commands.length || 0}`, - `Agents: ${preview.pack?.agents.length || 0}`, - `Modes: ${preview.pack?.modes.length || 0}`, - `Skills: ${preview.pack?.skills.length || 0}`, - `Plugins: ${preview.pack?.plugins.length || 0}`, - `MCP files: ${preview.pack?.mcp.files.length || 0}`, - `Prompt mode: ${preview.pack?.prompts.mode || "unchanged"}`, - `TUI profile/chrome: ${preview.pack && Object.keys(preview.pack.tui || {}).length ? "included" : "unchanged"}`, - `Model roles: ${preview.pack && Object.keys(preview.pack.models.roles || {}).length ? "included" : "unchanged"}`, - "", - `Active before: ${stateBefore.active.join(", ") || "none"}`, - `Active after: ${preview.package?.id || source.trim()}`, - "", - "Will not touch local skills/modes/sessions/auth.", - ].join("\n"), - ) - if (!confirmed) return - const result = await runtimeRegistryApply(source.trim(), mend.root) - await mend.reload() - toast.show({ - variant: "success", - message: `Package installed from ${result.source.id}.`, - duration: 5000, + value: "install-source", + category: "Install", + description: "Install a single-pack source or browse a multi-pack source.", + onSelect: async () => { + const source = await DialogPrompt.show(dialog, "Source id or GitHub URL", { + value: "official", + placeholder: "official or https://github.com/org/mendcode-package", + description: () => ( + Paste a saved source id or a public GitHub repo URL. + ), }) - await showPackageManager() + if (!source?.trim()) return + const sourceText = source.trim() + const sourceLooksLikeURL = /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(sourceText) + if (sourceLooksLikeURL && !isPublicGitHubMarketplaceURL(sourceText)) { + toast.show({ + variant: "error", + message: + "Package URL must be public https://github.com// with no query, hash, or credentials.", + duration: 7000, + }) + return + } + const sourceID = sourceLooksLikeURL ? marketplaceSourceIDFromURL(sourceText) : sourceText + let sourceAdded = false + try { + if (sourceLooksLikeURL) { + showDialogLoading("Adding source", `Saving ${sourceID}...`) + await runtimeRegistryAdd( + [ + sourceID, + "--type", + "github", + "--url", + sourceText, + "--note", + "TUI-added GitHub marketplace package source.", + ], + mend.root, + ) + sourceAdded = true + } + showDialogLoading("Previewing source", `Checking ${sourceID}...`) + const catalog = await runtimeRegistrySearch("", sourceID, mend.root) + if (catalog.results.length !== 1) { + toast.show({ + variant: "info", + message: `${sourceID} has ${catalog.results.length} packages. Choose one to install.`, + duration: 4000, + }) + await showRegistryMarketplace(sourceID, sourceAdded) + return + } + const detail = await runtimeRegistryShow(catalog.results[0]!.id, sourceID, mend.root) + const stateBefore = await listMendPackages(mend.root) + const confirmed = await DialogConfirm.show( + dialog, + detail.pack.title || detail.pack.id, + [ + marketplacePackDetails(detail.pack, sourceID), + "", + ...marketplaceSourceSafetyLines({ + sourceID, + sourceType: detail.source.type, + url: detail.source.url, + digest: detail.digest, + signature: detail.pack.signature, + }), + "", + `Active before: ${stateBefore.active.join(", ") || "none"}`, + `Active after: ${detail.pack.id}`, + "", + "Will not touch local skills/modes/sessions/auth.", + ].join("\n"), + ) + if (!confirmed) { + if (sourceAdded) await runtimeRegistryRemove(sourceID, mend.root).catch(() => undefined) + return + } + showDialogLoading("Installing package", `Installing ${detail.pack.id}...`) + const result = await runtimeRegistryInstallPack(detail.pack.id, sourceID, mend.root) + await mend.reload() + toast.show({ + variant: "success", + message: `Package installed: ${result.package.id}.`, + duration: 5000, + }) + await showPackageManager() + } catch (error) { + if (sourceAdded) await runtimeRegistryRemove(sourceID, mend.root).catch(() => undefined) + toast.show({ variant: "error", message: errorMessage(error), duration: 7000 }) + } }, }, { @@ -2349,33 +3327,49 @@ function App(props: { onSnapshot?: () => Promise }) { onSelect: () => void showRegistryMarketplace("official"), }, ...(state.enabled.length - ? [{ - title: "Deselect all packages", - value: "disable-all", - category: "Active", - description: "Return to local config.", - onSelect: async () => { - const files = state.enabled.flatMap((item) => item.copied) - const confirmed = await confirmPackageTransition({ - title: "Deselect all packages", - action: "Deselect every active package and return to local-only runtime.", - activeBefore: state.active, - activeAfter: [], - files, - }) - if (!confirmed) return - await disableAllMendPackages(mend.root) - await refreshPackagesRuntime() - toast.show({ variant: "success", message: "All packages deselected.", duration: 4000 }) - await showPackageManager() + ? [ + { + title: "Deselect all packages", + value: "disable-all", + category: "Active", + description: "Return to local config.", + onSelect: async () => { + const files = state.enabled.flatMap((item) => item.copied) + const confirmed = await confirmPackageTransition({ + title: "Deselect all packages", + action: "Deselect every active package and return to local-only runtime.", + activeBefore: state.active, + activeAfter: [], + files, + }) + if (!confirmed) return + await disableAllMendPackages(mend.root) + await refreshPackagesRuntime() + toast.show({ variant: "success", message: "All packages deselected.", duration: 4000 }) + await showPackageManager() + }, }, - }] + ] : []), ...installed.map((item) => ({ - title: `${item.enabled ? "[x]" : "[ ]"} ${item.title || item.id}`, + title: marketplaceBadgeTitle(item.title || item.id, item.enabled ? "active" : "installed"), value: item.id, - category: item.enabled ? "Active package" : "Installed package", + category: marketplaceStatusCategory({ + badge: item.enabled ? "active" : "installed", + channel: item.channel, + sourceID: item.sourceType, + }), description: item.description || "Installed overlay.", + searchText: marketplaceSearchText([ + item.id, + item.title, + item.description, + item.root, + item.version, + item.channel, + item.sourceType, + item.enabled ? "active enabled selected" : "installed inactive disabled", + ]), footer: item.version || item.channel || item.sourceType, onSelect: async () => { const activeAfter = item.enabled @@ -2387,7 +3381,10 @@ function App(props: { onSnapshot?: () => Promise }) { activeBefore: state.active, activeAfter, files: item.copied, - extra: [`Package root: ${item.root}`, `Version/channel: ${item.version || item.channel || item.sourceType}`], + extra: [ + `Package root: ${item.root}`, + `Version/channel: ${item.version || item.channel || item.sourceType}`, + ], }) if (!confirmed) return await setMendPackageEnabled(item.id, !item.enabled, mend.root) @@ -2412,7 +3409,10 @@ function App(props: { onSnapshot?: () => Promise }) { activeBefore: state.active, activeAfter: state.active.filter((id) => id !== item.id), files: item.copied, - extra: ["The downloaded overlay copy will be deleted.", "Local source/customization files stay on disk."], + extra: [ + "The downloaded overlay copy will be deleted.", + "Local source/customization files stay on disk.", + ], }) if (!confirmed) return await removeMendPackage(item.id, mend.root) @@ -2471,6 +3471,28 @@ function App(props: { onSnapshot?: () => Promise }) { slashes.map((item) => `${item.display} ${item.description || ""}`).join("\n") || "No slash commands available.", ) } + function loopSlashPrompt(args: string) { + const request = args.trim() + return [ + request + ? `Create or control a MendCode Loop Workflow for this request:\n${request}` + : "Start a guided MendCode Loop Workflow setup for this session.", + "", + "Use exactly the `loop` tool, not shell commands. If the request already includes the objective, cadence, iteration limit, permission mode, and stop conditions, your first loop tool call must be action `activate`. Do not call `show` or `list` before creating the loop.", + "If the request is to stop, remove, delete, pause, resume, or run the current loop and no loop id is visible, call the matching `loop` action without `workflowID`; the tool resolves the current session's contextual loop.", + "Ask with the `question` tool only when a critical setting is missing: objective, budget mode, iteration cap or unbounded mode, cadence, model/provider, max wall-clock runtime, permission mode, or stop condition.", + "Before activating, design the loop strategy from the goal: choose `budgetMode` as `fixed` only for exactly-N iteration jobs, `max-goal` when maxTurns is a budget cap to complete a goal as early as possible, and `unbounded-monitor` for ongoing monitors. For `max-goal`, provide concrete `completionCriteria`, `successChecks`, `targetTurns`, and `reserveTurns`; do not divide the work across every max iteration. Aim to finish in the minimum responsible turns, then use remaining turns only for retry/verification if needed. Set `notifyOwnerOnComplete: true` for goal-completion loops so the parent session gets a completion summary.", + 'Default to report-only unless I explicitly allow edits. Spanish/English requests such as codear, implementar, fixear, editar, hacer cambios, probar, compilar, run tests, or build are explicit edit permission for the loop; use permissionMode `normal` or `custom`, set `reportOnly: false`, and keep safety gates for push/merge/release/destructive shell. If I choose a model and reasoning effort/variant, pass `model` as provider/model and pass the effort as `variant` (for example `variant: "medium"`), or use provider/model#variant. For interval cadence, set `triggerMode: "interval"` and convert the interval to `intervalMs`; for a local daily schedule, set `triggerMode: "daily"`, `dailyAt` as `HH:mm`, and an explicit IANA `timezone`. Preserve the current session model by omitting `model` unless I choose one.', + "Do not hand-render Markdown tables or duplicate status cards after the tool call. Let the Loop Workflow card render from tool metadata, then give a one-line confirmation.", + ].join("\n") + } + function fillLoopSlashPrompt(args = "", submit = false) { + const ref = promptRef.current + if (!ref) return + ref.set({ input: submit ? loopSlashPrompt(args) : `/loop ${args}`.trimEnd(), parts: [] }) + ref.focus() + if (submit) setTimeout(() => promptRef.current?.submit(), 0) + } const showCustomizationCapabilities = async () => { await DialogAlert.show( dialog, @@ -2485,6 +3507,166 @@ function App(props: { onSnapshot?: () => Promise }) { ].join("\n\n"), ) } + const showCustomization = () => { + const actions: TuiCustomizationAction[] = [ + { + value: "advanced.home.identity", + title: "Home identity", + category: "Advanced profile", + description: "Choose the generated title or mascot identity for Home.", + status: mend.profile.identity.logoMode === "mascot" ? "ASCII mascot" : "ASCII title", + onSelect: showHomeIdentityMode, + }, + { + value: "advanced.home.title", + title: "Home title text", + category: "Advanced profile", + description: "Change the product name used by Home and the default terminal title.", + status: mend.profile.identity.productName || "MendCode", + onSelect: showHomeTitleText, + }, + { + value: "advanced.home.mascot", + title: "Home mascot ASCII", + category: "Advanced profile", + description: "Replace or reset the Home mascot text.", + status: mend.profile.surfaces.homeLogo?.text ? "custom" : "default", + onSelect: showHomeMascotText, + }, + { + value: "advanced.home.font", + title: "Home title font", + category: "Advanced profile", + description: "Choose the ASCII title renderer.", + status: + mend.profile.identity.logoFont === "small" + ? "Small" + : mend.profile.identity.logoFont === "standard" + ? "Standard" + : mend.profile.identity.logoFont === "shadow" + ? "Shadow" + : "MendCode", + onSelect: showHomeLogoFont, + }, + { + value: "advanced.home.welcome", + title: "Home welcome layout", + category: "Advanced profile", + description: "Choose centered or split Home content.", + status: mend.profile.surfaces.homeWelcome?.mode === "split" ? "Split" : "Centered", + onSelect: showHomeWelcomeMode, + }, + { + value: "advanced.home.panel", + title: "Home split panel", + category: "Advanced profile", + description: "Choose actions or Agent View for the split panel.", + status: mend.profile.surfaces.homeWelcome?.rightPanel === "actions" ? "Actions" : "Agent View", + onSelect: showHomeSplitPanel, + }, + { + value: "advanced.prompt.chrome", + title: "Prompt chrome", + category: "Advanced profile", + description: "Choose the prompt frame and border treatment.", + status: + mend.profile.promptChrome.preset === "top-bottom" + ? "Top + bottom" + : mend.profile.promptChrome.preset === "ascii-box" + ? "ASCII box" + : mend.profile.promptChrome.preset === "minimal" + ? "Minimal" + : "Full box", + onSelect: showPromptChromePresets, + }, + { + value: "advanced.prompt.lead", + title: "Prompt lead string", + category: "Advanced profile", + description: "Change the marker displayed before prompt input.", + status: mend.profile.promptChrome.glyphs?.leadText || "blank", + onSelect: showPromptLeadString, + }, + { + value: "advanced.prompt.status", + title: "Prompt status placement", + category: "Advanced profile", + description: "Choose where prompt metadata is rendered.", + status: + (mend.profile.promptStatus.placementByPreset?.[mend.profile.promptChrome.preset] || + (mend.profile.promptChrome.preset === "ascii-box" ? "inside" : "outside")) === "inside" + ? "Inside" + : "Outside", + onSelect: showPromptStatusPlacement, + }, + { + value: "advanced.presentation.profile", + title: "Chat presentation", + category: "Advanced profile", + description: "Choose raw, minimal, or MendCode message presentation.", + status: presentationProfileTitle(mend.profile.presentation.profile), + onSelect: showPresentationProfile, + }, + { + value: "advanced.presentation.renderer", + title: "Message renderer", + category: "Advanced profile", + description: "Choose plain, Markdown, or rich message rendering.", + status: mend.profile.presentation.message.renderer, + onSelect: showMessageRenderer, + }, + { + value: "advanced.compaction.style", + title: "Context pack presentation", + category: "Context pack", + description: "Choose the normal, arcade, minimal, or quiet context packing surface.", + status: compactionStyleTitle(mend.profile.presentation.compaction.style), + onSelect: showCompactionStyle, + }, + { + value: "advanced.compaction.arcade", + title: "Context pack arcade", + category: "Context pack", + description: "Choose Snake, Stars, Blocks, or no arcade surface during compaction.", + status: compactionArcadeTitle(mend.profile.presentation.compaction.arcade), + onSelect: showCompactionArcade, + }, + { + value: "advanced.compaction.progress", + title: "Context pack progress", + category: "Context pack", + description: "Show or hide the context packing stage row.", + status: mend.profile.presentation.compaction.showProgress ? "On" : "Off", + onSelect: showCompactionProgress, + }, + { + value: "advanced.compaction.scratchpad", + title: "Context pack scratchpad", + category: "Context pack", + description: "Show or hide the editable follow-up scratchpad.", + status: mend.profile.presentation.compaction.allowScratchpad ? "On" : "Off", + onSelect: showCompactionScratchpad, + }, + { + value: "advanced.prompt.submit", + title: "Submit scroll behavior", + category: "Advanced profile", + description: "Choose how the session follows submitted prompts.", + status: sessionSubmitScrollMode() === "clear" ? "Clear sent message" : "Normal follow", + onSelect: showSessionSubmitScrollMode, + }, + { + value: "advanced.api", + title: "View customization API", + category: "About & API", + description: "Inspect public extension surfaces and safe routing capabilities.", + status: "read-only", + onSelect: showCustomizationCapabilities, + }, + ] + dialog.replace(() => ) + dialog.setSize("command") + } const editMemoryEntry = async (entry: MemoryEntry) => { const text = await DialogPrompt.show(dialog, `Edit ${entry.scope} memory`, { value: entry.text, @@ -2542,9 +3724,34 @@ function App(props: { onSnapshot?: () => Promise }) { const addMemoryEntryFromDialog = async (scope: "global" | "project") => { const text = await DialogPrompt.show(dialog, `Add ${scope} memory`, { placeholder: "Memory text" }) if (!text?.trim()) return - await appendMemoryEntry({ scope, text, source: "tui-memory-manager" }, memoryRoot()) - toast.show({ variant: "success", message: `${scope} memory added.`, duration: 3000 }) - await showMemoryManager(scope) + try { + const entry = await appendMemoryEntry({ scope, text, source: "tui-memory-manager" }, memoryRoot()) + toast.show({ variant: "success", message: `${scope} memory added: ${entry.id}`, duration: 4000 }) + await showMemoryManager(scope) + } catch (error) { + toast.show({ + variant: "error", + message: `Could not add ${scope} memory: ${error instanceof Error ? error.message : String(error)}`, + duration: 6000, + }) + } + } + const memoryProposalApplyLabel = (proposal: MemoryProposal) => { + const operation = proposal.operation ?? "add" + if (operation === "update") return "Update memory" + if (operation === "remove") return "Remove memory" + return "Save as memory" + } + const memoryProposalAppliedLabel = (proposal: MemoryProposal) => { + const operation = proposal.operation ?? "add" + if (operation === "update") return "Memory updated" + if (operation === "remove") return "Memory removed" + return "Memory saved" + } + const memoryProposalDescription = (proposal: MemoryProposal) => { + const operation = proposal.operation ?? "add" + const target = proposal.targetEntryID ? ` · target ${proposal.targetEntryID}` : "" + return `${operation} · ${proposal.scope} · ${proposal.sensitivity}${target}` } const editMemoryProposalFromDialog = async (proposal: MemoryProposal) => { const text = await DialogPrompt.show(dialog, "Edit memory proposal", { @@ -2579,20 +3786,23 @@ function App(props: { onSnapshot?: () => Promise }) { title: proposal.scope === "global" ? "[scope] Move to project" : "[scope] Move to global", value: "scope", category: proposal.scope, - description: "Change where this memory will live before applying it.", - disabled: proposal.status !== "pending", + description: + (proposal.operation ?? "add") === "add" + ? "Change where this memory will live before applying it." + : "Targeted update/remove proposals keep the scope of their target memory.", + disabled: proposal.status !== "pending" || (proposal.operation ?? "add") !== "add", onSelect: () => void changeMemoryProposalScope(proposal, proposal.scope === "global" ? "project" : "global"), }, { - title: "[apply] Save as memory", + title: `[apply] ${memoryProposalApplyLabel(proposal)}`, value: "apply", category: proposal.scope, - description: proposal.text, + description: memoryProposalDescription(proposal), disabled: proposal.status !== "pending", onSelect: async () => { await applyMemoryProposal(proposal.id, memoryRoot()) - toast.show({ variant: "success", message: "Memory proposal applied.", duration: 3000 }) + toast.show({ variant: "success", message: `${memoryProposalAppliedLabel(proposal)}.`, duration: 3000 }) await showMemoryManager("proposals") }, }, @@ -2627,7 +3837,7 @@ function App(props: { onSnapshot?: () => Promise }) { const ok = await DialogConfirm.show( dialog, "Apply Memory Proposals", - `Save ${pending.length} ${label} memory proposal${pending.length === 1 ? "" : "s"} as memory?`, + `Apply ${pending.length} ${label} memory proposal${pending.length === 1 ? "" : "s"}? Add proposals create memories, update proposals replace target memories, and remove proposals delete target memories.`, "cancel", ) if (!ok) return @@ -2682,9 +3892,9 @@ function App(props: { onSnapshot?: () => Promise }) { title: `[apply] Apply all pending (${proposals.length})`, value: "bulk-apply-all", category: "Bulk actions", - description: "Save every pending proposal as memory.", + description: "Apply every pending add, update, and remove proposal.", previewTitle: "Apply all pending proposals", - previewBody: `Save all ${proposals.length} pending memory proposal${proposals.length === 1 ? "" : "s"}. Applied proposals disappear from this review queue.`, + previewBody: `Apply all ${proposals.length} pending memory proposal${proposals.length === 1 ? "" : "s"}. Add creates entries, update replaces target entries, and remove deletes target entries.`, previewMeta: "bulk · all scopes", onSelect: () => void applyMemoryProposalsBulk(proposals, "pending"), }, @@ -2706,9 +3916,9 @@ function App(props: { onSnapshot?: () => Promise }) { title: `[apply] Apply project pending (${projectProposals.length})`, value: "bulk-apply-project", category: "Bulk actions", - description: "Save every project-scoped pending proposal.", + description: "Apply every project-scoped pending proposal.", previewTitle: "Apply project proposals", - previewBody: `Save all ${projectProposals.length} project memory proposal${projectProposals.length === 1 ? "" : "s"}.`, + previewBody: `Apply all ${projectProposals.length} project memory proposal${projectProposals.length === 1 ? "" : "s"}.`, previewMeta: "bulk · project", onSelect: () => void applyMemoryProposalsBulk(projectProposals, "project"), }, @@ -2740,13 +3950,19 @@ function App(props: { onSnapshot?: () => Promise }) { : []), ] const proposalOptions: MemoryManagerOption[] = proposals.map((proposal) => ({ - title: `[${proposal.status}] ${proposal.text.slice(0, 68)}`, + title: `[${proposal.status}][${proposal.operation ?? "add"}] ${proposal.text.slice(0, 62)}`, value: proposal.id, category: "Proposals", - description: `${proposal.scope} · ${proposal.sensitivity}`, + description: memoryProposalDescription(proposal), footer: proposal.createdAt.slice(0, 10), previewTitle: proposal.status === "pending" ? "Pending memory proposal" : "Memory proposal", - previewBody: [proposal.text, proposal.reason ? `Why: ${proposal.reason}` : ""].filter(Boolean).join("\n\n"), + previewBody: [ + memoryProposalDescription(proposal), + proposal.text, + proposal.reason ? `Why: ${proposal.reason}` : "", + ] + .filter(Boolean) + .join("\n\n"), previewMeta: `${proposal.scope} · ${proposal.sensitivity} · confidence ${Math.round((proposal.confidence ?? 0) * 100)}% · durability ${Math.round((proposal.durability ?? 0) * 100)}% · change risk ${Math.round((proposal.changeRisk ?? 0) * 100)}%`, onSelect: () => showMemoryProposalActions(proposal), })) @@ -2763,8 +3979,10 @@ function App(props: { onSnapshot?: () => Promise }) { `Memory learning: ${status.output ? "on" : "off"} · creates approval-gated proposals after chats`, `Entries: global ${status.entries.global.count} · project ${status.entries.project.count}`, `Proposals: pending ${status.proposals.pending} · applied ${status.proposals.applied} · rejected ${status.proposals.rejected}`, + `Extraction queue: ${status.extraction.queued} queued · ${status.extraction.running} running · ${status.extraction.failed} failed`, `Runtime caps: project ${status.projectMaxEntries}/request · global ${status.globalCompactionMaxEntries}/after compaction`, `Extractor: ${status.extractorRole} · output model calls ${status.outputCallsProviders ? "possible" : "off"}`, + `Dream consolidation: ${status.dreamConsolidationPolicy}`, `Project path: ${status.paths.projectEntries}`, `Global path: ${status.paths.globalEntries}`, ].join("\n"), @@ -2788,9 +4006,8 @@ function App(props: { onSnapshot?: () => Promise }) { ), }, { - title: status.input && status.output - ? "[on] Memory input and learning enabled" - : "Enable memory input and learning", + title: + status.input && status.output ? "[on] Memory input and learning enabled" : "Enable memory input and learning", value: "memory-enable-io", category: "Settings", description: "Inject memory and create approval-gated proposals after chats.", @@ -2814,10 +4031,7 @@ function App(props: { onSnapshot?: () => Promise }) { "Saved memory entries and pending proposals remain on disk, but they will not be injected or generated while memory is disabled.", previewMeta: "project config", onSelect: () => - void updateMemoryConfigFromDialog( - { enabled: false, use: false, generate: false }, - "Memory disabled.", - ), + void updateMemoryConfigFromDialog({ enabled: false, use: false, generate: false }, "Memory disabled."), }, ] const manualActionOptions: MemoryManagerOption[] = [ @@ -2894,12 +4108,17 @@ function App(props: { onSnapshot?: () => Promise }) { } command.register(() => [ { - title: "Permission mode", + title: "Approval mode", value: "mendcode.permission.status", category: mendCategory, - description: "Show current permission config and where to enable Smart Approval or Full Access", - enabled: route.data.type !== "session", - onSelect: () => void showGlobalPermissionStatus(), + description: "Set the default Approval Mode for a future session", + slash: { name: "permission", aliases: ["permissions", "approval"] }, + enabled: route.data.type === "home", + onSelect: () => { + void showDefaultPermissionMode().catch((error) => { + toast.show({ message: errorMessage(error), variant: "error", duration: 5000 }) + }) + }, }, { title: "Status", @@ -2915,16 +4134,16 @@ function App(props: { onSnapshot?: () => Promise }) { slash: { name: "setup", aliases: ["configure", "onboarding"] }, onSelect: () => { dialog.clear() - route.navigate({ type: "setup" }) + route.navigate(setupRoute()) }, }, { - title: "Configure Provider", + title: "Connect Provider", value: "mendcode.ai.status", category: mendCategory, onSelect: () => { dialog.clear() - route.navigate({ type: "setup", step: "provider" }) + route.navigate(setupRoute("provider")) }, }, { @@ -2933,7 +4152,7 @@ function App(props: { onSnapshot?: () => Promise }) { category: mendCategory, onSelect: () => { dialog.clear() - route.navigate({ type: "setup", step: "models" }) + route.navigate(setupRoute("models")) }, }, { @@ -2942,17 +4161,26 @@ function App(props: { onSnapshot?: () => Promise }) { category: mendCategory, onSelect: () => { dialog.clear() - route.navigate({ type: "setup", step: "budget" }) + route.navigate(setupRoute("budget")) }, }, { - title: "Prompt modes", + title: "Prompt context", value: "mendcode.prompt.mode", category: mendCategory, suggested: true, slash: { name: "prompt-mode", aliases: ["prompt", "modes"] }, onSelect: showPromptModes, }, + { + title: "Mode picker", + value: "agent.mode.picker", + keybind: "agent_mode_picker", + category: mendCategory, + suggested: true, + enabled: promptRouteActive(), + onSelect: showAgentModePicker, + }, { title: "Prompt chrome", value: "mendcode.prompt.chrome", @@ -2969,6 +4197,14 @@ function App(props: { onSnapshot?: () => Promise }) { slash: { name: "presentation", aliases: ["chat-presentation", "render-mode"] }, onSelect: showPresentationProfile, }, + { + title: "Message rendering", + value: "mendcode.message.renderer", + category: mendCategory, + suggested: true, + slash: { name: "message-rendering", aliases: ["message-renderer", "markdown-rendering"] }, + onSelect: showMessageRenderer, + }, { title: "Submit scroll behavior", value: "mendcode.session.submit_scroll", @@ -3033,16 +4269,16 @@ function App(props: { onSnapshot?: () => Promise }) { onSelect: () => void showHomeTitleText(), }, { - title: "Home title font", - value: "mendcode.home.font", + title: "Home mascot ASCII", + value: "mendcode.home.logo.text", category: mendCategory, - onSelect: showHomeLogoFont, + onSelect: () => void showHomeMascotText(), }, { - title: "Home ASCII size", - value: "mendcode.home.logo.size", + title: "Home title font", + value: "mendcode.home.font", category: mendCategory, - onSelect: showHomeLogoSize, + onSelect: showHomeLogoFont, }, { title: "Home welcome mode", @@ -3062,18 +4298,25 @@ function App(props: { onSnapshot?: () => Promise }) { title: "Cycle prompt mode", value: "mendcode.prompt.mode.cycle", category: mendCategory, + hidden: true, onSelect: async () => { const result = await cyclePromptMode(mend.root) await mend.reload() - toast.show({ variant: "info", message: `Prompt mode is now ${result.mode}.`, duration: 4000 }) + toast.show({ variant: "info", message: `Prompt context is now ${promptModeLabel(result)}.`, duration: 4000 }) }, }, + { + title: "Customize TUI", + value: "mendcode.customization.open", + category: mendCategory, + suggested: true, + slash: { name: "customize", aliases: ["customization", "capabilities", "tui-customization"] }, + onSelect: showCustomization, + }, { title: "Customization capabilities", value: "mendcode.customization.capabilities", category: mendCategory, - suggested: true, - slash: { name: "customization", aliases: ["capabilities", "tui-customization"] }, onSelect: () => void showCustomizationCapabilities(), }, { @@ -3102,7 +4345,7 @@ function App(props: { onSnapshot?: () => Promise }) { value: "mendcode.marketplace", category: mendCategory, suggested: true, - slash: { name: "marketplace", aliases: ["registry", "packs"] }, + slash: { name: "marketplace" }, onSelect: () => void showRegistryMarketplace(), }, { @@ -3110,24 +4353,51 @@ function App(props: { onSnapshot?: () => Promise }) { value: "mendcode.registry.status", category: mendCategory, onSelect: async () => { - await DialogAlert.show(dialog, "MendCode Runtime Registry", registryStatusText(await runtimeRegistryStatus(mend.root))) + await DialogAlert.show( + dialog, + "MendCode Runtime Registry", + registryStatusText(await runtimeRegistryStatus(mend.root)), + ) }, }, { - title: "Memory status", + title: "Memory Manager", value: "mendcode.memory.status", category: mendCategory, - hidden: true, - slash: { name: "memory", aliases: ["mem"] }, - onSelect: () => void showMemoryManager(), + suggested: true, + slash: { name: "memory-manager", aliases: ["mem", "memory"] }, + onSelect: () => void showMemoryManager("proposals"), }, { - title: "Memory Manager", + title: "Memory Center", value: "mendcode.memory.manager", category: mendCategory, suggested: true, - slash: { name: "memory", aliases: ["mem", "memories", "memory-manager"] }, - onSelect: () => void showMemoryManager(), + slash: { name: "memory-center", aliases: ["memories"] }, + onSelect: () => { + dialog.clear() + route.navigate({ + type: "memory", + returnTo: + route.data.type === "session" ? { type: "session", sessionID: route.data.sessionID } : { type: "home" }, + }) + }, + }, + { + title: "Open Memory Graph", + value: "mendcode.memory.graph", + category: mendCategory, + suggested: true, + slash: { name: "memory-graph", aliases: ["graph"] }, + onSelect: () => { + dialog.clear() + route.navigate({ + type: "memory", + view: "graph", + returnTo: + route.data.type === "session" ? { type: "session", sessionID: route.data.sessionID } : { type: "home" }, + }) + }, }, { title: "Enable memory input", @@ -3137,7 +4407,11 @@ function App(props: { onSnapshot?: () => Promise }) { onSelect: async (dialog) => { await writeProjectMemoryConfig({ enabled: true, use: true, generate: false }, memoryRoot()) await mend.reload() - toast.show({ variant: "success", message: "Memory input enabled. Output proposals remain off.", duration: 4000 }) + toast.show({ + variant: "success", + message: "Memory input enabled. Output proposals remain off.", + duration: 4000, + }) dialog.clear() }, }, @@ -3168,11 +4442,91 @@ function App(props: { onSnapshot?: () => Promise }) { dialog.clear() }, }, + { + title: "Usage Insights", + value: "mendcode.stats.insights", + category: mendCategory, + suggested: true, + slash: { name: "stats", aliases: ["usage", "insights", "activity"] }, + onSelect: (dialog) => { + route.navigate(statsRoute("global")) + dialog.clear() + }, + }, + { + title: "Project Usage Insights", + value: "mendcode.stats.project", + category: mendCategory, + slash: { name: "stats-project", aliases: ["project-stats", "project-usage"] }, + onSelect: (dialog) => { + route.navigate(statsRoute("project")) + dialog.clear() + }, + }, + { + title: "Release channel", + value: "mendcode.release.channel", + category: mendCategory, + description: "Choose stable, beta or nightly without installing an update", + slash: { name: "release-channel" }, + onSelect: () => void showReleaseChannel(), + }, + { + title: "Loop Workflows", + value: "mendcode.loops.dashboard", + category: mendCategory, + suggested: true, + slash: { name: "loops", aliases: ["loop-dashboard", "loop-center"] }, + onSelect: (dialog) => { + route.navigate(loopsRoute()) + dialog.clear() + }, + }, + { + title: "Workflow Runs", + value: "mendcode.workflows.dashboard", + category: mendCategory, + suggested: true, + slash: { name: "workflows", aliases: ["workflow-dashboard", "workflow-center"] }, + onSelect: (dialog) => { + route.navigate(workflowsRoute()) + dialog.clear() + }, + }, + { + title: "Create Loop Workflow", + value: "mendcode.loop.create", + category: mendCategory, + description: "Create or control a Loop Workflow from the current prompt", + slash: { name: "loop" }, + enabled: route.data.type !== "session", + onSelect: (dialog) => { + dialog.clear() + route.navigate({ type: "home" }) + setTimeout(() => fillLoopSlashPrompt(""), 0) + }, + onSlash: (dialog, input) => { + dialog.clear() + route.navigate({ type: "home" }) + setTimeout(() => fillLoopSlashPrompt(input.arguments, true), 0) + }, + }, + { + title: "Changes Review", + value: "mendcode.changes.review", + category: mendCategory, + suggested: true, + slash: { name: "changes", aliases: ["diff", "review-changes"] }, + onSelect: (dialog) => { + route.navigate(changesRoute()) + dialog.clear() + }, + }, { title: "Skills, commands, prompt assets", value: "mendcode.assets", category: mendCategory, - slash: { name: "mend-assets", aliases: ["commands"] }, + slash: { name: "mend-assets" }, onSelect: () => void showMendAssets(), }, { @@ -3277,6 +4631,7 @@ function App(props: { onSnapshot?: () => Promise }) { keybind: "model_list", suggested: true, category: "Agent", + enabled: promptRouteActive(), slash: { name: "models", }, @@ -3290,6 +4645,7 @@ function App(props: { onSnapshot?: () => Promise }) { keybind: "model_cycle_recent", category: "Agent", hidden: true, + enabled: promptRouteActive(), onSelect: () => { local.model.cycle(1) }, @@ -3300,6 +4656,7 @@ function App(props: { onSnapshot?: () => Promise }) { keybind: "model_cycle_recent_reverse", category: "Agent", hidden: true, + enabled: promptRouteActive(), onSelect: () => { local.model.cycle(-1) }, @@ -3310,6 +4667,7 @@ function App(props: { onSnapshot?: () => Promise }) { keybind: "model_cycle_favorite", category: "Agent", hidden: true, + enabled: promptRouteActive(), onSelect: () => { local.model.cycleFavorite(1) }, @@ -3320,6 +4678,7 @@ function App(props: { onSnapshot?: () => Promise }) { keybind: "model_cycle_favorite_reverse", category: "Agent", hidden: true, + enabled: promptRouteActive(), onSelect: () => { local.model.cycleFavorite(-1) }, @@ -3329,6 +4688,7 @@ function App(props: { onSnapshot?: () => Promise }) { value: "agent.list", keybind: "agent_list", category: "Agent", + enabled: promptRouteActive(), slash: { name: "agents", }, @@ -3353,8 +4713,10 @@ function App(props: { onSnapshot?: () => Promise }) { keybind: "agent_cycle", category: "Agent", hidden: true, + enabled: promptRouteActive(), onSelect: () => { local.agent.move(1) + local.model.pinAgentCurrent() }, }, { @@ -3362,6 +4724,7 @@ function App(props: { onSnapshot?: () => Promise }) { value: "variant.cycle", keybind: "variant_cycle", category: "Agent", + enabled: promptRouteActive(), onSelect: () => { local.model.variant.cycle() }, @@ -3372,6 +4735,7 @@ function App(props: { onSnapshot?: () => Promise }) { keybind: "variant_list", category: "Agent", hidden: local.model.variant.list().length === 0, + enabled: promptRouteActive(), slash: { name: "variants", }, @@ -3385,12 +4749,14 @@ function App(props: { onSnapshot?: () => Promise }) { keybind: "agent_cycle_reverse", category: "Agent", hidden: true, + enabled: promptRouteActive(), onSelect: () => { local.agent.move(-1) + local.model.pinAgentCurrent() }, }, { - title: "Connect provider", + title: "Connect Provider", value: "provider.connect", suggested: !connected(), slash: { @@ -3399,7 +4765,7 @@ function App(props: { onSnapshot?: () => Promise }) { onSelect: () => { dialog.replace(() => ) }, - category: "Provider", + category: "Connect Provider", }, ...(sync.data.console_state.switchableOrgCount > 1 ? [ @@ -3464,6 +4830,11 @@ function App(props: { onSnapshot?: () => Promise }) { { title: "Help", value: "help.show", + keybind: ["setup", "stats", "memory", "changes", "loops", "workflows", "session-history"].includes( + route.data.type, + ) + ? "help" + : undefined, slash: { name: "help", }, @@ -3509,10 +4880,52 @@ function App(props: { onSnapshot?: () => Promise }) { dialog.clear() }, }, + { + title: "Show diagnostics", + category: "System", + value: "app.diagnostics", + slash: { name: "diagnostics", aliases: ["diag"] }, + hidden: !props.onDiagnostics, + description: "Read current TUI and connected runtime diagnostics on demand.", + onSelect: async (dialog) => { + try { + const diagnostics = await props.onDiagnostics?.() + if (!diagnostics) { + dialog.clear() + toast.show({ variant: "error", message: "Diagnostics are unavailable.", duration: 4000 }) + return + } + await DialogAlert.show( + dialog, + "MendCode Diagnostics", + formatDiagnostics({ + ...diagnostics, + ui: { + sessionCount: sync.data.session.length, + cachedSessionCount: Object.keys(sync.data.message).length, + cachedMessageCount: Object.values(sync.data.message).reduce( + (total, messages) => total + (messages?.length ?? 0), + 0, + ), + cachedPartCount: Object.values(sync.data.part).reduce( + (total, parts) => total + (parts?.length ?? 0), + 0, + ), + route: route.data.type, + }, + }), + ) + } catch (error) { + dialog.clear() + toast.show({ variant: "error", message: errorMessage(error), duration: 5000 }) + } + }, + }, { title: "Write heap snapshot", category: "System", value: "app.heap_snapshot", + hidden: !props.onSnapshot, onSelect: async (dialog) => { const files = await props.onSnapshot?.() toast.show({ @@ -3536,6 +4949,7 @@ function App(props: { onSnapshot?: () => Promise }) { }) renderer.suspend() + releaseTerminalInputModes() // pid=0 means send the signal to all processes in the process group process.kill(0, "SIGTSTP") }, @@ -3546,12 +4960,9 @@ function App(props: { onSnapshot?: () => Promise }) { keybind: "terminal_title_toggle", category: "System", onSelect: (dialog) => { - setTerminalTitleEnabled((prev) => { - const next = !prev - kv.set("terminal_title_enabled", next) - if (!next) renderer.setTerminalTitle("") - return next - }) + const next = !terminalTitleEnabled() + writeMendTuiCustomization((key, fallback) => kv.get(key, fallback), kv.set, { terminalTitle: next }) + if (!next) renderer.setTerminalTitle("") dialog.clear() }, }, @@ -3564,6 +4975,14 @@ function App(props: { onSnapshot?: () => Promise }) { dialog.clear() }, }, + { + title: "Replay MendCode intro", + value: "app.replay.intro", + category: "System", + slash: { name: "intro", aliases: ["replay-intro"] }, + description: "Preview the first-run intro without changing Setup state.", + onSelect: () => replayFirstRunIntro(), + }, { title: kv.get("file_context_enabled", true) ? "Disable file context" : "Enable file context", value: "app.toggle.file_context", @@ -3610,63 +5029,164 @@ function App(props: { onSnapshot?: () => Promise }) { }, ]) - event.on(TuiEvent.CommandExecute.type, (evt) => { - command.trigger(evt.properties.command) - }) + const appEventUnsubscribers: Array<() => void> = [] + appEventUnsubscribers.push( + event.on(TuiEvent.CommandExecute.type, (evt) => { + command.trigger(evt.properties.command) + }), + ) - event.on(TuiEvent.ToastShow.type, (evt) => { - toast.show({ + appEventUnsubscribers.push( + event.on(TuiEvent.ToastShow.type, (evt) => { + toast.show({ + title: evt.properties.title, + message: evt.properties.message, + variant: evt.properties.variant, + duration: evt.properties.duration, + }) + }), + ) + + const backgroundTaskNotificationIDs = new Set() + const ownerWakeIDs = new Set() + const unsubscribeBackgroundEvents = event.subscribe((incoming) => { + const evt = incoming as unknown as { + type?: string + properties?: { + eventID?: string + wakeID?: string + parentSessionID?: string + taskIDs?: string[] + taskTitles?: string[] + state?: "needs_input" | "completed" | "failed" | "cancelled" | "interrupted" + title?: string + summary?: string + error?: string + } + } + if (evt.type === "background_task.owner_wake" && evt.properties?.wakeID) { + if (ownerWakeIDs.has(evt.properties.wakeID)) return + if (ownerWakeIDs.size >= 500) { + const oldest = ownerWakeIDs.values().next().value + if (oldest) ownerWakeIDs.delete(oldest) + } + ownerWakeIDs.add(evt.properties.wakeID) + const titles = evt.properties.taskTitles?.filter(Boolean) ?? [] + const count = evt.properties.taskIDs?.length ?? titles.length + toast.show({ + title: "Background work finished", + message: `${titles.join(", ") || `${count} background task${count === 1 ? "" : "s"}`} finished; an automatic follow-up started`, + variant: "info", + duration: 8_000, + }) + return + } + if (evt.type !== "background_task.notification" || !evt.properties?.eventID || !evt.properties.state) return + if (backgroundTaskNotificationIDs.has(evt.properties.eventID)) return + if (backgroundTaskNotificationIDs.size >= 500) { + const oldest = backgroundTaskNotificationIDs.values().next().value + if (oldest) backgroundTaskNotificationIDs.delete(oldest) + } + backgroundTaskNotificationIDs.add(evt.properties.eventID) + const state = evt.properties.state + const notification = backgroundTaskToast({ + state, title: evt.properties.title, - message: evt.properties.message, - variant: evt.properties.variant, - duration: evt.properties.duration, + summary: evt.properties.summary, + error: evt.properties.error, }) + if (notification) toast.show(notification) }) + appEventUnsubscribers.push(unsubscribeBackgroundEvents) - event.on(TuiEvent.SessionSelect.type, (evt) => { - route.navigate({ - type: "session", - sessionID: evt.properties.sessionID, - }) + onCleanup(() => { + for (const unsubscribe of appEventUnsubscribers) unsubscribe() + appEventUnsubscribers.length = 0 + backgroundTaskNotificationIDs.clear() + ownerWakeIDs.clear() }) - event.on("session.deleted", (evt) => { - if (route.data.type === "session" && route.data.sessionID === evt.properties.info.id) { - route.navigate({ type: "home" }) - toast.show({ - variant: "info", - message: "The current session was deleted", + appEventUnsubscribers.push( + event.on(TuiEvent.SessionSelect.type, (evt) => { + route.navigate({ + type: "session", + sessionID: evt.properties.sessionID, }) - } - }) + }), + ) - event.on("session.error", (evt) => { - const error = evt.properties.error - if (error && typeof error === "object" && error.name === "MessageAbortedError") return - const message = errorMessage(error) + appEventUnsubscribers.push( + event.on("session.deleted", (evt) => { + if (route.data.type === "session" && route.data.sessionID === evt.properties.info.id) { + route.navigate({ type: "home" }) + toast.show({ + variant: "info", + message: "The current session was deleted", + }) + } + }), + ) - toast.show({ - variant: "error", - message, - duration: 5000, + appEventUnsubscribers.push( + event.on("session.error", (evt) => { + const error = evt.properties.error + if (error && typeof error === "object" && error.name === "MessageAbortedError") return + const message = errorMessage(error) + + toast.show({ + variant: "error", + message, + duration: 5000, + }) + }), + ) + + async function releaseChannelRequest(channel?: "stable" | "beta" | "nightly") { + const headers = new Headers(sdk.headers) + headers.set("content-type", "application/json") + const response = await sdk.fetch(new URL("/global/release-channel", sdk.url), { + method: channel ? "PUT" : "GET", headers, + body: channel ? JSON.stringify({ channel }) : undefined, signal: AbortSignal.timeout(5000), }) - }) + if (!response.ok) throw new Error("The server could not read or change the release channel.") + const result = await response.json() as { channel?: string } + if (result.channel !== "stable" && result.channel !== "beta" && result.channel !== "nightly") throw new Error("Invalid release channel response.") + return result.channel + } - event.on("installation.update-available", async (evt) => { - const version = evt.properties.version + async function showReleaseChannel() { + try { + const current = await releaseChannelRequest() + dialog.replace(() => { + if (option.value !== "stable" && option.value !== "beta" && option.value !== "nightly") return + void releaseChannelRequest(option.value).then((channel) => { + dialog.clear() + toast.show({ variant: "info", message: `Release channel: ${channel}. Run mendcode upgrade when you want to install.`, duration: 6000 }) + }).catch((error) => toast.show({ variant: "error", message: errorMessage(error), duration: 6000 })) + }} />) + } catch (error) { toast.show({ variant: "error", message: errorMessage(error), duration: 6000 }) } + } - const skipped = kv.get("skipped_version") + const showUpdateAvailable = async (version: string) => { + const skipped = skippedUpdateVersion(kv.store) if (skipped && !semver.gt(version, skipped)) return + const channel = await releaseChannelRequest().catch(() => undefined) const choice = await DialogConfirm.show( dialog, - `Update Available`, + channel ? `Update Available · ${channel}` : "Update Available", `A new release v${version} is available. Would you like to update now?`, "skip", ) if (choice === false) { - kv.set("skipped_version", version) + kv.set(SKIPPED_UPDATE_VERSION_KEY, version) return } @@ -3678,13 +5198,21 @@ function App(props: { onSnapshot?: () => Promise }) { duration: 30000, }) - const result = await sdk.client.global.upgrade({ target: version }) + const result = await sdk.client.global.upgrade({ target: version }).catch((error: unknown) => ({ + error, + data: undefined, + })) if (result.error || !result.data?.success) { toast.show({ variant: "error", title: "Update Failed", - message: "Update failed", + message: + result.error !== undefined + ? errorMessage(result.error) + : result.data?.success === false + ? result.data.error + : "Update failed", duration: 10000, }) return @@ -3692,19 +5220,79 @@ function App(props: { onSnapshot?: () => Promise }) { await DialogAlert.show( dialog, - "Update Complete", - `Successfully updated to ${productName()} runtime v${result.data.version}. Please restart the application.`, + "Restart Required", + `${productName()} runtime v${result.data.version} was installed. Restart the application to check startup.`, ) void exit() - }) + } + + appEventUnsubscribers.push( + event.on("installation.update-available", async (evt) => { + await showUpdateAvailable(evt.properties.version) + }), + ) const plugin = createMemo(() => { if (!ready()) return if (route.data.type !== "plugin") return const render = routeView(route.data.id) if (!render) return route.navigate({ type: "home" })} /> - return render({ params: route.data.data }) + const value = render({ params: route.data.data }) as unknown + if (typeof value === "string" || typeof value === "number") { + return ( + + {String(value)} + + ) + } + if (typeof value === "boolean") return null + return value as JSX.Element + }) + const homePromptReady = createMemo(() => + homePromptBootstrapReady({ + providerMetadataReady: sync.providerMetadataReady, + modelPolicyReady: local.model.ready, + }), + ) + const startupReady = createMemo( + () => + ready() && + pluginsReady() && + sync.status !== "loading" && + (route.data.type !== "home" || homePromptReady()), + ) + let startupReported = false + const startupDeadline = props.onStartupReady ? setTimeout(() => { + if (startupReported) return + toast.show({ + variant: "error", title: "Update startup timed out", + message: "Backend and TUI readiness were not confirmed. Run mendcode upgrade --check for the startup record.", + duration: 30_000, + }) + }, 30_000) : undefined + onCleanup(() => clearTimeout(startupDeadline)) + createEffect(() => { + if (startupReported || !startupReady() || sync.status !== "complete") return + startupReported = true + clearTimeout(startupDeadline) + void props.onStartupReady?.().catch((error) => { + toast.show({ variant: "error", title: "Update startup check failed", message: errorMessage(error), duration: 10_000 }) + }) + }) + const startupMessage = createMemo(() => + startupLoadingText({ pluginsReady: pluginsReady(), syncLoading: sync.status === "loading" }), + ) + let startupUpdateChecked = false + createEffect(() => { + if (startupUpdateChecked || !startupReady() || !kv.ready) return + startupUpdateChecked = true + void checkUpgrade(sync.data.config.autoupdate) + .then((result) => { + if (result?.type !== "notify") return + return showUpdateAvailable(result.version) + }) + .catch(() => {}) }) return ( @@ -3727,8 +5315,8 @@ function App(props: { onSnapshot?: () => Promise }) { - - + + @@ -3736,11 +5324,44 @@ function App(props: { onSnapshot?: () => Promise }) { + + + + + + + + + + + + + + + + + + - {plugin()} + ( + + )} + > + {plugin()} + - + + + + kv.get("animations_enabled", true) === true} + handoffLabel={() => (route.data.type === "setup" ? "MENDCODE / SETUP" : undefined)} + onComplete={completeFirstRunIntro} + /> + ) } diff --git a/src/mendcode/packages/opencode/src/cli/cmd/tui/attach.ts b/src/mendcode/packages/opencode/src/cli/cmd/tui/attach.ts index 2936ce63..02741b52 100644 --- a/src/mendcode/packages/opencode/src/cli/cmd/tui/attach.ts +++ b/src/mendcode/packages/opencode/src/cli/cmd/tui/attach.ts @@ -6,6 +6,18 @@ import { TuiConfig } from "@/cli/cmd/tui/config/tui" import { errorMessage } from "@/util/error" import { validateSession } from "./validate-session" import { ServerAuth } from "@/server/auth" +import { loadMendTuiProfile } from "@/mend/profile" +import { isProcessMemoryUsage, processMemoryUsage, type DiagnosticsSnapshot } from "@/util/process-memory" + +async function readServerDiagnostics(input: { url: string; headers: RequestInit["headers"] }) { + const response = await fetch(new URL("/global/diagnostics/memory", input.url), { + headers: input.headers, + }) + if (!response.ok) throw new Error(`diagnostics endpoint returned HTTP ${response.status}`) + const value: unknown = await response.json() + if (!isProcessMemoryUsage(value)) throw new Error("diagnostics endpoint returned an invalid response") + return value +} export const AttachCommand = cmd({ command: "attach ", @@ -44,6 +56,11 @@ export const AttachCommand = cmd({ alias: ["u"], type: "string", describe: "basic auth username (defaults to OPENCODE_SERVER_USERNAME or 'mendcode')", + }) + .option("diagnostics", { + type: "boolean", + default: false, + describe: "enable the on-demand diagnostics command", }), handler: async (args) => { const unguard = win32InstallCtrlCGuard() @@ -68,6 +85,7 @@ export const AttachCommand = cmd({ })() const headers = ServerAuth.headers({ password: args.password, username: args.username }) const config = await TuiConfig.get() + const mendProfile = await loadMendTuiProfile(directory ?? process.cwd(), config) try { await validateSession({ @@ -84,7 +102,26 @@ export const AttachCommand = cmd({ await tui({ url: args.url, + ...(args.diagnostics + ? { + async onDiagnostics(): Promise { + const tui = processMemoryUsage("tui") + try { + return { + tui, + server: await readServerDiagnostics({ url: args.url, headers }), + } + } catch (error) { + return { + tui, + serverError: errorMessage(error), + } + } + }, + } + : {}), config, + mendProfile, args: { continue: args.continue, sessionID: args.session, diff --git a/src/mendcode/packages/opencode/src/cli/cmd/tui/component/agent-command-panel.tsx b/src/mendcode/packages/opencode/src/cli/cmd/tui/component/agent-command-panel.tsx new file mode 100644 index 00000000..9c59630e --- /dev/null +++ b/src/mendcode/packages/opencode/src/cli/cmd/tui/component/agent-command-panel.tsx @@ -0,0 +1,141 @@ +import { createMemo, createSignal, For, Show } from "solid-js" +import type { TuiThemeCurrent } from "@mendcode/plugin/tui" +import { Locale } from "@/util/locale" +import { + agentViewCommandStateRank, + formatAgentViewCommandSummary, + isAgentViewCommandActionable, + type AgentViewCommand, +} from "../util/agent-view" + +export function AgentCommandPanel(props: { + commands: readonly AgentViewCommand[] + sessionID: string + width: number + height?: number + busyID?: string + theme: Pick + onUpdate: (command: AgentViewCommand, state: "accepted" | "rejected") => void + onOpenSession?: (sessionID: string) => void +}) { + const [expanded, setExpanded] = createSignal(false) + const active = createMemo(() => + props.commands + .filter((command) => agentViewCommandStateRank(command) < 2) + .toSorted( + (a, b) => + Number(b.targetSessionID === props.sessionID && isAgentViewCommandActionable(b)) - + Number(a.targetSessionID === props.sessionID && isAgentViewCommandActionable(a)) || + agentViewCommandStateRank(a) - agentViewCommandStateRank(b) || + b.time.updated - a.time.updated, + ), + ) + const history = createMemo(() => + props.commands + .filter((command) => agentViewCommandStateRank(command) >= 2) + .toSorted((a, b) => b.time.updated - a.time.updated), + ) + const visible = createMemo(() => [...active().slice(0, 4), ...(expanded() ? history().slice(0, 4) : [])]) + const rows = () => ( + <> + + {(command) => { + const incoming = () => command.targetSessionID === props.sessionID + const actionable = () => incoming() && isAgentViewCommandActionable(command) + const busy = () => props.busyID === command.id + const sender = () => + incoming() ? command.payload?.sourceTitle || command.sourceSessionID : command.targetSessionID + const relatedSessionID = () => (incoming() ? command.sourceSessionID : command.targetSessionID) + const canOpen = () => + Boolean(props.onOpenSession && relatedSessionID() && relatedSessionID() !== props.sessionID) + const trailingWidth = () => (canOpen() ? 7 : 0) + (actionable() ? 19 : 0) + return ( + + + + {Locale.truncate( + `${incoming() ? "←" : "→"} ${Locale.truncate(sender().replace(/\s+/g, " "), 24)} · ${formatAgentViewCommandSummary(command)}`, + Math.max(1, props.width - trailingWidth()), + )} + + + { + const sessionID = relatedSessionID() + if (sessionID) props.onOpenSession?.(sessionID) + }} + > + [open] + + + + { + if (!busy()) props.onUpdate(command, "accepted") + }} + > + [accept] + + { + if (!busy()) props.onUpdate(command, "rejected") + }} + > + [reject] + + + + + + {Locale.truncate(command.error!.replace(/\s+/g, " "), props.width)} + + + + ) + }} + + 4 || (expanded() && history().length > 4)}> + + More commands in Agent View + + + + ) + + return ( + 0}> + + setExpanded((value) => !value)} + > + {history().length > 0 ? (expanded() ? "▾ " : "▸ ") : ""}Commands + {active().length > 0 ? ` · ${active().length} active` : ""} + {history().length > 0 ? ` · ${history().length} past` : ""} + + + + {rows()} + + + + + ) +} diff --git a/src/mendcode/packages/opencode/src/cli/cmd/tui/component/command-deck.tsx b/src/mendcode/packages/opencode/src/cli/cmd/tui/component/command-deck.tsx new file mode 100644 index 00000000..7e602976 --- /dev/null +++ b/src/mendcode/packages/opencode/src/cli/cmd/tui/component/command-deck.tsx @@ -0,0 +1,231 @@ +import { TextAttributes } from "@opentui/core" +import { useTerminalDimensions } from "@opentui/solid" +import { For, Show, createMemo, type JSX } from "solid-js" +import type { Route } from "@tui/context/route" +import { useTheme } from "@tui/context/theme" + +export type CommandDeckPage = "loops" | "workflows" | "stats" | "memory" | "changes" | "setup" + +type CommandDeckText = string | (() => string) + +type CommandDeckProps = { + page: CommandDeckPage + subtitle?: CommandDeckText + status?: CommandDeckText + summary?: CommandDeckText + rail?: JSX.Element + context?: JSX.Element + footer?: CommandDeckText + children: JSX.Element +} + +type CommandDeckContextProps = { + title: string + rows?: Array<[string, string]> + children?: JSX.Element +} + +const PAGE_LABELS: Record = { + loops: "LOOPS", + workflows: "WORKFLOWS", + stats: "STATS", + memory: "MEMORY", + changes: "CHANGES", + setup: "SETUP", +} + +function readText(value: CommandDeckText | undefined, fallback = "") { + if (typeof value === "function") return value() + return value ?? fallback +} + +function wrapFooter(value: string, width: number) { + const tokens = value.split(/\s{2,}| · /).map((token) => token.trim()).filter(Boolean) + if (tokens.length === 0) return [""] + const lines: string[] = [] + let line = "" + for (const token of tokens) { + const next = line ? `${line} ${token}` : token + if (line && next.length > width) { + lines.push(line) + line = token + continue + } + line = next + } + if (line) lines.push(line) + return lines +} + +export function commandDeckLayout(input: { width: number; height: number; hasRail?: boolean; hasContext?: boolean }) { + const width = Math.max(0, input.width) + const height = Math.max(0, input.height) + const hasRail = input.hasRail ?? true + const hasContext = input.hasContext ?? true + const wide = width >= 120 && height >= 24 + const railWidth = Math.min(48, Math.max(24, Math.floor(width * 0.2))) + const contextWidth = Math.min(50, Math.max(30, Math.floor(width * 0.24))) + const sideWidth = (hasRail ? railWidth : 0) + (hasContext ? contextWidth : 0) + const sideChrome = sideWidth === 0 ? 2 : sideWidth + (hasRail && hasContext ? 4 : 3) + return { + wide, + compact: width < 96 || height < 22, + railWidth, + contextWidth, + contentWidth: Math.max(30, width - (wide ? sideChrome : 2)), + } +} + +export function commandDeckRouteTarget(route: Route, page: CommandDeckPage): Route { + const returnTo = "returnTo" in route ? route.returnTo : undefined + const returnProps = returnTo ? { returnTo } : {} + if (page === "setup") return { type: "setup", ...returnProps } + if (page === "stats") { + return { + type: "stats", + scope: route.type === "stats" ? (route.scope ?? "global") : "global", + ...returnProps, + } + } + if (page === "memory") return { type: "memory", ...returnProps } + if (page === "changes") return { type: "changes", ...returnProps } + if (page === "workflows") return { type: "workflows", ...returnProps } + return { type: "loops", ...returnProps } +} + +function Rail(props: { + content?: JSX.Element +}) { + return ( + + {props.content} + + ) +} + +export function CommandDeckContext(props: CommandDeckContextProps) { + const { theme } = useTheme() + return ( + + + {props.title} + + + {(row) => ( + + + {row[0]} + + + {row[1]} + + + )} + + {props.children} + + ) +} + +export function CommandDeck(props: CommandDeckProps) { + const { theme } = useTheme() + const dimensions = useTerminalDimensions() + const layout = createMemo(() => commandDeckLayout({ + ...dimensions(), + hasRail: Boolean(props.rail), + hasContext: Boolean(props.context), + })) + const status = createMemo(() => readText(props.status, "LIVE")) + const subtitle = createMemo(() => readText(props.subtitle)) + const summary = createMemo(() => readText(props.summary)) + const footer = createMemo(() => readText(props.footer, "↑↓ Navigate Enter Open r Refresh ? Help q Back")) + const footerLines = createMemo(() => wrapFooter(footer(), Math.max(20, dimensions().width - 2))) + + return ( + + + + MENDCODE / {PAGE_LABELS[props.page]} + + + + ● {status()} + + + + + {subtitle()} + + + + {summary()} + + + + {props.children} + + + {props.context} + + + + } + > + + + + + + + + + {props.children} + + + + {props.context} + + + + + + + {(line) => ( + + {line} + + )} + + + + ) +} diff --git a/src/mendcode/packages/opencode/src/cli/cmd/tui/component/compaction-panel.tsx b/src/mendcode/packages/opencode/src/cli/cmd/tui/component/compaction-panel.tsx new file mode 100644 index 00000000..f8d782b7 --- /dev/null +++ b/src/mendcode/packages/opencode/src/cli/cmd/tui/component/compaction-panel.tsx @@ -0,0 +1,956 @@ +import { createEffect, createMemo, createSignal, For, onCleanup, Show, type JSX } from "solid-js" +import type { BoxRenderable, MouseEvent, Renderable, TextareaRenderable } from "@opentui/core" +import { useKeyboard, useRenderer, useTerminalDimensions } from "@opentui/solid" +import { SplitBorder } from "./border" +import { useTheme } from "../context/theme" +import { useMendTuiProfile } from "../context/mend" +import { useKV } from "../context/kv" +import { usePromptRef } from "../context/prompt" +import { useTextareaKeybindings } from "./textarea-keybindings" +import { Locale } from "@/util/locale" +import { errorMessage } from "@/util/error" +import { compactionArcadeFrames, compactionStageStates } from "@/mend/tui/presentation" + +type SnakeDirection = "up" | "down" | "left" | "right" +type SnakePoint = { x: number; y: number } +type SnakeState = { + body: SnakePoint[] + food: SnakePoint + direction: SnakeDirection + pendingDirection: SnakeDirection + score: number + highScore: number + alive: boolean + paused: boolean +} + +export type CompactionArcadeKeyEvent = { + name: string + sequence?: string + preventDefault: () => void + stopPropagation?: () => void +} + +export type CompactionArcadeCellTone = "primary" | "muted" | "text" | "wall" | "empty" | "head" | "body" | "food" | "danger" | "accent" + +export type CompactionArcadeCell = { + text: string + tone?: CompactionArcadeCellTone +} + +export type CompactionArcadeRender = { + title?: string + status?: string + lines?: string[] + cells?: CompactionArcadeCell[][] +} + +export type CompactionArcadeGame = { + id: string + label: string + intervalMs?: number + initialState: () => unknown + tick?: (state: unknown) => unknown + key?: (state: unknown, key: string) => unknown | undefined + render: (state: unknown) => CompactionArcadeRender +} + +export function shouldRenderCompactionArcade(input: { + style: "minimal" | "cockpit" | "arcade" | "quiet" + arcade: string + completed?: boolean + terminal?: boolean +}) { + return input.style === "arcade" && input.arcade !== "off" +} + +export function shouldRunCompactionArcade(input: { + style: "minimal" | "cockpit" | "arcade" | "quiet" + arcade: string + completed?: boolean + terminal?: boolean +}) { + return shouldRenderCompactionArcade(input) && !input.terminal && !input.completed +} + +export function compactionPanelIsPacked(input: { completed?: boolean; terminal?: boolean; hasSummaryBody?: boolean }) { + return input.completed === true || input.terminal === true +} + +export function compactionPanelHeading(input: { style: "minimal" | "cockpit" | "arcade" | "quiet"; packed: boolean; failure?: "interrupted" | "failed" }) { + if (input.failure) return `Compaction ${input.failure}` + if (input.style === "arcade" && input.packed) return "Arcade complete · Context packed" + return input.packed ? "Context packed" : "Packing context" +} + +export function shouldAcceptCompactionArcadeFocus(input: { + arcadeFocused: boolean + currentFocusedRenderable?: unknown + arcadeInput?: unknown +}) { + return input.arcadeFocused && input.currentFocusedRenderable === input.arcadeInput +} + +export function shouldRestoreCompactionPromptFocus(input: { + arcadeOwnsFocus: boolean + arcadeWasFocused?: boolean + previousFocusAvailable: boolean + promptAvailable: boolean +}) { + if (!input.arcadeOwnsFocus && !input.arcadeWasFocused) return false + return input.previousFocusAvailable || input.promptAvailable +} + +export function compactionTranscriptToggleLabel(expanded: boolean) { + return expanded ? "▾ hide compacted transcript" : "▸ show compacted transcript" +} + +let focusedCompactionArcade: BoxRenderable | undefined +let focusedCompactionArcadeBlur: (() => void) | undefined + +export function blurCompactionArcade() { + const blur = focusedCompactionArcadeBlur + if (!blur) return false + blur() + return true +} + +export function isCompactionArcadeFocused() { + const arcade = focusedCompactionArcade + return Boolean(arcade && !arcade.isDestroyed && arcade.focused) +} + +export function shouldBlurCompactionArcadeWhenOffscreen(input: { + focused: boolean + screenY?: number + height?: number + viewportHeight?: number +}) { + if (!input.focused) return false + if (input.screenY === undefined || input.height === undefined || input.viewportHeight === undefined) return false + if (!Number.isFinite(input.screenY) || !Number.isFinite(input.height) || !Number.isFinite(input.viewportHeight)) return false + if (input.height <= 0 || input.viewportHeight <= 0) return false + return input.screenY + input.height <= 0 || input.screenY >= input.viewportHeight +} + +const snakeSize = 16 +const snakeWidth = snakeSize +const snakeHeight = snakeSize +const snakeCellWidth = 2 +const snakeGlobalHighScoreKey = "mendcode.arcade.snake.high_score" + +function sameSnakePoint(a: SnakePoint, b: SnakePoint) { + return a.x === b.x && a.y === b.y +} + +function oppositeSnakeDirection(a: SnakeDirection, b: SnakeDirection) { + return (a === "up" && b === "down") || (a === "down" && b === "up") || (a === "left" && b === "right") || (a === "right" && b === "left") +} + +function randomSnakeInt(max: number) { + return Math.floor(Math.random() * max) +} + +function randomSnakeRange(min: number, max: number) { + return min + randomSnakeInt(Math.max(1, max - min + 1)) +} + +function snakeDelta(direction: SnakeDirection): SnakePoint { + if (direction === "up") return { x: 0, y: -1 } + if (direction === "down") return { x: 0, y: 1 } + if (direction === "left") return { x: -1, y: 0 } + return { x: 1, y: 0 } +} + +function randomSnakeDirection(): SnakeDirection { + return (["up", "down", "left", "right"] as const)[randomSnakeInt(4)] ?? "right" +} + +function randomSnakeHead(direction: SnakeDirection): SnakePoint { + const minCross = 3 + const maxCross = snakeSize - 4 + const minForward = 5 + const maxForward = snakeSize - 6 + if (direction === "right") return { x: randomSnakeRange(minCross, maxForward), y: randomSnakeRange(minCross, maxCross) } + if (direction === "left") return { x: randomSnakeRange(minForward, maxCross), y: randomSnakeRange(minCross, maxCross) } + if (direction === "down") return { x: randomSnakeRange(minCross, maxCross), y: randomSnakeRange(minCross, maxForward) } + return { x: randomSnakeRange(minCross, maxCross), y: randomSnakeRange(minForward, maxCross) } +} + +function initialSnakeState(highScore = 0): SnakeState { + const direction = randomSnakeDirection() + const head = randomSnakeHead(direction) + const delta = snakeDelta(direction) + const body = [head, { x: head.x - delta.x, y: head.y - delta.y }, { x: head.x - delta.x * 2, y: head.y - delta.y * 2 }] + return { + body, + food: nextSnakeFood(body), + direction, + pendingDirection: direction, + score: 0, + highScore, + alive: true, + paused: false, + } +} + +function normalizedSnakeHighScore(value: unknown) { + if (typeof value !== "number" || !Number.isFinite(value)) return 0 + return Math.max(0, Math.floor(value)) +} + +function normalizedArcadeKey(name: string, sequence?: string) { + if (sequence === "\u001b[A") return "up" + if (sequence === "\u001b[B") return "down" + if (sequence === "\u001b[C") return "right" + if (sequence === "\u001b[D") return "left" + const key = name.toLowerCase().replace(/^arrow/, "") + if (key === " " || key === "spacebar") return "space" + if (key === "esc") return "escape" + return key +} + +function snakeDirectionFromKey(name: string): SnakeDirection | undefined { + const key = normalizedArcadeKey(name) + if (key === "up" || key === "w") return "up" + if (key === "down" || key === "s") return "down" + if (key === "left" || key === "a") return "left" + if (key === "right" || key === "d") return "right" + return undefined +} + +function nextSnakeFood(body: SnakePoint[]): SnakePoint { + const open = Array.from({ length: snakeWidth * snakeHeight }, (_, index) => ({ + x: index % snakeWidth, + y: Math.floor(index / snakeWidth), + })).filter((point) => !body.some((item) => sameSnakePoint(item, point))) + return open[randomSnakeInt(open.length)] ?? { x: 0, y: 0 } +} + +function advanceSnake(state: SnakeState): SnakeState { + if (!state.alive || state.paused) return state + const direction = state.pendingDirection + const head = state.body[0] ?? { x: 0, y: 0 } + const nextHead = + direction === "up" + ? { x: head.x, y: head.y - 1 } + : direction === "down" + ? { x: head.x, y: head.y + 1 } + : direction === "left" + ? { x: head.x - 1, y: head.y } + : { x: head.x + 1, y: head.y } + const eating = sameSnakePoint(nextHead, state.food) + const collisionBody = eating ? state.body : state.body.slice(0, -1) + if ( + nextHead.x < 0 || + nextHead.y < 0 || + nextHead.x >= snakeWidth || + nextHead.y >= snakeHeight || + collisionBody.some((point) => sameSnakePoint(point, nextHead)) + ) { + return { ...state, direction, alive: false, highScore: Math.max(state.highScore, state.score) } + } + const body = eating ? [nextHead, ...state.body] : [nextHead, ...state.body.slice(0, -1)] + const score = eating ? state.score + 1 : state.score + return { + ...state, + body, + direction, + score, + highScore: Math.max(state.highScore, score), + food: eating ? nextSnakeFood(body) : state.food, + } +} + +function turnSnake(state: SnakeState, direction: SnakeDirection): SnakeState { + if (!state.alive) return state + if (oppositeSnakeDirection(state.direction, direction)) return state + return { ...state, pendingDirection: direction, paused: false } +} + +function snakeRenderCell(text: string, tone: CompactionArcadeCellTone): CompactionArcadeCell { + return { text: text.padEnd(snakeCellWidth, " ").slice(0, snakeCellWidth), tone } +} + +function renderSnakeCells(state: SnakeState): CompactionArcadeCell[][] { + const rows: CompactionArcadeCell[][] = [[{ text: "╭" + "─".repeat(snakeWidth * snakeCellWidth) + "╮", tone: "wall" }]] + for (let y = 0; y < snakeHeight; y++) { + rows.push([ + { text: "│", tone: "wall" }, + ...Array.from({ length: snakeWidth }, (_, x) => { + const point = { x, y } + if (sameSnakePoint(state.body[0] ?? { x: -1, y: -1 }, point)) return snakeRenderCell("◉", "head") + if (state.body.slice(1).some((item) => sameSnakePoint(item, point))) return snakeRenderCell("●", "body") + if (sameSnakePoint(state.food, point)) return snakeRenderCell("◆", "food") + return snakeRenderCell("·", "empty") + }), + { text: "│", tone: "wall" }, + ]) + } + rows.push([{ text: "╰" + "─".repeat(snakeWidth * snakeCellWidth) + "╯", tone: "wall" }]) + return rows +} + +const snakeArcadeGame: CompactionArcadeGame = { + id: "snake", + label: "Snake", + intervalMs: 150, + initialState: () => initialSnakeState(), + tick: (state) => advanceSnake(state as SnakeState), + key: (state, name) => { + const snake = state as SnakeState + const key = normalizedArcadeKey(name) + const direction = snakeDirectionFromKey(key) + if (direction) return turnSnake(snake, direction) + if (key === "space") return snake.alive ? { ...snake, paused: !snake.paused } : snake + if (key === "r") return initialSnakeState(snake.highScore) + return undefined + }, + render: (state) => { + const snake = state as SnakeState + return { + title: `Snake · Score ${snake.score} · Best ${snake.highScore}`, + status: snake.alive ? (snake.paused ? "Paused" : "Focused controls active") : "Game over. Press R to reset.", + cells: renderSnakeCells(snake), + } + }, +} + +const compactionArcadeGameRegistry = new Map([[snakeArcadeGame.id, snakeArcadeGame]]) + +export function registerCompactionArcadeGame(game: CompactionArcadeGame) { + if (!game.id.trim()) throw new Error("Compaction arcade game id is required") + compactionArcadeGameRegistry.set(game.id, game) + return true +} + +export function unregisterCompactionArcadeGame(id: string) { + if (id === snakeArcadeGame.id) return false + return compactionArcadeGameRegistry.delete(id) +} + +export function registeredCompactionArcadeGame(id: string) { + return compactionArcadeGameRegistry.get(id) +} + +export function CompactionPanel(props: { + reason: "auto" | "manual" + overflow?: boolean + resume?: boolean + postPrompt?: string + include?: string + tailStartID?: string + hasSummaryBody?: boolean + completed?: boolean + terminal?: boolean + summaryPreview?: string + failure?: "interrupted" | "failed" + transcriptPreview?: string + summaryContent?: JSX.Element + scratchpad?: { + key: string + initialValue?: string + loading?: boolean + readOnly?: boolean + onSave?: (value: string) => Promise + note?: string + } +}) { + const { theme } = useTheme() + const dimensions = useTerminalDimensions() + const renderer = useRenderer() + const mend = useMendTuiProfile() + const kv = useKV() + const promptRef = usePromptRef() + const textareaKeybindings = useTextareaKeybindings() + const config = createMemo(() => mend.profile.presentation.compaction) + const packed = createMemo(() => compactionPanelIsPacked(props)) + const stages = createMemo(() => + compactionStageStates({ + hasSummary: packed(), + resume: props.resume, + postPrompt: props.postPrompt, + include: props.include, + tailStartID: props.tailStartID, + }), + ) + const chips = createMemo(() => + [ + props.reason, + props.overflow ? "overflow" : undefined, + props.resume ? "resume" : undefined, + props.tailStartID ? "preserved tail" : undefined, + props.include ? "transcript kept" : undefined, + ].filter((value): value is string => Boolean(value)), + ) + const [arcadeTick, setArcadeTick] = createSignal(0) + const [arcadeFocused, setArcadeFocused] = createSignal(false) + const [arcadeState, setArcadeState] = createSignal(snakeArcadeGame.initialState()) + const [summaryExpanded, setSummaryExpanded] = createSignal(false) + const activeArcadeGame = createMemo(() => + shouldRenderCompactionArcade({ ...config(), completed: packed(), terminal: props.terminal }) + ? registeredCompactionArcadeGame(config().arcade) + : undefined, + ) + const arcadeRender = createMemo(() => activeArcadeGame()?.render(arcadeState())) + const arcadeFrame = createMemo(() => { + if (!shouldRenderCompactionArcade({ ...config(), completed: packed(), terminal: props.terminal }) || activeArcadeGame()) return [] + const frames = compactionArcadeFrames(config().arcade) + const frame = frames[arcadeTick() % Math.max(1, frames.length)] + return frame ? [frame] : [] + }) + const summaryAvailable = createMemo(() => + !props.failure && Boolean(props.summaryContent || props.summaryPreview?.trim() || props.transcriptPreview?.trim()), + ) + + const scratchpadEnabled = createMemo(() => config().allowScratchpad && Boolean(props.scratchpad)) + const scratchpadReadOnly = createMemo(() => Boolean(props.terminal || props.scratchpad?.readOnly)) + const followUpText = createMemo(() => (props.scratchpad?.initialValue ?? props.postPrompt ?? "").trim()) + const tailDetail = createMemo(() => + props.tailStartID + ? `tail: ${Locale.truncate(props.tailStartID, 28)}` + : props.include + ? `tail: ${Locale.truncate(props.include, 32)}` + : undefined, + ) + const compactionDetails = createMemo(() => + [ + packed() ? "packed" : "packing", + props.reason, + props.overflow ? "overflow" : undefined, + tailDetail(), + props.resume ? "resume" : undefined, + followUpText() ? "follow-up saved" : undefined, + ] + .filter((value): value is string => Boolean(value)) + .join(" · "), + ) + const [draft, setDraft] = createSignal(props.scratchpad?.initialValue ?? "") + const [saved, setSaved] = createSignal(props.scratchpad?.initialValue ?? "") + const [saveState, setSaveState] = createSignal<"saved" | "pending" | "saving" | "local" | "error">( + props.scratchpad?.onSave ? "saved" : "local", + ) + const [saveFailure, setSaveFailure] = createSignal() + let scratchpadInput: TextareaRenderable | undefined + let arcadeBox: BoxRenderable | undefined + let arcadePreviousFocus: Renderable | null = null + let lastScratchpadKey: string | undefined + let lastArcadeGameID: string | undefined + let saveTimer: ReturnType | undefined + let saveTicket = 0 + let focusRestoreToken = 0 + + function globalSnakeHighScore() { + return normalizedSnakeHighScore(kv.get(snakeGlobalHighScoreKey, 0)) + } + + function persistSnakeHighScore(state: unknown) { + if (activeArcadeGame()?.id !== snakeArcadeGame.id) return + const highScore = normalizedSnakeHighScore((state as SnakeState).highScore) + if (highScore <= globalSnakeHighScore()) return + kv.set(snakeGlobalHighScoreKey, highScore) + } + + function setArcadeStateAndPersist(next: unknown) { + setArcadeState(next) + persistSnakeHighScore(next) + } + + function arcadeOwnsFocus() { + return shouldAcceptCompactionArcadeFocus({ + arcadeFocused: arcadeFocused(), + currentFocusedRenderable: renderer.currentFocusedRenderable, + arcadeInput: arcadeBox, + }) + } + + function restoreFocusAfterArcadeBlur(previousFocus?: Renderable | null) { + const token = ++focusRestoreToken + setTimeout(() => { + if (token !== focusRestoreToken) return + if (renderer.currentFocusedRenderable && renderer.currentFocusedRenderable !== arcadeBox) return + if (previousFocus && !previousFocus.isDestroyed && previousFocus !== arcadeBox) { + previousFocus.focus() + return + } + promptRef.current?.focus() + }, 0) + } + + function isArcadeEventTarget(target: Renderable | null | undefined) { + let current = target + while (current) { + if (current === arcadeBox) return true + current = current.parent + } + return false + } + + function focusArcade() { + if (!shouldRunCompactionArcade({ ...config(), completed: packed(), terminal: props.terminal })) return + if (!activeArcadeGame() || !arcadeBox || arcadeBox.isDestroyed) return + focusRestoreToken += 1 + const currentFocus = renderer.currentFocusedRenderable + arcadePreviousFocus = currentFocus === arcadeBox ? null : currentFocus + arcadeBox.focus() + if (renderer.currentFocusedRenderable !== arcadeBox) { + arcadePreviousFocus = null + return + } + focusedCompactionArcade = arcadeBox + focusedCompactionArcadeBlur = () => blurArcade(undefined, { consume: false }) + setArcadeFocused(true) + } + + function blurArcade(event?: { preventDefault?: () => void; stopPropagation?: () => void }, input?: { consume?: boolean }) { + const ownsFocus = arcadeOwnsFocus() + const wasFocused = arcadeFocused() || focusedCompactionArcade === arcadeBox + const previousFocus = arcadePreviousFocus + const prompt = promptRef.current + const previousFocusAvailable = Boolean(previousFocus && !previousFocus.isDestroyed && previousFocus !== arcadeBox) + arcadePreviousFocus = null + if (focusedCompactionArcade === arcadeBox) { + focusedCompactionArcade = undefined + focusedCompactionArcadeBlur = undefined + } + setArcadeFocused(false) + if (arcadeBox && !arcadeBox.isDestroyed) arcadeBox.blur() + if ( + shouldRestoreCompactionPromptFocus({ + arcadeOwnsFocus: ownsFocus, + arcadeWasFocused: wasFocused, + previousFocusAvailable, + promptAvailable: Boolean(prompt), + }) + ) { + restoreFocusAfterArcadeBlur(previousFocusAvailable ? previousFocus : undefined) + } + if (input?.consume === false) return + event?.preventDefault?.() + event?.stopPropagation?.() + } + + function blurArcadeIfOffscreen() { + if (!arcadeBox || arcadeBox.isDestroyed) return false + if (!shouldBlurCompactionArcadeWhenOffscreen({ + focused: arcadeOwnsFocus(), + screenY: arcadeBox.screenY, + height: arcadeBox.height, + viewportHeight: dimensions().height, + })) return false + blurArcade(undefined, { consume: false }) + return true + } + + onCleanup(() => { + focusRestoreToken += 1 + blurArcade(undefined, { consume: false }) + }) + + function consumeMouseEvent(event?: { preventDefault?: () => void; stopPropagation?: () => void }) { + event?.preventDefault?.() + event?.stopPropagation?.() + } + + function toggleCompactionTranscript(event?: { preventDefault?: () => void; stopPropagation?: () => void }) { + blurArcade(event, { consume: false }) + consumeMouseEvent(event) + setSummaryExpanded((value) => !value) + } + + function arcadeCellColor(tone: CompactionArcadeCellTone | undefined) { + if (tone === "head") return theme.success + if (tone === "food") return theme.warning + if (tone === "body") return theme.primary + if (tone === "wall") return theme.borderActive + if (tone === "empty" || tone === "muted") return theme.textMuted + if (tone === "danger") return theme.error + if (tone === "accent") return theme.accent + if (tone === "text") return theme.text + return theme.primary + } + + function handleArcadeKey(event: CompactionArcadeKeyEvent) { + if (!shouldRunCompactionArcade({ ...config(), completed: packed(), terminal: props.terminal })) return false + const game = activeArcadeGame() + if (!game) return false + const key = normalizedArcadeKey(event.name, event.sequence) + if (key === "escape") { + blurArcade(event) + return true + } + const next = game.id === snakeArcadeGame.id && key === "r" + ? initialSnakeState(globalSnakeHighScore()) + : game.key?.(arcadeState(), key) + if (next === undefined) return false + setArcadeStateAndPersist(next) + event.preventDefault() + event.stopPropagation?.() + return true + } + + createEffect(() => { + if (!shouldRunCompactionArcade({ ...config(), completed: packed(), terminal: props.terminal })) { + blurArcade(undefined, { consume: false }) + return + } + const timer = setInterval(() => { + const game = activeArcadeGame() + if (game) { + if (!arcadeOwnsFocus()) return + if (blurArcadeIfOffscreen()) return + const state = arcadeState() + const next = game.tick?.(state) ?? state + if (next !== state) setArcadeStateAndPersist(next) + } + else setArcadeTick((value) => value + 1) + }, activeArcadeGame()?.intervalMs ?? 240) + onCleanup(() => clearInterval(timer)) + }) + + createEffect(() => { + const game = activeArcadeGame() + const id = game?.id + if (id === lastArcadeGameID) return + lastArcadeGameID = id + blurArcade(undefined, { consume: false }) + if (game) { + const state = game.id === snakeArcadeGame.id ? initialSnakeState(globalSnakeHighScore()) : game.initialState() + setArcadeStateAndPersist(state) + } + }) + + createEffect(() => { + const game = activeArcadeGame() + if (game?.id !== snakeArcadeGame.id) return + const highScore = globalSnakeHighScore() + setArcadeState((state) => { + const snake = state as SnakeState + if (snake.highScore >= highScore) return state + return { ...snake, highScore } + }) + }) + + useKeyboard((event) => { + if (!arcadeOwnsFocus()) { + if (arcadeFocused()) { + arcadePreviousFocus = null + if (focusedCompactionArcade === arcadeBox) { + focusedCompactionArcade = undefined + focusedCompactionArcadeBlur = undefined + } + setArcadeFocused(false) + } + return + } + if (blurArcadeIfOffscreen()) return + if (scratchpadInput && !scratchpadInput.isDestroyed && scratchpadInput.focused) return + if (handleArcadeKey(event)) return + event.preventDefault() + event.stopPropagation?.() + }) + + createEffect(() => { + const scratchpad = props.scratchpad + if (!scratchpadEnabled() || !scratchpad) return + const key = scratchpad.key + const initialValue = scratchpad.initialValue ?? "" + if (key !== lastScratchpadKey) { + lastScratchpadKey = key + setDraft(initialValue) + setSaved(initialValue) + setSaveState(scratchpad.onSave ? "saved" : "local") + setSaveFailure(undefined) + if (scratchpadInput && !scratchpadInput.isDestroyed && scratchpadInput.plainText !== initialValue) scratchpadInput.setText(initialValue) + return + } + if (scratchpad.loading) return + if (draft() !== saved()) return + if (saved() === initialValue) return + setDraft(initialValue) + setSaved(initialValue) + setSaveState(scratchpad.onSave ? "saved" : "local") + setSaveFailure(undefined) + if (scratchpadInput && !scratchpadInput.isDestroyed && scratchpadInput.plainText !== initialValue) scratchpadInput.setText(initialValue) + }) + + createEffect(() => { + const scratchpad = props.scratchpad + const value = draft() + if (!scratchpadEnabled() || !scratchpad) return + if (scratchpadReadOnly()) return + if (scratchpad.loading) return + if (!scratchpad.onSave) { + setSaveState("local") + return + } + if (value === saved()) { + if (saveState() === "pending" || saveState() === "saving") setSaveState("saved") + return + } + if (saveTimer) clearTimeout(saveTimer) + setSaveState("pending") + const ticket = ++saveTicket + saveTimer = setTimeout(async () => { + setSaveState("saving") + try { + await scratchpad.onSave?.(value) + if (ticket !== saveTicket) return + setSaved(value) + setSaveState("saved") + setSaveFailure(undefined) + } catch (error) { + if (ticket !== saveTicket) return + setSaveState("error") + setSaveFailure(errorMessage(error)) + } + }, 500) + onCleanup(() => { + if (saveTimer) clearTimeout(saveTimer) + }) + }) + + const scratchpadStatus = createMemo(() => { + const scratchpad = props.scratchpad + if (!scratchpadEnabled() || !scratchpad) return undefined + if (props.failure) return "Compaction did not complete. This follow-up was not sent." + if (scratchpad.loading) return "Loading scratchpad…" + if (scratchpadReadOnly()) return followUpText() ? "Follow-up was sent after compaction." : undefined + if (saveState() === "saving" || saveState() === "pending") return "Saving scratchpad…" + if (saveState() === "error") return `Scratchpad save failed · ${saveFailure() ?? "Unknown error"}` + if (!scratchpad.onSave) return scratchpad.note ?? "Scratchpad is local only in this view" + return scratchpad.note ?? "Scratchpad saved to the compaction resume prompt" + }) + + if (config().style === "quiet") { + return + } + + if (config().style === "minimal") { + return ( + + + ◈ {compactionPanelHeading({ style: config().style, packed: packed(), failure: props.failure })} + + + {props.failure ? "Compaction did not complete." : packed() ? "Context packed." : "Preparing a shorter context…"} + + + ) + } + + return ( + { + if (arcadeOwnsFocus() && !isArcadeEventTarget(event.target)) blurArcade(event, { consume: false }) + }} + > + + + ◈ {compactionPanelHeading({ style: config().style, packed: packed(), failure: props.failure })} + + + + 0}> + + + {(chip) => ( + + {chip} + + )} + + + + + + + {(stage, index) => { + const color = createMemo(() => { + if (stage.state === "done") return theme.borderActive + if (stage.state === "active") return theme.primary + return theme.textMuted + }) + const glyph = createMemo(() => { + if (stage.state === "done") return "●" + if (stage.state === "active") return "◐" + return "○" + }) + return ( + + {glyph()} {stage.label} + + ─ + + + ) + }} + + + + + + + { + arcadeBox = value + }} + flexDirection="column" + alignItems="center" + focusable={shouldRunCompactionArcade({ ...config(), completed: packed(), terminal: props.terminal })} + border={["top", "bottom", "left", "right"]} + borderColor={arcadeFocused() ? theme.borderActive : theme.border} + paddingLeft={2} + paddingRight={2} + paddingTop={1} + paddingBottom={1} + onMouseDown={(event) => { + focusArcade() + event.preventDefault() + event.stopPropagation() + }} + onKeyDown={(event) => { + if (handleArcadeKey(event)) return + event.preventDefault() + event.stopPropagation?.() + }} + > + + {packed() || props.terminal + ? "○ Final board · compaction complete" + : arcadeFocused() + ? "● GAME FOCUSED · Press Esc to type in chat" + : "○ Click game to play · chat keeps typing until game is focused"} + + + {arcadeRender()?.title} · ↑↓←→/WASD · Space pause · R reset + + + {(row) => ( + + {(cell) => {cell.text}} + + )} + + {(line) => {line}} + + {(status) => {status()}} + + + + + 0}> + + {(line) => {line}} + + + + + + {props.failure ? `Compaction ${props.failure}` : `${config().style === "arcade" && packed() ? "Arcade complete · " : ""}Compacted memory · ${packed() ? "packed" : "packing"}`} + + + toggleCompactionTranscript(event)} + onMouseUp={consumeMouseEvent} + > + {compactionTranscriptToggleLabel(summaryExpanded())} + + + + + + Writing summary… + + } + > + + {props.summaryPreview + ? Locale.truncate(props.summaryPreview ?? "", 220) + : "Summary output is not available yet."} + + } + > + {props.summaryContent} + + + + + Focus: {Locale.truncate(props.transcriptPreview ?? "", 120)} + + + + + + + + {scratchpadReadOnly() ? "Follow-up" : "Scratchpad · click to focus"} + + + {followUpText() ? Locale.truncate(followUpText(), 220) : "No follow-up message was written."} + + } + > +