diff --git a/.github/TEAM_MEMBERS b/.github/TEAM_MEMBERS new file mode 100644 index 000000000000..22c9a923d33f --- /dev/null +++ b/.github/TEAM_MEMBERS @@ -0,0 +1,15 @@ +adamdotdevin +Brendonovich +fwang +Hona +iamdavidhill +jayair +jlongster +kitlangton +kommander +MrMushrooooom +nexxeln +R44VC0RP +rekram1-node +RhysSullivan +thdxr diff --git a/.github/actions/setup-bun/action.yml b/.github/actions/setup-bun/action.yml index 65fbf0f3d601..20d53e81e8c2 100644 --- a/.github/actions/setup-bun/action.yml +++ b/.github/actions/setup-bun/action.yml @@ -3,11 +3,13 @@ description: "Setup Bun with caching and install dependencies" runs: using: "composite" steps: - - name: Mount Bun Cache - uses: useblacksmith/stickydisk@v1 + - name: Cache Bun dependencies + uses: actions/cache@v4 with: - key: ${{ github.repository }}-bun-cache-${{ runner.os }} - path: ~/.bun + path: ~/.bun/install/cache + key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }} + restore-keys: | + ${{ runner.os }}-bun- - name: Setup Bun uses: oven-sh/setup-bun@v2 diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 8cf030eceb0c..393bf90518e9 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,7 +1,29 @@ +### Issue for this PR + +Closes # + +### Type of change + +- [ ] Bug fix +- [ ] New feature +- [ ] Refactor / code improvement +- [ ] Documentation + ### What does this PR do? -Please provide a description of the issue (if there is one), the changes you made to fix it, and why they work. It is expected that you understand why your changes work and if you do not understand why at least say as much so a maintainer knows how much to value the PR. +Please provide a description of the issue, the changes you made to fix it, and why they work. It is expected that you understand why your changes work and if you do not understand why at least say as much so a maintainer knows how much to value the PR. **If you paste a large clearly AI generated description here your PR may be IGNORED or CLOSED!** ### How did you verify your code works? + +### Screenshots / recordings + +_If this is a UI change, please include a screenshot or recording._ + +### Checklist + +- [ ] I have tested my changes locally +- [ ] I have not included unrelated changes in this PR + +_If you do not follow this template your PR will be automatically rejected._ diff --git a/.github/workflows/duplicate-issues.yml b/.github/workflows/duplicate-issues.yml index 87e655fe4bf7..6c1943fe7b8a 100644 --- a/.github/workflows/duplicate-issues.yml +++ b/.github/workflows/duplicate-issues.yml @@ -2,10 +2,11 @@ name: duplicate-issues on: issues: - types: [opened] + types: [opened, edited] jobs: check-duplicates: + if: github.event.action == 'opened' runs-on: blacksmith-4vcpu-ubuntu-2404 permissions: contents: read @@ -34,7 +35,7 @@ jobs: "webfetch": "deny" } run: | - opencode run -m opencode/claude-haiku-4-5 "A new issue has been created: + opencode run -m opencode/claude-sonnet-4-6 "A new issue has been created: Issue number: ${{ github.event.issue.number }} @@ -115,3 +116,62 @@ jobs: If you believe this was flagged incorrectly, please let a maintainer know. Remember: post at most ONE comment combining all findings. If everything is fine, post nothing." + + recheck-compliance: + if: github.event.action == 'edited' && contains(github.event.issue.labels.*.name, 'needs:compliance') + runs-on: blacksmith-4vcpu-ubuntu-2404 + permissions: + contents: read + issues: write + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - uses: ./.github/actions/setup-bun + + - name: Install opencode + run: curl -fsSL https://opencode.ai/install | bash + + - name: Recheck compliance + env: + OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + OPENCODE_PERMISSION: | + { + "bash": { + "*": "deny", + "gh issue*": "allow" + }, + "webfetch": "deny" + } + run: | + opencode run -m opencode/claude-sonnet-4-6 "Issue #${{ github.event.issue.number }} was previously flagged as non-compliant and has been edited. + + Lookup this issue with gh issue view ${{ github.event.issue.number }}. + + Re-check whether the issue now follows our contributing guidelines and issue templates. + + This project has three issue templates that every issue MUST use one of: + + 1. Bug Report - requires a Description field with real content + 2. Feature Request - requires a verification checkbox and description, title should start with [FEATURE]: + 3. Question - requires the Question field with real content + + Additionally check: + - No AI-generated walls of text (long, AI-generated descriptions are not acceptable) + - The issue has real content, not just template placeholder text left unchanged + - Bug reports should include some context about how to reproduce + - Feature requests should explain the problem or need + - We want to push for having the user provide system description & information + + Do NOT be nitpicky about optional fields. Only flag real problems like: no template used, required fields empty or placeholder text only, obviously AI-generated walls of text, or completely empty/nonsensical content. + + If the issue is NOW compliant: + 1. Remove the needs:compliance label: gh issue edit ${{ github.event.issue.number }} --remove-label needs:compliance + 2. Find and delete the previous compliance comment (the one containing ) using: gh api repos/${{ github.repository }}/issues/${{ github.event.issue.number }}/comments --jq '.[] | select(.body | contains(\"\")) | .id' then delete it with: gh api -X DELETE repos/${{ github.repository }}/issues/${{ github.event.issue.number }}/comments/{id} + 3. Post a short comment thanking them for updating the issue. + + If the issue is STILL not compliant: + Post a comment explaining what still needs to be fixed. Keep the needs:compliance label." diff --git a/.github/workflows/nix-desktop.yml.disabled b/.github/workflows/nix-desktop.yml.disabled deleted file mode 100644 index 031eff6a6914..000000000000 --- a/.github/workflows/nix-desktop.yml.disabled +++ /dev/null @@ -1,46 +0,0 @@ -name: nix-desktop - -on: - push: - branches: [dev] - paths: - - "flake.nix" - - "flake.lock" - - "nix/**" - - "packages/app/**" - - "packages/desktop/**" - - ".github/workflows/nix-desktop.yml" - pull_request: - paths: - - "flake.nix" - - "flake.lock" - - "nix/**" - - "packages/app/**" - - "packages/desktop/**" - - ".github/workflows/nix-desktop.yml" - workflow_dispatch: - -jobs: - nix-desktop: - strategy: - fail-fast: false - matrix: - os: - - blacksmith-4vcpu-ubuntu-2404 - - blacksmith-4vcpu-ubuntu-2404-arm - - macos-15-intel - - macos-latest - runs-on: ${{ matrix.os }} - timeout-minutes: 60 - steps: - - name: Checkout repository - uses: actions/checkout@v6 - - - name: Setup Nix - uses: nixbuild/nix-quick-install-action@v34 - - - name: Build desktop via flake - run: | - set -euo pipefail - nix --version - nix build .#desktop -L diff --git a/.github/workflows/nix-eval.yml b/.github/workflows/nix-eval.yml new file mode 100644 index 000000000000..c76b2c972973 --- /dev/null +++ b/.github/workflows/nix-eval.yml @@ -0,0 +1,95 @@ +name: nix-eval + +on: + push: + branches: [dev] + pull_request: + branches: [dev] + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + nix-eval: + runs-on: blacksmith-4vcpu-ubuntu-2404 + timeout-minutes: 15 + steps: + - name: Checkout repository + uses: actions/checkout@v6 + + - name: Setup Nix + uses: nixbuild/nix-quick-install-action@v34 + + - name: Evaluate flake outputs (all systems) + run: | + set -euo pipefail + nix --version + + echo "=== Flake metadata ===" + nix flake metadata + + echo "" + echo "=== Flake structure ===" + nix flake show --all-systems + + SYSTEMS="x86_64-linux aarch64-linux x86_64-darwin aarch64-darwin" + PACKAGES="opencode" + # TODO: move 'desktop' to PACKAGES when #11755 is fixed + OPTIONAL_PACKAGES="desktop" + + echo "" + echo "=== Evaluating packages for all systems ===" + for system in $SYSTEMS; do + echo "" + echo "--- $system ---" + for pkg in $PACKAGES; do + printf " %s: " "$pkg" + if output=$(nix eval ".#packages.$system.$pkg.drvPath" --raw 2>&1); then + echo "✓" + else + echo "✗" + echo "::error::Evaluation failed for packages.$system.$pkg" + echo "$output" + exit 1 + fi + done + done + + echo "" + echo "=== Evaluating optional packages ===" + for system in $SYSTEMS; do + echo "" + echo "--- $system ---" + for pkg in $OPTIONAL_PACKAGES; do + printf " %s: " "$pkg" + if output=$(nix eval ".#packages.$system.$pkg.drvPath" --raw 2>&1); then + echo "✓" + else + echo "✗" + echo "::warning::Evaluation failed for packages.$system.$pkg" + echo "$output" + fi + done + done + + echo "" + echo "=== Evaluating devShells for all systems ===" + for system in $SYSTEMS; do + printf "%s: " "$system" + if output=$(nix eval ".#devShells.$system.default.drvPath" --raw 2>&1); then + echo "✓" + else + echo "✗" + echo "::error::Evaluation failed for devShells.$system.default" + echo "$output" + exit 1 + fi + done + + echo "" + echo "=== All evaluations passed ===" diff --git a/.github/workflows/nix-hashes.yml b/.github/workflows/nix-hashes.yml index 894dbf47b1ea..2529c14c2087 100644 --- a/.github/workflows/nix-hashes.yml +++ b/.github/workflows/nix-hashes.yml @@ -6,7 +6,7 @@ permissions: on: workflow_dispatch: push: - branches: [dev] + branches: [dev, beta] paths: - "bun.lock" - "package.json" diff --git a/.github/workflows/pr-management.yml b/.github/workflows/pr-management.yml index 008272415492..35bd7ae36f2d 100644 --- a/.github/workflows/pr-management.yml +++ b/.github/workflows/pr-management.yml @@ -6,17 +6,6 @@ on: jobs: check-duplicates: - if: | - github.event.pull_request.user.login != 'actions-user' && - github.event.pull_request.user.login != 'opencode' && - github.event.pull_request.user.login != 'rekram1-node' && - github.event.pull_request.user.login != 'thdxr' && - github.event.pull_request.user.login != 'kommander' && - github.event.pull_request.user.login != 'jayair' && - github.event.pull_request.user.login != 'fwang' && - github.event.pull_request.user.login != 'adamdotdevin' && - github.event.pull_request.user.login != 'iamdavidhill' && - github.event.pull_request.user.login != 'opencode-agent[bot]' runs-on: blacksmith-4vcpu-ubuntu-2404 permissions: contents: read @@ -27,16 +16,31 @@ jobs: with: fetch-depth: 1 + - name: Check team membership + id: team-check + run: | + LOGIN="${{ github.event.pull_request.user.login }}" + if [ "$LOGIN" = "opencode-agent[bot]" ] || grep -qxF "$LOGIN" .github/TEAM_MEMBERS; then + echo "is_team=true" >> "$GITHUB_OUTPUT" + echo "Skipping: $LOGIN is a team member or bot" + else + echo "is_team=false" >> "$GITHUB_OUTPUT" + fi + - name: Setup Bun + if: steps.team-check.outputs.is_team != 'true' uses: ./.github/actions/setup-bun - name: Install dependencies + if: steps.team-check.outputs.is_team != 'true' run: bun install - name: Install opencode + if: steps.team-check.outputs.is_team != 'true' run: curl -fsSL https://opencode.ai/install | bash - name: Build prompt + if: steps.team-check.outputs.is_team != 'true' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} PR_NUMBER: ${{ github.event.pull_request.number }} @@ -53,6 +57,7 @@ jobs: } > pr_info.txt - name: Check for duplicate PRs + if: steps.team-check.outputs.is_team != 'true' env: OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/pr-standards.yml b/.github/workflows/pr-standards.yml index 397f794a1cd5..27581d06b768 100644 --- a/.github/workflows/pr-standards.yml +++ b/.github/workflows/pr-standards.yml @@ -6,19 +6,9 @@ on: jobs: check-standards: - if: | - github.event.pull_request.user.login != 'actions-user' && - github.event.pull_request.user.login != 'opencode' && - github.event.pull_request.user.login != 'rekram1-node' && - github.event.pull_request.user.login != 'thdxr' && - github.event.pull_request.user.login != 'kommander' && - github.event.pull_request.user.login != 'jayair' && - github.event.pull_request.user.login != 'fwang' && - github.event.pull_request.user.login != 'adamdotdevin' && - github.event.pull_request.user.login != 'iamdavidhill' && - github.event.pull_request.user.login != 'opencode-agent[bot]' runs-on: ubuntu-latest permissions: + contents: read pull-requests: write steps: - name: Check PR standards @@ -26,6 +16,30 @@ jobs: with: script: | const pr = context.payload.pull_request; + const login = pr.user.login; + + // Skip PRs older than Feb 18, 2026 at 6PM EST (Feb 19, 2026 00:00 UTC) + const cutoff = new Date('2026-02-19T00:00:00Z'); + const prCreated = new Date(pr.created_at); + if (prCreated < cutoff) { + console.log(`Skipping: PR #${pr.number} was created before cutoff (${prCreated.toISOString()})`); + return; + } + + // Check if author is a team member or bot + if (login === 'opencode-agent[bot]') return; + const { data: file } = await github.rest.repos.getContent({ + owner: context.repo.owner, + repo: context.repo.repo, + path: '.github/TEAM_MEMBERS', + ref: 'dev' + }); + const members = Buffer.from(file.content, 'base64').toString().split('\n').map(l => l.trim()).filter(Boolean); + if (members.includes(login)) { + console.log(`Skipping: ${login} is a team member`); + return; + } + const title = pr.title; async function addLabel(label) { @@ -137,3 +151,201 @@ jobs: await removeLabel('needs:issue'); console.log('PR meets all standards'); + + check-compliance: + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + steps: + - name: Check PR template compliance + uses: actions/github-script@v7 + with: + script: | + const pr = context.payload.pull_request; + const login = pr.user.login; + + // Skip PRs older than Feb 18, 2026 at 6PM EST (Feb 19, 2026 00:00 UTC) + const cutoff = new Date('2026-02-19T00:00:00Z'); + const prCreated = new Date(pr.created_at); + if (prCreated < cutoff) { + console.log(`Skipping: PR #${pr.number} was created before cutoff (${prCreated.toISOString()})`); + return; + } + + // Check if author is a team member or bot + if (login === 'opencode-agent[bot]') return; + const { data: file } = await github.rest.repos.getContent({ + owner: context.repo.owner, + repo: context.repo.repo, + path: '.github/TEAM_MEMBERS', + ref: 'dev' + }); + const members = Buffer.from(file.content, 'base64').toString().split('\n').map(l => l.trim()).filter(Boolean); + if (members.includes(login)) { + console.log(`Skipping: ${login} is a team member`); + return; + } + + const body = pr.body || ''; + const title = pr.title; + const isDocsOrRefactor = /^(docs|refactor)\s*(\([a-zA-Z0-9-]+\))?\s*:/.test(title); + + const issues = []; + + // Check: template sections exist + const hasWhatSection = /### What does this PR do\?/.test(body); + const hasTypeSection = /### Type of change/.test(body); + const hasVerifySection = /### How did you verify your code works\?/.test(body); + const hasChecklistSection = /### Checklist/.test(body); + const hasIssueSection = /### Issue for this PR/.test(body); + + if (!hasWhatSection || !hasTypeSection || !hasVerifySection || !hasChecklistSection || !hasIssueSection) { + issues.push('PR description is missing required template sections. Please use the [PR template](../blob/dev/.github/pull_request_template.md).'); + } + + // Check: "What does this PR do?" has real content (not just placeholder text) + if (hasWhatSection) { + const whatMatch = body.match(/### What does this PR do\?\s*\n([\s\S]*?)(?=###|$)/); + const whatContent = whatMatch ? whatMatch[1].trim() : ''; + const placeholder = 'Please provide a description of the issue'; + const onlyPlaceholder = whatContent.includes(placeholder) && whatContent.replace(placeholder, '').replace(/[*\s]/g, '').length < 20; + if (!whatContent || onlyPlaceholder) { + issues.push('"What does this PR do?" section is empty or only contains placeholder text. Please describe your changes.'); + } + } + + // Check: at least one "Type of change" checkbox is checked + if (hasTypeSection) { + const typeMatch = body.match(/### Type of change\s*\n([\s\S]*?)(?=###|$)/); + const typeContent = typeMatch ? typeMatch[1] : ''; + const hasCheckedBox = /- \[x\]/i.test(typeContent); + if (!hasCheckedBox) { + issues.push('No "Type of change" checkbox is checked. Please select at least one.'); + } + } + + // Check: issue reference (skip for docs/refactor) + if (!isDocsOrRefactor && hasIssueSection) { + const issueMatch = body.match(/### Issue for this PR\s*\n([\s\S]*?)(?=###|$)/); + const issueContent = issueMatch ? issueMatch[1].trim() : ''; + const hasIssueRef = /(closes|fixes|resolves)\s+#\d+/i.test(issueContent) || /#\d+/.test(issueContent); + if (!hasIssueRef) { + issues.push('No issue referenced. Please add `Closes #` linking to the relevant issue.'); + } + } + + // Check: "How did you verify" has content + if (hasVerifySection) { + const verifyMatch = body.match(/### How did you verify your code works\?\s*\n([\s\S]*?)(?=###|$)/); + const verifyContent = verifyMatch ? verifyMatch[1].trim() : ''; + if (!verifyContent) { + issues.push('"How did you verify your code works?" section is empty. Please explain how you tested.'); + } + } + + // Check: checklist boxes are checked + if (hasChecklistSection) { + const checklistMatch = body.match(/### Checklist\s*\n([\s\S]*?)(?=###|$)/); + const checklistContent = checklistMatch ? checklistMatch[1] : ''; + const unchecked = (checklistContent.match(/- \[ \]/g) || []).length; + const checked = (checklistContent.match(/- \[x\]/gi) || []).length; + if (checked < 2) { + issues.push('Not all checklist items are checked. Please confirm you have tested locally and have not included unrelated changes.'); + } + } + + // Helper functions + async function addLabel(label) { + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number, + labels: [label] + }); + } + + async function removeLabel(label) { + try { + await github.rest.issues.removeLabel({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number, + name: label + }); + } catch (e) {} + } + + const hasComplianceLabel = pr.labels.some(l => l.name === 'needs:compliance'); + + if (issues.length > 0) { + // Non-compliant + if (!hasComplianceLabel) { + await addLabel('needs:compliance'); + } + + const marker = ''; + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number + }); + const existing = comments.find(c => c.body.includes(marker)); + + const body_text = `${marker} + This PR doesn't fully meet our [contributing guidelines](../blob/dev/CONTRIBUTING.md) and [PR template](../blob/dev/.github/pull_request_template.md). + + **What needs to be fixed:** + ${issues.map(i => `- ${i}`).join('\n')} + + Please edit this PR description to address the above within **2 hours**, or it will be automatically closed. + + If you believe this was flagged incorrectly, please let a maintainer know.`; + + if (existing) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: existing.id, + body: body_text + }); + } else { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number, + body: body_text + }); + } + + console.log(`PR #${pr.number} is non-compliant: ${issues.join(', ')}`); + } else if (hasComplianceLabel) { + // Was non-compliant, now fixed + await removeLabel('needs:compliance'); + + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number + }); + const marker = ''; + const existing = comments.find(c => c.body.includes(marker)); + if (existing) { + await github.rest.issues.deleteComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: existing.id + }); + } + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number, + body: 'Thanks for updating your PR! It now meets our contributing guidelines. :+1:' + }); + + console.log(`PR #${pr.number} is now compliant, label removed`); + } else { + console.log(`PR #${pr.number} is compliant`); + } diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index a1b492258b73..431581f5966e 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -137,7 +137,7 @@ jobs: if: contains(matrix.settings.host, 'ubuntu') uses: actions/cache@v4 with: - path: /var/cache/apt/archives + path: ~/apt-cache key: ${{ runner.os }}-${{ matrix.settings.target }}-apt-${{ hashFiles('.github/workflows/publish.yml') }} restore-keys: | ${{ runner.os }}-${{ matrix.settings.target }}-apt- @@ -145,8 +145,10 @@ jobs: - name: install dependencies (ubuntu only) if: contains(matrix.settings.host, 'ubuntu') run: | + mkdir -p ~/apt-cache && chmod -R a+rw ~/apt-cache sudo apt-get update - sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf + sudo apt-get install -y --no-install-recommends -o dir::cache::archives="$HOME/apt-cache" libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf + sudo chmod -R a+rw ~/apt-cache - name: install Rust stable uses: dtolnay/rust-toolchain@stable @@ -169,13 +171,23 @@ jobs: GH_TOKEN: ${{ github.token }} GITHUB_RUN_ID: ${{ github.run_id }} + - name: Resolve tauri portable SHA + if: contains(matrix.settings.host, 'ubuntu') + run: echo "TAURI_PORTABLE_SHA=$(git ls-remote https://github.com/tauri-apps/tauri.git refs/heads/feat/truly-portable-appimage | cut -f1)" >> "$GITHUB_ENV" + # Fixes AppImage build issues, can be removed when https://github.com/tauri-apps/tauri/pull/12491 is released - name: Install tauri-cli from portable appimage branch + uses: taiki-e/cache-cargo-install-action@v3 if: contains(matrix.settings.host, 'ubuntu') - run: | - cargo install tauri-cli --git https://github.com/tauri-apps/tauri --branch feat/truly-portable-appimage --force - echo "Installed tauri-cli version:" - cargo tauri --version + with: + tool: tauri-cli + git: https://github.com/tauri-apps/tauri + # branch: feat/truly-portable-appimage + rev: ${{ env.TAURI_PORTABLE_SHA }} + + - name: Show tauri-cli version + if: contains(matrix.settings.host, 'ubuntu') + run: cargo tauri --version - name: Build and upload artifacts uses: tauri-apps/tauri-action@390cbe447412ced1303d35abe75287949e43437a diff --git a/.opencode/agent/translator.md b/.opencode/agent/translator.md index dec6fa6c4fc3..7886cf5f395e 100644 --- a/.opencode/agent/translator.md +++ b/.opencode/agent/translator.md @@ -359,6 +359,7 @@ opencode serve --hostname 0.0.0.0 --port 4096 opencode serve [--port ] [--hostname ] [--cors ] opencode session [command] opencode session list +opencode session delete opencode stats opencode uninstall opencode upgrade @@ -598,6 +599,7 @@ OPENCODE_EXPERIMENTAL_MARKDOWN OPENCODE_EXPERIMENTAL_OUTPUT_TOKEN_MAX OPENCODE_EXPERIMENTAL_OXFMT OPENCODE_EXPERIMENTAL_PLAN_MODE +OPENCODE_ENABLE_QUESTION_TOOL OPENCODE_FAKE_VCS OPENCODE_GIT_BASH_PATH OPENCODE_MODEL diff --git a/.opencode/agent/triage.md b/.opencode/agent/triage.md index 5d1147a88594..a77b92737bc9 100644 --- a/.opencode/agent/triage.md +++ b/.opencode/agent/triage.md @@ -1,7 +1,7 @@ --- mode: primary hidden: true -model: opencode/claude-haiku-4-5 +model: opencode/minimax-m2.5 color: "#44BA81" tools: "*": false @@ -12,6 +12,8 @@ You are a triage agent responsible for triaging github issues. Use your github-triage tool to triage issues. +This file is the source of truth for ownership/routing rules. + ## Labels ### windows @@ -43,12 +45,34 @@ Desktop app issues: **Only** add if the issue explicitly mentions nix. +If the issue does not mention nix, do not add nix. + +If the issue mentions nix, assign to `rekram1-node`. + #### zen **Only** add if the issue mentions "zen" or "opencode zen" or "opencode black". If the issue doesn't have "zen" or "opencode black" in it then don't add zen label +#### core + +Use for core server issues in `packages/opencode/`, excluding `packages/opencode/src/cli/cmd/tui/`. + +Examples: + +- LSP server behavior +- Harness behavior (agent + tools) +- Feature requests for server behavior +- Agent context construction +- API endpoints +- Provider integration issues +- New, broken, or poor-quality models + +#### acp + +If the issue mentions acp support, assign acp label. + #### docs Add if the issue requests better documentation or docs updates. @@ -66,13 +90,51 @@ TUI issues potentially caused by our underlying TUI library: When assigning to people here are the following rules: -adamdotdev: -ONLY assign adam if the issue will have the "desktop" label. +Desktop / Web: +Use for desktop-labeled issues only. + +- adamdotdevin +- iamdavidhill +- Brendonovich +- nexxeln + +Zen: +ONLY assign if the issue will have the "zen" label. + +- fwang +- MrMushrooooom + +TUI (`packages/opencode/src/cli/cmd/tui/...`): + +- thdxr for TUI UX/UI product decisions and interaction flow +- kommander for OpenTUI engine issues: rendering artifacts, keybind handling, terminal compatibility, SSH behavior, and low-level perf bottlenecks +- rekram1-node for TUI bugs that are not clearly OpenTUI engine issues + +Core (`packages/opencode/...`, excluding TUI subtree): + +- thdxr for sqlite/snapshot/memory bugs and larger architectural core features +- jlongster for opencode server + API feature work (tool currently remaps jlongster -> thdxr until assignable) +- rekram1-node for harness issues, provider issues, and other bug-squashing + +For core bugs that do not clearly map, either thdxr or rekram1-node is acceptable. + +Docs: + +- R44VC0RP + +Windows: + +- Hona (assign any issue that mentions Windows or is likely Windows-specific) + +Determinism rules: + +- If title + body does not contain "zen", do not add the "zen" label +- If "nix" label is added but title + body does not mention nix/nixos, the tool will drop "nix" +- If title + body mentions nix/nixos, assign to `rekram1-node` +- If "desktop" label is added, the tool will override assignee and randomly pick one Desktop / Web owner -fwang: -ONLY assign fwang if the issue will have the "zen" label. +In all other cases, choose the team/section with the most overlap with the issue and assign a member from that team at random. -jayair: -ONLY assign jayair if the issue will have the "docs" label. +ACP: -In all other cases use best judgment. Avoid assigning to kommander needlessly, when in doubt assign to rekram1-node. +- rekram1-node (assign any acp issues to rekram1-node) diff --git a/.opencode/opencode.jsonc b/.opencode/opencode.jsonc index e2350c907b52..3497847a6765 100644 --- a/.opencode/opencode.jsonc +++ b/.opencode/opencode.jsonc @@ -1,8 +1,5 @@ { "$schema": "https://opencode.ai/config.json", - // "enterprise": { - // "url": "https://enterprise.dev.opencode.ai", - // }, "provider": { "opencode": { "options": {}, diff --git a/.opencode/tool/github-triage.ts b/.opencode/tool/github-triage.ts index 1e216f1c8daa..ed80f49d5413 100644 --- a/.opencode/tool/github-triage.ts +++ b/.opencode/tool/github-triage.ts @@ -1,8 +1,22 @@ /// -// import { Octokit } from "@octokit/rest" import { tool } from "@opencode-ai/plugin" import DESCRIPTION from "./github-triage.txt" +const TEAM = { + desktop: ["adamdotdevin", "iamdavidhill", "Brendonovich", "nexxeln"], + zen: ["fwang", "MrMushrooooom"], + tui: ["thdxr", "kommander", "rekram1-node"], + core: ["thdxr", "rekram1-node", "jlongster"], + docs: ["R44VC0RP"], + windows: ["Hona"], +} as const + +const ASSIGNEES = [...new Set(Object.values(TEAM).flat())] + +function pick(items: readonly T[]) { + return items[Math.floor(Math.random() * items.length)]! +} + function getIssueNumber(): number { const issue = parseInt(process.env.ISSUE_NUMBER ?? "", 10) if (!issue) throw new Error("ISSUE_NUMBER env var not set") @@ -29,60 +43,69 @@ export default tool({ description: DESCRIPTION, args: { assignee: tool.schema - .enum(["thdxr", "adamdotdevin", "rekram1-node", "fwang", "jayair", "kommander"]) + .enum(ASSIGNEES as [string, ...string[]]) .describe("The username of the assignee") .default("rekram1-node"), labels: tool.schema - .array(tool.schema.enum(["nix", "opentui", "perf", "desktop", "zen", "docs", "windows"])) + .array(tool.schema.enum(["nix", "opentui", "perf", "web", "desktop", "zen", "docs", "windows", "core"])) .describe("The labels(s) to add to the issue") .default([]), }, async execute(args) { const issue = getIssueNumber() - // const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN }) const owner = "anomalyco" const repo = "opencode" const results: string[] = [] + let labels = [...new Set(args.labels.map((x) => (x === "desktop" ? "web" : x)))] + const web = labels.includes("web") + const text = `${process.env.ISSUE_TITLE ?? ""}\n${process.env.ISSUE_BODY ?? ""}`.toLowerCase() + const zen = /\bzen\b/.test(text) || text.includes("opencode black") + const nix = /\bnix(os)?\b/.test(text) + + if (labels.includes("nix") && !nix) { + labels = labels.filter((x) => x !== "nix") + results.push("Dropped label: nix (issue does not mention nix)") + } + + const assignee = nix ? "rekram1-node" : web ? pick(TEAM.desktop) : args.assignee - if (args.assignee === "adamdotdevin" && !args.labels.includes("desktop")) { - throw new Error("Only desktop issues should be assigned to adamdotdevin") + if (labels.includes("zen") && !zen) { + throw new Error("Only add the zen label when issue title/body contains 'zen'") } - if (args.assignee === "fwang" && !args.labels.includes("zen")) { - throw new Error("Only zen issues should be assigned to fwang") + if (web && !nix && !(TEAM.desktop as readonly string[]).includes(assignee)) { + throw new Error("Web issues must be assigned to adamdotdevin, iamdavidhill, Brendonovich, or nexxeln") } - if (args.assignee === "kommander" && !args.labels.includes("opentui")) { + if ((TEAM.zen as readonly string[]).includes(assignee) && !labels.includes("zen")) { + throw new Error("Only zen issues should be assigned to fwang or MrMushrooooom") + } + + if (assignee === "Hona" && !labels.includes("windows")) { + throw new Error("Only windows issues should be assigned to Hona") + } + + if (assignee === "R44VC0RP" && !labels.includes("docs")) { + throw new Error("Only docs issues should be assigned to R44VC0RP") + } + + if (assignee === "kommander" && !labels.includes("opentui")) { throw new Error("Only opentui issues should be assigned to kommander") } - // await octokit.rest.issues.addAssignees({ - // owner, - // repo, - // issue_number: issue, - // assignees: [args.assignee], - // }) await githubFetch(`/repos/${owner}/${repo}/issues/${issue}/assignees`, { method: "POST", - body: JSON.stringify({ assignees: [args.assignee] }), + body: JSON.stringify({ assignees: [assignee] }), }) - results.push(`Assigned @${args.assignee} to issue #${issue}`) - - const labels: string[] = args.labels.map((label) => (label === "desktop" ? "web" : label)) + results.push(`Assigned @${assignee} to issue #${issue}`) if (labels.length > 0) { - // await octokit.rest.issues.addLabels({ - // owner, - // repo, - // issue_number: issue, - // labels, - // }) await githubFetch(`/repos/${owner}/${repo}/issues/${issue}/labels`, { method: "POST", body: JSON.stringify({ labels }), }) - results.push(`Added labels: ${args.labels.join(", ")}`) + results.push(`Added labels: ${labels.join(", ")}`) } return results.join("\n") diff --git a/.opencode/tool/github-triage.txt b/.opencode/tool/github-triage.txt index ae47cf4cb0a8..4369ed23512f 100644 --- a/.opencode/tool/github-triage.txt +++ b/.opencode/tool/github-triage.txt @@ -1,88 +1,6 @@ Use this tool to assign and/or label a GitHub issue. -You can assign the following users: -- thdxr -- adamdotdevin -- fwang -- jayair -- kommander -- rekram1-node +Choose labels and assignee using the current triage policy and ownership rules. +Pick the most fitting labels for the issue and assign one owner. - -You can use the following labels: -- nix -- opentui -- perf -- web -- zen -- docs - -Always try to assign an issue, if in doubt, assign rekram1-node to it. - -## Breakdown of responsibilities: - -### thdxr - -Dax is responsible for managing core parts of the application, for large feature requests, api changes, or things that require significant changes to the codebase assign him. - -This relates to OpenCode server primarily but has overlap with just about anything - -### adamdotdevin - -Adam is responsible for managing the Desktop/Web app. If there is an issue relating to the desktop app or `opencode web` command. Assign him. - - -### fwang - -Frank is responsible for managing Zen, if you see complaints about OpenCode Zen, maybe it's the dashboard, the model quality, billing issues, etc. Assign him to the issue. - -### jayair - -Jay is responsible for documentation. If there is an issue relating to documentation assign him. - -### kommander - -Sebastian is responsible for managing an OpenTUI (a library for building terminal user interfaces). OpenCode's TUI is built with OpenTUI. If there are issues about: -- random characters on screen -- keybinds not working on different terminals -- general terminal stuff -Then assign the issue to Him. - -### rekram1-node - -ALL BUGS SHOULD BE assigned to rekram1-node unless they have the `opentui` label. - -Assign Aiden to an issue as a catch all, if you can't assign anyone else. Most of the time this will be bugs/polish things. -If no one else makes sense to assign, assign rekram1-node to it. - -Always assign to aiden if the issue mentions "acp", "zed", or model performance issues - -## Breakdown of Labels: - -### nix - -Any issue that mentions nix, or nixos should have a nix label - -### opentui - -Anything relating to the TUI itself should have an opentui label - -### perf - -Anything related to slow performance, high ram, high cpu usage, or any other performance related issue should have a perf label - -### desktop - -Anything related to `opencode web` command or the desktop app should have a desktop label. Never add this label for anything terminal/tui related - -### zen - -Anything related to OpenCode Zen, billing, or model quality from Zen should have a zen label - -### docs - -Anything related to the documentation should have a docs label - -### windows - -Use for any issue that involves the windows OS +If unsure, choose the team/section with the most overlap with the issue and assign a member from that team at random. diff --git a/.zed/settings.json b/.zed/settings.json new file mode 100644 index 000000000000..a3a5e1e2b219 --- /dev/null +++ b/.zed/settings.json @@ -0,0 +1,9 @@ +{ + "format_on_save": "on", + "formatter": { + "external": { + "command": "bunx", + "arguments": ["prettier", "--stdin-filepath", "{buffer_path}"] + } + } +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4bec009ef467..2ae3fc6f2fb5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -24,6 +24,11 @@ If you are unsure if a PR would be accepted, feel free to ask a maintainer or lo Want to take on an issue? Leave a comment and a maintainer may assign it to you unless it is something we are already working on. +## Adding New Providers + +New providers shouldn't require many if ANY code changes, but if you want to add support for a new provider first make a PR to: +https://github.com/anomalyco/models.dev + ## Developing OpenCode - Requirements: Bun 1.3+ diff --git a/README.ar.md b/README.ar.md index edac204a2851..f24e598d5eb9 100644 --- a/README.ar.md +++ b/README.ar.md @@ -31,7 +31,8 @@ Norsk | Português (Brasil) | ไทย | - Türkçe + Türkçe | + Українська

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.br.md b/README.br.md index c185603efbbd..4802c4996f63 100644 --- a/README.br.md +++ b/README.br.md @@ -31,7 +31,8 @@ Norsk | Português (Brasil) | ไทย | - Türkçe + Türkçe | + Українська

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.bs.md b/README.bs.md index d64a69c0d765..9ad6852018c0 100644 --- a/README.bs.md +++ b/README.bs.md @@ -32,7 +32,8 @@ Norsk | Português (Brasil) | ไทย | - Türkçe + Türkçe | + Українська

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.da.md b/README.da.md index 7f3d5aa5ddec..4b1302dbc3c2 100644 --- a/README.da.md +++ b/README.da.md @@ -31,7 +31,8 @@ Norsk | Português (Brasil) | ไทย | - Türkçe + Türkçe | + Українська

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.de.md b/README.de.md index 2aa78657ca9e..16116dc72f23 100644 --- a/README.de.md +++ b/README.de.md @@ -31,7 +31,8 @@ Norsk | Português (Brasil) | ไทย | - Türkçe + Türkçe | + Українська

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.es.md b/README.es.md index 2b80427ab247..5c18ff4aca7c 100644 --- a/README.es.md +++ b/README.es.md @@ -31,7 +31,8 @@ Norsk | Português (Brasil) | ไทย | - Türkçe + Türkçe | + Українська

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.fr.md b/README.fr.md index bc3fe9e75798..0382164bedc5 100644 --- a/README.fr.md +++ b/README.fr.md @@ -31,7 +31,8 @@ Norsk | Português (Brasil) | ไทย | - Türkçe + Türkçe | + Українська

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.it.md b/README.it.md index 6da7d51fc684..c966ccec4916 100644 --- a/README.it.md +++ b/README.it.md @@ -31,7 +31,8 @@ Norsk | Português (Brasil) | ไทย | - Türkçe + Türkçe | + Українська

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.ja.md b/README.ja.md index 7a0bbb08f38c..11109e7eb408 100644 --- a/README.ja.md +++ b/README.ja.md @@ -31,7 +31,8 @@ Norsk | Português (Brasil) | ไทย | - Türkçe + Türkçe | + Українська

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.ko.md b/README.ko.md index 1c931c31f3c0..23fea76b1ebd 100644 --- a/README.ko.md +++ b/README.ko.md @@ -31,7 +31,8 @@ Norsk | Português (Brasil) | ไทย | - Türkçe + Türkçe | + Українська

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.md b/README.md index bd01fc94e8f1..99b4b2c50ff9 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,8 @@ Norsk | Português (Brasil) | ไทย | - Türkçe + Türkçe | + Українська

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.no.md b/README.no.md index 092316bae1b9..9b9e90dc3850 100644 --- a/README.no.md +++ b/README.no.md @@ -31,7 +31,8 @@ Norsk | Português (Brasil) | ไทย | - Türkçe + Türkçe | + Українська

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.pl.md b/README.pl.md index a225d82539ed..fced98dfc3a1 100644 --- a/README.pl.md +++ b/README.pl.md @@ -31,7 +31,8 @@ Norsk | Português (Brasil) | ไทย | - Türkçe + Türkçe | + Українська

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.ru.md b/README.ru.md index c13f039d1689..a7c590c16b7c 100644 --- a/README.ru.md +++ b/README.ru.md @@ -31,7 +31,8 @@ Norsk | Português (Brasil) | ไทย | - Türkçe + Türkçe | + Українська

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.th.md b/README.th.md index ba2db8a850a8..0999167f239c 100644 --- a/README.th.md +++ b/README.th.md @@ -31,7 +31,8 @@ Norsk | Português (Brasil) | ไทย | - Türkçe + Türkçe | + Українська

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.tr.md b/README.tr.md index 635a5782fef1..67f84e4ddbce 100644 --- a/README.tr.md +++ b/README.tr.md @@ -31,7 +31,8 @@ Norsk | Português (Brasil) | ไทย | - Türkçe + Türkçe | + Українська

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.uk.md b/README.uk.md new file mode 100644 index 000000000000..77e859a45d73 --- /dev/null +++ b/README.uk.md @@ -0,0 +1,139 @@ +

+ + + + + OpenCode logo + + +

+

AI-агент для програмування з відкритим кодом.

+

+ Discord + npm + Build status +

+ +

+ English | + 简体中文 | + 繁體中文 | + 한국어 | + Deutsch | + Español | + Français | + Italiano | + Dansk | + 日本語 | + Polski | + Русский | + Bosanski | + العربية | + Norsk | + Português (Brasil) | + ไทย | + Türkçe | + Українська +

+ +[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) + +--- + +### Встановлення + +```bash +# YOLO +curl -fsSL https://opencode.ai/install | bash + +# Менеджери пакетів +npm i -g opencode-ai@latest # або bun/pnpm/yarn +scoop install opencode # Windows +choco install opencode # Windows +brew install anomalyco/tap/opencode # macOS і Linux (рекомендовано, завжди актуально) +brew install opencode # macOS і Linux (офіційна формула Homebrew, оновлюється рідше) +sudo pacman -S opencode # Arch Linux (Stable) +paru -S opencode-bin # Arch Linux (Latest from AUR) +mise use -g opencode # Будь-яка ОС +nix run nixpkgs#opencode # або github:anomalyco/opencode для найновішої dev-гілки +``` + +> [!TIP] +> Перед встановленням видаліть версії старші за 0.1.x. + +### Десктопний застосунок (BETA) + +OpenCode також доступний як десктопний застосунок. Завантажуйте напряму зі [сторінки релізів](https://github.com/anomalyco/opencode/releases) або [opencode.ai/download](https://opencode.ai/download). + +| Платформа | Завантаження | +| --------------------- | ------------------------------------- | +| macOS (Apple Silicon) | `opencode-desktop-darwin-aarch64.dmg` | +| macOS (Intel) | `opencode-desktop-darwin-x64.dmg` | +| Windows | `opencode-desktop-windows-x64.exe` | +| Linux | `.deb`, `.rpm` або AppImage | + +```bash +# macOS (Homebrew) +brew install --cask opencode-desktop +# Windows (Scoop) +scoop bucket add extras; scoop install extras/opencode-desktop +``` + +#### Каталог встановлення + +Скрипт встановлення дотримується такого порядку пріоритету для шляху встановлення: + +1. `$OPENCODE_INSTALL_DIR` - Користувацький каталог встановлення +2. `$XDG_BIN_DIR` - Шлях, сумісний зі специфікацією XDG Base Directory +3. `$HOME/bin` - Стандартний каталог користувацьких бінарників (якщо існує або його можна створити) +4. `$HOME/.opencode/bin` - Резервний варіант за замовчуванням + +```bash +# Приклади +OPENCODE_INSTALL_DIR=/usr/local/bin curl -fsSL https://opencode.ai/install | bash +XDG_BIN_DIR=$HOME/.local/bin curl -fsSL https://opencode.ai/install | bash +``` + +### Агенти + +OpenCode містить два вбудовані агенти, між якими можна перемикатися клавішею `Tab`. + +- **build** - Агент за замовчуванням із повним доступом для завдань розробки +- **plan** - Агент лише для читання для аналізу та дослідження коду + - За замовчуванням забороняє редагування файлів + - Запитує дозвіл перед запуском bash-команд + - Ідеально підходить для дослідження незнайомих кодових баз або планування змін + +Також доступний допоміжний агент **general** для складного пошуку та багатокрокових завдань. +Він використовується всередині системи й може бути викликаний у повідомленнях через `@general`. + +Дізнайтеся більше про [agents](https://opencode.ai/docs/agents). + +### Документація + +Щоб дізнатися більше про налаштування OpenCode, [**перейдіть до нашої документації**](https://opencode.ai/docs). + +### Внесок + +Якщо ви хочете зробити внесок в OpenCode, будь ласка, прочитайте нашу [документацію для контриб'юторів](./CONTRIBUTING.md) перед надсиланням pull request. + +### Проєкти на базі OpenCode + +Якщо ви працюєте над проєктом, пов'язаним з OpenCode, і використовуєте "opencode" у назві, наприклад "opencode-dashboard" або "opencode-mobile", додайте примітку до свого README. +Уточніть, що цей проєкт не створений командою OpenCode і жодним чином не афілійований із нами. + +### FAQ + +#### Чим це відрізняється від Claude Code? + +За можливостями це дуже схоже на Claude Code. Ось ключові відмінності: + +- 100% open source +- Немає прив'язки до конкретного провайдера. Ми рекомендуємо моделі, які надаємо через [OpenCode Zen](https://opencode.ai/zen), але OpenCode також працює з Claude, OpenAI, Google і навіть локальними моделями. З розвитком моделей різниця між ними зменшуватиметься, а ціни падатимуть, тому незалежність від провайдера має значення. +- Підтримка LSP з коробки +- Фокус на TUI. OpenCode створено користувачами neovim та авторами [terminal.shop](https://terminal.shop); ми й надалі розширюватимемо межі можливого в терміналі. +- Клієнт-серверна архітектура. Наприклад, це дає змогу запускати OpenCode на вашому комп'ютері й керувати ним віддалено з мобільного застосунку, тобто TUI-фронтенд - лише один із можливих клієнтів. + +--- + +**Приєднуйтеся до нашої спільноти** [Discord](https://discord.gg/opencode) | [X.com](https://x.com/opencode) diff --git a/README.zh.md b/README.zh.md index b2f288f5ba5c..113d476b2ed3 100644 --- a/README.zh.md +++ b/README.zh.md @@ -31,7 +31,8 @@ Norsk | Português (Brasil) | ไทย | - Türkçe + Türkçe | + Українська

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.zht.md b/README.zht.md index be4ef053c012..b5181044438d 100644 --- a/README.zht.md +++ b/README.zht.md @@ -31,7 +31,8 @@ Norsk | Português (Brasil) | ไทย | - Türkçe + Türkçe | + Українська

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/SECURITY.md b/SECURITY.md index 93c7341cef6e..e7e59f4a27ac 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,5 +1,11 @@ # Security +## IMPORTANT + +We do not accept AI generated security reports. We receive a large number of +these and we absolutely do not have the resources to review them all. If you +submit one that will be an automatic ban from the project. + ## Threat Model ### Overview diff --git a/bun.lock b/bun.lock index 59106e14afcb..2df39fa547b5 100644 --- a/bun.lock +++ b/bun.lock @@ -14,16 +14,17 @@ "devDependencies": { "@actions/artifact": "5.0.1", "@tsconfig/bun": "catalog:", + "@types/mime-types": "3.0.1", "husky": "9.1.7", "prettier": "3.6.2", "semver": "^7.6.0", - "sst": "3.17.23", + "sst": "3.18.10", "turbo": "2.5.6", }, }, "packages/app": { "name": "@opencode-ai/app", - "version": "1.2.4", + "version": "1.2.6", "dependencies": { "@kobalte/core": "catalog:", "@opencode-ai/sdk": "workspace:*", @@ -73,7 +74,7 @@ }, "packages/console/app": { "name": "@opencode-ai/console-app", - "version": "1.2.4", + "version": "1.2.6", "dependencies": { "@cloudflare/vite-plugin": "1.15.2", "@ibm/plex": "6.4.1", @@ -107,7 +108,7 @@ }, "packages/console/core": { "name": "@opencode-ai/console-core", - "version": "1.2.4", + "version": "1.2.6", "dependencies": { "@aws-sdk/client-sts": "3.782.0", "@jsx-email/render": "1.1.1", @@ -134,7 +135,7 @@ }, "packages/console/function": { "name": "@opencode-ai/console-function", - "version": "1.2.4", + "version": "1.2.6", "dependencies": { "@ai-sdk/anthropic": "2.0.0", "@ai-sdk/openai": "2.0.2", @@ -158,7 +159,7 @@ }, "packages/console/mail": { "name": "@opencode-ai/console-mail", - "version": "1.2.4", + "version": "1.2.6", "dependencies": { "@jsx-email/all": "2.2.3", "@jsx-email/cli": "1.4.3", @@ -182,7 +183,7 @@ }, "packages/desktop": { "name": "@opencode-ai/desktop", - "version": "1.2.4", + "version": "1.2.6", "dependencies": { "@opencode-ai/app": "workspace:*", "@opencode-ai/ui": "workspace:*", @@ -215,7 +216,7 @@ }, "packages/enterprise": { "name": "@opencode-ai/enterprise", - "version": "1.2.4", + "version": "1.2.6", "dependencies": { "@opencode-ai/ui": "workspace:*", "@opencode-ai/util": "workspace:*", @@ -244,7 +245,7 @@ }, "packages/function": { "name": "@opencode-ai/function", - "version": "1.2.4", + "version": "1.2.6", "dependencies": { "@octokit/auth-app": "8.0.1", "@octokit/rest": "catalog:", @@ -260,7 +261,7 @@ }, "packages/opencode": { "name": "opencode", - "version": "1.2.4", + "version": "1.2.6", "bin": { "opencode": "./bin/opencode", }, @@ -287,9 +288,10 @@ "@ai-sdk/togetherai": "1.0.34", "@ai-sdk/vercel": "1.0.33", "@ai-sdk/xai": "2.0.51", + "@aws-sdk/credential-providers": "3.993.0", "@clack/prompts": "1.0.0-alpha.1", - "@gitlab/gitlab-ai-provider": "3.5.0", - "@gitlab/opencode-gitlab-auth": "1.3.2", + "@gitlab/gitlab-ai-provider": "3.6.0", + "@gitlab/opencode-gitlab-auth": "1.3.3", "@hono/standard-validator": "0.1.5", "@hono/zod-validator": "catalog:", "@modelcontextprotocol/sdk": "1.25.2", @@ -319,11 +321,13 @@ "diff": "catalog:", "drizzle-orm": "1.0.0-beta.12-a5629fb", "fuzzysort": "3.1.0", + "google-auth-library": "10.5.0", "gray-matter": "4.0.3", "hono": "catalog:", "hono-openapi": "catalog:", "ignore": "7.0.5", "jsonc-parser": "3.3.1", + "mime-types": "3.0.2", "minimatch": "10.0.3", "open": "10.1.2", "opentui-spinner": "0.0.6", @@ -356,6 +360,7 @@ "@tsconfig/bun": "catalog:", "@types/babel__core": "7.20.5", "@types/bun": "catalog:", + "@types/mime-types": "3.0.1", "@types/turndown": "5.0.5", "@types/yargs": "17.0.33", "@typescript/native-preview": "catalog:", @@ -369,7 +374,7 @@ }, "packages/plugin": { "name": "@opencode-ai/plugin", - "version": "1.2.4", + "version": "1.2.6", "dependencies": { "@opencode-ai/sdk": "workspace:*", "zod": "catalog:", @@ -389,7 +394,7 @@ }, "packages/sdk/js": { "name": "@opencode-ai/sdk", - "version": "1.2.4", + "version": "1.2.6", "devDependencies": { "@hey-api/openapi-ts": "0.90.10", "@tsconfig/node22": "catalog:", @@ -400,7 +405,7 @@ }, "packages/slack": { "name": "@opencode-ai/slack", - "version": "1.2.4", + "version": "1.2.6", "dependencies": { "@opencode-ai/sdk": "workspace:*", "@slack/bolt": "^3.17.1", @@ -413,7 +418,7 @@ }, "packages/ui": { "name": "@opencode-ai/ui", - "version": "1.2.4", + "version": "1.2.6", "dependencies": { "@kobalte/core": "catalog:", "@opencode-ai/sdk": "workspace:*", @@ -455,7 +460,7 @@ }, "packages/util": { "name": "@opencode-ai/util", - "version": "1.2.4", + "version": "1.2.6", "dependencies": { "zod": "catalog:", }, @@ -466,7 +471,7 @@ }, "packages/web": { "name": "@opencode-ai/web", - "version": "1.2.4", + "version": "1.2.6", "dependencies": { "@astrojs/cloudflare": "12.6.3", "@astrojs/markdown-remark": "6.3.1", @@ -667,27 +672,35 @@ "@aws-crypto/util": ["@aws-crypto/util@5.2.0", "", { "dependencies": { "@aws-sdk/types": "^3.222.0", "@smithy/util-utf8": "^2.0.0", "tslib": "^2.6.2" } }, "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ=="], + "@aws-sdk/client-cognito-identity": ["@aws-sdk/client-cognito-identity@3.993.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.11", "@aws-sdk/credential-provider-node": "^3.972.10", "@aws-sdk/middleware-host-header": "^3.972.3", "@aws-sdk/middleware-logger": "^3.972.3", "@aws-sdk/middleware-recursion-detection": "^3.972.3", "@aws-sdk/middleware-user-agent": "^3.972.11", "@aws-sdk/region-config-resolver": "^3.972.3", "@aws-sdk/types": "^3.973.1", "@aws-sdk/util-endpoints": "3.993.0", "@aws-sdk/util-user-agent-browser": "^3.972.3", "@aws-sdk/util-user-agent-node": "^3.972.9", "@smithy/config-resolver": "^4.4.6", "@smithy/core": "^3.23.2", "@smithy/fetch-http-handler": "^5.3.9", "@smithy/hash-node": "^4.2.8", "@smithy/invalid-dependency": "^4.2.8", "@smithy/middleware-content-length": "^4.2.8", "@smithy/middleware-endpoint": "^4.4.16", "@smithy/middleware-retry": "^4.4.33", "@smithy/middleware-serde": "^4.2.9", "@smithy/middleware-stack": "^4.2.8", "@smithy/node-config-provider": "^4.3.8", "@smithy/node-http-handler": "^4.4.10", "@smithy/protocol-http": "^5.3.8", "@smithy/smithy-client": "^4.11.5", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@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.32", "@smithy/util-defaults-mode-node": "^4.2.35", "@smithy/util-endpoints": "^3.2.8", "@smithy/util-middleware": "^4.2.8", "@smithy/util-retry": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7Ne3Yk/bgQPVebAkv7W+RfhiwTRSbfER9BtbhOa2w/+dIr902LrJf6vrZlxiqaJbGj2ALx8M+ZK1YIHVxSwu9A=="], + "@aws-sdk/client-s3": ["@aws-sdk/client-s3@3.933.0", "", { "dependencies": { "@aws-crypto/sha1-browser": "5.2.0", "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.932.0", "@aws-sdk/credential-provider-node": "3.933.0", "@aws-sdk/middleware-bucket-endpoint": "3.930.0", "@aws-sdk/middleware-expect-continue": "3.930.0", "@aws-sdk/middleware-flexible-checksums": "3.932.0", "@aws-sdk/middleware-host-header": "3.930.0", "@aws-sdk/middleware-location-constraint": "3.930.0", "@aws-sdk/middleware-logger": "3.930.0", "@aws-sdk/middleware-recursion-detection": "3.933.0", "@aws-sdk/middleware-sdk-s3": "3.932.0", "@aws-sdk/middleware-ssec": "3.930.0", "@aws-sdk/middleware-user-agent": "3.932.0", "@aws-sdk/region-config-resolver": "3.930.0", "@aws-sdk/signature-v4-multi-region": "3.932.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/eventstream-serde-browser": "^4.2.5", "@smithy/eventstream-serde-config-resolver": "^4.3.5", "@smithy/eventstream-serde-node": "^4.2.5", "@smithy/fetch-http-handler": "^5.3.6", "@smithy/hash-blob-browser": "^4.2.6", "@smithy/hash-node": "^4.2.5", "@smithy/hash-stream-node": "^4.2.5", "@smithy/invalid-dependency": "^4.2.5", "@smithy/md5-js": "^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-stream": "^4.5.6", "@smithy/util-utf8": "^4.2.0", "@smithy/util-waiter": "^4.2.5", "tslib": "^2.6.2" } }, "sha512-KxwZvdxdCeWK6o8mpnb+kk7Kgb8V+8AjTwSXUWH1UAD85B0tjdo1cSfE5zoR5fWGol4Ml5RLez12a6LPhsoTqA=="], - "@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-sso": ["@aws-sdk/client-sso@3.993.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.11", "@aws-sdk/middleware-host-header": "^3.972.3", "@aws-sdk/middleware-logger": "^3.972.3", "@aws-sdk/middleware-recursion-detection": "^3.972.3", "@aws-sdk/middleware-user-agent": "^3.972.11", "@aws-sdk/region-config-resolver": "^3.972.3", "@aws-sdk/types": "^3.973.1", "@aws-sdk/util-endpoints": "3.993.0", "@aws-sdk/util-user-agent-browser": "^3.972.3", "@aws-sdk/util-user-agent-node": "^3.972.9", "@smithy/config-resolver": "^4.4.6", "@smithy/core": "^3.23.2", "@smithy/fetch-http-handler": "^5.3.9", "@smithy/hash-node": "^4.2.8", "@smithy/invalid-dependency": "^4.2.8", "@smithy/middleware-content-length": "^4.2.8", "@smithy/middleware-endpoint": "^4.4.16", "@smithy/middleware-retry": "^4.4.33", "@smithy/middleware-serde": "^4.2.9", "@smithy/middleware-stack": "^4.2.8", "@smithy/node-config-provider": "^4.3.8", "@smithy/node-http-handler": "^4.4.10", "@smithy/protocol-http": "^5.3.8", "@smithy/smithy-client": "^4.11.5", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@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.32", "@smithy/util-defaults-mode-node": "^4.2.35", "@smithy/util-endpoints": "^3.2.8", "@smithy/util-middleware": "^4.2.8", "@smithy/util-retry": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-VLUN+wIeNX24fg12SCbzTUBnBENlL014yMKZvRhPkcn4wHR6LKgNrjsG3fZ03Xs0XoKaGtNFi1VVrq666sGBoQ=="], "@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-env": ["@aws-sdk/credential-provider-env@3.932.0", "", { "dependencies": { "@aws-sdk/core": "3.932.0", "@aws-sdk/types": "3.930.0", "@smithy/property-provider": "^4.2.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-ozge/c7NdHUDyHqro6+P5oHt8wfKSUBN+olttiVfBe9Mw3wBMpPa3gQ0pZnG+gwBkKskBuip2bMR16tqYvUSEA=="], + "@aws-sdk/credential-provider-cognito-identity": ["@aws-sdk/credential-provider-cognito-identity@3.972.3", "", { "dependencies": { "@aws-sdk/client-cognito-identity": "3.980.0", "@aws-sdk/types": "^3.973.1", "@smithy/property-provider": "^4.2.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-dW/DqTk90XW7hIngqntAVtJJyrkS51wcLhGz39lOMe0TlSmZl+5R/UGnAZqNbXmWuJHLzxe+MLgagxH41aTsAQ=="], + + "@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.972.9", "", { "dependencies": { "@aws-sdk/core": "^3.973.11", "@aws-sdk/types": "^3.973.1", "@smithy/property-provider": "^4.2.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-ZptrOwQynfupubvcngLkbdIq/aXvl/czdpEG8XJ8mN8Nb19BR0jaK0bR+tfuMU36Ez9q4xv7GGkHFqEEP2hUUQ=="], + + "@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.972.11", "", { "dependencies": { "@aws-sdk/core": "^3.973.11", "@aws-sdk/types": "^3.973.1", "@smithy/fetch-http-handler": "^5.3.9", "@smithy/node-http-handler": "^4.4.10", "@smithy/property-provider": "^4.2.8", "@smithy/protocol-http": "^5.3.8", "@smithy/smithy-client": "^4.11.5", "@smithy/types": "^4.12.0", "@smithy/util-stream": "^4.5.12", "tslib": "^2.6.2" } }, "sha512-hECWoOoH386bGr89NQc9vA/abkGf5TJrMREt+lhNcnSNmoBS04fK7vc3LrJBSQAUGGVj0Tz3f4dHB3w5veovig=="], - "@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.932.0", "", { "dependencies": { "@aws-sdk/core": "3.932.0", "@aws-sdk/types": "3.930.0", "@smithy/fetch-http-handler": "^5.3.6", "@smithy/node-http-handler": "^4.4.5", "@smithy/property-provider": "^4.2.5", "@smithy/protocol-http": "^5.3.5", "@smithy/smithy-client": "^4.9.5", "@smithy/types": "^4.9.0", "@smithy/util-stream": "^4.5.6", "tslib": "^2.6.2" } }, "sha512-b6N9Nnlg8JInQwzBkUq5spNaXssM3h3zLxGzpPrnw0nHSIWPJPTbZzA5Ca285fcDUFuKP+qf3qkuqlAjGOdWhg=="], + "@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.972.9", "", { "dependencies": { "@aws-sdk/core": "^3.973.11", "@aws-sdk/credential-provider-env": "^3.972.9", "@aws-sdk/credential-provider-http": "^3.972.11", "@aws-sdk/credential-provider-login": "^3.972.9", "@aws-sdk/credential-provider-process": "^3.972.9", "@aws-sdk/credential-provider-sso": "^3.972.9", "@aws-sdk/credential-provider-web-identity": "^3.972.9", "@aws-sdk/nested-clients": "3.993.0", "@aws-sdk/types": "^3.973.1", "@smithy/credential-provider-imds": "^4.2.8", "@smithy/property-provider": "^4.2.8", "@smithy/shared-ini-file-loader": "^4.4.3", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-zr1csEu9n4eDiHMTYJabX1mDGuGLgjgUnNckIivvk43DocJC9/f6DefFrnUPZXE+GHtbW50YuXb+JIxKykU74A=="], - "@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.933.0", "", { "dependencies": { "@aws-sdk/core": "3.932.0", "@aws-sdk/credential-provider-env": "3.932.0", "@aws-sdk/credential-provider-http": "3.932.0", "@aws-sdk/credential-provider-process": "3.932.0", "@aws-sdk/credential-provider-sso": "3.933.0", "@aws-sdk/credential-provider-web-identity": "3.933.0", "@aws-sdk/nested-clients": "3.933.0", "@aws-sdk/types": "3.930.0", "@smithy/credential-provider-imds": "^4.2.5", "@smithy/property-provider": "^4.2.5", "@smithy/shared-ini-file-loader": "^4.4.0", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-HygGyKuMG5AaGXsmM0d81miWDon55xwalRHB3UmDg3QBhtunbNIoIaWUbNTKuBZXcIN6emeeEZw/YgSMqLc0YA=="], + "@aws-sdk/credential-provider-login": ["@aws-sdk/credential-provider-login@3.972.9", "", { "dependencies": { "@aws-sdk/core": "^3.973.11", "@aws-sdk/nested-clients": "3.993.0", "@aws-sdk/types": "^3.973.1", "@smithy/property-provider": "^4.2.8", "@smithy/protocol-http": "^5.3.8", "@smithy/shared-ini-file-loader": "^4.4.3", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-m4RIpVgZChv0vWS/HKChg1xLgZPpx8Z+ly9Fv7FwA8SOfuC6I3htcSaBz2Ch4bneRIiBUhwP4ziUo0UZgtJStQ=="], "@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.933.0", "", { "dependencies": { "@aws-sdk/credential-provider-env": "3.932.0", "@aws-sdk/credential-provider-http": "3.932.0", "@aws-sdk/credential-provider-ini": "3.933.0", "@aws-sdk/credential-provider-process": "3.932.0", "@aws-sdk/credential-provider-sso": "3.933.0", "@aws-sdk/credential-provider-web-identity": "3.933.0", "@aws-sdk/types": "3.930.0", "@smithy/credential-provider-imds": "^4.2.5", "@smithy/property-provider": "^4.2.5", "@smithy/shared-ini-file-loader": "^4.4.0", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-L2dE0Y7iMLammQewPKNeEh1z/fdJyYEU+/QsLBD9VEh+SXcN/FIyTi21Isw8wPZN6lMB9PDVtISzBnF8HuSFrw=="], - "@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.932.0", "", { "dependencies": { "@aws-sdk/core": "3.932.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-BodZYKvT4p/Dkm28Ql/FhDdS1+p51bcZeMMu2TRtU8PoMDHnVDhHz27zASEKSZwmhvquxHrZHB0IGuVqjZUtSQ=="], + "@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.972.9", "", { "dependencies": { "@aws-sdk/core": "^3.973.11", "@aws-sdk/types": "^3.973.1", "@smithy/property-provider": "^4.2.8", "@smithy/shared-ini-file-loader": "^4.4.3", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-gOWl0Fe2gETj5Bk151+LYKpeGi2lBDLNu+NMNpHRlIrKHdBmVun8/AalwMK8ci4uRfG5a3/+zvZBMpuen1SZ0A=="], - "@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.933.0", "", { "dependencies": { "@aws-sdk/client-sso": "3.933.0", "@aws-sdk/core": "3.932.0", "@aws-sdk/token-providers": "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-/R1DBR7xNcuZIhS2RirU+P2o8E8/fOk+iLAhbqeSTq+g09fP/F6W7ouFpS5eVE2NIfWG7YBFoVddOhvuqpn51g=="], + "@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.972.9", "", { "dependencies": { "@aws-sdk/client-sso": "3.993.0", "@aws-sdk/core": "^3.973.11", "@aws-sdk/token-providers": "3.993.0", "@aws-sdk/types": "^3.973.1", "@smithy/property-provider": "^4.2.8", "@smithy/shared-ini-file-loader": "^4.4.3", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-ey7S686foGTArvFhi3ifQXmgptKYvLSGE2250BAQceMSXZddz7sUSNERGJT2S7u5KIe/kgugxrt01hntXVln6w=="], - "@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@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-c7Eccw2lhFx2/+qJn3g+uIDWRuWi2A6Sz3PVvckFUEzPsP0dPUo19hlvtarwP5GzrsXn0yEPRVhpewsIaSCGaQ=="], + "@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.972.9", "", { "dependencies": { "@aws-sdk/core": "^3.973.11", "@aws-sdk/nested-clients": "3.993.0", "@aws-sdk/types": "^3.973.1", "@smithy/property-provider": "^4.2.8", "@smithy/shared-ini-file-loader": "^4.4.3", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-8LnfS76nHXoEc9aRRiMMpxZxJeDG0yusdyo3NvPhCgESmBUgpMa4luhGbClW5NoX/qRcGxxM6Z/esqANSNMTow=="], + + "@aws-sdk/credential-providers": ["@aws-sdk/credential-providers@3.993.0", "", { "dependencies": { "@aws-sdk/client-cognito-identity": "3.993.0", "@aws-sdk/core": "^3.973.11", "@aws-sdk/credential-provider-cognito-identity": "^3.972.3", "@aws-sdk/credential-provider-env": "^3.972.9", "@aws-sdk/credential-provider-http": "^3.972.11", "@aws-sdk/credential-provider-ini": "^3.972.9", "@aws-sdk/credential-provider-login": "^3.972.9", "@aws-sdk/credential-provider-node": "^3.972.10", "@aws-sdk/credential-provider-process": "^3.972.9", "@aws-sdk/credential-provider-sso": "^3.972.9", "@aws-sdk/credential-provider-web-identity": "^3.972.9", "@aws-sdk/nested-clients": "3.993.0", "@aws-sdk/types": "^3.973.1", "@smithy/config-resolver": "^4.4.6", "@smithy/core": "^3.23.2", "@smithy/credential-provider-imds": "^4.2.8", "@smithy/node-config-provider": "^4.3.8", "@smithy/property-provider": "^4.2.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-1M/nukgPSLqe9krzOKHnE8OylUaKAiokAV3xRLdeExVHcRE7WG5uzCTKWTj1imKvPjDqXq/FWhlbbdWIn7xIwA=="], "@aws-sdk/middleware-bucket-endpoint": ["@aws-sdk/middleware-bucket-endpoint@3.930.0", "", { "dependencies": { "@aws-sdk/types": "3.930.0", "@aws-sdk/util-arn-parser": "3.893.0", "@smithy/node-config-provider": "^4.3.5", "@smithy/protocol-http": "^5.3.5", "@smithy/types": "^4.9.0", "@smithy/util-config-provider": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-cnCLWeKPYgvV4yRYPFH6pWMdUByvu2cy2BAlfsPpvnm4RaVioztyvxmQj5PmVN5fvWs5w/2d6U7le8X9iye2sA=="], @@ -709,13 +722,13 @@ "@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.932.0", "", { "dependencies": { "@aws-sdk/core": "3.932.0", "@aws-sdk/types": "3.930.0", "@aws-sdk/util-endpoints": "3.930.0", "@smithy/core": "^3.18.2", "@smithy/protocol-http": "^5.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-9BGTbJyA/4PTdwQWE9hAFIJGpsYkyEW20WON3i15aDqo5oRZwZmqaVageOD57YYqG8JDJjvcwKyDdR4cc38dvg=="], - "@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/nested-clients": ["@aws-sdk/nested-clients@3.993.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.11", "@aws-sdk/middleware-host-header": "^3.972.3", "@aws-sdk/middleware-logger": "^3.972.3", "@aws-sdk/middleware-recursion-detection": "^3.972.3", "@aws-sdk/middleware-user-agent": "^3.972.11", "@aws-sdk/region-config-resolver": "^3.972.3", "@aws-sdk/types": "^3.973.1", "@aws-sdk/util-endpoints": "3.993.0", "@aws-sdk/util-user-agent-browser": "^3.972.3", "@aws-sdk/util-user-agent-node": "^3.972.9", "@smithy/config-resolver": "^4.4.6", "@smithy/core": "^3.23.2", "@smithy/fetch-http-handler": "^5.3.9", "@smithy/hash-node": "^4.2.8", "@smithy/invalid-dependency": "^4.2.8", "@smithy/middleware-content-length": "^4.2.8", "@smithy/middleware-endpoint": "^4.4.16", "@smithy/middleware-retry": "^4.4.33", "@smithy/middleware-serde": "^4.2.9", "@smithy/middleware-stack": "^4.2.8", "@smithy/node-config-provider": "^4.3.8", "@smithy/node-http-handler": "^4.4.10", "@smithy/protocol-http": "^5.3.8", "@smithy/smithy-client": "^4.11.5", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@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.32", "@smithy/util-defaults-mode-node": "^4.2.35", "@smithy/util-endpoints": "^3.2.8", "@smithy/util-middleware": "^4.2.8", "@smithy/util-retry": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-iOq86f2H67924kQUIPOAvlmMaOAvOLoDOIb66I2YqSUpMYB6ufiuJW3RlREgskxv86S5qKzMnfy/X6CqMjK6XQ=="], "@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.930.0", "", { "dependencies": { "@aws-sdk/types": "3.930.0", "@smithy/config-resolver": "^4.4.3", "@smithy/node-config-provider": "^4.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-KL2JZqH6aYeQssu1g1KuWsReupdfOoxD6f1as2VC+rdwYFUu4LfzMsFfXnBvvQWWqQ7rZHWOw1T+o5gJmg7Dzw=="], "@aws-sdk/signature-v4-multi-region": ["@aws-sdk/signature-v4-multi-region@3.932.0", "", { "dependencies": { "@aws-sdk/middleware-sdk-s3": "3.932.0", "@aws-sdk/types": "3.930.0", "@smithy/protocol-http": "^5.3.5", "@smithy/signature-v4": "^5.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-NCIRJvoRc9246RZHIusY1+n/neeG2yGhBGdKhghmrNdM+mLLN6Ii7CKFZjx3DhxtpHMpl1HWLTMhdVrGwP2upw=="], - "@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/token-providers": ["@aws-sdk/token-providers@3.993.0", "", { "dependencies": { "@aws-sdk/core": "^3.973.11", "@aws-sdk/nested-clients": "3.993.0", "@aws-sdk/types": "^3.973.1", "@smithy/property-provider": "^4.2.8", "@smithy/shared-ini-file-loader": "^4.4.3", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-+35g4c+8r7sB9Sjp1KPdM8qxGn6B/shBjJtEUN4e+Edw9UEQlZKIzioOGu3UAbyE0a/s450LdLZr4wbJChtmww=="], "@aws-sdk/types": ["@aws-sdk/types@3.930.0", "", { "dependencies": { "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-we/vaAgwlEFW7IeftmCLlLMw+6hFs3DzZPJw7lVHbj/5HJ0bz9gndxEsS2lQoeJ1zhiiLqAqvXxmM43s0MBg0A=="], @@ -989,9 +1002,9 @@ "@fontsource/inter": ["@fontsource/inter@5.2.8", "", {}, "sha512-P6r5WnJoKiNVV+zvW2xM13gNdFhAEpQ9dQJHt3naLvfg+LkF2ldgSLiF4T41lf1SQCM9QmkqPTn4TH568IRagg=="], - "@gitlab/gitlab-ai-provider": ["@gitlab/gitlab-ai-provider@3.5.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": ">=2.0.0", "@ai-sdk/provider-utils": ">=3.0.0" } }, "sha512-OoAwCz4fOci3h/2l+PRHMclclh3IaFq8w1es2wvBJ8ca7vtglKsBYT7dvmYpsXlu7pg9mopbjcexvmVCQEUTAQ=="], + "@gitlab/gitlab-ai-provider": ["@gitlab/gitlab-ai-provider@3.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": ">=2.0.0", "@ai-sdk/provider-utils": ">=3.0.0" } }, "sha512-8LmcIQ86xkMtC7L4P1/QYVEC+yKMTRerfPeniaaQGalnzXKtX6iMHLjLPOL9Rxp55lOXi6ed0WrFuJzZx+fNRg=="], - "@gitlab/opencode-gitlab-auth": ["@gitlab/opencode-gitlab-auth@1.3.2", "", { "dependencies": { "@fastify/rate-limit": "^10.2.0", "@opencode-ai/plugin": "*", "fastify": "^5.2.0", "open": "^10.0.0" } }, "sha512-pvGrC+aDVLY8bRCC/fZaG/Qihvt2r4by5xbTo5JTSz9O7yIcR6xG2d9Wkuu4bcXFz674z2C+i5bUk+J/RSdBpg=="], + "@gitlab/opencode-gitlab-auth": ["@gitlab/opencode-gitlab-auth@1.3.3", "", { "dependencies": { "@fastify/rate-limit": "^10.2.0", "@opencode-ai/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=="], @@ -1609,7 +1622,7 @@ "@smithy/config-resolver": ["@smithy/config-resolver@4.4.6", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.8", "@smithy/types": "^4.12.0", "@smithy/util-config-provider": "^4.2.0", "@smithy/util-endpoints": "^3.2.8", "@smithy/util-middleware": "^4.2.8", "tslib": "^2.6.2" } }, "sha512-qJpzYC64kaj3S0fueiu3kXm8xPrR3PcXDPEgnaNMRn0EjNSZFoFjvbUp0YUDsRhN1CB90EnHJtbxWKevnH99UQ=="], - "@smithy/core": ["@smithy/core@3.23.0", "", { "dependencies": { "@smithy/middleware-serde": "^4.2.9", "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-middleware": "^4.2.8", "@smithy/util-stream": "^4.5.12", "@smithy/util-utf8": "^4.2.0", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-Yq4UPVoQICM9zHnByLmG8632t2M0+yap4T7ANVw482J0W7HW0pOuxwVmeOwzJqX2Q89fkXz0Vybz55Wj2Xzrsg=="], + "@smithy/core": ["@smithy/core@3.23.2", "", { "dependencies": { "@smithy/middleware-serde": "^4.2.9", "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-middleware": "^4.2.8", "@smithy/util-stream": "^4.5.12", "@smithy/util-utf8": "^4.2.0", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-HaaH4VbGie4t0+9nY3tNBRSxVTr96wzIqexUa6C2qx3MPePAuz7lIxPxYtt1Wc//SPfJLNoZJzfdt0B6ksj2jA=="], "@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.8", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.8", "@smithy/property-provider": "^4.2.8", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "tslib": "^2.6.2" } }, "sha512-FNT0xHS1c/CPN8upqbMFP83+ul5YgdisfCfkZ86Jh2NSmnqw/AJ6x5pEogVCTVvSm7j9MopRU89bmDelxuDMYw=="], @@ -1639,9 +1652,9 @@ "@smithy/middleware-content-length": ["@smithy/middleware-content-length@4.2.8", "", { "dependencies": { "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-RO0jeoaYAB1qBRhfVyq0pMgBoUK34YEJxVxyjOWYZiOKOq2yMZ4MnVXMZCUDenpozHue207+9P5ilTV1zeda0A=="], - "@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.4.14", "", { "dependencies": { "@smithy/core": "^3.23.0", "@smithy/middleware-serde": "^4.2.9", "@smithy/node-config-provider": "^4.3.8", "@smithy/shared-ini-file-loader": "^4.4.3", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-middleware": "^4.2.8", "tslib": "^2.6.2" } }, "sha512-FUFNE5KVeaY6U/GL0nzAAHkaCHzXLZcY1EhtQnsAqhD8Du13oPKtMB9/0WK4/LK6a/T5OZ24wPoSShff5iI6Ag=="], + "@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.4.16", "", { "dependencies": { "@smithy/core": "^3.23.2", "@smithy/middleware-serde": "^4.2.9", "@smithy/node-config-provider": "^4.3.8", "@smithy/shared-ini-file-loader": "^4.4.3", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-middleware": "^4.2.8", "tslib": "^2.6.2" } }, "sha512-L5GICFCSsNhbJ5JSKeWFGFy16Q2OhoBizb3X2DrxaJwXSEujVvjG9Jt386dpQn2t7jINglQl0b4K/Su69BdbMA=="], - "@smithy/middleware-retry": ["@smithy/middleware-retry@4.4.31", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.8", "@smithy/protocol-http": "^5.3.8", "@smithy/service-error-classification": "^4.2.8", "@smithy/smithy-client": "^4.11.3", "@smithy/types": "^4.12.0", "@smithy/util-middleware": "^4.2.8", "@smithy/util-retry": "^4.2.8", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-RXBzLpMkIrxBPe4C8OmEOHvS8aH9RUuCOH++Acb5jZDEblxDjyg6un72X9IcbrGTJoiUwmI7hLypNfuDACypbg=="], + "@smithy/middleware-retry": ["@smithy/middleware-retry@4.4.33", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.8", "@smithy/protocol-http": "^5.3.8", "@smithy/service-error-classification": "^4.2.8", "@smithy/smithy-client": "^4.11.5", "@smithy/types": "^4.12.0", "@smithy/util-middleware": "^4.2.8", "@smithy/util-retry": "^4.2.8", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-jLqZOdJhtIL4lnA9hXnAG6GgnJlo1sD3FqsTxm9wSfjviqgWesY/TMBVnT84yr4O0Vfe0jWoXlfFbzsBVph3WA=="], "@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.9", "", { "dependencies": { "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-eMNiej0u/snzDvlqRGSN3Vl0ESn3838+nKyVfF2FKNXFbi4SERYT6PR392D39iczngbqqGG0Jl1DlCnp7tBbXQ=="], @@ -1665,7 +1678,7 @@ "@smithy/signature-v4": ["@smithy/signature-v4@5.3.8", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.8", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-6A4vdGj7qKNRF16UIcO8HhHjKW27thsxYci+5r/uVRkdcBEkOEiY8OMPuydLX4QHSrJqGHPJzPRwwVTqbLZJhg=="], - "@smithy/smithy-client": ["@smithy/smithy-client@4.11.3", "", { "dependencies": { "@smithy/core": "^3.23.0", "@smithy/middleware-endpoint": "^4.4.14", "@smithy/middleware-stack": "^4.2.8", "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "@smithy/util-stream": "^4.5.12", "tslib": "^2.6.2" } }, "sha512-Q7kY5sDau8OoE6Y9zJoRGgje8P4/UY0WzH8R2ok0PDh+iJ+ZnEKowhjEqYafVcubkbYxQVaqwm3iufktzhprGg=="], + "@smithy/smithy-client": ["@smithy/smithy-client@4.11.5", "", { "dependencies": { "@smithy/core": "^3.23.2", "@smithy/middleware-endpoint": "^4.4.16", "@smithy/middleware-stack": "^4.2.8", "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "@smithy/util-stream": "^4.5.12", "tslib": "^2.6.2" } }, "sha512-xixwBRqoeP2IUgcAl3U9dvJXc+qJum4lzo3maaJxifsZxKUYLfVfCXvhT4/jD01sRrHg5zjd1cw2Zmjr4/SuKQ=="], "@smithy/types": ["@smithy/types@4.12.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-9YcuJVTOBDjg9LWo23Qp0lTQ3D7fQsQtwle0jVfpbUHy9qBwCEgKuVH4FqFB3VYu0nwdHKiEMA+oXz7oV8X1kw=="], @@ -1681,9 +1694,9 @@ "@smithy/util-config-provider": ["@smithy/util-config-provider@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q=="], - "@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.3.30", "", { "dependencies": { "@smithy/property-provider": "^4.2.8", "@smithy/smithy-client": "^4.11.3", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-cMni0uVU27zxOiU8TuC8pQLC1pYeZ/xEMxvchSK/ILwleRd1ugobOcIRr5vXtcRqKd4aBLWlpeBoDPJJ91LQng=="], + "@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.3.32", "", { "dependencies": { "@smithy/property-provider": "^4.2.8", "@smithy/smithy-client": "^4.11.5", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-092sjYfFMQ/iaPH798LY/OJFBcYu0sSK34Oy9vdixhsU36zlZu8OcYjF3TD4e2ARupyK7xaxPXl+T0VIJTEkkg=="], - "@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.2.33", "", { "dependencies": { "@smithy/config-resolver": "^4.4.6", "@smithy/credential-provider-imds": "^4.2.8", "@smithy/node-config-provider": "^4.3.8", "@smithy/property-provider": "^4.2.8", "@smithy/smithy-client": "^4.11.3", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-LEb2aq5F4oZUSzWBG7S53d4UytZSkOEJPXcBq/xbG2/TmK9EW5naUZ8lKu1BEyWMzdHIzEVN16M3k8oxDq+DJA=="], + "@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.2.35", "", { "dependencies": { "@smithy/config-resolver": "^4.4.6", "@smithy/credential-provider-imds": "^4.2.8", "@smithy/node-config-provider": "^4.3.8", "@smithy/property-provider": "^4.2.8", "@smithy/smithy-client": "^4.11.5", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-miz/ggz87M8VuM29y7jJZMYkn7+IErM5p5UgKIf8OtqVs/h2bXr1Bt3uTsREsI/4nK8a0PQERbAPsVPVNIsG7Q=="], "@smithy/util-endpoints": ["@smithy/util-endpoints@3.2.8", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-8JaVTn3pBDkhZgHQ8R0epwWt+BqPSLCjdjXXusK1onwJlRuN69fbvSK66aIKKO7SwVFM6x2J2ox5X8pOaWcUEw=="], @@ -1917,6 +1930,8 @@ "@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=="], + "@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="], "@types/mssql": ["@types/mssql@9.1.9", "", { "dependencies": { "@types/node": "*", "tarn": "^3.0.1", "tedious": "*" } }, "sha512-P0nCgw6vzY23UxZMnbI4N7fnLGANt4LI4yvxze1paPj+LuN28cFv5EI+QidP8udnId/BKhkcRhm/BleNsjK65A=="], @@ -1983,7 +1998,7 @@ "@typescript/native-preview-win32-x64": ["@typescript/native-preview-win32-x64@7.0.0-dev.20251207.1", "", { "os": "win32", "cpu": "x64" }, "sha512-5l51HlXjX7lXwo65DEl1IaCFLjmkMtL6K3NrSEamPNeNTtTQwZRa3pQ9V65dCglnnCQ0M3+VF1RqzC7FU0iDKg=="], - "@typescript/vfs": ["@typescript/vfs@1.6.2", "", { "dependencies": { "debug": "^4.1.1" }, "peerDependencies": { "typescript": "*" } }, "sha512-hoBwJwcbKHmvd2QVebiytN1aELvpk9B74B4L1mFm/XT1Q/VOYAWl2vQ9AWRFtQq8zmz6enTpfTV8WRc4ATjW/g=="], + "@typescript/vfs": ["@typescript/vfs@1.6.4", "", { "dependencies": { "debug": "^4.4.3" }, "peerDependencies": { "typescript": "*" } }, "sha512-PJFXFS4ZJKiJ9Qiuix6Dz/OwEIqHD7Dme1UwZhTK11vR+5dqW2ACbdndWQexBzCx+CPuMe5WBYQWCsFyGlQLlQ=="], "@typespec/ts-http-runtime": ["@typespec/ts-http-runtime@0.3.3", "", { "dependencies": { "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.0", "tslib": "^2.6.2" } }, "sha512-91fp6CAAJSRtH5ja95T1FHSKa8aPW9/Zw6cta81jlZTUw/+Vq8jM/AfF/14h2b71wwR84JUTW/3Y8QPhDAawFA=="], @@ -2049,7 +2064,7 @@ "ai-gateway-provider": ["ai-gateway-provider@2.3.1", "", { "dependencies": { "@ai-sdk/provider": "^2.0.0", "@ai-sdk/provider-utils": "^3.0.19", "ai": "^5.0.116" }, "optionalDependencies": { "@ai-sdk/amazon-bedrock": "^3.0.71", "@ai-sdk/anthropic": "^2.0.56", "@ai-sdk/azure": "^2.0.90", "@ai-sdk/cerebras": "^1.0.33", "@ai-sdk/cohere": "^2.0.21", "@ai-sdk/deepgram": "^1.0.21", "@ai-sdk/deepseek": "^1.0.32", "@ai-sdk/elevenlabs": "^1.0.21", "@ai-sdk/fireworks": "^1.0.30", "@ai-sdk/google": "^2.0.51", "@ai-sdk/google-vertex": "3.0.90", "@ai-sdk/groq": "^2.0.33", "@ai-sdk/mistral": "^2.0.26", "@ai-sdk/openai": "^2.0.88", "@ai-sdk/perplexity": "^2.0.22", "@ai-sdk/xai": "^2.0.42", "@openrouter/ai-sdk-provider": "^1.5.3" }, "peerDependencies": { "@ai-sdk/openai-compatible": "^1.0.29" } }, "sha512-PqI6TVNEDNwr7kOhy7XUGnA8XJB1SpeA9aLqGjr0CyWkKgH+y+ofPm8MZGZ74DOwVejDF+POZq0Qs9jKEKUeYg=="], - "ajv": ["ajv@8.17.1", "", { "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-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="], + "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=="], @@ -2131,11 +2146,11 @@ "axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="], - "b4a": ["b4a@1.7.4", "", { "peerDependencies": { "react-native-b4a": "*" }, "optionalPeers": ["react-native-b4a"] }, "sha512-u20zJLDaSWpxaZ+zaAkEIB2dZZ1o+DF4T/MRbmsvGp9nletHOyiai19OzX1fF8xUBYsO1bPXxODvcd0978pnug=="], + "b4a": ["b4a@1.7.5", "", { "peerDependencies": { "react-native-b4a": "*" }, "optionalPeers": ["react-native-b4a"] }, "sha512-iEsKNwDh1wiWTps1/hdkNdmBgDlDVZP5U57ZVOlt+dNFqpc/lpPouCIxZw+DYBgc4P9NDfIZMPNR4CHNhzwLIA=="], "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.3", "", { "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-5HOwwt0BYiv/zxl7j8Pf2bGL6rDXfV6nUhLs8ygBX+EFJXzBPHM/euj9j/6deMZ6wa52Wb2PBaAV5U/jKwIY1w=="], + "babel-plugin-jsx-dom-expressions": ["babel-plugin-jsx-dom-expressions@0.40.5", "", { "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-8TFKemVLDYezqqv4mWz+PhRrkryTzivTGu0twyLrOkVZ0P63COx2Y04eVsUjFlwSOXui1z3P3Pn209dokWnirg=="], "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=="], @@ -2211,13 +2226,13 @@ "bun-webgpu": ["bun-webgpu@0.1.4", "", { "dependencies": { "@webgpu/types": "^0.1.60" }, "optionalDependencies": { "bun-webgpu-darwin-arm64": "^0.1.4", "bun-webgpu-darwin-x64": "^0.1.4", "bun-webgpu-linux-x64": "^0.1.4", "bun-webgpu-win32-x64": "^0.1.4" } }, "sha512-Kw+HoXl1PMWJTh9wvh63SSRofTA8vYBFCw0XEP1V1fFdQEDhI8Sgf73sdndE/oDpN/7CMx0Yv/q8FCvO39ROMQ=="], - "bun-webgpu-darwin-arm64": ["bun-webgpu-darwin-arm64@0.1.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-eDgLN9teKTfmvrCqgwwmWNsNszxYs7IZdCqk0S1DCarvMhr4wcajoSBlA/nQA0/owwLduPTS8xxCnQp4/N/gDg=="], + "bun-webgpu-darwin-arm64": ["bun-webgpu-darwin-arm64@0.1.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-qM7W5IaFpWYGPDcNiQ8DOng3noQ97gxpH2MFH1mGsdKwI0T4oy++egSh5Z7s6AQx8WKgc9GzAsTUM4KZkFdacw=="], - "bun-webgpu-darwin-x64": ["bun-webgpu-darwin-x64@0.1.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-X+PjwJUWenUmdQBP8EtdItMyieQ6Nlpn+BH518oaouDiSnWj5+b0Y7DNDZJq7Ezom4EaxmqL/uGYZK3aCQ7CXg=="], + "bun-webgpu-darwin-x64": ["bun-webgpu-darwin-x64@0.1.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-oVoIsme27pcXB68YxnQSAgdNGCa4A3PGWYIBUewOh9VnJaoik4JenGb5Yy+svGE+ETFhQXV9nhHqgMPsDRrO6A=="], - "bun-webgpu-linux-x64": ["bun-webgpu-linux-x64@0.1.4", "", { "os": "linux", "cpu": "x64" }, "sha512-zMLs2YIGB+/jxrYFXaFhVKX/GBt05UTF45lc9srcHc9JXGjEj+12CIo1CHLTAWatXMTqt0Jsu6ukWEoWVT/ayA=="], + "bun-webgpu-linux-x64": ["bun-webgpu-linux-x64@0.1.5", "", { "os": "linux", "cpu": "x64" }, "sha512-+SYt09k+xDEl/GfcU7L1zdNgm7IlvAFKV5Xl/auBwuprKG5UwXNhjRlRAWfhTMCUZWN+NDf8E+ZQx0cQi9K2/g=="], - "bun-webgpu-win32-x64": ["bun-webgpu-win32-x64@0.1.4", "", { "os": "win32", "cpu": "x64" }, "sha512-Z5yAK28xrcm8Wb5k7TZ8FJKpOI/r+aVCRdlHYAqI2SDJFN3nD4mJs900X6kNVmG/xFzb5yOuKVYWGg+6ZXWbyA=="], + "bun-webgpu-win32-x64": ["bun-webgpu-win32-x64@0.1.5", "", { "os": "win32", "cpu": "x64" }, "sha512-zvnUl4EAsQbKsmZVu+lEJcH8axQ7MiCfqg2OmnHd6uw1THABmHaX0GbpKiHshdgadNN2Nf+4zDyTJB5YMcAdrA=="], "bundle-name": ["bundle-name@4.1.0", "", { "dependencies": { "run-applescript": "^7.0.0" } }, "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q=="], @@ -2237,7 +2252,7 @@ "camelcase-css": ["camelcase-css@2.0.1", "", {}, "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA=="], - "caniuse-lite": ["caniuse-lite@1.0.30001769", "", {}, "sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg=="], + "caniuse-lite": ["caniuse-lite@1.0.30001770", "", {}, "sha512-x/2CLQ1jHENRbHg5PSId2sXq1CIO1CISvwWAj027ltMVG2UNgW+w9oH2+HzgEIRFembL8bUlXtfbBHR1fCg2xw=="], "ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="], @@ -2471,7 +2486,7 @@ "enhanced-resolve": ["enhanced-resolve@5.19.0", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.0" } }, "sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg=="], - "entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="], + "entities": ["entities@7.0.1", "", {}, "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA=="], "error-stack-parser": ["error-stack-parser@2.1.4", "", { "dependencies": { "stackframe": "^1.3.4" } }, "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ=="], @@ -2707,7 +2722,7 @@ "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.6.1", "", { "dependencies": { "@types/node": ">=20.0.0", "@types/whatwg-mimetype": "^3.0.2", "@types/ws": "^8.18.1", "entities": "^6.0.1", "whatwg-mimetype": "^3.0.0", "ws": "^8.18.3" } }, "sha512-+0vhESXXhFwkdjZnJ5DlmJIfUYGgIEEjzIjB+aKJbFuqlvvKyOi+XkI1fYbgYR9QCxG5T08koxsQ6HrQfa5gCQ=="], + "happy-dom": ["happy-dom@20.6.2", "", { "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-Xk/Y0cuq9ngN/my8uvK4gKoyDl6sBKkIl8A/hJ0IabZVH7E5SJLHNE7uKRPVmSrQbhJaLIHTEcvTct4GgNtsRA=="], "has-bigints": ["has-bigints@1.1.0", "", {}, "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg=="], @@ -2919,7 +2934,7 @@ "is-whitespace": ["is-whitespace@0.3.0", "", {}, "sha512-RydPhl4S6JwAyj0JJjshWJEFG6hNye3pZFBRZaTUfZFwGHxzppNaNOVgQuS/E/SlhrApuMXrpnK1EEIXfdo3Dg=="], - "is-wsl": ["is-wsl@3.1.0", "", { "dependencies": { "is-inside-container": "^1.0.0" } }, "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw=="], + "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=="], @@ -3497,7 +3512,7 @@ "punycode": ["punycode@1.3.2", "", {}, "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw=="], - "qs": ["qs@6.14.2", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q=="], + "qs": ["qs@6.15.0", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ=="], "quansync": ["quansync@0.2.11", "", {}, "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA=="], @@ -3759,23 +3774,23 @@ "srvx": ["srvx@0.9.8", "", { "bin": { "srvx": "bin/srvx.mjs" } }, "sha512-RZaxTKJEE/14HYn8COLuUOJAt0U55N9l1Xf6jj+T0GoA01EUH1Xz5JtSUOI+EHn+AEgPCVn7gk6jHJffrr06fQ=="], - "sst": ["sst@3.17.23", "", { "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.17.23", "sst-darwin-x64": "3.17.23", "sst-linux-arm64": "3.17.23", "sst-linux-x64": "3.17.23", "sst-linux-x86": "3.17.23", "sst-win32-arm64": "3.17.23", "sst-win32-x64": "3.17.23", "sst-win32-x86": "3.17.23" }, "bin": { "sst": "bin/sst.mjs" } }, "sha512-TwKgUgDnZdc1Swe+bvCNeyO4dQnYz5cTodMpYj3jlXZdK9/KNz0PVxT1f0u5E76i1pmilXrUBL/f7iiMPw4RDg=="], + "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=="], - "sst-darwin-arm64": ["sst-darwin-arm64@3.17.23", "", { "os": "darwin", "cpu": "arm64" }, "sha512-R6kvmF+rUideOoU7KBs2SdvrIupoE+b+Dor/eq9Uo4Dojj7KvYDZI/EDm8sSCbbcx/opiWeyNqKtlnLEdCxE6g=="], + "sst-darwin-arm64": ["sst-darwin-arm64@3.18.10", "", { "os": "darwin", "cpu": "arm64" }, "sha512-N3MwIpMZhhdZKDqLp9ZQNlwkWix5+q+N0PWstuTomYwgZOxCCe6u9IIsoIszSk+GAJJN/jvGZyLiXKeV4iiQvw=="], - "sst-darwin-x64": ["sst-darwin-x64@3.17.23", "", { "os": "darwin", "cpu": "x64" }, "sha512-WW4P1S35iYCifQXxD+sE3wuzcN+LHLpuKMaNoaBqEcWGZnH3IPaDJ7rpLF0arkDAo/z3jZmWWzOCkr0JuqJ8vQ=="], + "sst-darwin-x64": ["sst-darwin-x64@3.18.10", "", { "os": "darwin", "cpu": "x64" }, "sha512-nQ0jMKkPOa+kj6Ygz8+kYhBua/vgNTLkd+4r8NSmk7v+Zs78lKnx3T//kEzS0yik6Q6QwGfokwrTcA1Jii2xSw=="], - "sst-linux-arm64": ["sst-linux-arm64@3.17.23", "", { "os": "linux", "cpu": "arm64" }, "sha512-TjtNqgIh7RlAWgPLFCAt0mXvIB+J7WjmRvIRrAdX0mXsndOiBJ/DMOgXSLVsIWHCfPj8MIEot/hWpnJgXgIeag=="], + "sst-linux-arm64": ["sst-linux-arm64@3.18.10", "", { "os": "linux", "cpu": "arm64" }, "sha512-mj9VNj3SvLS+HaXx2PhCX0aTA7CwJNoM6JhRc0s/zCilqchcvqDjbhpYBJO4brEPv6aOaaa7T3WvIQqtYauK4Q=="], - "sst-linux-x64": ["sst-linux-x64@3.17.23", "", { "os": "linux", "cpu": "x64" }, "sha512-qdqJiEbYfCjZlI3F/TA6eoIU7JXVkEEI/UMILNf2JWhky0KQdCW2Xyz+wb6c0msVJCWdUM/uj+1DaiP2eXvghw=="], + "sst-linux-x64": ["sst-linux-x64@3.18.10", "", { "os": "linux", "cpu": "x64" }, "sha512-7iy1Eq2eqnT9Ag/8OVgC04vRjV7AAQyf/BvzLc+6Sz+GvRiKA8VEuPnbXNYQF+NIvEqsawfcd7MknSTtImpsvQ=="], - "sst-linux-x86": ["sst-linux-x86@3.17.23", "", { "os": "linux", "cpu": "none" }, "sha512-aGmUujIvoNlmAABEGsOgfY1rxD9koC6hN8bnTLbDI+oI/u/zjHYh50jsbL0p3TlaHpwF/lxP3xFSuT6IKp+KgA=="], + "sst-linux-x86": ["sst-linux-x86@3.18.10", "", { "os": "linux", "cpu": "none" }, "sha512-77qZSuPZeQ5bdRCiq1pQEdY8EcGNHboKrx4P2yFid2FBDKJsXxOXtIxJdloyx+ljBn0+nxl/g040QBmXxdc9tA=="], - "sst-win32-arm64": ["sst-win32-arm64@3.17.23", "", { "os": "win32", "cpu": "arm64" }, "sha512-ZxdkGqYDrrZGz98rijDCN+m5yuCcwD6Bc9/6hubLsvdpNlVorUqzpg801Ec97xSK0nIC9g6pNiRyxAcsQQstUg=="], + "sst-win32-arm64": ["sst-win32-arm64@3.18.10", "", { "os": "win32", "cpu": "arm64" }, "sha512-aY+FhMxvYs8crlrKALpLn/kKmud8YQj6LkMHsrOAAIJhfNyxhCja2vrYQaY+bcqdsS5W2LMVcS2hyaMqKXZKcg=="], - "sst-win32-x64": ["sst-win32-x64@3.17.23", "", { "os": "win32", "cpu": "x64" }, "sha512-yc9cor4MS49Ccy2tQCF1tf6M81yLeSGzGL+gjhUxpVKo2pN3bxl3w70eyU/mTXSEeyAmG9zEfbt6FNu4sy5cUA=="], + "sst-win32-x64": ["sst-win32-x64@3.18.10", "", { "os": "win32", "cpu": "x64" }, "sha512-rY+yJXOpG+P5xXnaQRpCvBK2zwwLhjzpYidGkp6F+cGgiVdh2Wre/CIQNRaVHr20ncj8lLe/RsHWa9QCNM48jg=="], - "sst-win32-x86": ["sst-win32-x86@3.17.23", "", { "os": "win32", "cpu": "none" }, "sha512-DIp3s54IpNAfdYjSRt6McvkbEPQDMxUu6RUeRAd2C+FcTJgTloon/ghAPQBaDgu2VoVgymjcJARO/XyfKcCLOQ=="], + "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=="], @@ -3841,19 +3856,19 @@ "tapable": ["tapable@2.3.0", "", {}, "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg=="], - "tar": ["tar@7.5.7", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.1.0", "yallist": "^5.0.0" } }, "sha512-fov56fJiRuThVFXD6o6/Q354S7pnWMJIVlDBYijsTNx6jKSE4pvrDTs6lUnmGvNyfJwFQQwWy3owKz1ucIhveQ=="], + "tar": ["tar@7.5.9", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.1.0", "yallist": "^5.0.0" } }, "sha512-BTLcK0xsDh2+PUe9F6c2TlRp4zOOBMTkoQHQIWSIzI0R7KG46uEwq4OPk2W7bZcprBMsuaeFsqwYr7pjh6CuHg=="], "tar-stream": ["tar-stream@3.1.7", "", { "dependencies": { "b4a": "^1.6.4", "fast-fifo": "^1.2.0", "streamx": "^2.15.0" } }, "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ=="], "tarn": ["tarn@3.0.2", "", {}, "sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ=="], - "tedious": ["tedious@19.2.1", "", { "dependencies": { "@azure/core-auth": "^1.7.2", "@azure/identity": "^4.2.1", "@azure/keyvault-keys": "^4.4.0", "@js-joda/core": "^5.6.5", "@types/node": ">=18", "bl": "^6.1.4", "iconv-lite": "^0.7.0", "js-md4": "^0.3.2", "native-duplexpair": "^1.0.0", "sprintf-js": "^1.1.3" } }, "sha512-pk1Q16Yl62iocuQB+RWbg6rFUFkIyzqOFQ6NfysCltRvQqKwfurgj8v/f2X+CKvDhSL4IJ0cCOfCHDg9PWEEYA=="], + "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=="], "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.0", "", { "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-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg=="], - "text-decoder": ["text-decoder@1.2.4", "", { "dependencies": { "b4a": "^1.6.4" } }, "sha512-mzlffA3tBNhziEHPK5L5InZg1d/ElNIpJhnhbDRNUtem/edZcJ5zg5FgwKKKOyklxk+6Jt+TrSu83musmvrDlg=="], + "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=="], @@ -3961,7 +3976,7 @@ "uncrypto": ["uncrypto@0.1.3", "", {}, "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q=="], - "undici": ["undici@7.21.0", "", {}, "sha512-Hn2tCQpoDt1wv23a68Ctc8Cr/BHpUSfaPYrkajTXOS9IKpxVRx/X5m1K2YkbK2ipgZgxXSgsUinl3x+2YdSSfg=="], + "undici": ["undici@7.22.0", "", {}, "sha512-RqslV2Us5BrllB+JeiZnK4peryVTndy9Dnqq62S3yYRRTj0tFQCwEniUy2167skdGOy3vqRzEvl1Dm4sV2ReDg=="], "undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], @@ -4127,7 +4142,7 @@ "xml-parse-from-string": ["xml-parse-from-string@1.0.1", "", {}, "sha512-ErcKwJTF54uRzzNMXq2X5sMIy88zJvfN2DmdoQvy7PAFJ+tPRU6ydWuOKNMyfmOjdyBQTFREi60s0Y0SyI0G0g=="], - "xml2js": ["xml2js@0.6.2", "", { "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" } }, "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA=="], + "xml2js": ["xml2js@0.5.0", "", { "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" } }, "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA=="], "xmlbuilder": ["xmlbuilder@11.0.1", "", {}, "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="], @@ -4247,6 +4262,48 @@ "@aws-crypto/util/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="], + "@aws-sdk/client-cognito-identity/@aws-sdk/core": ["@aws-sdk/core@3.973.11", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@aws-sdk/xml-builder": "^3.972.5", "@smithy/core": "^3.23.2", "@smithy/node-config-provider": "^4.3.8", "@smithy/property-provider": "^4.2.8", "@smithy/protocol-http": "^5.3.8", "@smithy/signature-v4": "^5.3.8", "@smithy/smithy-client": "^4.11.5", "@smithy/types": "^4.12.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-wdQ8vrvHkKIV7yNUKXyjPWKCdYEUrZTHJ8Ojd5uJxXp9vqPCkUR1dpi1NtOLcrDgueJH7MUH5lQZxshjFPSbDA=="], + + "@aws-sdk/client-cognito-identity/@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.972.10", "", { "dependencies": { "@aws-sdk/credential-provider-env": "^3.972.9", "@aws-sdk/credential-provider-http": "^3.972.11", "@aws-sdk/credential-provider-ini": "^3.972.9", "@aws-sdk/credential-provider-process": "^3.972.9", "@aws-sdk/credential-provider-sso": "^3.972.9", "@aws-sdk/credential-provider-web-identity": "^3.972.9", "@aws-sdk/types": "^3.973.1", "@smithy/credential-provider-imds": "^4.2.8", "@smithy/property-provider": "^4.2.8", "@smithy/shared-ini-file-loader": "^4.4.3", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-70nCESlvnzjo4LjJ8By8MYIiBogkYPSXl3WmMZfH9RZcB/Nt9qVWbFpYj6Fk1vLa4Vk8qagFVeXgxdieMxG1QA=="], + + "@aws-sdk/client-cognito-identity/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.972.3", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-aknPTb2M+G3s+0qLCx4Li/qGZH8IIYjugHMv15JTYMe6mgZO8VBpYgeGYsNMGCqCZOcWzuf900jFBG5bopfzmA=="], + + "@aws-sdk/client-cognito-identity/@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.972.3", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-Ftg09xNNRqaz9QNzlfdQWfpqMCJbsQdnZVJP55jfhbKi1+FTWxGuvfPoBhDHIovqWKjqbuiew3HuhxbJ0+OjgA=="], + + "@aws-sdk/client-cognito-identity/@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.972.3", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-PY57QhzNuXHnwbJgbWYTrqIDHYSeOlhfYERTAuc16LKZpTZRJUjzBFokp9hF7u1fuGeE3D70ERXzdbMBOqQz7Q=="], + + "@aws-sdk/client-cognito-identity/@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.972.11", "", { "dependencies": { "@aws-sdk/core": "^3.973.11", "@aws-sdk/types": "^3.973.1", "@aws-sdk/util-endpoints": "3.993.0", "@smithy/core": "^3.23.2", "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-R8CvPsPHXwzIHCAza+bllY6PrctEk4lYq/SkHJz9NLoBHCcKQrbOcsfXxO6xmipSbUNIbNIUhH0lBsJGgsRdiw=="], + + "@aws-sdk/client-cognito-identity/@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.972.3", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@smithy/config-resolver": "^4.4.6", "@smithy/node-config-provider": "^4.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-v4J8qYAWfOMcZ4MJUyatntOicTzEMaU7j3OpkRCGGFSL2NgXQ5VbxauIyORA+pxdKZ0qQG2tCQjQjZDlXEC3Ow=="], + + "@aws-sdk/client-cognito-identity/@aws-sdk/types": ["@aws-sdk/types@3.973.1", "", { "dependencies": { "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-DwHBiMNOB468JiX6+i34c+THsKHErYUdNQ3HexeXZvVn4zouLjgaS4FejiGSi2HyBuzuyHg7SuOPmjSvoU9NRg=="], + + "@aws-sdk/client-cognito-identity/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.993.0", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-endpoints": "^3.2.8", "tslib": "^2.6.2" } }, "sha512-j6vioBeRZ4eHX4SWGvGPpwGg/xSOcK7f1GL0VM+rdf3ZFTIsUEhCFmD78B+5r2PgztcECSzEfvHQX01k8dPQPw=="], + + "@aws-sdk/client-cognito-identity/@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.972.3", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@smithy/types": "^4.12.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-JurOwkRUcXD/5MTDBcqdyQ9eVedtAsZgw5rBwktsPTN7QtPiS2Ld1jkJepNgYoCufz1Wcut9iup7GJDoIHp8Fw=="], + + "@aws-sdk/client-cognito-identity/@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.972.9", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "^3.972.11", "@aws-sdk/types": "^3.973.1", "@smithy/node-config-provider": "^4.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-JNswdsLdQemxqaSIBL2HRhsHPUBBziAgoi5RQv6/9avmE5g5RSdt1hWr3mHJ7OxqRYf+KeB11ExWbiqfrnoeaA=="], + + "@aws-sdk/client-sso/@aws-sdk/core": ["@aws-sdk/core@3.973.11", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@aws-sdk/xml-builder": "^3.972.5", "@smithy/core": "^3.23.2", "@smithy/node-config-provider": "^4.3.8", "@smithy/property-provider": "^4.2.8", "@smithy/protocol-http": "^5.3.8", "@smithy/signature-v4": "^5.3.8", "@smithy/smithy-client": "^4.11.5", "@smithy/types": "^4.12.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-wdQ8vrvHkKIV7yNUKXyjPWKCdYEUrZTHJ8Ojd5uJxXp9vqPCkUR1dpi1NtOLcrDgueJH7MUH5lQZxshjFPSbDA=="], + + "@aws-sdk/client-sso/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.972.3", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-aknPTb2M+G3s+0qLCx4Li/qGZH8IIYjugHMv15JTYMe6mgZO8VBpYgeGYsNMGCqCZOcWzuf900jFBG5bopfzmA=="], + + "@aws-sdk/client-sso/@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.972.3", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-Ftg09xNNRqaz9QNzlfdQWfpqMCJbsQdnZVJP55jfhbKi1+FTWxGuvfPoBhDHIovqWKjqbuiew3HuhxbJ0+OjgA=="], + + "@aws-sdk/client-sso/@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.972.3", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-PY57QhzNuXHnwbJgbWYTrqIDHYSeOlhfYERTAuc16LKZpTZRJUjzBFokp9hF7u1fuGeE3D70ERXzdbMBOqQz7Q=="], + + "@aws-sdk/client-sso/@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.972.11", "", { "dependencies": { "@aws-sdk/core": "^3.973.11", "@aws-sdk/types": "^3.973.1", "@aws-sdk/util-endpoints": "3.993.0", "@smithy/core": "^3.23.2", "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-R8CvPsPHXwzIHCAza+bllY6PrctEk4lYq/SkHJz9NLoBHCcKQrbOcsfXxO6xmipSbUNIbNIUhH0lBsJGgsRdiw=="], + + "@aws-sdk/client-sso/@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.972.3", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@smithy/config-resolver": "^4.4.6", "@smithy/node-config-provider": "^4.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-v4J8qYAWfOMcZ4MJUyatntOicTzEMaU7j3OpkRCGGFSL2NgXQ5VbxauIyORA+pxdKZ0qQG2tCQjQjZDlXEC3Ow=="], + + "@aws-sdk/client-sso/@aws-sdk/types": ["@aws-sdk/types@3.973.1", "", { "dependencies": { "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-DwHBiMNOB468JiX6+i34c+THsKHErYUdNQ3HexeXZvVn4zouLjgaS4FejiGSi2HyBuzuyHg7SuOPmjSvoU9NRg=="], + + "@aws-sdk/client-sso/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.993.0", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-endpoints": "^3.2.8", "tslib": "^2.6.2" } }, "sha512-j6vioBeRZ4eHX4SWGvGPpwGg/xSOcK7f1GL0VM+rdf3ZFTIsUEhCFmD78B+5r2PgztcECSzEfvHQX01k8dPQPw=="], + + "@aws-sdk/client-sso/@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.972.3", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@smithy/types": "^4.12.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-JurOwkRUcXD/5MTDBcqdyQ9eVedtAsZgw5rBwktsPTN7QtPiS2Ld1jkJepNgYoCufz1Wcut9iup7GJDoIHp8Fw=="], + + "@aws-sdk/client-sso/@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.972.9", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "^3.972.11", "@aws-sdk/types": "^3.973.1", "@smithy/node-config-provider": "^4.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-JNswdsLdQemxqaSIBL2HRhsHPUBBziAgoi5RQv6/9avmE5g5RSdt1hWr3mHJ7OxqRYf+KeB11ExWbiqfrnoeaA=="], + "@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=="], @@ -4269,6 +4326,80 @@ "@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/credential-provider-cognito-identity/@aws-sdk/client-cognito-identity": ["@aws-sdk/client-cognito-identity@3.980.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.5", "@aws-sdk/credential-provider-node": "^3.972.4", "@aws-sdk/middleware-host-header": "^3.972.3", "@aws-sdk/middleware-logger": "^3.972.3", "@aws-sdk/middleware-recursion-detection": "^3.972.3", "@aws-sdk/middleware-user-agent": "^3.972.5", "@aws-sdk/region-config-resolver": "^3.972.3", "@aws-sdk/types": "^3.973.1", "@aws-sdk/util-endpoints": "3.980.0", "@aws-sdk/util-user-agent-browser": "^3.972.3", "@aws-sdk/util-user-agent-node": "^3.972.3", "@smithy/config-resolver": "^4.4.6", "@smithy/core": "^3.22.0", "@smithy/fetch-http-handler": "^5.3.9", "@smithy/hash-node": "^4.2.8", "@smithy/invalid-dependency": "^4.2.8", "@smithy/middleware-content-length": "^4.2.8", "@smithy/middleware-endpoint": "^4.4.12", "@smithy/middleware-retry": "^4.4.29", "@smithy/middleware-serde": "^4.2.9", "@smithy/middleware-stack": "^4.2.8", "@smithy/node-config-provider": "^4.3.8", "@smithy/node-http-handler": "^4.4.8", "@smithy/protocol-http": "^5.3.8", "@smithy/smithy-client": "^4.11.1", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@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.28", "@smithy/util-defaults-mode-node": "^4.2.31", "@smithy/util-endpoints": "^3.2.8", "@smithy/util-middleware": "^4.2.8", "@smithy/util-retry": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-nLgMW2drTzv+dTo3ORCcotQPcrUaTQ+xoaDTdSaUXdZO7zbbVyk7ysE5GDTnJdZWcUjHOSB8xfNQhOTTNVPhFw=="], + + "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/types": ["@aws-sdk/types@3.973.1", "", { "dependencies": { "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-DwHBiMNOB468JiX6+i34c+THsKHErYUdNQ3HexeXZvVn4zouLjgaS4FejiGSi2HyBuzuyHg7SuOPmjSvoU9NRg=="], + + "@aws-sdk/credential-provider-env/@aws-sdk/core": ["@aws-sdk/core@3.973.11", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@aws-sdk/xml-builder": "^3.972.5", "@smithy/core": "^3.23.2", "@smithy/node-config-provider": "^4.3.8", "@smithy/property-provider": "^4.2.8", "@smithy/protocol-http": "^5.3.8", "@smithy/signature-v4": "^5.3.8", "@smithy/smithy-client": "^4.11.5", "@smithy/types": "^4.12.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-wdQ8vrvHkKIV7yNUKXyjPWKCdYEUrZTHJ8Ojd5uJxXp9vqPCkUR1dpi1NtOLcrDgueJH7MUH5lQZxshjFPSbDA=="], + + "@aws-sdk/credential-provider-env/@aws-sdk/types": ["@aws-sdk/types@3.973.1", "", { "dependencies": { "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-DwHBiMNOB468JiX6+i34c+THsKHErYUdNQ3HexeXZvVn4zouLjgaS4FejiGSi2HyBuzuyHg7SuOPmjSvoU9NRg=="], + + "@aws-sdk/credential-provider-http/@aws-sdk/core": ["@aws-sdk/core@3.973.11", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@aws-sdk/xml-builder": "^3.972.5", "@smithy/core": "^3.23.2", "@smithy/node-config-provider": "^4.3.8", "@smithy/property-provider": "^4.2.8", "@smithy/protocol-http": "^5.3.8", "@smithy/signature-v4": "^5.3.8", "@smithy/smithy-client": "^4.11.5", "@smithy/types": "^4.12.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-wdQ8vrvHkKIV7yNUKXyjPWKCdYEUrZTHJ8Ojd5uJxXp9vqPCkUR1dpi1NtOLcrDgueJH7MUH5lQZxshjFPSbDA=="], + + "@aws-sdk/credential-provider-http/@aws-sdk/types": ["@aws-sdk/types@3.973.1", "", { "dependencies": { "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-DwHBiMNOB468JiX6+i34c+THsKHErYUdNQ3HexeXZvVn4zouLjgaS4FejiGSi2HyBuzuyHg7SuOPmjSvoU9NRg=="], + + "@aws-sdk/credential-provider-ini/@aws-sdk/core": ["@aws-sdk/core@3.973.11", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@aws-sdk/xml-builder": "^3.972.5", "@smithy/core": "^3.23.2", "@smithy/node-config-provider": "^4.3.8", "@smithy/property-provider": "^4.2.8", "@smithy/protocol-http": "^5.3.8", "@smithy/signature-v4": "^5.3.8", "@smithy/smithy-client": "^4.11.5", "@smithy/types": "^4.12.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-wdQ8vrvHkKIV7yNUKXyjPWKCdYEUrZTHJ8Ojd5uJxXp9vqPCkUR1dpi1NtOLcrDgueJH7MUH5lQZxshjFPSbDA=="], + + "@aws-sdk/credential-provider-ini/@aws-sdk/types": ["@aws-sdk/types@3.973.1", "", { "dependencies": { "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-DwHBiMNOB468JiX6+i34c+THsKHErYUdNQ3HexeXZvVn4zouLjgaS4FejiGSi2HyBuzuyHg7SuOPmjSvoU9NRg=="], + + "@aws-sdk/credential-provider-login/@aws-sdk/core": ["@aws-sdk/core@3.973.11", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@aws-sdk/xml-builder": "^3.972.5", "@smithy/core": "^3.23.2", "@smithy/node-config-provider": "^4.3.8", "@smithy/property-provider": "^4.2.8", "@smithy/protocol-http": "^5.3.8", "@smithy/signature-v4": "^5.3.8", "@smithy/smithy-client": "^4.11.5", "@smithy/types": "^4.12.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-wdQ8vrvHkKIV7yNUKXyjPWKCdYEUrZTHJ8Ojd5uJxXp9vqPCkUR1dpi1NtOLcrDgueJH7MUH5lQZxshjFPSbDA=="], + + "@aws-sdk/credential-provider-login/@aws-sdk/types": ["@aws-sdk/types@3.973.1", "", { "dependencies": { "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-DwHBiMNOB468JiX6+i34c+THsKHErYUdNQ3HexeXZvVn4zouLjgaS4FejiGSi2HyBuzuyHg7SuOPmjSvoU9NRg=="], + + "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.932.0", "", { "dependencies": { "@aws-sdk/core": "3.932.0", "@aws-sdk/types": "3.930.0", "@smithy/property-provider": "^4.2.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-ozge/c7NdHUDyHqro6+P5oHt8wfKSUBN+olttiVfBe9Mw3wBMpPa3gQ0pZnG+gwBkKskBuip2bMR16tqYvUSEA=="], + + "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.932.0", "", { "dependencies": { "@aws-sdk/core": "3.932.0", "@aws-sdk/types": "3.930.0", "@smithy/fetch-http-handler": "^5.3.6", "@smithy/node-http-handler": "^4.4.5", "@smithy/property-provider": "^4.2.5", "@smithy/protocol-http": "^5.3.5", "@smithy/smithy-client": "^4.9.5", "@smithy/types": "^4.9.0", "@smithy/util-stream": "^4.5.6", "tslib": "^2.6.2" } }, "sha512-b6N9Nnlg8JInQwzBkUq5spNaXssM3h3zLxGzpPrnw0nHSIWPJPTbZzA5Ca285fcDUFuKP+qf3qkuqlAjGOdWhg=="], + + "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.933.0", "", { "dependencies": { "@aws-sdk/core": "3.932.0", "@aws-sdk/credential-provider-env": "3.932.0", "@aws-sdk/credential-provider-http": "3.932.0", "@aws-sdk/credential-provider-process": "3.932.0", "@aws-sdk/credential-provider-sso": "3.933.0", "@aws-sdk/credential-provider-web-identity": "3.933.0", "@aws-sdk/nested-clients": "3.933.0", "@aws-sdk/types": "3.930.0", "@smithy/credential-provider-imds": "^4.2.5", "@smithy/property-provider": "^4.2.5", "@smithy/shared-ini-file-loader": "^4.4.0", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-HygGyKuMG5AaGXsmM0d81miWDon55xwalRHB3UmDg3QBhtunbNIoIaWUbNTKuBZXcIN6emeeEZw/YgSMqLc0YA=="], + + "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.932.0", "", { "dependencies": { "@aws-sdk/core": "3.932.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-BodZYKvT4p/Dkm28Ql/FhDdS1+p51bcZeMMu2TRtU8PoMDHnVDhHz27zASEKSZwmhvquxHrZHB0IGuVqjZUtSQ=="], + + "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.933.0", "", { "dependencies": { "@aws-sdk/client-sso": "3.933.0", "@aws-sdk/core": "3.932.0", "@aws-sdk/token-providers": "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-/R1DBR7xNcuZIhS2RirU+P2o8E8/fOk+iLAhbqeSTq+g09fP/F6W7ouFpS5eVE2NIfWG7YBFoVddOhvuqpn51g=="], + + "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@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-c7Eccw2lhFx2/+qJn3g+uIDWRuWi2A6Sz3PVvckFUEzPsP0dPUo19hlvtarwP5GzrsXn0yEPRVhpewsIaSCGaQ=="], + + "@aws-sdk/credential-provider-process/@aws-sdk/core": ["@aws-sdk/core@3.973.11", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@aws-sdk/xml-builder": "^3.972.5", "@smithy/core": "^3.23.2", "@smithy/node-config-provider": "^4.3.8", "@smithy/property-provider": "^4.2.8", "@smithy/protocol-http": "^5.3.8", "@smithy/signature-v4": "^5.3.8", "@smithy/smithy-client": "^4.11.5", "@smithy/types": "^4.12.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-wdQ8vrvHkKIV7yNUKXyjPWKCdYEUrZTHJ8Ojd5uJxXp9vqPCkUR1dpi1NtOLcrDgueJH7MUH5lQZxshjFPSbDA=="], + + "@aws-sdk/credential-provider-process/@aws-sdk/types": ["@aws-sdk/types@3.973.1", "", { "dependencies": { "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-DwHBiMNOB468JiX6+i34c+THsKHErYUdNQ3HexeXZvVn4zouLjgaS4FejiGSi2HyBuzuyHg7SuOPmjSvoU9NRg=="], + + "@aws-sdk/credential-provider-sso/@aws-sdk/core": ["@aws-sdk/core@3.973.11", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@aws-sdk/xml-builder": "^3.972.5", "@smithy/core": "^3.23.2", "@smithy/node-config-provider": "^4.3.8", "@smithy/property-provider": "^4.2.8", "@smithy/protocol-http": "^5.3.8", "@smithy/signature-v4": "^5.3.8", "@smithy/smithy-client": "^4.11.5", "@smithy/types": "^4.12.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-wdQ8vrvHkKIV7yNUKXyjPWKCdYEUrZTHJ8Ojd5uJxXp9vqPCkUR1dpi1NtOLcrDgueJH7MUH5lQZxshjFPSbDA=="], + + "@aws-sdk/credential-provider-sso/@aws-sdk/types": ["@aws-sdk/types@3.973.1", "", { "dependencies": { "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-DwHBiMNOB468JiX6+i34c+THsKHErYUdNQ3HexeXZvVn4zouLjgaS4FejiGSi2HyBuzuyHg7SuOPmjSvoU9NRg=="], + + "@aws-sdk/credential-provider-web-identity/@aws-sdk/core": ["@aws-sdk/core@3.973.11", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@aws-sdk/xml-builder": "^3.972.5", "@smithy/core": "^3.23.2", "@smithy/node-config-provider": "^4.3.8", "@smithy/property-provider": "^4.2.8", "@smithy/protocol-http": "^5.3.8", "@smithy/signature-v4": "^5.3.8", "@smithy/smithy-client": "^4.11.5", "@smithy/types": "^4.12.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-wdQ8vrvHkKIV7yNUKXyjPWKCdYEUrZTHJ8Ojd5uJxXp9vqPCkUR1dpi1NtOLcrDgueJH7MUH5lQZxshjFPSbDA=="], + + "@aws-sdk/credential-provider-web-identity/@aws-sdk/types": ["@aws-sdk/types@3.973.1", "", { "dependencies": { "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-DwHBiMNOB468JiX6+i34c+THsKHErYUdNQ3HexeXZvVn4zouLjgaS4FejiGSi2HyBuzuyHg7SuOPmjSvoU9NRg=="], + + "@aws-sdk/credential-providers/@aws-sdk/core": ["@aws-sdk/core@3.973.11", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@aws-sdk/xml-builder": "^3.972.5", "@smithy/core": "^3.23.2", "@smithy/node-config-provider": "^4.3.8", "@smithy/property-provider": "^4.2.8", "@smithy/protocol-http": "^5.3.8", "@smithy/signature-v4": "^5.3.8", "@smithy/smithy-client": "^4.11.5", "@smithy/types": "^4.12.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-wdQ8vrvHkKIV7yNUKXyjPWKCdYEUrZTHJ8Ojd5uJxXp9vqPCkUR1dpi1NtOLcrDgueJH7MUH5lQZxshjFPSbDA=="], + + "@aws-sdk/credential-providers/@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.972.10", "", { "dependencies": { "@aws-sdk/credential-provider-env": "^3.972.9", "@aws-sdk/credential-provider-http": "^3.972.11", "@aws-sdk/credential-provider-ini": "^3.972.9", "@aws-sdk/credential-provider-process": "^3.972.9", "@aws-sdk/credential-provider-sso": "^3.972.9", "@aws-sdk/credential-provider-web-identity": "^3.972.9", "@aws-sdk/types": "^3.973.1", "@smithy/credential-provider-imds": "^4.2.8", "@smithy/property-provider": "^4.2.8", "@smithy/shared-ini-file-loader": "^4.4.3", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-70nCESlvnzjo4LjJ8By8MYIiBogkYPSXl3WmMZfH9RZcB/Nt9qVWbFpYj6Fk1vLa4Vk8qagFVeXgxdieMxG1QA=="], + + "@aws-sdk/credential-providers/@aws-sdk/types": ["@aws-sdk/types@3.973.1", "", { "dependencies": { "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-DwHBiMNOB468JiX6+i34c+THsKHErYUdNQ3HexeXZvVn4zouLjgaS4FejiGSi2HyBuzuyHg7SuOPmjSvoU9NRg=="], + + "@aws-sdk/nested-clients/@aws-sdk/core": ["@aws-sdk/core@3.973.11", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@aws-sdk/xml-builder": "^3.972.5", "@smithy/core": "^3.23.2", "@smithy/node-config-provider": "^4.3.8", "@smithy/property-provider": "^4.2.8", "@smithy/protocol-http": "^5.3.8", "@smithy/signature-v4": "^5.3.8", "@smithy/smithy-client": "^4.11.5", "@smithy/types": "^4.12.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-wdQ8vrvHkKIV7yNUKXyjPWKCdYEUrZTHJ8Ojd5uJxXp9vqPCkUR1dpi1NtOLcrDgueJH7MUH5lQZxshjFPSbDA=="], + + "@aws-sdk/nested-clients/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.972.3", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-aknPTb2M+G3s+0qLCx4Li/qGZH8IIYjugHMv15JTYMe6mgZO8VBpYgeGYsNMGCqCZOcWzuf900jFBG5bopfzmA=="], + + "@aws-sdk/nested-clients/@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.972.3", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-Ftg09xNNRqaz9QNzlfdQWfpqMCJbsQdnZVJP55jfhbKi1+FTWxGuvfPoBhDHIovqWKjqbuiew3HuhxbJ0+OjgA=="], + + "@aws-sdk/nested-clients/@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.972.3", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-PY57QhzNuXHnwbJgbWYTrqIDHYSeOlhfYERTAuc16LKZpTZRJUjzBFokp9hF7u1fuGeE3D70ERXzdbMBOqQz7Q=="], + + "@aws-sdk/nested-clients/@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.972.11", "", { "dependencies": { "@aws-sdk/core": "^3.973.11", "@aws-sdk/types": "^3.973.1", "@aws-sdk/util-endpoints": "3.993.0", "@smithy/core": "^3.23.2", "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-R8CvPsPHXwzIHCAza+bllY6PrctEk4lYq/SkHJz9NLoBHCcKQrbOcsfXxO6xmipSbUNIbNIUhH0lBsJGgsRdiw=="], + + "@aws-sdk/nested-clients/@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.972.3", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@smithy/config-resolver": "^4.4.6", "@smithy/node-config-provider": "^4.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-v4J8qYAWfOMcZ4MJUyatntOicTzEMaU7j3OpkRCGGFSL2NgXQ5VbxauIyORA+pxdKZ0qQG2tCQjQjZDlXEC3Ow=="], + + "@aws-sdk/nested-clients/@aws-sdk/types": ["@aws-sdk/types@3.973.1", "", { "dependencies": { "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-DwHBiMNOB468JiX6+i34c+THsKHErYUdNQ3HexeXZvVn4zouLjgaS4FejiGSi2HyBuzuyHg7SuOPmjSvoU9NRg=="], + + "@aws-sdk/nested-clients/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.993.0", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-endpoints": "^3.2.8", "tslib": "^2.6.2" } }, "sha512-j6vioBeRZ4eHX4SWGvGPpwGg/xSOcK7f1GL0VM+rdf3ZFTIsUEhCFmD78B+5r2PgztcECSzEfvHQX01k8dPQPw=="], + + "@aws-sdk/nested-clients/@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.972.3", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@smithy/types": "^4.12.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-JurOwkRUcXD/5MTDBcqdyQ9eVedtAsZgw5rBwktsPTN7QtPiS2Ld1jkJepNgYoCufz1Wcut9iup7GJDoIHp8Fw=="], + + "@aws-sdk/nested-clients/@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.972.9", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "^3.972.11", "@aws-sdk/types": "^3.973.1", "@smithy/node-config-provider": "^4.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-JNswdsLdQemxqaSIBL2HRhsHPUBBziAgoi5RQv6/9avmE5g5RSdt1hWr3mHJ7OxqRYf+KeB11ExWbiqfrnoeaA=="], + + "@aws-sdk/token-providers/@aws-sdk/core": ["@aws-sdk/core@3.973.11", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@aws-sdk/xml-builder": "^3.972.5", "@smithy/core": "^3.23.2", "@smithy/node-config-provider": "^4.3.8", "@smithy/property-provider": "^4.2.8", "@smithy/protocol-http": "^5.3.8", "@smithy/signature-v4": "^5.3.8", "@smithy/smithy-client": "^4.11.5", "@smithy/types": "^4.12.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-wdQ8vrvHkKIV7yNUKXyjPWKCdYEUrZTHJ8Ojd5uJxXp9vqPCkUR1dpi1NtOLcrDgueJH7MUH5lQZxshjFPSbDA=="], + + "@aws-sdk/token-providers/@aws-sdk/types": ["@aws-sdk/types@3.973.1", "", { "dependencies": { "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-DwHBiMNOB468JiX6+i34c+THsKHErYUdNQ3HexeXZvVn4zouLjgaS4FejiGSi2HyBuzuyHg7SuOPmjSvoU9NRg=="], + "@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=="], @@ -4277,8 +4408,6 @@ "@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.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="], "@azure/msal-node/uuid": ["uuid@8.3.2", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="], @@ -4299,7 +4428,7 @@ "@fastify/proxy-addr/ipaddr.js": ["ipaddr.js@2.3.0", "", {}, "sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg=="], - "@gitlab/gitlab-ai-provider/openai": ["openai@6.21.0", "", { "peerDependencies": { "ws": "^8.18.0", "zod": "^3.25 || ^4.0" }, "optionalPeers": ["ws", "zod"], "bin": { "openai": "bin/cli" } }, "sha512-26dQFi76dB8IiN/WKGQOV+yKKTTlRCxQjoi2WLt0kMcH8pvxVyvfdBDkld5GTl7W1qvBpwVOtFcsqktj3fBRpA=="], + "@gitlab/gitlab-ai-provider/openai": ["openai@6.22.0", "", { "peerDependencies": { "ws": "^8.18.0", "zod": "^3.25 || ^4.0" }, "optionalPeers": ["ws", "zod"], "bin": { "openai": "bin/cli" } }, "sha512-7Yvy17F33Bi9RutWbsaYt5hJEEJ/krRPOrwan+f9aCPuMat1WVsb2VNSII5W1EksKT6fF69TG/xj4XzodK3JZw=="], "@gitlab/gitlab-ai-provider/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], @@ -4501,7 +4630,9 @@ "accepts/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], - "ai-gateway-provider/@ai-sdk/anthropic": ["@ai-sdk/anthropic@2.0.62", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.21" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-I3RhaOEMnWlWnrvjNBOYvUb19Dwf2nw01IruZrVJRDi688886e11wnd5DxrBZLd2V29Gizo3vpOPnnExsA+wTA=="], + "ai-gateway-provider/@ai-sdk/anthropic": ["@ai-sdk/anthropic@2.0.63", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.21" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-zXlUPCkumnvp8lWS9VFcen/MLF6CL/t1zAKDhpobYj9y/nmylQrKtRvn3RwH871Wd3dF3KYEUXd6M2c6dfCKOA=="], + + "ai-gateway-provider/@ai-sdk/google": ["@ai-sdk/google@2.0.53", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.21" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-ccCxr5mrd3AC2CjLq4e1ST7+UiN5T2Pdmgi0XdWM3QohmNBwUQ/RBG7BvL+cB/ex/j6y64tkMmpYz9zBw/SEFQ=="], "ai-gateway-provider/@ai-sdk/google-vertex": ["@ai-sdk/google-vertex@3.0.90", "", { "dependencies": { "@ai-sdk/anthropic": "2.0.56", "@ai-sdk/google": "2.0.46", "@ai-sdk/provider": "2.0.0", "@ai-sdk/provider-utils": "3.0.19", "google-auth-library": "^10.5.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-C9MLe1KZGg1ZbupV2osygHtL5qngyCDA6ATatunyfTbIe8TXKG8HGni/3O6ifbnI5qxTidIn150Ox7eIFZVMYg=="], @@ -4509,6 +4640,8 @@ "ai-gateway-provider/@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@1.0.33", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.21" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-2KMcR2xAul3u5dGZD7gONgbIki3Hg7Ey+sFu7gsiJ4U2iRU0GDV3ccNq79dTuAEXPDFcOWCUpW8A8jXc0kxJxQ=="], + "ai-gateway-provider/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@3.0.21", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@standard-schema/spec": "^1.0.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-veuMwTLxsgh31Jjn0SnBABnM1f7ebHhRWcV2ZuY3hP3iJDCZ8VXBaYqcHXoOQDqUXTCas08sKQcHyWK+zl882Q=="], + "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=="], "anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], @@ -4529,6 +4662,8 @@ "aws-sdk/events": ["events@1.1.1", "", {}, "sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw=="], + "aws-sdk/xml2js": ["xml2js@0.6.2", "", { "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" } }, "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA=="], + "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=="], "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=="], @@ -4539,6 +4674,10 @@ "body-parser/iconv-lite": ["iconv-lite@0.4.24", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3" } }, "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA=="], + "body-parser/qs": ["qs@6.14.2", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q=="], + + "buffer/ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="], + "bun-webgpu/@webgpu/types": ["@webgpu/types@0.1.69", "", {}, "sha512-RPmm6kgRbI8e98zSD3RVACvnuktIja5+yLgDAkTmxLr90BEwdTXRQWNLF3ETTTyH/8mKhznZuN5AveXYFEsMGQ=="], "c12/chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "^5.0.0" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="], @@ -4573,6 +4712,8 @@ "express/path-to-regexp": ["path-to-regexp@0.1.12", "", {}, "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ=="], + "express/qs": ["qs@6.14.2", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q=="], + "fetch-blob/web-streams-polyfill": ["web-streams-polyfill@3.3.3", "", {}, "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw=="], "finalhandler/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], @@ -4581,7 +4722,7 @@ "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=="], - "glob/minimatch": ["minimatch@10.2.0", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-ugkC31VaVg9cF0DFVoADH12k6061zNZkZON+aX8AWsR9GhPcErkcMBceb6znR8wLERM2AkkOxy2nWRLpT9Jq5w=="], + "glob/minimatch": ["minimatch@10.2.1", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-MClCe8IL5nRRmawL6ib/eT4oLyeKMGCghibcDWK+J0hh0Q8kqSdia6BvbRMVk6mPa6WqUa5uR2oxt6C5jd533A=="], "globby/ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="], @@ -4619,8 +4760,6 @@ "mssql/commander": ["commander@11.1.0", "", {}, "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ=="], - "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=="], - "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=="], "npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="], @@ -4649,10 +4788,10 @@ "p-locate/p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="], - "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=="], + "path-scurry/lru-cache": ["lru-cache@11.2.6", "", {}, "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ=="], "pixelmatch/pngjs": ["pngjs@6.0.0", "", {}, "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg=="], @@ -4709,6 +4848,8 @@ "tar/yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="], + "tedious/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], + "terser/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="], "token-types/ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="], @@ -4725,6 +4866,8 @@ "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=="], + "unstorage/lru-cache": ["lru-cache@11.2.6", "", {}, "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ=="], + "utif2/pako": ["pako@1.0.11", "", {}, "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="], "vitest/tinyexec": ["tinyexec@1.0.2", "", {}, "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg=="], @@ -4745,6 +4888,8 @@ "wrap-ansi-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + "xml2js/sax": ["sax@1.4.4", "", {}, "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw=="], + "yaml-language-server/lodash": ["lodash@4.17.21", "", {}, "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="], "yaml-language-server/request-light": ["request-light@0.5.8", "", {}, "sha512-3Zjgh+8b5fhRJBQZoy+zbVKpAQGLyka0MPgW3zruTF4dFFJ8Fqcfu9YsAvi/rvdcaTeWG3MkbZv4WKxAn/84Lg=="], @@ -4785,6 +4930,10 @@ "@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.5", "", { "dependencies": { "@smithy/types": "^4.12.0", "fast-xml-parser": "5.3.6", "tslib": "^2.6.2" } }, "sha512-mCae5Ys6Qm1LDu0qdGwx2UQ63ONUe+FHw908fJzLDqFKTDBK4LDZUqKWm4OkTCNFq19bftjsBSESIGLD/s3/rA=="], + + "@aws-sdk/client-sso/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.5", "", { "dependencies": { "@smithy/types": "^4.12.0", "fast-xml-parser": "5.3.6", "tslib": "^2.6.2" } }, "sha512-mCae5Ys6Qm1LDu0qdGwx2UQ63ONUe+FHw908fJzLDqFKTDBK4LDZUqKWm4OkTCNFq19bftjsBSESIGLD/s3/rA=="], + "@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=="], @@ -4797,6 +4946,54 @@ "@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/client-cognito-identity/@aws-sdk/core": ["@aws-sdk/core@3.973.11", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@aws-sdk/xml-builder": "^3.972.5", "@smithy/core": "^3.23.2", "@smithy/node-config-provider": "^4.3.8", "@smithy/property-provider": "^4.2.8", "@smithy/protocol-http": "^5.3.8", "@smithy/signature-v4": "^5.3.8", "@smithy/smithy-client": "^4.11.5", "@smithy/types": "^4.12.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-wdQ8vrvHkKIV7yNUKXyjPWKCdYEUrZTHJ8Ojd5uJxXp9vqPCkUR1dpi1NtOLcrDgueJH7MUH5lQZxshjFPSbDA=="], + + "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/client-cognito-identity/@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.972.10", "", { "dependencies": { "@aws-sdk/credential-provider-env": "^3.972.9", "@aws-sdk/credential-provider-http": "^3.972.11", "@aws-sdk/credential-provider-ini": "^3.972.9", "@aws-sdk/credential-provider-process": "^3.972.9", "@aws-sdk/credential-provider-sso": "^3.972.9", "@aws-sdk/credential-provider-web-identity": "^3.972.9", "@aws-sdk/types": "^3.973.1", "@smithy/credential-provider-imds": "^4.2.8", "@smithy/property-provider": "^4.2.8", "@smithy/shared-ini-file-loader": "^4.4.3", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-70nCESlvnzjo4LjJ8By8MYIiBogkYPSXl3WmMZfH9RZcB/Nt9qVWbFpYj6Fk1vLa4Vk8qagFVeXgxdieMxG1QA=="], + + "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/client-cognito-identity/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.972.3", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-aknPTb2M+G3s+0qLCx4Li/qGZH8IIYjugHMv15JTYMe6mgZO8VBpYgeGYsNMGCqCZOcWzuf900jFBG5bopfzmA=="], + + "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/client-cognito-identity/@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.972.3", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-Ftg09xNNRqaz9QNzlfdQWfpqMCJbsQdnZVJP55jfhbKi1+FTWxGuvfPoBhDHIovqWKjqbuiew3HuhxbJ0+OjgA=="], + + "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/client-cognito-identity/@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.972.3", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-PY57QhzNuXHnwbJgbWYTrqIDHYSeOlhfYERTAuc16LKZpTZRJUjzBFokp9hF7u1fuGeE3D70ERXzdbMBOqQz7Q=="], + + "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/client-cognito-identity/@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.972.11", "", { "dependencies": { "@aws-sdk/core": "^3.973.11", "@aws-sdk/types": "^3.973.1", "@aws-sdk/util-endpoints": "3.993.0", "@smithy/core": "^3.23.2", "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-R8CvPsPHXwzIHCAza+bllY6PrctEk4lYq/SkHJz9NLoBHCcKQrbOcsfXxO6xmipSbUNIbNIUhH0lBsJGgsRdiw=="], + + "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/client-cognito-identity/@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.972.3", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@smithy/config-resolver": "^4.4.6", "@smithy/node-config-provider": "^4.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-v4J8qYAWfOMcZ4MJUyatntOicTzEMaU7j3OpkRCGGFSL2NgXQ5VbxauIyORA+pxdKZ0qQG2tCQjQjZDlXEC3Ow=="], + + "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/client-cognito-identity/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.980.0", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-endpoints": "^3.2.8", "tslib": "^2.6.2" } }, "sha512-AjKBNEc+rjOZQE1HwcD9aCELqg1GmUj1rtICKuY8cgwB73xJ4U/kNyqKKpN2k9emGqlfDY2D8itIp/vDc6OKpw=="], + + "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/client-cognito-identity/@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.972.3", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@smithy/types": "^4.12.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-JurOwkRUcXD/5MTDBcqdyQ9eVedtAsZgw5rBwktsPTN7QtPiS2Ld1jkJepNgYoCufz1Wcut9iup7GJDoIHp8Fw=="], + + "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/client-cognito-identity/@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.972.9", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "^3.972.11", "@aws-sdk/types": "^3.973.1", "@smithy/node-config-provider": "^4.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-JNswdsLdQemxqaSIBL2HRhsHPUBBziAgoi5RQv6/9avmE5g5RSdt1hWr3mHJ7OxqRYf+KeB11ExWbiqfrnoeaA=="], + + "@aws-sdk/credential-provider-env/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.5", "", { "dependencies": { "@smithy/types": "^4.12.0", "fast-xml-parser": "5.3.6", "tslib": "^2.6.2" } }, "sha512-mCae5Ys6Qm1LDu0qdGwx2UQ63ONUe+FHw908fJzLDqFKTDBK4LDZUqKWm4OkTCNFq19bftjsBSESIGLD/s3/rA=="], + + "@aws-sdk/credential-provider-http/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.5", "", { "dependencies": { "@smithy/types": "^4.12.0", "fast-xml-parser": "5.3.6", "tslib": "^2.6.2" } }, "sha512-mCae5Ys6Qm1LDu0qdGwx2UQ63ONUe+FHw908fJzLDqFKTDBK4LDZUqKWm4OkTCNFq19bftjsBSESIGLD/s3/rA=="], + + "@aws-sdk/credential-provider-ini/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.5", "", { "dependencies": { "@smithy/types": "^4.12.0", "fast-xml-parser": "5.3.6", "tslib": "^2.6.2" } }, "sha512-mCae5Ys6Qm1LDu0qdGwx2UQ63ONUe+FHw908fJzLDqFKTDBK4LDZUqKWm4OkTCNFq19bftjsBSESIGLD/s3/rA=="], + + "@aws-sdk/credential-provider-login/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.5", "", { "dependencies": { "@smithy/types": "^4.12.0", "fast-xml-parser": "5.3.6", "tslib": "^2.6.2" } }, "sha512-mCae5Ys6Qm1LDu0qdGwx2UQ63ONUe+FHw908fJzLDqFKTDBK4LDZUqKWm4OkTCNFq19bftjsBSESIGLD/s3/rA=="], + + "@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/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/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.5", "", { "dependencies": { "@smithy/types": "^4.12.0", "fast-xml-parser": "5.3.6", "tslib": "^2.6.2" } }, "sha512-mCae5Ys6Qm1LDu0qdGwx2UQ63ONUe+FHw908fJzLDqFKTDBK4LDZUqKWm4OkTCNFq19bftjsBSESIGLD/s3/rA=="], + + "@aws-sdk/credential-provider-sso/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.5", "", { "dependencies": { "@smithy/types": "^4.12.0", "fast-xml-parser": "5.3.6", "tslib": "^2.6.2" } }, "sha512-mCae5Ys6Qm1LDu0qdGwx2UQ63ONUe+FHw908fJzLDqFKTDBK4LDZUqKWm4OkTCNFq19bftjsBSESIGLD/s3/rA=="], + + "@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.5", "", { "dependencies": { "@smithy/types": "^4.12.0", "fast-xml-parser": "5.3.6", "tslib": "^2.6.2" } }, "sha512-mCae5Ys6Qm1LDu0qdGwx2UQ63ONUe+FHw908fJzLDqFKTDBK4LDZUqKWm4OkTCNFq19bftjsBSESIGLD/s3/rA=="], + + "@aws-sdk/credential-providers/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.5", "", { "dependencies": { "@smithy/types": "^4.12.0", "fast-xml-parser": "5.3.6", "tslib": "^2.6.2" } }, "sha512-mCae5Ys6Qm1LDu0qdGwx2UQ63ONUe+FHw908fJzLDqFKTDBK4LDZUqKWm4OkTCNFq19bftjsBSESIGLD/s3/rA=="], + + "@aws-sdk/nested-clients/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.5", "", { "dependencies": { "@smithy/types": "^4.12.0", "fast-xml-parser": "5.3.6", "tslib": "^2.6.2" } }, "sha512-mCae5Ys6Qm1LDu0qdGwx2UQ63ONUe+FHw908fJzLDqFKTDBK4LDZUqKWm4OkTCNFq19bftjsBSESIGLD/s3/rA=="], + + "@aws-sdk/token-providers/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.5", "", { "dependencies": { "@smithy/types": "^4.12.0", "fast-xml-parser": "5.3.6", "tslib": "^2.6.2" } }, "sha512-mCae5Ys6Qm1LDu0qdGwx2UQ63ONUe+FHw908fJzLDqFKTDBK4LDZUqKWm4OkTCNFq19bftjsBSESIGLD/s3/rA=="], + "@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.2", "", {}, "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ=="], "@azure/core-xml/fast-xml-parser/strnum": ["strnum@2.1.2", "", {}, "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ=="], @@ -5005,8 +5202,6 @@ "accepts/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], - "ai-gateway-provider/@ai-sdk/anthropic/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@3.0.21", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@standard-schema/spec": "^1.0.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-veuMwTLxsgh31Jjn0SnBABnM1f7ebHhRWcV2ZuY3hP3iJDCZ8VXBaYqcHXoOQDqUXTCas08sKQcHyWK+zl882Q=="], - "ai-gateway-provider/@ai-sdk/google-vertex/@ai-sdk/anthropic": ["@ai-sdk/anthropic@2.0.56", "", { "dependencies": { "@ai-sdk/provider": "2.0.0", "@ai-sdk/provider-utils": "3.0.19" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-XHJKu0Yvfu9SPzRfsAFESa+9T7f2YJY6TxykKMfRsAwpeWAiX/Gbx5J5uM15AzYC3Rw8tVP3oH+j7jEivENirQ=="], "ai-gateway-provider/@ai-sdk/google-vertex/@ai-sdk/google": ["@ai-sdk/google@2.0.46", "", { "dependencies": { "@ai-sdk/provider": "2.0.0", "@ai-sdk/provider-utils": "3.0.19" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-8PK6u4sGE/kXebd7ZkTp+0aya4kNqzoqpS5m7cHY2NfTK6fhPc6GNvE+MZIZIoHQTp5ed86wGBdeBPpFaaUtyg=="], @@ -5015,7 +5210,7 @@ "ai-gateway-provider/@ai-sdk/google-vertex/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@3.0.19", "", { "dependencies": { "@ai-sdk/provider": "2.0.0", "@standard-schema/spec": "^1.0.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-W41Wc9/jbUVXVwCN/7bWa4IKe8MtxO3EyA0Hfhx6grnmiYlCvpI8neSYWFE0zScXJkgA/YK3BRybzgyiXuu6JA=="], - "ai-gateway-provider/@ai-sdk/openai-compatible/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@3.0.21", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@standard-schema/spec": "^1.0.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-veuMwTLxsgh31Jjn0SnBABnM1f7ebHhRWcV2ZuY3hP3iJDCZ8VXBaYqcHXoOQDqUXTCas08sKQcHyWK+zl882Q=="], + "ai-gateway-provider/@ai-sdk/openai/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@3.0.20", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@standard-schema/spec": "^1.0.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-iXHVe0apM2zUEzauqJwqmpC37A5rihrStAih5Ks+JE32iTe4LZ58y17UGBjpQQTCRw9YxMeo2UFLxLpBluyvLQ=="], "ansi-align/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], @@ -5035,6 +5230,8 @@ "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=="], + "aws-sdk/xml2js/sax": ["sax@1.4.4", "", {}, "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw=="], + "babel-plugin-module-resolver/glob/minimatch": ["minimatch@8.0.4", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA=="], "babel-plugin-module-resolver/glob/minipass": ["minipass@4.2.8", "", {}, "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ=="], @@ -5069,8 +5266,6 @@ "lazystream/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="], - "mssql/tedious/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], - "opencode/@ai-sdk/anthropic/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@3.0.21", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@standard-schema/spec": "^1.0.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-veuMwTLxsgh31Jjn0SnBABnM1f7ebHhRWcV2ZuY3hP3iJDCZ8VXBaYqcHXoOQDqUXTCas08sKQcHyWK+zl882Q=="], "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=="], @@ -5237,6 +5432,10 @@ "@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.3.6", "", { "dependencies": { "strnum": "^2.1.2" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-QNI3sAvSvaOiaMl8FYU4trnEzCwiRr8XMWgAHzlrWpTSj+QaCSvOf1h82OEP1s4hiAXhnbXSyFWCf4ldZzZRVA=="], + + "@aws-sdk/client-sso/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.3.6", "", { "dependencies": { "strnum": "^2.1.2" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-QNI3sAvSvaOiaMl8FYU4trnEzCwiRr8XMWgAHzlrWpTSj+QaCSvOf1h82OEP1s4hiAXhnbXSyFWCf4ldZzZRVA=="], + "@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=="], @@ -5245,6 +5444,32 @@ "@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/client-cognito-identity/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.5", "", { "dependencies": { "@smithy/types": "^4.12.0", "fast-xml-parser": "5.3.6", "tslib": "^2.6.2" } }, "sha512-mCae5Ys6Qm1LDu0qdGwx2UQ63ONUe+FHw908fJzLDqFKTDBK4LDZUqKWm4OkTCNFq19bftjsBSESIGLD/s3/rA=="], + + "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/client-cognito-identity/@aws-sdk/middleware-user-agent/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.993.0", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-endpoints": "^3.2.8", "tslib": "^2.6.2" } }, "sha512-j6vioBeRZ4eHX4SWGvGPpwGg/xSOcK7f1GL0VM+rdf3ZFTIsUEhCFmD78B+5r2PgztcECSzEfvHQX01k8dPQPw=="], + + "@aws-sdk/credential-provider-env/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.3.6", "", { "dependencies": { "strnum": "^2.1.2" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-QNI3sAvSvaOiaMl8FYU4trnEzCwiRr8XMWgAHzlrWpTSj+QaCSvOf1h82OEP1s4hiAXhnbXSyFWCf4ldZzZRVA=="], + + "@aws-sdk/credential-provider-http/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.3.6", "", { "dependencies": { "strnum": "^2.1.2" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-QNI3sAvSvaOiaMl8FYU4trnEzCwiRr8XMWgAHzlrWpTSj+QaCSvOf1h82OEP1s4hiAXhnbXSyFWCf4ldZzZRVA=="], + + "@aws-sdk/credential-provider-ini/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.3.6", "", { "dependencies": { "strnum": "^2.1.2" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-QNI3sAvSvaOiaMl8FYU4trnEzCwiRr8XMWgAHzlrWpTSj+QaCSvOf1h82OEP1s4hiAXhnbXSyFWCf4ldZzZRVA=="], + + "@aws-sdk/credential-provider-login/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.3.6", "", { "dependencies": { "strnum": "^2.1.2" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-QNI3sAvSvaOiaMl8FYU4trnEzCwiRr8XMWgAHzlrWpTSj+QaCSvOf1h82OEP1s4hiAXhnbXSyFWCf4ldZzZRVA=="], + + "@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-process/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.3.6", "", { "dependencies": { "strnum": "^2.1.2" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-QNI3sAvSvaOiaMl8FYU4trnEzCwiRr8XMWgAHzlrWpTSj+QaCSvOf1h82OEP1s4hiAXhnbXSyFWCf4ldZzZRVA=="], + + "@aws-sdk/credential-provider-sso/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.3.6", "", { "dependencies": { "strnum": "^2.1.2" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-QNI3sAvSvaOiaMl8FYU4trnEzCwiRr8XMWgAHzlrWpTSj+QaCSvOf1h82OEP1s4hiAXhnbXSyFWCf4ldZzZRVA=="], + + "@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.3.6", "", { "dependencies": { "strnum": "^2.1.2" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-QNI3sAvSvaOiaMl8FYU4trnEzCwiRr8XMWgAHzlrWpTSj+QaCSvOf1h82OEP1s4hiAXhnbXSyFWCf4ldZzZRVA=="], + + "@aws-sdk/credential-providers/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.3.6", "", { "dependencies": { "strnum": "^2.1.2" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-QNI3sAvSvaOiaMl8FYU4trnEzCwiRr8XMWgAHzlrWpTSj+QaCSvOf1h82OEP1s4hiAXhnbXSyFWCf4ldZzZRVA=="], + + "@aws-sdk/nested-clients/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.3.6", "", { "dependencies": { "strnum": "^2.1.2" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-QNI3sAvSvaOiaMl8FYU4trnEzCwiRr8XMWgAHzlrWpTSj+QaCSvOf1h82OEP1s4hiAXhnbXSyFWCf4ldZzZRVA=="], + + "@aws-sdk/token-providers/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.3.6", "", { "dependencies": { "strnum": "^2.1.2" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-QNI3sAvSvaOiaMl8FYU4trnEzCwiRr8XMWgAHzlrWpTSj+QaCSvOf1h82OEP1s4hiAXhnbXSyFWCf4ldZzZRVA=="], + "@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=="], @@ -5395,8 +5620,34 @@ "@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.1.2", "", {}, "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ=="], + + "@aws-sdk/client-sso/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.2", "", {}, "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ=="], + "@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/credential-provider-cognito-identity/@aws-sdk/client-cognito-identity/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.3.6", "", { "dependencies": { "strnum": "^2.1.2" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-QNI3sAvSvaOiaMl8FYU4trnEzCwiRr8XMWgAHzlrWpTSj+QaCSvOf1h82OEP1s4hiAXhnbXSyFWCf4ldZzZRVA=="], + + "@aws-sdk/credential-provider-env/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.2", "", {}, "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ=="], + + "@aws-sdk/credential-provider-http/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.2", "", {}, "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ=="], + + "@aws-sdk/credential-provider-ini/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.2", "", {}, "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ=="], + + "@aws-sdk/credential-provider-login/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.2", "", {}, "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ=="], + + "@aws-sdk/credential-provider-process/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.2", "", {}, "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ=="], + + "@aws-sdk/credential-provider-sso/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.2", "", {}, "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ=="], + + "@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.2", "", {}, "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ=="], + + "@aws-sdk/credential-providers/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.2", "", {}, "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ=="], + + "@aws-sdk/nested-clients/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.2", "", {}, "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ=="], + + "@aws-sdk/token-providers/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.2", "", {}, "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ=="], + "@jsx-email/cli/tailwindcss/chokidar/readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], "@solidjs/start/shiki/@shikijs/engine-javascript/oniguruma-to-es/regex": ["regex@5.1.1", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-dN5I359AVGPnwzJm2jN1k0W9LPZ+ePvoOeVMMfqIMFz53sSwXkxaJoxr50ptnsC771lK95BnTrVSZxq0b9yCGw=="], @@ -5431,6 +5682,8 @@ "tw-to-css/tailwindcss/chokidar/readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], + "@aws-sdk/credential-provider-cognito-identity/@aws-sdk/client-cognito-identity/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.2", "", {}, "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ=="], + "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=="], diff --git a/github/sst-env.d.ts b/github/sst-env.d.ts index f742a1200444..3b8cffd4fd6a 100644 --- a/github/sst-env.d.ts +++ b/github/sst-env.d.ts @@ -2,6 +2,7 @@ /* tslint:disable */ /* eslint-disable */ /* deno-fmt-ignore-file */ +/* biome-ignore-all lint: auto-generated */ /// diff --git a/infra/console.ts b/infra/console.ts index 4e5a14b04573..3f3c2b8d9351 100644 --- a/infra/console.ts +++ b/infra/console.ts @@ -145,6 +145,16 @@ const ZEN_MODELS = [ new sst.Secret("ZEN_MODELS18"), new sst.Secret("ZEN_MODELS19"), new sst.Secret("ZEN_MODELS20"), + new sst.Secret("ZEN_MODELS21"), + new sst.Secret("ZEN_MODELS22"), + new sst.Secret("ZEN_MODELS23"), + new sst.Secret("ZEN_MODELS24"), + new sst.Secret("ZEN_MODELS25"), + new sst.Secret("ZEN_MODELS26"), + new sst.Secret("ZEN_MODELS27"), + new sst.Secret("ZEN_MODELS28"), + new sst.Secret("ZEN_MODELS29"), + new sst.Secret("ZEN_MODELS30"), ] const STRIPE_SECRET_KEY = new sst.Secret("STRIPE_SECRET_KEY") const STRIPE_PUBLISHABLE_KEY = new sst.Secret("STRIPE_PUBLISHABLE_KEY") @@ -204,9 +214,9 @@ new sst.cloudflare.x.SolidStart("Console", { }, transform: { server: { + placement: { region: "aws:us-east-1" }, transform: { worker: { - placement: { mode: "smart" }, tailConsumers: [{ service: logProcessor.nodes.worker.scriptName }], }, }, diff --git a/nix/hashes.json b/nix/hashes.json index fde268ba83ad..8441e5a36385 100644 --- a/nix/hashes.json +++ b/nix/hashes.json @@ -1,8 +1,8 @@ { "nodeModules": { - "x86_64-linux": "sha256-5pgd2xuvIIkTbIOGIdK5MIXo6O9qRpvk1RKQZ1e1R+8=", - "aarch64-linux": "sha256-FZiHwihM4b82ipQ9XfW08X+sd5CvZhx/+pU/8X1zsns=", - "aarch64-darwin": "sha256-iZv0w1NthV53pY5uvuf3JlI14GeKmCu7WHwGSRdEQeM=", - "x86_64-darwin": "sha256-c3Zm3P1goFPgg3vNAZPMFOhHX/gyTmsCN/PKbGO/v0E=" + "x86_64-linux": "sha256-zs3o4OrLGqECnOxzbawP1UC+a7U3pZKr9QE+36qW+iA=", + "aarch64-linux": "sha256-bg0xtNJBbaZpDleCw+S6aay9Ntcil/h4HW7a1jGfc8Q=", + "aarch64-darwin": "sha256-alEZaFnNgd/7evGv+HLUieeRr8+YVN/FxhH2sNQBMcQ=", + "x86_64-darwin": "sha256-NMBZX6Y7JCUqK6ntCoaf7/a6tFArzDSV/TnBCTtwGMw=" } } diff --git a/package.json b/package.json index 5d93205056bd..f1ba10269c8d 100644 --- a/package.json +++ b/package.json @@ -69,10 +69,11 @@ "devDependencies": { "@actions/artifact": "5.0.1", "@tsconfig/bun": "catalog:", + "@types/mime-types": "3.0.1", "husky": "9.1.7", "prettier": "3.6.2", "semver": "^7.6.0", - "sst": "3.17.23", + "sst": "3.18.10", "turbo": "2.5.6" }, "dependencies": { diff --git a/packages/app/e2e/commands/input-focus.spec.ts b/packages/app/e2e/commands/input-focus.spec.ts new file mode 100644 index 000000000000..4ba1aa3e6908 --- /dev/null +++ b/packages/app/e2e/commands/input-focus.spec.ts @@ -0,0 +1,15 @@ +import { test, expect } from "../fixtures" +import { promptSelector } from "../selectors" + +test("ctrl+l focuses the prompt", async ({ page, gotoSession }) => { + await gotoSession() + + const prompt = page.locator(promptSelector) + await expect(prompt).toBeVisible() + + await page.locator("main").click({ position: { x: 5, y: 5 } }) + await expect(prompt).not.toBeFocused() + + await page.keyboard.press("Control+L") + await expect(prompt).toBeFocused() +}) diff --git a/packages/app/e2e/commands/panels.spec.ts b/packages/app/e2e/commands/panels.spec.ts new file mode 100644 index 000000000000..58c1f0a9af3d --- /dev/null +++ b/packages/app/e2e/commands/panels.spec.ts @@ -0,0 +1,31 @@ +import { test, expect } from "../fixtures" +import { modKey } from "../utils" + +const expanded = async (el: { getAttribute: (name: string) => Promise }) => { + const value = await el.getAttribute("aria-expanded") + if (value !== "true" && value !== "false") throw new Error(`Expected aria-expanded to be true|false, got: ${value}`) + return value === "true" +} + +test("review panel can be toggled via keybind", async ({ page, gotoSession }) => { + await gotoSession() + + const treeToggle = page.getByRole("button", { name: "Toggle file tree" }).first() + await expect(treeToggle).toBeVisible() + if (await expanded(treeToggle)) await treeToggle.click() + await expect(treeToggle).toHaveAttribute("aria-expanded", "false") + + const reviewToggle = page.getByRole("button", { name: "Toggle review" }).first() + await expect(reviewToggle).toBeVisible() + if (await expanded(reviewToggle)) await reviewToggle.click() + await expect(reviewToggle).toHaveAttribute("aria-expanded", "false") + await expect(page.locator("#review-panel")).toHaveCount(0) + + await page.keyboard.press(`${modKey}+Shift+R`) + await expect(reviewToggle).toHaveAttribute("aria-expanded", "true") + await expect(page.locator("#review-panel")).toBeVisible() + + await page.keyboard.press(`${modKey}+Shift+R`) + await expect(reviewToggle).toHaveAttribute("aria-expanded", "false") + await expect(page.locator("#review-panel")).toHaveCount(0) +}) diff --git a/packages/app/e2e/commands/tab-close.spec.ts b/packages/app/e2e/commands/tab-close.spec.ts new file mode 100644 index 000000000000..981ee561e2bb --- /dev/null +++ b/packages/app/e2e/commands/tab-close.spec.ts @@ -0,0 +1,32 @@ +import { test, expect } from "../fixtures" +import { promptSelector } from "../selectors" +import { modKey } from "../utils" + +test("mod+w closes the active file tab", async ({ page, gotoSession }) => { + await gotoSession() + + await page.locator(promptSelector).click() + await page.keyboard.type("/open") + await expect(page.locator('[data-slash-id="file.open"]').first()).toBeVisible() + await page.keyboard.press("Enter") + + const dialog = page + .getByRole("dialog") + .filter({ has: page.getByPlaceholder(/search files/i) }) + .first() + await expect(dialog).toBeVisible() + + await dialog.getByRole("textbox").first().fill("package.json") + const item = dialog.locator('[data-slot="list-item"][data-key^="file:"]').first() + await expect(item).toBeVisible({ timeout: 30_000 }) + await item.click() + await expect(dialog).toHaveCount(0) + + const tab = page.getByRole("tab", { name: "package.json" }).first() + await expect(tab).toBeVisible() + await tab.click() + await expect(tab).toHaveAttribute("aria-selected", "true") + + await page.keyboard.press(`${modKey}+W`) + await expect(page.getByRole("tab", { name: "package.json" })).toHaveCount(0) +}) diff --git a/packages/app/e2e/models/model-picker.spec.ts b/packages/app/e2e/models/model-picker.spec.ts index 01e72464cc56..220a0baa1a89 100644 --- a/packages/app/e2e/models/model-picker.spec.ts +++ b/packages/app/e2e/models/model-picker.spec.ts @@ -28,7 +28,6 @@ test("smoke model selection updates prompt footer", async ({ page, gotoSession } const key = await target.getAttribute("data-key") if (!key) throw new Error("Failed to resolve model key from list item") - const name = (await target.locator("span").first().innerText()).trim() const model = key.split(":").slice(1).join(":") await input.fill(model) @@ -37,6 +36,13 @@ test("smoke model selection updates prompt footer", async ({ page, gotoSession } await expect(dialog).toHaveCount(0) - const form = page.locator(promptSelector).locator("xpath=ancestor::form[1]") - await expect(form.locator('[data-component="button"]').filter({ hasText: name }).first()).toBeVisible() + await page.locator(promptSelector).click() + await page.keyboard.type("/model") + await expect(command).toBeVisible() + await command.hover() + await page.keyboard.press("Enter") + + const dialogAgain = page.getByRole("dialog") + await expect(dialogAgain).toBeVisible() + await expect(dialogAgain.locator(`[data-slot="list-item"][data-key="${key}"][data-selected="true"]`)).toBeVisible() }) diff --git a/packages/app/e2e/prompt/prompt-drop-file-uri.spec.ts b/packages/app/e2e/prompt/prompt-drop-file-uri.spec.ts new file mode 100644 index 000000000000..add2d8d8bc52 --- /dev/null +++ b/packages/app/e2e/prompt/prompt-drop-file-uri.spec.ts @@ -0,0 +1,22 @@ +import { test, expect } from "../fixtures" +import { promptSelector } from "../selectors" + +test("dropping text/plain file: uri inserts a file pill", async ({ page, gotoSession }) => { + await gotoSession() + + const prompt = page.locator(promptSelector) + await prompt.click() + + const path = process.platform === "win32" ? "C:\\opencode-e2e-drop.txt" : "/tmp/opencode-e2e-drop.txt" + const dt = await page.evaluateHandle((text) => { + const dt = new DataTransfer() + dt.setData("text/plain", text) + return dt + }, `file:${path}`) + + await page.dispatchEvent("body", "drop", { dataTransfer: dt }) + + const pill = page.locator(`${promptSelector} [data-type="file"]`).first() + await expect(pill).toBeVisible() + await expect(pill).toHaveAttribute("data-path", path) +}) diff --git a/packages/app/e2e/prompt/prompt-drop-file.spec.ts b/packages/app/e2e/prompt/prompt-drop-file.spec.ts new file mode 100644 index 000000000000..0a138de9977b --- /dev/null +++ b/packages/app/e2e/prompt/prompt-drop-file.spec.ts @@ -0,0 +1,30 @@ +import { test, expect } from "../fixtures" +import { promptSelector } from "../selectors" + +test("dropping an image file adds an attachment", async ({ page, gotoSession }) => { + await gotoSession() + + const prompt = page.locator(promptSelector) + await prompt.click() + + const png = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO3+4uQAAAAASUVORK5CYII=" + const dt = await page.evaluateHandle((b64) => { + const dt = new DataTransfer() + const bytes = Uint8Array.from(atob(b64), (c) => c.charCodeAt(0)) + const file = new File([bytes], "drop.png", { type: "image/png" }) + dt.items.add(file) + return dt + }, png) + + await page.dispatchEvent("body", "drop", { dataTransfer: dt }) + + const img = page.locator('img[alt="drop.png"]').first() + await expect(img).toBeVisible() + + const remove = page.getByRole("button", { name: "Remove attachment" }).first() + await expect(remove).toBeVisible() + + await img.hover() + await remove.click() + await expect(page.locator('img[alt="drop.png"]')).toHaveCount(0) +}) diff --git a/packages/app/e2e/prompt/prompt-multiline.spec.ts b/packages/app/e2e/prompt/prompt-multiline.spec.ts new file mode 100644 index 000000000000..216aa3fdaec2 --- /dev/null +++ b/packages/app/e2e/prompt/prompt-multiline.spec.ts @@ -0,0 +1,18 @@ +import { test, expect } from "../fixtures" +import { promptSelector } from "../selectors" + +test("shift+enter inserts a newline without submitting", async ({ page, gotoSession }) => { + await gotoSession() + + await expect(page).toHaveURL(/\/session\/?$/) + + const prompt = page.locator(promptSelector) + await prompt.click() + await page.keyboard.type("line one") + await page.keyboard.press("Shift+Enter") + await page.keyboard.type("line two") + + await expect(page).toHaveURL(/\/session\/?$/) + await expect(prompt).toContainText("line one") + await expect(prompt).toContainText("line two") +}) diff --git a/packages/app/e2e/prompt/prompt-slash-terminal.spec.ts b/packages/app/e2e/prompt/prompt-slash-terminal.spec.ts new file mode 100644 index 000000000000..eefce19dc0bb --- /dev/null +++ b/packages/app/e2e/prompt/prompt-slash-terminal.spec.ts @@ -0,0 +1,23 @@ +import { test, expect } from "../fixtures" +import { promptSelector, terminalSelector } from "../selectors" + +test("/terminal toggles the terminal panel", async ({ page, gotoSession }) => { + await gotoSession() + + const prompt = page.locator(promptSelector) + const terminal = page.locator(terminalSelector) + + await expect(terminal).not.toBeVisible() + + await prompt.click() + await page.keyboard.type("/terminal") + await expect(page.locator('[data-slash-id="terminal.toggle"]').first()).toBeVisible() + await page.keyboard.press("Enter") + await expect(terminal).toBeVisible() + + await prompt.click() + await page.keyboard.type("/terminal") + await expect(page.locator('[data-slash-id="terminal.toggle"]').first()).toBeVisible() + await page.keyboard.press("Enter") + await expect(terminal).not.toBeVisible() +}) diff --git a/packages/app/package.json b/packages/app/package.json index 31afda656629..b92abb413d9e 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/app", - "version": "1.2.4", + "version": "1.2.6", "description": "", "type": "module", "exports": { diff --git a/packages/app/src/app.tsx b/packages/app/src/app.tsx index 1121c2e955ac..1be9f38d7482 100644 --- a/packages/app/src/app.tsx +++ b/packages/app/src/app.tsx @@ -1,35 +1,36 @@ import "@/index.css" -import { ErrorBoundary, Show, Suspense, lazy, type JSX, type ParentProps } from "solid-js" -import { Router, Route, Navigate } from "@solidjs/router" -import { MetaProvider } from "@solidjs/meta" -import { Font } from "@opencode-ai/ui/font" -import { MarkedProvider } from "@opencode-ai/ui/context/marked" -import { DiffComponentProvider } from "@opencode-ai/ui/context/diff" -import { CodeComponentProvider } from "@opencode-ai/ui/context/code" +import { Code } from "@opencode-ai/ui/code" import { I18nProvider } from "@opencode-ai/ui/context" +import { CodeComponentProvider } from "@opencode-ai/ui/context/code" +import { DialogProvider } from "@opencode-ai/ui/context/dialog" +import { DiffComponentProvider } from "@opencode-ai/ui/context/diff" +import { MarkedProvider } from "@opencode-ai/ui/context/marked" import { Diff } from "@opencode-ai/ui/diff" -import { Code } from "@opencode-ai/ui/code" +import { Font } from "@opencode-ai/ui/font" import { ThemeProvider } from "@opencode-ai/ui/theme" +import { MetaProvider } from "@solidjs/meta" +import { Navigate, Route, Router } from "@solidjs/router" +import { ErrorBoundary, type JSX, lazy, type ParentProps, Show, Suspense } from "solid-js" +import { CommandProvider } from "@/context/command" +import { CommentsProvider } from "@/context/comments" +import { FileProvider } from "@/context/file" +import { GlobalSDKProvider } from "@/context/global-sdk" import { GlobalSyncProvider } from "@/context/global-sync" -import { PermissionProvider } from "@/context/permission" +import { HighlightsProvider } from "@/context/highlights" +import { LanguageProvider, useLanguage } from "@/context/language" import { LayoutProvider } from "@/context/layout" -import { GlobalSDKProvider } from "@/context/global-sdk" -import { normalizeServerUrl, ServerProvider, useServer } from "@/context/server" -import { SettingsProvider } from "@/context/settings" -import { TerminalProvider } from "@/context/terminal" -import { PromptProvider } from "@/context/prompt" -import { FileProvider } from "@/context/file" -import { CommentsProvider } from "@/context/comments" -import { NotificationProvider } from "@/context/notification" import { ModelsProvider } from "@/context/models" -import { DialogProvider } from "@opencode-ai/ui/context/dialog" -import { CommandProvider } from "@/context/command" -import { LanguageProvider, useLanguage } from "@/context/language" +import { NotificationProvider } from "@/context/notification" +import { PermissionProvider } from "@/context/permission" import { usePlatform } from "@/context/platform" -import { HighlightsProvider } from "@/context/highlights" -import Layout from "@/pages/layout" +import { PromptProvider } from "@/context/prompt" +import { type ServerConnection, ServerProvider, useServer } from "@/context/server" +import { SettingsProvider } from "@/context/settings" +import { TerminalProvider } from "@/context/terminal" import DirectoryLayout from "@/pages/directory-layout" +import Layout from "@/pages/layout" import { ErrorPage } from "./pages/error" + const Home = lazy(() => import("@/pages/home")) const Session = lazy(() => import("@/pages/session")) const Loading = () =>
@@ -57,7 +58,11 @@ function UiI18nBridge(props: ParentProps) { declare global { interface Window { - __OPENCODE__?: { updaterEnabled?: boolean; serverPassword?: string; deepLinks?: string[]; wsl?: boolean } + __OPENCODE__?: { + updaterEnabled?: boolean + deepLinks?: string[] + wsl?: boolean + } } } @@ -107,30 +112,6 @@ function RouterRoot(props: ParentProps<{ appChildren?: JSX.Element }>) { ) } -const getStoredDefaultServerUrl = (platform: ReturnType) => { - if (platform.platform !== "web") return - const result = platform.getDefaultServerUrl?.() - if (result instanceof Promise) return - if (!result) return - return normalizeServerUrl(result) -} - -const resolveDefaultServerUrl = (props: { - defaultUrl?: string - storedDefaultServerUrl?: string - hostname: string - origin: string - isDev: boolean - devHost?: string - devPort?: string -}) => { - if (props.defaultUrl) return props.defaultUrl - if (props.storedDefaultServerUrl) return props.storedDefaultServerUrl - if (props.hostname.includes("opencode.ai")) return "http://localhost:4096" - if (props.isDev) return `http://${props.devHost ?? "localhost"}:${props.devPort ?? "4096"}` - return props.origin -} - export function AppBaseProviders(props: ParentProps) { return ( @@ -157,27 +138,19 @@ export function AppBaseProviders(props: ParentProps) { function ServerKey(props: ParentProps) { const server = useServer() return ( - + {props.children} ) } -export function AppInterface(props: { defaultUrl?: string; children?: JSX.Element; isSidecar?: boolean }) { - const platform = usePlatform() - const storedDefaultServerUrl = getStoredDefaultServerUrl(platform) - const defaultServerUrl = resolveDefaultServerUrl({ - defaultUrl: props.defaultUrl, - storedDefaultServerUrl, - hostname: location.hostname, - origin: window.location.origin, - isDev: import.meta.env.DEV, - devHost: import.meta.env.VITE_OPENCODE_SERVER_HOST, - devPort: import.meta.env.VITE_OPENCODE_SERVER_PORT, - }) - +export function AppInterface(props: { + children?: JSX.Element + defaultServer: ServerConnection.Key + servers?: Array +}) { return ( - + diff --git a/packages/app/src/components/dialog-select-model.tsx b/packages/app/src/components/dialog-select-model.tsx index a196db231a67..9f7afb8cd27d 100644 --- a/packages/app/src/components/dialog-select-model.tsx +++ b/packages/app/src/components/dialog-select-model.tsx @@ -121,7 +121,7 @@ export function ModelSelectorPopover(props: { }} modal={false} placement="top-start" - gutter={8} + gutter={4} > {props.children} diff --git a/packages/app/src/components/dialog-select-server.tsx b/packages/app/src/components/dialog-select-server.tsx index 4c37806365a2..76c8ff60ef06 100644 --- a/packages/app/src/components/dialog-select-server.tsx +++ b/packages/app/src/components/dialog-select-server.tsx @@ -1,19 +1,18 @@ -import { createResource, createEffect, createMemo, onCleanup, Show } from "solid-js" -import { createStore, reconcile } from "solid-js/store" +import { Button } from "@opencode-ai/ui/button" import { useDialog } from "@opencode-ai/ui/context/dialog" import { Dialog } from "@opencode-ai/ui/dialog" -import { List } from "@opencode-ai/ui/list" -import { Button } from "@opencode-ai/ui/button" +import { DropdownMenu } from "@opencode-ai/ui/dropdown-menu" import { IconButton } from "@opencode-ai/ui/icon-button" +import { List } from "@opencode-ai/ui/list" import { TextField } from "@opencode-ai/ui/text-field" -import { normalizeServerUrl, useServer } from "@/context/server" -import { usePlatform } from "@/context/platform" -import { useNavigate } from "@solidjs/router" -import { useLanguage } from "@/context/language" -import { DropdownMenu } from "@opencode-ai/ui/dropdown-menu" -import { useGlobalSDK } from "@/context/global-sdk" import { showToast } from "@opencode-ai/ui/toast" +import { useNavigate } from "@solidjs/router" +import { createEffect, createMemo, createResource, onCleanup, Show } from "solid-js" +import { createStore, reconcile } from "solid-js/store" import { ServerRow } from "@/components/server/server-row" +import { useLanguage } from "@/context/language" +import { usePlatform } from "@/context/platform" +import { normalizeServerUrl, ServerConnection, useServer } from "@/context/server" import { checkServerHealth, type ServerHealth } from "@/utils/server-health" interface AddRowProps { @@ -89,7 +88,7 @@ function useServerPreview(fetcher: typeof fetch) { if (!looksComplete(value)) return const normalized = normalizeServerUrl(value) if (!normalized) return - const result = await checkServerHealth(normalized, fetcher) + const result = await checkServerHealth({ url: normalized }, fetcher) setStatus(result.healthy) } @@ -171,14 +170,13 @@ export function DialogSelectServer() { const dialog = useDialog() const server = useServer() const platform = usePlatform() - const globalSDK = useGlobalSDK() const language = useLanguage() const fetcher = platform.fetch ?? globalThis.fetch const { defaultUrl, canDefault, setDefault } = useDefaultServer(platform, language) const { previewStatus } = useServerPreview(fetcher) let listRoot: HTMLDivElement | undefined const [store, setStore] = createStore({ - status: {} as Record, + status: {} as Record, addServer: { url: "", adding: false, @@ -214,24 +212,25 @@ export function DialogSelectServer() { }) } - const replaceServer = (original: string, next: string) => { - const active = server.url - const nextActive = active === original ? next : active + const replaceServer = (original: ServerConnection.Http, next: string) => { + const active = server.key + const newConn = server.add(next) + if (!newConn) return - server.add(next) + const nextActive = active === ServerConnection.key(original) ? ServerConnection.key(newConn) : active if (nextActive) server.setActive(nextActive) - server.remove(original) + server.remove(ServerConnection.key(original)) } const items = createMemo(() => { - const current = server.url + const current = server.current const list = server.list if (!current) return list if (!list.includes(current)) return [current, ...list] return [current, ...list.filter((x) => x !== current)] }) - const current = createMemo(() => items().find((x) => x === server.url) ?? items()[0]) + const current = createMemo(() => items().find((x) => ServerConnection.key(x) === server.key) ?? items()[0]) const sortedItems = createMemo(() => { const list = items() @@ -246,17 +245,17 @@ export function DialogSelectServer() { return list.slice().sort((a, b) => { if (a === active) return -1 if (b === active) return 1 - const diff = rank(store.status[a]) - rank(store.status[b]) + const diff = rank(store.status[ServerConnection.key(a)]) - rank(store.status[ServerConnection.key(b)]) if (diff !== 0) return diff return (order.get(a) ?? 0) - (order.get(b) ?? 0) }) }) async function refreshHealth() { - const results: Record = {} + const results: Record = {} await Promise.all( - items().map(async (url) => { - results[url] = await checkServerHealth(url, fetcher) + items().map(async (conn) => { + results[ServerConnection.key(conn)] = await checkServerHealth(conn.http, fetcher) }), ) setStore("status", reconcile(results)) @@ -269,15 +268,15 @@ export function DialogSelectServer() { onCleanup(() => clearInterval(interval)) }) - async function select(value: string, persist?: boolean) { - if (!persist && store.status[value]?.healthy === false) return + async function select(conn: ServerConnection.Any, persist?: boolean) { + if (!persist && store.status[ServerConnection.key(conn)]?.healthy === false) return dialog.close() if (persist) { - server.add(value) + server.add(conn.http.url) navigate("/") return } - server.setActive(value) + server.setActive(ServerConnection.key(conn)) navigate("/") } @@ -311,7 +310,7 @@ export function DialogSelectServer() { setStore("addServer", { adding: true, error: "" }) - const result = await checkServerHealth(normalized, fetcher) + const result = await checkServerHealth({ url: normalized }, fetcher) setStore("addServer", { adding: false }) if (!result.healthy) { @@ -320,25 +319,25 @@ export function DialogSelectServer() { } resetAdd() - await select(normalized, true) + await select({ type: "http", http: { url: normalized } }, true) } - async function handleEdit(original: string, value: string) { - if (store.editServer.busy) return + async function handleEdit(original: ServerConnection.Any, value: string) { + if (store.editServer.busy || original.type !== "http") return const normalized = normalizeServerUrl(value) if (!normalized) { resetEdit() return } - if (normalized === original) { + if (normalized === original.http.url) { resetEdit() return } setStore("editServer", { busy: true, error: "" }) - const result = await checkServerHealth(normalized, fetcher) + const result = await checkServerHealth({ url: normalized }, fetcher) setStore("editServer", { busy: false }) if (!result.healthy) { @@ -366,7 +365,7 @@ export function DialogSelectServer() { handleAdd(store.addServer.url) } - const handleEditKey = (event: KeyboardEvent, original: string) => { + const handleEditKey = (event: KeyboardEvent, original: ServerConnection.Any) => { event.stopPropagation() if (event.key === "Escape") { event.preventDefault() @@ -378,7 +377,7 @@ export function DialogSelectServer() { handleEdit(original, store.editServer.value) } - async function handleRemove(url: string) { + async function handleRemove(url: ServerConnection.Key) { server.remove(url) if ((await platform.getDefaultServerUrl?.()) === url) { platform.setDefaultServerUrl?.(null) @@ -390,11 +389,14 @@ export function DialogSelectServer() {
(listRoot = el)}> x} + key={(x) => x.http.url} onSelect={(x) => { if (x) select(x) }} @@ -425,10 +427,11 @@ export function DialogSelectServer() { } > {(i) => { + const key = ServerConnection.key(i) return (
+ {language.t("dialog.server.status.default")} @@ -456,59 +459,63 @@ export function DialogSelectServer() { } /> - +
- +

{language.t("dialog.server.current")}

- - e.stopPropagation()} - onPointerDown={(e: PointerEvent) => e.stopPropagation()} - /> - - - { - setStore("editServer", { - id: i, - value: i, - error: "", - status: store.status[i]?.healthy, - }) - }} - > - {language.t("dialog.server.menu.edit")} - - - setDefault(i)}> - - {language.t("dialog.server.menu.default")} - + + + e.stopPropagation()} + onPointerDown={(e: PointerEvent) => e.stopPropagation()} + /> + + + { + setStore("editServer", { + id: i.http.url, + value: i.http.url, + error: "", + status: store.status[ServerConnection.key(i)]?.healthy, + }) + }} + > + {language.t("dialog.server.menu.edit")} - - - setDefault(null)}> + + setDefault(i.http.url)}> + + {language.t("dialog.server.menu.default")} + + + + + setDefault(null)}> + + {language.t("dialog.server.menu.defaultRemove")} + + + + + handleRemove(ServerConnection.key(i))} + class="text-text-on-critical-base hover:bg-surface-critical-weak" + > - {language.t("dialog.server.menu.defaultRemove")} + {language.t("dialog.server.menu.delete")} - - - handleRemove(i)} - class="text-text-on-critical-base hover:bg-surface-critical-weak" - > - {language.t("dialog.server.menu.delete")} - - - - + + + +
diff --git a/packages/app/src/components/file-tree.tsx b/packages/app/src/components/file-tree.tsx index 758f5a83f532..cec094354254 100644 --- a/packages/app/src/components/file-tree.tsx +++ b/packages/app/src/components/file-tree.tsx @@ -71,13 +71,13 @@ const kindLabel = (kind: Kind) => { const kindTextColor = (kind: Kind) => { if (kind === "add") return "color: var(--icon-diff-add-base)" if (kind === "del") return "color: var(--icon-diff-delete-base)" - return "color: var(--icon-warning-active)" + return "color: var(--icon-diff-modified-base)" } const kindDotColor = (kind: Kind) => { if (kind === "add") return "background-color: var(--icon-diff-add-base)" if (kind === "del") return "background-color: var(--icon-diff-delete-base)" - return "background-color: var(--icon-warning-active)" + return "background-color: var(--icon-diff-modified-base)" } const visibleKind = (node: FileNode, kinds?: ReadonlyMap, marks?: Set) => { @@ -447,12 +447,13 @@ export default function FileTree(props: { }) return ( -
+
{(node) => { const expanded = () => file.tree.state(node.path)?.expanded ?? false const deep = () => deeps().get(node.path) ?? -1 const kind = () => visibleKind(node, kinds(), marks()) + const active = () => !!kind() && !node.ignored return ( @@ -530,7 +531,37 @@ export default function FileTree(props: { onClick={() => props.onFileClick?.(node)} >
- + + + + + + + + + + + + + + diff --git a/packages/app/src/components/prompt-input.tsx b/packages/app/src/components/prompt-input.tsx index 8e8c3c895b47..599711a9b321 100644 --- a/packages/app/src/components/prompt-input.tsx +++ b/packages/app/src/components/prompt-input.tsx @@ -1,5 +1,5 @@ import { useFilteredList } from "@opencode-ai/ui/hooks" -import { createEffect, on, Component, Show, For, onCleanup, Switch, Match, createMemo, createSignal } from "solid-js" +import { createEffect, on, Component, Show, onCleanup, Switch, Match, createMemo, createSignal } from "solid-js" import { createStore } from "solid-js/store" import { createFocusSignal } from "@solid-primitives/active-element" import { useLocal } from "@/context/local" @@ -26,13 +26,13 @@ import type { IconName } from "@opencode-ai/ui/icons/provider" import { Tooltip, TooltipKeybind } from "@opencode-ai/ui/tooltip" import { IconButton } from "@opencode-ai/ui/icon-button" import { Select } from "@opencode-ai/ui/select" +import { RadioGroup } from "@opencode-ai/ui/radio-group" import { useDialog } from "@opencode-ai/ui/context/dialog" import { ModelSelectorPopover } from "@/components/dialog-select-model" import { DialogSelectModelUnpaid } from "@/components/dialog-select-model-unpaid" import { useProviders } from "@/hooks/use-providers" import { useCommand } from "@/context/command" import { Persist, persisted } from "@/utils/persist" -import { SessionContextUsage } from "@/components/session-context-usage" import { usePermission } from "@/context/permission" import { useLanguage } from "@/context/language" import { usePlatform } from "@/context/platform" @@ -94,7 +94,6 @@ export const PromptInput: Component = (props) => { const local = useLocal() const files = useFile() const prompt = usePrompt() - const commentCount = createMemo(() => prompt.context.items().filter((item) => !!item.comment?.trim()).length) const layout = useLayout() const comments = useComments() const params = useParams() @@ -105,11 +104,12 @@ export const PromptInput: Component = (props) => { const language = useLanguage() const platform = usePlatform() let editorRef!: HTMLDivElement - let fileInputRef!: HTMLInputElement + let fileInputRef: HTMLInputElement | undefined let scrollRef!: HTMLDivElement let slashPopoverRef!: HTMLDivElement const mirror = { input: false } + const inset = 44 const scrollCursorIntoView = () => { const container = scrollRef @@ -119,7 +119,14 @@ export const PromptInput: Component = (props) => { const range = selection.getRangeAt(0) if (!editorRef.contains(range.startContainer)) return - const rect = range.getBoundingClientRect() + const cursor = getCursorPosition(editorRef) + const length = promptLength(prompt.current().filter((part) => part.type !== "image")) + if (cursor >= length) { + container.scrollTop = container.scrollHeight + return + } + + const rect = range.getClientRects().item(0) ?? range.getBoundingClientRect() if (!rect.height) return const containerRect = container.getBoundingClientRect() @@ -132,8 +139,8 @@ export const PromptInput: Component = (props) => { return } - if (bottom > container.scrollTop + container.clientHeight - padding) { - container.scrollTop = bottom - container.clientHeight + padding + if (bottom > container.scrollTop + container.clientHeight - inset) { + container.scrollTop = bottom - container.clientHeight + inset } } @@ -223,16 +230,26 @@ export const PromptInput: Component = (props) => { mode: "normal", applyingHistory: false, }) - const placeholder = createMemo(() => - promptPlaceholder({ - mode: store.mode, - commentCount: commentCount(), - example: language.t(EXAMPLES[store.placeholder]), - t: (key, params) => language.t(key as Parameters[0], params as never), - }), - ) - const MAX_HISTORY = 100 + const commentCount = createMemo(() => { + if (store.mode === "shell") return 0 + return prompt.context.items().filter((item) => !!item.comment?.trim()).length + }) + + const contextItems = createMemo(() => { + const items = prompt.context.items() + if (store.mode !== "shell") return items + return items.filter((item) => !item.comment?.trim()) + }) + + const hasUserPrompt = createMemo(() => { + const sessionID = params.id + if (!sessionID) return false + const messages = sync.data.message[sessionID] + if (!messages) return false + return messages.some((m) => m.role === "user") + }) + const [history, setHistory] = persisted( Persist.global("prompt-history", ["prompt-history.v1"]), createStore<{ @@ -250,6 +267,18 @@ export const PromptInput: Component = (props) => { }), ) + const suggest = createMemo(() => !hasUserPrompt()) + + const placeholder = createMemo(() => + promptPlaceholder({ + mode: store.mode, + commentCount: commentCount(), + example: suggest() ? language.t(EXAMPLES[store.placeholder]) : "", + suggest: suggest(), + t: (key, params) => language.t(key as Parameters[0], params as never), + }), + ) + const applyHistoryPrompt = (p: Prompt, position: "start" | "end") => { const length = position === "start" ? 0 : promptLength(p) setStore("applyingHistory", true) @@ -280,6 +309,45 @@ export const PromptInput: Component = (props) => { } const isFocused = createFocusSignal(() => editorRef) + const escBlur = () => platform.platform === "desktop" && platform.os === "macos" + + const pick = () => fileInputRef?.click() + + const setMode = (mode: "normal" | "shell") => { + setStore("mode", mode) + setStore("popover", null) + requestAnimationFrame(() => editorRef?.focus()) + } + + const shellModeKey = "mod+shift+x" + const normalModeKey = "mod+shift+e" + + command.register("prompt-input", () => [ + { + id: "file.attach", + title: language.t("prompt.action.attachFile"), + category: language.t("command.category.file"), + keybind: "mod+u", + disabled: store.mode !== "normal", + onSelect: pick, + }, + { + id: "prompt.mode.shell", + title: language.t("command.prompt.mode.shell"), + category: language.t("command.category.session"), + keybind: shellModeKey, + disabled: store.mode === "shell", + onSelect: () => setMode("shell"), + }, + { + id: "prompt.mode.normal", + title: language.t("command.prompt.mode.normal"), + category: language.t("command.category.session"), + keybind: normalModeKey, + disabled: store.mode === "normal", + onSelect: () => setMode("normal"), + }, + ]) const closePopover = () => setStore("popover", null) @@ -325,6 +393,7 @@ export const PromptInput: Component = (props) => { createEffect(() => { params.id if (params.id) return + if (!suggest()) return const interval = setInterval(() => { setStore("placeholder", (prev) => (prev + 1) % EXAMPLES.length) }, 6500) @@ -334,15 +403,10 @@ export const PromptInput: Component = (props) => { const [composing, setComposing] = createSignal(false) const isImeComposing = (event: KeyboardEvent) => event.isComposing || composing() || event.keyCode === 229 - createEffect(() => { - if (!isFocused()) closePopover() - }) - - // Safety: reset composing state on focus change to prevent stuck state - // This handles edge cases where compositionend event may not fire - createEffect(() => { - if (!isFocused()) setComposing(false) - }) + const handleBlur = () => { + closePopover() + setComposing(false) + } const agentList = createMemo(() => sync.data.agent @@ -815,6 +879,13 @@ export const PromptInput: Component = (props) => { }) const handleKeyDown = (event: KeyboardEvent) => { + if ((event.metaKey || event.ctrlKey) && !event.altKey && !event.shiftKey && event.key.toLowerCase() === "u") { + event.preventDefault() + if (store.mode !== "normal") return + pick() + return + } + if (event.key === "Backspace") { const selection = window.getSelection() if (selection && selection.isCollapsed) { @@ -842,13 +913,39 @@ export const PromptInput: Component = (props) => { return } } - if (store.mode === "shell") { - const { collapsed, cursorPosition, textLength } = getCaretState() - if (event.key === "Escape") { + + if (event.key === "Escape") { + if (store.popover) { + closePopover() + event.preventDefault() + event.stopPropagation() + return + } + + if (store.mode === "shell") { setStore("mode", "normal") event.preventDefault() + event.stopPropagation() + return + } + + if (working()) { + abort() + event.preventDefault() + event.stopPropagation() + return + } + + if (escBlur()) { + editorRef.blur() + event.preventDefault() + event.stopPropagation() return } + } + + if (store.mode === "shell") { + const { collapsed, cursorPosition, textLength } = getCaretState() if (event.key === "Backspace" && collapsed && cursorPosition === 0 && textLength === 0) { setStore("mode", "normal") event.preventDefault() @@ -911,31 +1008,13 @@ export const PromptInput: Component = (props) => { if (!collapsed) return const cursorPosition = getCursorPosition(editorRef) - const textLength = promptLength(prompt.current()) const textContent = prompt .current() .map((part) => ("content" in part ? part.content : "")) .join("") const direction = event.key === "ArrowUp" ? "up" : "down" - if (!canNavigateHistoryAtCursor(direction, textContent, cursorPosition)) return - const isEmpty = textContent.trim() === "" || textLength <= 1 - const hasNewlines = textContent.includes("\n") - const inHistory = store.historyIndex >= 0 - const atStart = cursorPosition <= (isEmpty ? 1 : 0) - const atEnd = cursorPosition >= (isEmpty ? textLength - 1 : textLength) - const allowUp = isEmpty || atStart || (!hasNewlines && !inHistory) || (inHistory && atEnd) - const allowDown = isEmpty || atEnd || (!hasNewlines && !inHistory) || (inHistory && atStart) - - if (direction === "up") { - if (!allowUp) return - if (navigateHistory("up")) { - event.preventDefault() - } - return - } - - if (!allowDown) return - if (navigateHistory("down")) { + if (!canNavigateHistoryAtCursor(direction, textContent, cursorPosition, store.historyIndex >= 0)) return + if (navigateHistory(direction)) { event.preventDefault() } return @@ -945,17 +1024,12 @@ export const PromptInput: Component = (props) => { if (event.key === "Enter" && !event.shiftKey) { handleSubmit(event) } - if (event.key === "Escape") { - if (store.popover) { - closePopover() - } else if (working()) { - abort() - } - } } + const variants = createMemo(() => ["default", ...local.model.variant.list()]) + return ( -
+
(slashPopoverRef = el)} @@ -975,8 +1049,8 @@ export const PromptInput: Component = (props) => { onSubmit={handleSubmit} classList={{ "group/prompt-input": true, - "bg-surface-raised-stronger-non-alpha shadow-xs-border relative": true, - "rounded-[14px] overflow-clip focus-within:shadow-xs-border": true, + "bg-surface-raised-stronger-non-alpha shadow-xs-border relative z-10": true, + "rounded-[12px] overflow-clip focus-within:shadow-xs-border": true, "border-icon-info-active border-dashed": store.draggingType !== null, [props.class ?? ""]: !!props.class, }} @@ -986,7 +1060,7 @@ export const PromptInput: Component = (props) => { label={language.t(store.draggingType === "@mention" ? "prompt.dropzone.file.label" : "prompt.dropzone.label")} /> { const active = comments.active() return !!item.commentID && item.commentID === active?.id && item.path === active?.file @@ -1006,62 +1080,196 @@ export const PromptInput: Component = (props) => { onRemove={removeImageAttachment} removeLabel={language.t("prompt.attachment.remove")} /> -
(scrollRef = el)}> -
{ - editorRef = el - props.ref?.(el) - }} - role="textbox" - aria-multiline="true" - aria-label={placeholder()} - contenteditable="true" - autocapitalize="off" - autocorrect="off" - spellcheck={false} - onInput={handleInput} - onPaste={handlePaste} - onCompositionStart={() => setComposing(true)} - onCompositionEnd={() => setComposing(false)} - onKeyDown={handleKeyDown} - classList={{ - "select-text": true, - "w-full p-3 pr-12 text-14-regular text-text-strong focus:outline-none whitespace-pre-wrap": true, - "[&_[data-type=file]]:text-syntax-property": true, - "[&_[data-type=agent]]:text-syntax-type": true, - "font-mono!": store.mode === "shell", - }} - /> - -
- {placeholder()} +
{ + const target = e.target + if (!(target instanceof HTMLElement)) return + if ( + target.closest( + '[data-action="prompt-attach"], [data-action="prompt-submit"], [data-action="prompt-permissions"]', + ) + ) { + return + } + editorRef?.focus() + }} + > +
(scrollRef = el)}> +
{ + editorRef = el + props.ref?.(el) + }} + role="textbox" + aria-multiline="true" + aria-label={placeholder()} + contenteditable="true" + autocapitalize="off" + autocorrect="off" + spellcheck={false} + onInput={handleInput} + onPaste={handlePaste} + onCompositionStart={() => setComposing(true)} + onCompositionEnd={() => setComposing(false)} + onBlur={handleBlur} + onKeyDown={handleKeyDown} + classList={{ + "select-text": true, + "w-full pl-3 pr-2 pt-2 pb-11 text-14-regular text-text-strong focus:outline-none whitespace-pre-wrap": true, + "[&_[data-type=file]]:text-syntax-property": true, + "[&_[data-type=agent]]:text-syntax-type": true, + "font-mono!": store.mode === "shell", + }} + /> + +
+ {placeholder()} +
+
+
+ +
+ { + const file = e.currentTarget.files?.[0] + if (file) addImageAttachment(file) + e.currentTarget.value = "" + }} + /> + +
+ + + + + + +
+ {language.t("prompt.action.stop")} + {language.t("common.key.esc")} +
+
+ +
+ {language.t("prompt.action.send")} + +
+
+ + } + > + +
+
+
+ + +
+
+ + + +
-
-
- - -
- - {language.t("prompt.mode.shell")} - {language.t("prompt.mode.shell.exit")} + + +
+
+
+ +
+ {language.t("prompt.mode.shell")} +
- - + + + (x === "default" ? language.t("common.default") : x)} + onSelect={(x) => local.model.variant.set(x === "default" ? undefined : x)} + class="capitalize max-w-[160px]" + valueClass="truncate text-13-regular" + triggerStyle={{ height: "28px" }} + variant="ghost" + /> + + +
+
+ mode} + label={(mode) => ( - + /> - - - -
-
- { - const file = e.currentTarget.files?.[0] - if (file) addImageAttachment(file) - e.currentTarget.value = "" - }} - /> -
- - - - - - -
- - -
- {language.t("prompt.action.stop")} - {language.t("common.key.esc")} -
-
- -
- {language.t("prompt.action.send")} - -
-
- - } - > - mode && setMode(mode)} + fill + pad="none" + class="w-[68px]" /> -
+
- +
) } diff --git a/packages/app/src/components/prompt-input/context-items.tsx b/packages/app/src/components/prompt-input/context-items.tsx index b575c3961110..b138fe3ef690 100644 --- a/packages/app/src/components/prompt-input/context-items.tsx +++ b/packages/app/src/components/prompt-input/context-items.tsx @@ -41,10 +41,9 @@ export const PromptContextItems: Component = (props) => { >
props.openComment(item)} diff --git a/packages/app/src/components/prompt-input/history.test.ts b/packages/app/src/components/prompt-input/history.test.ts index a37fdad6777a..b7a4f896b886 100644 --- a/packages/app/src/components/prompt-input/history.test.ts +++ b/packages/app/src/components/prompt-input/history.test.ts @@ -73,7 +73,7 @@ describe("prompt-input history", () => { expect(original[1].selection?.startLine).toBe(1) }) - test("canNavigateHistoryAtCursor only allows multiline boundaries", () => { + test("canNavigateHistoryAtCursor only allows prompt boundaries", () => { const value = "a\nb\nc" expect(canNavigateHistoryAtCursor("up", value, 0)).toBe(true) @@ -85,7 +85,16 @@ describe("prompt-input history", () => { expect(canNavigateHistoryAtCursor("up", value, 5)).toBe(false) expect(canNavigateHistoryAtCursor("down", value, 5)).toBe(true) - expect(canNavigateHistoryAtCursor("up", "abc", 1)).toBe(true) - expect(canNavigateHistoryAtCursor("down", "abc", 1)).toBe(true) + expect(canNavigateHistoryAtCursor("up", "abc", 0)).toBe(true) + expect(canNavigateHistoryAtCursor("down", "abc", 3)).toBe(true) + expect(canNavigateHistoryAtCursor("up", "abc", 1)).toBe(false) + expect(canNavigateHistoryAtCursor("down", "abc", 1)).toBe(false) + + expect(canNavigateHistoryAtCursor("up", "abc", 0, true)).toBe(true) + expect(canNavigateHistoryAtCursor("up", "abc", 3, true)).toBe(true) + expect(canNavigateHistoryAtCursor("down", "abc", 0, true)).toBe(true) + expect(canNavigateHistoryAtCursor("down", "abc", 3, true)).toBe(true) + expect(canNavigateHistoryAtCursor("up", "abc", 1, true)).toBe(false) + expect(canNavigateHistoryAtCursor("down", "abc", 1, true)).toBe(false) }) }) diff --git a/packages/app/src/components/prompt-input/history.ts b/packages/app/src/components/prompt-input/history.ts index f26f80848718..c279a3ed563b 100644 --- a/packages/app/src/components/prompt-input/history.ts +++ b/packages/app/src/components/prompt-input/history.ts @@ -4,11 +4,13 @@ const DEFAULT_PROMPT: Prompt = [{ type: "text", content: "", start: 0, end: 0 }] export const MAX_HISTORY = 100 -export function canNavigateHistoryAtCursor(direction: "up" | "down", text: string, cursor: number) { - if (!text.includes("\n")) return true +export function canNavigateHistoryAtCursor(direction: "up" | "down", text: string, cursor: number, inHistory = false) { const position = Math.max(0, Math.min(cursor, text.length)) - if (direction === "up") return !text.slice(0, position).includes("\n") - return !text.slice(position).includes("\n") + const atStart = position === 0 + const atEnd = position === text.length + if (inHistory) return atStart || atEnd + if (direction === "up") return position === 0 + return position === text.length } export function clonePromptParts(prompt: Prompt): Prompt { diff --git a/packages/app/src/components/prompt-input/placeholder.test.ts b/packages/app/src/components/prompt-input/placeholder.test.ts index b633df829561..5f6aa59e9a41 100644 --- a/packages/app/src/components/prompt-input/placeholder.test.ts +++ b/packages/app/src/components/prompt-input/placeholder.test.ts @@ -9,27 +9,40 @@ describe("promptPlaceholder", () => { mode: "shell", commentCount: 0, example: "example", + suggest: true, t, }) expect(value).toBe("prompt.placeholder.shell") }) test("returns summarize placeholders for comment context", () => { - expect(promptPlaceholder({ mode: "normal", commentCount: 1, example: "example", t })).toBe( + expect(promptPlaceholder({ mode: "normal", commentCount: 1, example: "example", suggest: true, t })).toBe( "prompt.placeholder.summarizeComment", ) - expect(promptPlaceholder({ mode: "normal", commentCount: 2, example: "example", t })).toBe( + expect(promptPlaceholder({ mode: "normal", commentCount: 2, example: "example", suggest: true, t })).toBe( "prompt.placeholder.summarizeComments", ) }) - test("returns default placeholder with example", () => { + test("returns default placeholder with example when suggestions enabled", () => { const value = promptPlaceholder({ mode: "normal", commentCount: 0, example: "translated-example", + suggest: true, t, }) expect(value).toBe("prompt.placeholder.normal:translated-example") }) + + test("returns simple placeholder when suggestions disabled", () => { + const value = promptPlaceholder({ + mode: "normal", + commentCount: 0, + example: "translated-example", + suggest: false, + t, + }) + expect(value).toBe("prompt.placeholder.simple") + }) }) diff --git a/packages/app/src/components/prompt-input/placeholder.ts b/packages/app/src/components/prompt-input/placeholder.ts index 07f6a43b510f..395fee51b1c1 100644 --- a/packages/app/src/components/prompt-input/placeholder.ts +++ b/packages/app/src/components/prompt-input/placeholder.ts @@ -2,6 +2,7 @@ type PromptPlaceholderInput = { mode: "normal" | "shell" commentCount: number example: string + suggest: boolean t: (key: string, params?: Record) => string } @@ -9,5 +10,6 @@ export function promptPlaceholder(input: PromptPlaceholderInput) { if (input.mode === "shell") return input.t("prompt.placeholder.shell") if (input.commentCount > 1) return input.t("prompt.placeholder.summarizeComments") if (input.commentCount === 1) return input.t("prompt.placeholder.summarizeComment") + if (!input.suggest) return input.t("prompt.placeholder.simple") return input.t("prompt.placeholder.normal", { example: input.example }) } diff --git a/packages/app/src/components/prompt-input/slash-popover.tsx b/packages/app/src/components/prompt-input/slash-popover.tsx index 259883d61e84..65eb01c797b8 100644 --- a/packages/app/src/components/prompt-input/slash-popover.tsx +++ b/packages/app/src/components/prompt-input/slash-popover.tsx @@ -40,9 +40,9 @@ export const PromptPopover: Component = (props) => { ref={(el) => { if (props.popover === "slash") props.setSlashPopoverRef(el) }} - class="absolute inset-x-0 -top-3 -translate-y-full origin-bottom-left max-h-80 min-h-10 - overflow-auto no-scrollbar flex flex-col p-2 rounded-md - border border-border-base bg-surface-raised-stronger-non-alpha shadow-md" + class="absolute inset-x-0 -top-2 -translate-y-full origin-bottom-left max-h-80 min-h-10 + overflow-auto no-scrollbar flex flex-col p-2 rounded-[12px] + bg-surface-raised-stronger-non-alpha shadow-[var(--shadow-lg-border-base)]" onMouseDown={(e) => e.preventDefault()} > diff --git a/packages/app/src/components/prompt-input/submit.test.ts b/packages/app/src/components/prompt-input/submit.test.ts index 475a0e20f291..c3d6a92813d3 100644 --- a/packages/app/src/components/prompt-input/submit.test.ts +++ b/packages/app/src/components/prompt-input/submit.test.ts @@ -12,24 +12,27 @@ let selected = "/repo/worktree-a" const promptValue: Prompt = [{ type: "text", content: "ls", start: 0, end: 2 }] -const clientFor = (directory: string) => ({ - session: { - create: async () => { - createdSessions.push(directory) - return { data: { id: `session-${createdSessions.length}` } } +const clientFor = (directory: string) => { + createdClients.push(directory) + return { + session: { + create: async () => { + createdSessions.push(directory) + return { data: { id: `session-${createdSessions.length}` } } + }, + shell: async () => { + sentShell.push(directory) + return { data: undefined } + }, + prompt: async () => ({ data: undefined }), + command: async () => ({ data: undefined }), + abort: async () => ({ data: undefined }), }, - shell: async () => { - sentShell.push(directory) - return { data: undefined } + worktree: { + create: async () => ({ data: { directory: `${directory}/new` } }), }, - prompt: async () => ({ data: undefined }), - command: async () => ({ data: undefined }), - abort: async () => ({ data: undefined }), - }, - worktree: { - create: async () => ({ data: { directory: `${directory}/new` } }), - }, -}) + } +} beforeAll(async () => { const rootClient = clientFor("/repo/main") @@ -88,11 +91,17 @@ beforeAll(async () => { })) mock.module("@/context/sdk", () => ({ - useSDK: () => ({ - directory: "/repo/main", - client: rootClient, - url: "http://localhost:4096", - }), + useSDK: () => { + const sdk = { + directory: "/repo/main", + client: rootClient, + url: "http://localhost:4096", + createClient(opts: any) { + return clientFor(opts.directory) + }, + } + return sdk + }, })) mock.module("@/context/sync", () => ({ diff --git a/packages/app/src/components/prompt-input/submit.ts b/packages/app/src/components/prompt-input/submit.ts index 9a1fba5d5c49..8a3dfc40da6c 100644 --- a/packages/app/src/components/prompt-input/submit.ts +++ b/packages/app/src/components/prompt-input/submit.ts @@ -1,21 +1,20 @@ -import { Accessor } from "solid-js" -import { useNavigate, useParams } from "@solidjs/router" -import { createOpencodeClient, type Message } from "@opencode-ai/sdk/v2/client" +import type { Message } from "@opencode-ai/sdk/v2/client" import { showToast } from "@opencode-ai/ui/toast" import { base64Encode } from "@opencode-ai/util/encode" -import { useLocal } from "@/context/local" -import { usePrompt, type ImageAttachmentPart, type Prompt } from "@/context/prompt" +import { useNavigate, useParams } from "@solidjs/router" +import type { Accessor } from "solid-js" +import type { FileSelection } from "@/context/file" +import { useGlobalSync } from "@/context/global-sync" +import { useLanguage } from "@/context/language" import { useLayout } from "@/context/layout" +import { useLocal } from "@/context/local" +import { type ImageAttachmentPart, type Prompt, usePrompt } from "@/context/prompt" import { useSDK } from "@/context/sdk" import { useSync } from "@/context/sync" -import { useGlobalSync } from "@/context/global-sync" -import { usePlatform } from "@/context/platform" -import { useLanguage } from "@/context/language" import { Identifier } from "@/utils/id" import { Worktree as WorktreeState } from "@/utils/worktree" -import type { FileSelection } from "@/context/file" -import { setCursorPosition } from "./editor-dom" import { buildRequestParts } from "./build-request-parts" +import { setCursorPosition } from "./editor-dom" type PendingPrompt = { abort: AbortController @@ -56,7 +55,6 @@ export function createPromptSubmit(input: PromptSubmitInput) { const sdk = useSDK() const sync = useSync() const globalSync = useGlobalSync() - const platform = usePlatform() const local = useLocal() const prompt = usePrompt() const layout = useLayout() @@ -80,6 +78,7 @@ export function createPromptSubmit(input: PromptSubmitInput) { queued.abort.abort() queued.cleanup() pending.delete(sessionID) + globalSync.todo.set(sessionID, undefined) return Promise.resolve() } return sdk.client.session @@ -87,6 +86,9 @@ export function createPromptSubmit(input: PromptSubmitInput) { sessionID, }) .catch(() => {}) + .finally(() => { + globalSync.todo.set(sessionID, undefined) + }) } const restoreCommentItems = (items: CommentItem[]) => { @@ -171,9 +173,7 @@ export function createPromptSubmit(input: PromptSubmitInput) { } if (sessionDirectory !== projectDirectory) { - client = createOpencodeClient({ - baseUrl: sdk.url, - fetch: platform.fetch, + client = sdk.createClient({ directory: sessionDirectory, throwOnError: true, }) @@ -368,7 +368,10 @@ export function createPromptSubmit(input: PromptSubmitInput) { const timer = { id: undefined as number | undefined } const timeout = new Promise>>((resolve) => { timer.id = window.setTimeout(() => { - resolve({ status: "failed", message: language.t("workspace.error.stillPreparing") }) + resolve({ + status: "failed", + message: language.t("workspace.error.stillPreparing"), + }) }, timeoutMs) }) diff --git a/packages/app/src/components/question-dock.tsx b/packages/app/src/components/question-dock.tsx index 5054253b87b5..cd2e495b1c4a 100644 --- a/packages/app/src/components/question-dock.tsx +++ b/packages/app/src/components/question-dock.tsx @@ -1,6 +1,7 @@ -import { For, Show, createMemo, type Component } from "solid-js" +import { For, Show, createMemo, onCleanup, onMount, type Component } from "solid-js" import { createStore } from "solid-js/store" import { Button } from "@opencode-ai/ui/button" +import { DockPrompt } from "@opencode-ai/ui/dock-prompt" import { Icon } from "@opencode-ai/ui/icon" import { showToast } from "@opencode-ai/ui/toast" import type { QuestionAnswer, QuestionRequest } from "@opencode-ai/sdk/v2" @@ -12,25 +13,98 @@ export const QuestionDock: Component<{ request: QuestionRequest }> = (props) => const language = useLanguage() const questions = createMemo(() => props.request.questions) - const single = createMemo(() => questions().length === 1 && questions()[0]?.multiple !== true) + const total = createMemo(() => questions().length) const [store, setStore] = createStore({ tab: 0, answers: [] as QuestionAnswer[], custom: [] as string[], + customOn: [] as boolean[], editing: false, sending: false, }) + let root: HTMLDivElement | undefined + const question = createMemo(() => questions()[store.tab]) - const confirm = createMemo(() => !single() && store.tab === questions().length) const options = createMemo(() => question()?.options ?? []) const input = createMemo(() => store.custom[store.tab] ?? "") + const on = createMemo(() => store.customOn[store.tab] === true) const multi = createMemo(() => question()?.multiple === true) - const customPicked = createMemo(() => { - const value = input() - if (!value) return false - return store.answers[store.tab]?.includes(value) ?? false + + const summary = createMemo(() => { + const n = Math.min(store.tab + 1, total()) + return `${n} of ${total()} questions` + }) + + const last = createMemo(() => store.tab >= total() - 1) + + const customUpdate = (value: string, selected: boolean = on()) => { + const prev = input().trim() + const next = value.trim() + + setStore("custom", store.tab, value) + if (!selected) return + + if (multi()) { + setStore("answers", store.tab, (current = []) => { + const removed = prev ? current.filter((item) => item.trim() !== prev) : current + if (!next) return removed + if (removed.some((item) => item.trim() === next)) return removed + return [...removed, next] + }) + return + } + + setStore("answers", store.tab, next ? [next] : []) + } + + const measure = () => { + if (!root) return + + const scroller = document.querySelector(".session-scroller") + const head = scroller instanceof HTMLElement ? scroller.firstElementChild : undefined + const top = + head instanceof HTMLElement && head.classList.contains("sticky") ? head.getBoundingClientRect().bottom : 0 + if (!top) { + root.style.removeProperty("--question-prompt-max-height") + return + } + + const dock = root.closest('[data-component="session-prompt-dock"]') + if (!(dock instanceof HTMLElement)) return + + const dockBottom = dock.getBoundingClientRect().bottom + const below = Math.max(0, dockBottom - root.getBoundingClientRect().bottom) + const gap = 8 + const max = Math.max(240, Math.floor(dockBottom - top - gap - below)) + root.style.setProperty("--question-prompt-max-height", `${max}px`) + } + + onMount(() => { + let raf: number | undefined + const update = () => { + if (raf !== undefined) cancelAnimationFrame(raf) + raf = requestAnimationFrame(() => { + raf = undefined + measure() + }) + } + + update() + window.addEventListener("resize", update) + + const dock = root?.closest('[data-component="session-prompt-dock"]') + const scroller = document.querySelector(".session-scroller") + const observer = new ResizeObserver(update) + if (dock instanceof HTMLElement) observer.observe(dock) + if (scroller instanceof HTMLElement) observer.observe(scroller) + + onCleanup(() => { + window.removeEventListener("resize", update) + observer.disconnect() + if (raf !== undefined) cancelAnimationFrame(raf) + }) }) const fail = (err: unknown) => { @@ -64,23 +138,13 @@ export const QuestionDock: Component<{ request: QuestionRequest }> = (props) => } } - const submit = () => { - void reply(questions().map((_, i) => store.answers[i] ?? [])) - } + const submit = () => void reply(questions().map((_, i) => store.answers[i] ?? [])) const pick = (answer: string, custom: boolean = false) => { setStore("answers", store.tab, [answer]) - - if (custom) { - setStore("custom", store.tab, answer) - } - - if (single()) { - void reply([[answer]]) - return - } - - setStore("tab", store.tab + 1) + if (custom) setStore("custom", store.tab, answer) + if (!custom) setStore("customOn", store.tab, false) + setStore("editing", false) } const toggle = (answer: string) => { @@ -90,16 +154,41 @@ export const QuestionDock: Component<{ request: QuestionRequest }> = (props) => }) } - const selectTab = (index: number) => { - setStore("tab", index) + const customToggle = () => { + if (store.sending) return + + if (!multi()) { + setStore("customOn", store.tab, true) + setStore("editing", true) + customUpdate(input(), true) + return + } + + const next = !on() + setStore("customOn", store.tab, next) + if (next) { + setStore("editing", true) + customUpdate(input(), true) + return + } + + const value = input().trim() + if (value) setStore("answers", store.tab, (current = []) => current.filter((item) => item.trim() !== value)) setStore("editing", false) } + const customOpen = () => { + if (store.sending) return + if (!on()) setStore("customOn", store.tab, true) + setStore("editing", true) + customUpdate(input(), true) + } + const selectOption = (optIndex: number) => { if (store.sending) return if (optIndex === options().length) { - setStore("editing", true) + customOpen() return } @@ -112,176 +201,225 @@ export const QuestionDock: Component<{ request: QuestionRequest }> = (props) => pick(opt.label) } - const handleCustomSubmit = (e: Event) => { - e.preventDefault() + const commitCustom = () => { + setStore("editing", false) + customUpdate(input()) + } + + const next = () => { if (store.sending) return + if (store.editing) commitCustom() - const value = input().trim() - if (!value) { - setStore("editing", false) + if (store.tab >= total() - 1) { + submit() return } - if (multi()) { - setStore("answers", store.tab, (current = []) => { - if (current.includes(value)) return current - return [...current, value] - }) - setStore("editing", false) - return - } + setStore("tab", store.tab + 1) + setStore("editing", false) + } + + const back = () => { + if (store.sending) return + if (store.tab <= 0) return + setStore("tab", store.tab - 1) + setStore("editing", false) + } - pick(value, true) + const jump = (tab: number) => { + if (store.sending) return + setStore("tab", tab) setStore("editing", false) } return ( -
- -
- - {(q, index) => { - const active = () => index() === store.tab - const answered = () => (store.answers[index()]?.length ?? 0) > 0 - return ( + (root = el)} + header={ + <> +
{summary()}
+
+ + {(_, i) => ( - ) - }} - - -
- - - -
-
- {question()?.question} - {multi() ? " " + language.t("ui.question.multiHint") : ""} + onClick={() => jump(i())} + aria-label={`${language.t("ui.tool.questions")} ${i() + 1}`} + /> + )} +
-
- - {(opt, i) => { - const picked = () => store.answers[store.tab]?.includes(opt.label) ?? false - return ( - +
+ 0}> + + + +
+ + } + > +
{question()?.question}
+ {language.t("ui.question.singleHint")}
}> +
{language.t("ui.question.multiHint")}
+ +
+ + {(opt, i) => { + const picked = () => store.answers[store.tab]?.includes(opt.label) ?? false + return ( + - ) - }} - + + + + {opt.label} + + {opt.description} + + + + ) + }} + + + selectOption(options().length)} + onClick={customOpen} > - {language.t("ui.messagePart.option.typeOwnAnswer")} - - {input()} - - - - + + + {language.t("ui.messagePart.option.typeOwnAnswer")} + {input() || language.t("ui.question.custom.placeholder")} + - -
- setTimeout(() => el.focus(), 0)} - type="text" - data-slot="custom-input" - placeholder={language.t("ui.question.custom.placeholder")} - value={input()} - disabled={store.sending} - onInput={(e) => { - setStore("custom", store.tab, e.currentTarget.value) - }} - /> - - -
-
-
-
-
- - -
-
{language.t("ui.messagePart.review.title")}
- - {(q, index) => { - const value = () => store.answers[index()]?.join(", ") ?? "" - const answered = () => Boolean(value()) - return ( -
- {q.question} - - {answered() ? value() : language.t("ui.question.review.notAnswered")} - -
- ) + } + > +
{ + if (store.sending) { + e.preventDefault() + return + } + if (e.target instanceof HTMLTextAreaElement) return + const input = e.currentTarget.querySelector('[data-slot="question-custom-input"]') + if (input instanceof HTMLTextAreaElement) input.focus() }} - -
-
- -
- - - - - - - - + + }> + + + + + + {language.t("ui.messagePart.option.typeOwnAnswer")} +
` @@ -46,20 +77,6 @@ describe("focusTerminalById", () => { }) }) -describe("combineCommandSections", () => { - test("keeps section order stable", () => { - const result = combineCommandSections([ - [{ id: "a", title: "A" }], - [ - { id: "b", title: "B" }, - { id: "c", title: "C" }, - ], - ]) - - expect(result.map((item) => item.id)).toEqual(["a", "b", "c"]) - }) -}) - describe("getTabReorderIndex", () => { test("returns target index for valid drag reorder", () => { expect(getTabReorderIndex(["a", "b", "c"], "a", "c")).toBe(2) diff --git a/packages/app/src/pages/session/helpers.ts b/packages/app/src/pages/session/helpers.ts index 6ead7a7f2f42..995f6eb191db 100644 --- a/packages/app/src/pages/session/helpers.ts +++ b/packages/app/src/pages/session/helpers.ts @@ -1,4 +1,3 @@ -import type { CommandOption } from "@/context/command" import { batch } from "solid-js" export const focusTerminalById = (id: string) => { @@ -36,8 +35,25 @@ export const createOpenReviewFile = (input: { } } -export const combineCommandSections = (sections: readonly (readonly CommandOption[])[]) => { - return sections.flatMap((section) => section) +export const createOpenSessionFileTab = (input: { + normalizeTab: (tab: string) => string + openTab: (tab: string) => void + pathFromTab: (tab: string) => string | undefined + loadFile: (path: string) => void + openReviewPanel: () => void + setActive: (tab: string) => void +}) => { + return (value: string) => { + const next = input.normalizeTab(value) + input.openTab(next) + + const path = input.pathFromTab(next) + if (!path) return + + input.loadFile(path) + input.openReviewPanel() + input.setActive(next) + } } export const getTabReorderIndex = (tabs: readonly string[], from: string, to: string) => { diff --git a/packages/app/src/pages/session/message-timeline.tsx b/packages/app/src/pages/session/message-timeline.tsx index d5f04ccf91c4..a7db4e83eb0e 100644 --- a/packages/app/src/pages/session/message-timeline.tsx +++ b/packages/app/src/pages/session/message-timeline.tsx @@ -1,13 +1,21 @@ -import { For, onCleanup, onMount, Show, type JSX } from "solid-js" +import { For, createEffect, createMemo, on, onCleanup, Show, type JSX } from "solid-js" +import { createStore, produce } from "solid-js/store" +import { useNavigate, useParams } from "@solidjs/router" import { Button } from "@opencode-ai/ui/button" import { Icon } from "@opencode-ai/ui/icon" import { IconButton } from "@opencode-ai/ui/icon-button" import { DropdownMenu } from "@opencode-ai/ui/dropdown-menu" +import { Dialog } from "@opencode-ai/ui/dialog" import { InlineInput } from "@opencode-ai/ui/inline-input" -import { Tooltip } from "@opencode-ai/ui/tooltip" import { SessionTurn } from "@opencode-ai/ui/session-turn" import type { UserMessage } from "@opencode-ai/sdk/v2" +import { showToast } from "@opencode-ai/ui/toast" import { shouldMarkBoundaryGesture, normalizeWheelDelta } from "@/pages/session/message-gesture" +import { SessionContextUsage } from "@/components/session-context-usage" +import { useDialog } from "@opencode-ai/ui/context/dialog" +import { useLanguage } from "@/context/language" +import { useSDK } from "@/context/sdk" +import { useSync } from "@/context/sync" const boundaryTarget = (root: HTMLElement, target: EventTarget | null) => { const current = target instanceof Element ? target : undefined @@ -53,29 +61,7 @@ export function MessageTimeline(props: { isDesktop: boolean onScrollSpyScroll: () => void onAutoScrollInteraction: (event: MouseEvent) => void - showHeader: boolean centered: boolean - title?: string - parentID?: string - openTitleEditor: () => void - closeTitleEditor: () => void - saveTitleEditor: () => void | Promise - titleRef: (el: HTMLInputElement) => void - titleState: { - draft: string - editing: boolean - saving: boolean - menuOpen: boolean - pendingRename: boolean - } - onTitleDraft: (value: string) => void - onTitleMenuOpen: (open: boolean) => void - onTitlePendingRename: (value: boolean) => void - onNavigateParent: () => void - sessionID: string - onArchiveSession: (sessionID: string) => void - onDeleteSession: (sessionID: string) => void - t: (key: string, vars?: Record) => string setContentRef: (el: HTMLDivElement) => void turnStart: number onRenderEarlier: () => void @@ -86,13 +72,234 @@ export function MessageTimeline(props: { anchor: (id: string) => string onRegisterMessage: (el: HTMLDivElement, id: string) => void onUnregisterMessage: (id: string) => void - onFirstTurnMount?: () => void lastUserMessageID?: string - expanded: Record - onToggleExpanded: (id: string) => void }) { let touchGesture: number | undefined + const params = useParams() + const navigate = useNavigate() + const sdk = useSDK() + const sync = useSync() + const dialog = useDialog() + const language = useLanguage() + + const sessionKey = createMemo(() => `${params.dir}${params.id ? "/" + params.id : ""}`) + const sessionID = createMemo(() => params.id) + const info = createMemo(() => { + const id = sessionID() + if (!id) return + return sync.session.get(id) + }) + const titleValue = createMemo(() => info()?.title) + const parentID = createMemo(() => info()?.parentID) + const showHeader = createMemo(() => !!(titleValue() || parentID())) + + const [title, setTitle] = createStore({ + draft: "", + editing: false, + saving: false, + menuOpen: false, + pendingRename: false, + }) + let titleRef: HTMLInputElement | undefined + + const errorMessage = (err: unknown) => { + if (err && typeof err === "object" && "data" in err) { + const data = (err as { data?: { message?: string } }).data + if (data?.message) return data.message + } + if (err instanceof Error) return err.message + return language.t("common.requestFailed") + } + + createEffect( + on( + sessionKey, + () => setTitle({ draft: "", editing: false, saving: false, menuOpen: false, pendingRename: false }), + { defer: true }, + ), + ) + + const openTitleEditor = () => { + if (!sessionID()) return + setTitle({ editing: true, draft: titleValue() ?? "" }) + requestAnimationFrame(() => { + titleRef?.focus() + titleRef?.select() + }) + } + + const closeTitleEditor = () => { + if (title.saving) return + setTitle({ editing: false, saving: false }) + } + + const saveTitleEditor = async () => { + const id = sessionID() + if (!id) return + if (title.saving) return + + const next = title.draft.trim() + if (!next || next === (titleValue() ?? "")) { + setTitle({ editing: false, saving: false }) + return + } + + setTitle("saving", true) + await sdk.client.session + .update({ sessionID: id, title: next }) + .then(() => { + sync.set( + produce((draft) => { + const index = draft.session.findIndex((s) => s.id === id) + if (index !== -1) draft.session[index].title = next + }), + ) + setTitle({ editing: false, saving: false }) + }) + .catch((err) => { + setTitle("saving", false) + showToast({ + title: language.t("common.requestFailed"), + description: errorMessage(err), + }) + }) + } + + const navigateAfterSessionRemoval = (sessionID: string, parentID?: string, nextSessionID?: string) => { + if (params.id !== sessionID) return + if (parentID) { + navigate(`/${params.dir}/session/${parentID}`) + return + } + if (nextSessionID) { + navigate(`/${params.dir}/session/${nextSessionID}`) + return + } + navigate(`/${params.dir}/session`) + } + + const archiveSession = async (sessionID: string) => { + const session = sync.session.get(sessionID) + if (!session) return + + const sessions = sync.data.session ?? [] + const index = sessions.findIndex((s) => s.id === sessionID) + const nextSession = index === -1 ? undefined : (sessions[index + 1] ?? sessions[index - 1]) + + await sdk.client.session + .update({ sessionID, time: { archived: Date.now() } }) + .then(() => { + sync.set( + produce((draft) => { + const index = draft.session.findIndex((s) => s.id === sessionID) + if (index !== -1) draft.session.splice(index, 1) + }), + ) + navigateAfterSessionRemoval(sessionID, session.parentID, nextSession?.id) + }) + .catch((err) => { + showToast({ + title: language.t("common.requestFailed"), + description: errorMessage(err), + }) + }) + } + + const deleteSession = async (sessionID: string) => { + const session = sync.session.get(sessionID) + if (!session) return false + + const sessions = (sync.data.session ?? []).filter((s) => !s.parentID && !s.time?.archived) + const index = sessions.findIndex((s) => s.id === sessionID) + const nextSession = index === -1 ? undefined : (sessions[index + 1] ?? sessions[index - 1]) + + const result = await sdk.client.session + .delete({ sessionID }) + .then((x) => x.data) + .catch((err) => { + showToast({ + title: language.t("session.delete.failed.title"), + description: errorMessage(err), + }) + return false + }) + + if (!result) return false + + sync.set( + produce((draft) => { + const removed = new Set([sessionID]) + + const byParent = new Map() + for (const item of draft.session) { + const parentID = item.parentID + if (!parentID) continue + const existing = byParent.get(parentID) + if (existing) { + existing.push(item.id) + continue + } + byParent.set(parentID, [item.id]) + } + + const stack = [sessionID] + while (stack.length) { + const parentID = stack.pop() + if (!parentID) continue + + const children = byParent.get(parentID) + if (!children) continue + + for (const child of children) { + if (removed.has(child)) continue + removed.add(child) + stack.push(child) + } + } + + draft.session = draft.session.filter((s) => !removed.has(s.id)) + }), + ) + + navigateAfterSessionRemoval(sessionID, session.parentID, nextSession?.id) + return true + } + + const navigateParent = () => { + const id = parentID() + if (!id) return + navigate(`/${params.dir}/session/${id}`) + } + + function DialogDeleteSession(props: { sessionID: string }) { + const name = createMemo(() => sync.session.get(props.sessionID)?.title ?? language.t("command.session.new")) + const handleDelete = async () => { + await deleteSession(props.sessionID) + dialog.close() + } + + return ( + +
+
+ + {language.t("session.delete.confirm", { name: name() })} + +
+
+ + +
+
+
+ ) + } + return (
- +
-
-
- +
+
+ - + - {props.title} +

+ {titleValue()}

} > props.onTitleDraft(event.currentTarget.value)} + ref={(el) => { + titleRef = el + }} + value={title.draft} + disabled={title.saving} + class="text-14-medium text-text-strong grow-1 min-w-0 pl-2 rounded-[6px]" + style={{ "--inline-input-shadow": "var(--shadow-xs-border-select)" }} + onInput={(event) => setTitle("draft", event.currentTarget.value)} onKeyDown={(event) => { event.stopPropagation() if (event.key === "Enter") { event.preventDefault() - void props.saveTitleEditor() + void saveTitleEditor() return } if (event.key === "Escape") { event.preventDefault() - props.closeTitleEditor() + closeTitleEditor() } }} - onBlur={props.closeTitleEditor} + onBlur={closeTitleEditor} />
- + {(id) => ( -
- - - - +
+ + setTitle("menuOpen", open)} + > + { - if (!props.titleState.pendingRename) return + if (!title.pendingRename) return event.preventDefault() - props.onTitlePendingRename(false) - props.openTitleEditor() + setTitle("pendingRename", false) + openTitleEditor() }} > { - props.onTitlePendingRename(true) - props.onTitleMenuOpen(false) + setTitle("pendingRename", true) + setTitle("menuOpen", false) }} > - {props.t("common.rename")} + {language.t("common.rename")} - props.onArchiveSession(id())}> - {props.t("common.archive")} + void archiveSession(id())}> + {language.t("common.archive")} - props.onDeleteSession(id())}> - {props.t("common.delete")} + dialog.show(() => )} + > + {language.t("common.delete")} @@ -263,7 +484,7 @@ export function MessageTimeline(props: {
0}>
@@ -288,45 +509,37 @@ export function MessageTimeline(props: { onClick={props.onLoadEarlier} > {props.historyLoading - ? props.t("session.messages.loadingEarlier") - : props.t("session.messages.loadEarlier")} + ? language.t("session.messages.loadingEarlier") + : language.t("session.messages.loadEarlier")}
- {(message) => { - if (import.meta.env.DEV && props.onFirstTurnMount) { - onMount(() => props.onFirstTurnMount?.()) - } - - return ( -
{ - props.onRegisterMessage(el, message.id) - onCleanup(() => props.onUnregisterMessage(message.id)) - }} - classList={{ - "min-w-0 w-full max-w-full": true, - "md:max-w-200 2xl:max-w-[1000px]": props.centered, + {(message) => ( +
{ + props.onRegisterMessage(el, message.id) + onCleanup(() => props.onUnregisterMessage(message.id)) + }} + classList={{ + "min-w-0 w-full max-w-full": true, + "md:max-w-200 2xl:max-w-[1000px]": props.centered, + }} + > + - props.onToggleExpanded(message.id)} - classes={{ - root: "min-w-0 w-full relative", - content: "flex flex-col justify-between !overflow-visible", - container: "w-full px-4 md:px-6", - }} - /> -
- ) - }} + /> +
+ )}
diff --git a/packages/app/src/pages/session/review-tab.tsx b/packages/app/src/pages/session/review-tab.tsx index 634491c72dcc..3a9f63949a41 100644 --- a/packages/app/src/pages/session/review-tab.tsx +++ b/packages/app/src/pages/session/review-tab.tsx @@ -144,8 +144,8 @@ export function SessionReviewTab(props: SessionReviewTabProps) { onOpenChange={props.view().review.setOpen} classes={{ root: props.classes?.root ?? "pb-6", - header: props.classes?.header ?? "px-6", - container: props.classes?.container ?? "px-6", + header: props.classes?.header ?? "px-3", + container: props.classes?.container ?? "px-3", }} diffs={props.diffs()} diffStyle={props.diffStyle} diff --git a/packages/app/src/pages/session/session-mobile-tabs.tsx b/packages/app/src/pages/session/session-mobile-tabs.tsx index 73aebc079aae..f97199b4947c 100644 --- a/packages/app/src/pages/session/session-mobile-tabs.tsx +++ b/packages/app/src/pages/session/session-mobile-tabs.tsx @@ -1,5 +1,6 @@ import { Show } from "solid-js" import { Tabs } from "@opencode-ai/ui/tabs" +import { useLanguage } from "@/context/language" export function SessionMobileTabs(props: { open: boolean @@ -8,8 +9,9 @@ export function SessionMobileTabs(props: { reviewCount: number onSession: () => void onChanges: () => void - t: (key: string, vars?: Record) => string }) { + const language = useLanguage() + return ( @@ -20,7 +22,7 @@ export function SessionMobileTabs(props: { classes={{ button: "w-full" }} onClick={props.onSession} > - {props.t("session.tab.session")} + {language.t("session.tab.session")} {props.hasReview - ? props.t("session.review.filesChanged", { count: props.reviewCount }) - : props.t("session.review.change.other")} + ? language.t("session.review.filesChanged", { count: props.reviewCount }) + : language.t("session.review.change.other")} diff --git a/packages/app/src/pages/session/session-prompt-dock.tsx b/packages/app/src/pages/session/session-prompt-dock.tsx index 8ec4f3b9f8c5..0e0d06071b81 100644 --- a/packages/app/src/pages/session/session-prompt-dock.tsx +++ b/packages/app/src/pages/session/session-prompt-dock.tsx @@ -1,133 +1,315 @@ -import { For, Show } from "solid-js" -import type { QuestionRequest } from "@opencode-ai/sdk/v2" +import { For, Show, createEffect, createMemo, createSignal, on, onCleanup } from "solid-js" +import type { PermissionRequest, QuestionRequest, Todo } from "@opencode-ai/sdk/v2" +import { useParams } from "@solidjs/router" import { Button } from "@opencode-ai/ui/button" -import { BasicTool } from "@opencode-ai/ui/basic-tool" +import { DockPrompt } from "@opencode-ai/ui/dock-prompt" +import { Icon } from "@opencode-ai/ui/icon" +import { showToast } from "@opencode-ai/ui/toast" import { PromptInput } from "@/components/prompt-input" import { QuestionDock } from "@/components/question-dock" -import { questionSubtitle } from "@/pages/session/session-prompt-helpers" +import { SessionTodoDock } from "@/components/session-todo-dock" +import { useGlobalSync } from "@/context/global-sync" +import { useLanguage } from "@/context/language" +import { usePrompt } from "@/context/prompt" +import { useSDK } from "@/context/sdk" +import { useSync } from "@/context/sync" +import { getSessionHandoff, setSessionHandoff } from "@/pages/session/handoff" export function SessionPromptDock(props: { centered: boolean - questionRequest: () => QuestionRequest | undefined - permissionRequest: () => { patterns: string[]; permission: string } | undefined - blocked: boolean - promptReady: boolean - handoffPrompt?: string - t: (key: string, vars?: Record) => string - responding: boolean - onDecide: (response: "once" | "always" | "reject") => void inputRef: (el: HTMLDivElement) => void newSessionWorktree: string onNewSessionWorktreeReset: () => void onSubmit: () => void setPromptDockRef: (el: HTMLDivElement) => void }) { + const params = useParams() + const sdk = useSDK() + const sync = useSync() + const globalSync = useGlobalSync() + const prompt = usePrompt() + const language = useLanguage() + + const sessionKey = createMemo(() => `${params.dir}${params.id ? "/" + params.id : ""}`) + const handoffPrompt = createMemo(() => getSessionHandoff(sessionKey())?.prompt) + + const todos = createMemo((): Todo[] => { + const id = params.id + if (!id) return [] + return globalSync.data.session_todo[id] ?? [] + }) + + const questionRequest = createMemo((): QuestionRequest | undefined => { + const sessionID = params.id + if (!sessionID) return + return sync.data.question[sessionID]?.[0] + }) + + const permissionRequest = createMemo((): PermissionRequest | undefined => { + const sessionID = params.id + if (!sessionID) return + return sync.data.permission[sessionID]?.[0] + }) + + const blocked = createMemo(() => !!permissionRequest() || !!questionRequest()) + + const previewPrompt = () => + prompt + .current() + .map((part) => { + if (part.type === "file") return `[file:${part.path}]` + if (part.type === "agent") return `@${part.name}` + if (part.type === "image") return `[image:${part.filename}]` + return part.content + }) + .join("") + .trim() + + createEffect(() => { + if (!prompt.ready()) return + setSessionHandoff(sessionKey(), { prompt: previewPrompt() }) + }) + + const [responding, setResponding] = createSignal() + const permissionResponding = () => { + const perm = permissionRequest() + if (!perm) return false + return responding() === perm.id + } + + const decide = (response: "once" | "always" | "reject") => { + const perm = permissionRequest() + if (!perm) return + if (responding() === perm.id) return + + setResponding(perm.id) + sdk.client.permission + .respond({ sessionID: perm.sessionID, permissionID: perm.id, response }) + .catch((err: unknown) => { + const message = err instanceof Error ? err.message : String(err) + showToast({ title: language.t("common.requestFailed"), description: message }) + }) + .finally(() => { + setResponding((id) => (id === perm.id ? undefined : id)) + }) + } + + const done = createMemo( + () => todos().length > 0 && todos().every((todo) => todo.status === "completed" || todo.status === "cancelled"), + ) + + const [dock, setDock] = createSignal(todos().length > 0) + const [closing, setClosing] = createSignal(false) + const [opening, setOpening] = createSignal(false) + let timer: number | undefined + let raf: number | undefined + + const scheduleClose = () => { + if (timer) window.clearTimeout(timer) + timer = window.setTimeout(() => { + setDock(false) + setClosing(false) + timer = undefined + }, 400) + } + + createEffect( + on( + () => [todos().length, done()] as const, + ([count, complete], prev) => { + if (raf) cancelAnimationFrame(raf) + raf = undefined + + if (count === 0) { + if (timer) window.clearTimeout(timer) + timer = undefined + setDock(false) + setClosing(false) + setOpening(false) + return + } + + if (!complete) { + if (timer) window.clearTimeout(timer) + timer = undefined + const wasHidden = !dock() || closing() + setDock(true) + setClosing(false) + if (wasHidden) { + setOpening(true) + raf = requestAnimationFrame(() => { + setOpening(false) + raf = undefined + }) + return + } + setOpening(false) + return + } + + if (prev && prev[1]) { + if (closing() && !timer) scheduleClose() + return + } + + setDock(true) + setOpening(false) + setClosing(true) + scheduleClose() + }, + ), + ) + + onCleanup(() => { + if (!timer) return + window.clearTimeout(timer) + }) + + onCleanup(() => { + if (!raf) return + cancelAnimationFrame(raf) + }) + return (
- + {(req) => { - const subtitle = questionSubtitle(req.questions.length, (key) => props.t(key)) return ( -
- +
) }} - - {(perm) => ( -
- - 0}> -
- - {(pattern) => {pattern}} - -
-
- -
- {props.t("settings.permissions.tool.doom_loop.description")} -
-
-
-
-
- - - -
+ + {(perm) => { + const toolDescription = () => { + const key = `settings.permissions.tool.${perm.permission}.description` + const value = language.t(key as Parameters[0]) + if (value === key) return "" + return value + } + + return ( +
+ + + + +
{language.t("notification.permission.title")}
+
+ } + footer={ + <> +
+
+ + + +
+ + } + > + +
+
+
+ + 0}> +
+
+
+
-
- )} + ) + }} - + - {props.handoffPrompt || props.t("prompt.loading")} + {handoffPrompt() || language.t("prompt.loading")}
} > - + +
+ +
+
+
+ +
diff --git a/packages/app/src/pages/session/session-side-panel.tsx b/packages/app/src/pages/session/session-side-panel.tsx index 33954f64a12d..07b18f3146d5 100644 --- a/packages/app/src/pages/session/session-side-panel.tsx +++ b/packages/app/src/pages/session/session-side-panel.tsx @@ -1,156 +1,268 @@ -import { For, Match, Show, Switch, createMemo, onCleanup, type JSX, type ValidComponent } from "solid-js" +import { For, Match, Show, Switch, createEffect, createMemo, onCleanup, type JSX } from "solid-js" +import { createStore } from "solid-js/store" +import { createMediaQuery } from "@solid-primitives/media" +import { useParams } from "@solidjs/router" import { Tabs } from "@opencode-ai/ui/tabs" import { IconButton } from "@opencode-ai/ui/icon-button" import { Tooltip, TooltipKeybind } from "@opencode-ai/ui/tooltip" import { ResizeHandle } from "@opencode-ai/ui/resize-handle" import { Mark } from "@opencode-ai/ui/logo" +import { DragDropProvider, DragDropSensors, DragOverlay, SortableProvider, closestCenter } from "@thisbeyond/solid-dnd" +import type { DragEvent } from "@thisbeyond/solid-dnd" +import { ConstrainDragYAxis, getDraggableId } from "@/utils/solid-dnd" +import { useDialog } from "@opencode-ai/ui/context/dialog" + import FileTree from "@/components/file-tree" import { SessionContextUsage } from "@/components/session-context-usage" -import { SessionContextTab, SortableTab, FileVisual } from "@/components/session" import { DialogSelectFile } from "@/components/dialog-select-file" -import { createFileTabListSync } from "@/pages/session/file-tab-scroll" -import { FileTabContent } from "@/pages/session/file-tabs" -import { StickyAddButton } from "@/pages/session/review-tab" -import { DragDropProvider, DragDropSensors, DragOverlay, SortableProvider, closestCenter } from "@thisbeyond/solid-dnd" -import { ConstrainDragYAxis } from "@/utils/solid-dnd" -import type { DragEvent } from "@thisbeyond/solid-dnd" -import { useComments } from "@/context/comments" +import { SessionContextTab, SortableTab, FileVisual } from "@/components/session" import { useCommand } from "@/context/command" -import { useDialog } from "@opencode-ai/ui/context/dialog" import { useFile, type SelectedLineRange } from "@/context/file" import { useLanguage } from "@/context/language" import { useLayout } from "@/context/layout" import { useSync } from "@/context/sync" -import type { Message, UserMessage } from "@opencode-ai/sdk/v2/client" - -type SessionSidePanelViewModel = { - messages: () => Message[] - visibleUserMessages: () => UserMessage[] - view: () => ReturnType["view"]> - info: () => ReturnType["session"]["get"]> -} +import { createFileTabListSync } from "@/pages/session/file-tab-scroll" +import { FileTabContent } from "@/pages/session/file-tabs" +import { createOpenSessionFileTab, getTabReorderIndex } from "@/pages/session/helpers" +import { StickyAddButton } from "@/pages/session/review-tab" +import { setSessionHandoff } from "@/pages/session/handoff" export function SessionSidePanel(props: { - open: boolean - reviewOpen: boolean - language: ReturnType - layout: ReturnType - command: ReturnType - dialog: ReturnType - file: ReturnType - comments: ReturnType - hasReview: boolean - reviewCount: number - reviewTab: boolean - contextOpen: () => boolean - openedTabs: () => string[] - activeTab: () => string - activeFileTab: () => string | undefined - tabs: () => ReturnType["tabs"]> - openTab: (value: string) => void - showAllFiles: () => void reviewPanel: () => JSX.Element - vm: SessionSidePanelViewModel - handoffFiles: () => Record | undefined - codeComponent: NonNullable - addCommentToContext: (input: { - file: string - selection: SelectedLineRange - comment: string - preview?: string - origin?: "review" | "file" - }) => void - activeDraggable: () => string | undefined - onDragStart: (event: unknown) => void - onDragEnd: () => void - onDragOver: (event: DragEvent) => void - fileTreeTab: () => "changes" | "all" - setFileTreeTabValue: (value: string) => void - diffsReady: boolean - diffFiles: string[] - kinds: Map activeDiff?: string focusReviewDiff: (path: string) => void }) { - const openedTabs = createMemo(() => props.openedTabs()) + const params = useParams() + const layout = useLayout() + const sync = useSync() + const file = useFile() + const language = useLanguage() + const command = useCommand() + const dialog = useDialog() + + const isDesktop = createMediaQuery("(min-width: 768px)") + const sessionKey = createMemo(() => `${params.dir}${params.id ? "/" + params.id : ""}`) + const tabs = createMemo(() => layout.tabs(sessionKey)) + const view = createMemo(() => layout.view(sessionKey)) + + const reviewOpen = createMemo(() => isDesktop() && view().reviewPanel.opened()) + const open = createMemo(() => isDesktop() && (view().reviewPanel.opened() || layout.fileTree.opened())) + const reviewTab = createMemo(() => isDesktop() && !layout.fileTree.opened()) + + const info = createMemo(() => (params.id ? sync.session.get(params.id) : undefined)) + const diffs = createMemo(() => (params.id ? (sync.data.session_diff[params.id] ?? []) : [])) + const reviewCount = createMemo(() => Math.max(info()?.summary?.files ?? 0, diffs().length)) + const hasReview = createMemo(() => reviewCount() > 0) + const diffsReady = createMemo(() => { + const id = params.id + if (!id) return true + if (!hasReview()) return true + return sync.data.session_diff[id] !== undefined + }) + + const diffFiles = createMemo(() => diffs().map((d) => d.file)) + const kinds = createMemo(() => { + const merge = (a: "add" | "del" | "mix" | undefined, b: "add" | "del" | "mix") => { + if (!a) return b + if (a === b) return a + return "mix" as const + } + + const normalize = (p: string) => p.replaceAll("\\\\", "/").replace(/\/+$/, "") + + const out = new Map() + for (const diff of diffs()) { + const file = normalize(diff.file) + const kind = diff.status === "added" ? "add" : diff.status === "deleted" ? "del" : "mix" + + out.set(file, kind) + + const parts = file.split("/") + for (const [idx] of parts.slice(0, -1).entries()) { + const dir = parts.slice(0, idx + 1).join("/") + if (!dir) continue + out.set(dir, merge(out.get(dir), kind)) + } + } + return out + }) + + const normalizeTab = (tab: string) => { + if (!tab.startsWith("file://")) return tab + return file.tab(tab) + } + + const openReviewPanel = () => { + if (!view().reviewPanel.opened()) view().reviewPanel.open() + } + + const openTab = createOpenSessionFileTab({ + normalizeTab, + openTab: tabs().open, + pathFromTab: file.pathFromTab, + loadFile: file.load, + openReviewPanel, + setActive: tabs().setActive, + }) + + const contextOpen = createMemo(() => tabs().active() === "context" || tabs().all().includes("context")) + const openedTabs = createMemo(() => + tabs() + .all() + .filter((tab) => tab !== "context" && tab !== "review"), + ) + + const activeTab = createMemo(() => { + const active = tabs().active() + if (active === "context") return "context" + if (active === "review" && reviewTab()) return "review" + if (active && file.pathFromTab(active)) return normalizeTab(active) + + const first = openedTabs()[0] + if (first) return first + if (contextOpen()) return "context" + if (reviewTab() && hasReview()) return "review" + return "empty" + }) + + const activeFileTab = createMemo(() => { + const active = activeTab() + if (!openedTabs().includes(active)) return + return active + }) + + const fileTreeTab = () => layout.fileTree.tab() + + const setFileTreeTabValue = (value: string) => { + if (value !== "changes" && value !== "all") return + layout.fileTree.setTab(value) + } + + const showAllFiles = () => { + if (fileTreeTab() !== "changes") return + layout.fileTree.setTab("all") + } + + const [store, setStore] = createStore({ + activeDraggable: undefined as string | undefined, + }) + + const handleDragStart = (event: unknown) => { + const id = getDraggableId(event) + if (!id) return + setStore("activeDraggable", id) + } + + const handleDragOver = (event: DragEvent) => { + const { draggable, droppable } = event + if (!draggable || !droppable) return + + const currentTabs = tabs().all() + const toIndex = getTabReorderIndex(currentTabs, draggable.id.toString(), droppable.id.toString()) + if (toIndex === undefined) return + tabs().move(draggable.id.toString(), toIndex) + } + + const handleDragEnd = () => { + setStore("activeDraggable", undefined) + } + + createEffect(() => { + if (!file.ready()) return + + setSessionHandoff(sessionKey(), { + files: tabs() + .all() + .reduce>((acc, tab) => { + const path = file.pathFromTab(tab) + if (!path) return acc + + const selected = file.selectedLines(path) + acc[path] = + selected && typeof selected === "object" && "start" in selected && "end" in selected + ? (selected as SelectedLineRange) + : null + + return acc + }, {}), + }) + }) return ( - +