diff --git a/.github/workflows/agents_desktop_build.yml b/.github/workflows/agents_desktop_build.yml new file mode 100644 index 0000000000..111ef40e99 --- /dev/null +++ b/.github/workflows/agents_desktop_build.yml @@ -0,0 +1,691 @@ +name: Agents Desktop Build + +on: + workflow_call: + inputs: + channel: + required: true + type: string + version: + required: true + type: string + git_ref: + required: true + type: string + publish: + required: true + type: boolean + sign: + required: true + type: boolean + release_tag: + required: false + type: string + default: '' + release_name: + required: false + type: string + default: '' + +jobs: + prepare-release: + name: Prepare + runs-on: ubuntu-latest + steps: + - name: Checkout + if: ${{ inputs.publish || (inputs.channel == 'pr' && github.event_name == 'pull_request') }} + uses: actions/checkout@v5.0.0 + with: + fetch-depth: 0 + ref: ${{ inputs.git_ref }} + + - name: Create or update PR artifact comment + if: ${{ inputs.channel == 'pr' && github.event_name == 'pull_request' }} + uses: actions/github-script@v7 + continue-on-error: true + with: + script: | + const marker = '' + const platforms = [ + ['macos-arm64', 'macOS Apple Silicon'], + ['macos-x64', 'macOS Intel'], + ['windows-x64', 'Windows x64'], + ['linux-x64', 'Linux x64'], + ] + const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}` + const sha = context.payload.pull_request.head.sha + const shortSha = sha.slice(0, 7) + const rows = platforms + .map(([, label]) => `| ${label} | Building | Pending |`) + .join('\n') + const body = [ + marker, + '## Electric Agents Desktop Builds', + '', + `Build artifacts for commit \`${shortSha}\` are in progress.`, + '', + '| Platform | Status | Artifact |', + '| --- | --- | --- |', + rows, + '', + `[Workflow run](${runUrl})`, + ].join('\n') + + const { owner, repo } = context.repo + const issue_number = context.payload.pull_request.number + const comments = await github.paginate(github.rest.issues.listComments, { + owner, + repo, + issue_number, + per_page: 100, + }) + const existing = comments.find((comment) => comment.body?.includes(marker)) + + if (existing) { + await github.rest.issues.updateComment({ + owner, + repo, + comment_id: existing.id, + body, + }) + } else { + await github.rest.issues.createComment({ + owner, + repo, + issue_number, + body, + }) + } + + - name: Create or update GitHub release + if: ${{ inputs.publish }} + shell: bash + env: + CHANNEL: ${{ inputs.channel }} + GH_TOKEN: ${{ github.token }} + RELEASE_NAME: ${{ inputs.release_name }} + RELEASE_TAG: ${{ inputs.release_tag }} + SIGN: ${{ inputs.sign }} + VERSION: ${{ inputs.version }} + run: | + set -euo pipefail + + if [[ -z "$RELEASE_TAG" ]]; then + echo "release_tag is required when publish is true" >&2 + exit 1 + fi + + COMMIT_SHA="$(git rev-parse HEAD)" + RUN_URL="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" + + if [[ "$CHANNEL" == "canary" ]]; then + git tag -f "$RELEASE_TAG" "$COMMIT_SHA" + git push origin "refs/tags/${RELEASE_TAG}" --force + + { + echo "Canary build for Electric Agents Desktop." + echo + echo "- Source commit: ${COMMIT_SHA}" + echo "- Workflow run: ${RUN_URL}" + echo "- Build timestamp: $(date -u +"%Y-%m-%dT%H:%M:%SZ")" + echo "- Desktop package version: ${VERSION}" + echo "- Signed/notarized: ${SIGN}" + echo + echo "Canary builds are pre-release quality and may be unsigned." + } > release-notes.md + + if gh release view "$RELEASE_TAG" >/dev/null 2>&1; then + gh release edit "$RELEASE_TAG" \ + --title "$RELEASE_NAME" \ + --notes-file release-notes.md \ + --prerelease + else + gh release create "$RELEASE_TAG" \ + --target "$COMMIT_SHA" \ + --title "$RELEASE_NAME" \ + --notes-file release-notes.md \ + --prerelease + fi + else + if gh release view "$RELEASE_TAG" >/dev/null 2>&1; then + gh release edit "$RELEASE_TAG" --title "$RELEASE_NAME" + else + gh release create "$RELEASE_TAG" \ + --target "$COMMIT_SHA" \ + --title "$RELEASE_NAME" \ + --notes "Desktop artifacts for Electric Agents ${VERSION}." + fi + fi + + build: + name: Build ${{ matrix.name }} + needs: prepare-release + runs-on: ${{ matrix.runs_on }} + strategy: + fail-fast: false + matrix: + include: + - name: macOS + id: macos + runs_on: macos-14 + builder_args: --mac --arm64 --x64 + - name: Windows x64 + id: windows-x64 + runs_on: windows-latest + builder_args: --win --x64 + - name: Linux x64 + id: linux-x64 + runs_on: ubuntu-latest + builder_args: --linux --x64 + + steps: + - name: Checkout + uses: actions/checkout@v5.0.0 + with: + fetch-depth: 0 + ref: ${{ inputs.git_ref }} + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.tool-versions' + cache: pnpm + + - name: Install dependencies + run: pnpm --filter @electric-ax/agents-desktop... install --frozen-lockfile + + - name: Build desktop type dependencies + run: pnpm --filter @electric-ax/agents... build + + - name: Typecheck desktop app + run: pnpm --filter @electric-ax/agents-desktop typecheck + + - name: Build desktop app + run: pnpm --filter @electric-ax/agents-desktop build + + - name: Build desktop icons + run: pnpm --filter @electric-ax/agents-desktop build:icons + + - name: Rebuild native modules + run: pnpm --filter @electric-ax/agents-desktop rebuild:native + + - name: Package macOS desktop app + if: ${{ matrix.id == 'macos' }} + shell: bash + env: + CSC_FOR_PULL_REQUEST: ${{ inputs.sign && 'false' || 'true' }} + CSC_IDENTITY_AUTO_DISCOVERY: ${{ inputs.sign && 'true' || 'false' }} + GH_TOKEN: ${{ github.token }} + run: | + set -euo pipefail + + builder_args=(${{ matrix.builder_args }}) + if [[ "${{ inputs.sign }}" != "true" ]]; then + builder_args+=("-c.mac.identity=-") + fi + + pnpm --filter @electric-ax/agents-desktop exec electron-builder "${builder_args[@]}" --publish never + + - name: Package desktop app + if: ${{ matrix.id != 'macos' }} + env: + CSC_IDENTITY_AUTO_DISCOVERY: ${{ inputs.sign && 'true' || 'false' }} + GH_TOKEN: ${{ github.token }} + run: pnpm --filter @electric-ax/agents-desktop exec electron-builder ${{ matrix.builder_args }} --publish never + + - name: Verify macOS app signatures + if: ${{ matrix.id == 'macos' }} + shell: bash + run: | + set -euo pipefail + + verify_signature() { + local app_dir="$1" + + codesign -dv --verbose=4 "$app_dir" + codesign --verify --deep --verbose=4 "$app_dir" + } + + verify_signature "packages/agents-desktop/release/mac-arm64/Electric Agents.app" + verify_signature "packages/agents-desktop/release/mac/Electric Agents.app" + + - name: Verify macOS native module architectures + if: ${{ matrix.id == 'macos' }} + shell: bash + run: | + set -euo pipefail + + check_arch() { + local app_dir="$1" + local expected="$2" + local found=0 + + while IFS= read -r -d '' node_file; do + found=1 + info="$(file "$node_file")" + echo "$info" + if [[ "$info" != *"$expected"* ]]; then + echo "Expected $node_file to contain $expected" >&2 + exit 1 + fi + done < <(find "$app_dir" -name '*.node' -print0) + + if [[ "$found" -eq 0 ]]; then + echo "No native .node files found under $app_dir" >&2 + exit 1 + fi + } + + check_arch "packages/agents-desktop/release/mac-arm64" "arm64" + check_arch "packages/agents-desktop/release/mac" "x86_64" + + - name: Upload macOS Apple Silicon DMG + id: upload-macos-arm64-dmg + if: ${{ matrix.id == 'macos' }} + uses: actions/upload-artifact@v4 + with: + name: electric-agents-desktop-${{ inputs.channel }}-macos-arm64-dmg + retention-days: ${{ inputs.channel == 'pr' && 7 || 30 }} + if-no-files-found: error + path: packages/agents-desktop/release/*mac-arm64.dmg + + - name: Upload macOS Intel DMG + id: upload-macos-x64-dmg + if: ${{ matrix.id == 'macos' }} + uses: actions/upload-artifact@v4 + with: + name: electric-agents-desktop-${{ inputs.channel }}-macos-x64-dmg + retention-days: ${{ inputs.channel == 'pr' && 7 || 30 }} + if-no-files-found: error + path: packages/agents-desktop/release/*mac-x64.dmg + + - name: Upload Windows installer + id: upload-windows-x64-exe + if: ${{ matrix.id == 'windows-x64' }} + uses: actions/upload-artifact@v4 + with: + name: electric-agents-desktop-${{ inputs.channel }}-windows-x64-exe + retention-days: ${{ inputs.channel == 'pr' && 7 || 30 }} + if-no-files-found: error + path: packages/agents-desktop/release/*.exe + + - name: Upload Linux AppImage + id: upload-linux-x64-appimage + if: ${{ matrix.id == 'linux-x64' }} + uses: actions/upload-artifact@v4 + with: + name: electric-agents-desktop-${{ inputs.channel }}-linux-x64-appimage + retention-days: ${{ inputs.channel == 'pr' && 7 || 30 }} + if-no-files-found: error + path: packages/agents-desktop/release/*.AppImage + + - name: Upload Linux deb + id: upload-linux-x64-deb + if: ${{ matrix.id == 'linux-x64' }} + uses: actions/upload-artifact@v4 + with: + name: electric-agents-desktop-${{ inputs.channel }}-linux-x64-deb + retention-days: ${{ inputs.channel == 'pr' && 7 || 30 }} + if-no-files-found: error + path: packages/agents-desktop/release/*.deb + + - name: Update PR artifact comment for ${{ matrix.name }} + if: ${{ always() && inputs.channel == 'pr' && github.event_name == 'pull_request' }} + uses: actions/github-script@v7 + continue-on-error: true + env: + LINUX_APPIMAGE_URL: ${{ steps.upload-linux-x64-appimage.outputs.artifact-url }} + LINUX_DEB_URL: ${{ steps.upload-linux-x64-deb.outputs.artifact-url }} + MACOS_ARM64_DMG_URL: ${{ steps.upload-macos-arm64-dmg.outputs.artifact-url }} + MACOS_X64_DMG_URL: ${{ steps.upload-macos-x64-dmg.outputs.artifact-url }} + PLATFORM_ID: ${{ matrix.id }} + PLATFORM_LABEL: ${{ matrix.name }} + WINDOWS_EXE_URL: ${{ steps.upload-windows-x64-exe.outputs.artifact-url }} + with: + script: | + const marker = '' + const platforms = [ + ['macos-arm64', 'macOS Apple Silicon'], + ['macos-x64', 'macOS Intel'], + ['windows-x64', 'Windows x64'], + ['linux-x64', 'Linux x64'], + ] + const { owner, repo } = context.repo + const issue_number = context.payload.pull_request.number + const runUrl = `${context.serverUrl}/${owner}/${repo}/actions/runs/${context.runId}` + const sha = context.payload.pull_request.head.sha + const shortSha = sha.slice(0, 7) + const label = process.env.PLATFORM_LABEL + const platformId = process.env.PLATFORM_ID + const rowsByLabel = buildRows() + + const comments = await github.paginate(github.rest.issues.listComments, { + owner, + repo, + issue_number, + per_page: 100, + }) + const existing = comments.find((comment) => comment.body?.includes(marker)) + let nextBody = existing?.body ?? renderInitialBody() + for (const [platformLabel, row] of rowsByLabel) { + nextBody = replacePlatformRow(nextBody, platformLabel, row) + } + + if (existing) { + await github.rest.issues.updateComment({ + owner, + repo, + comment_id: existing.id, + body: nextBody, + }) + } else { + await github.rest.issues.createComment({ + owner, + repo, + issue_number, + body: nextBody, + }) + } + + function renderInitialBody() { + return [ + marker, + '## Electric Agents Desktop Builds', + '', + `Build artifacts for commit \`${shortSha}\` are in progress.`, + '', + '| Platform | Status | Artifact |', + '| --- | --- | --- |', + platforms + .map(([, platformLabel]) => `| ${platformLabel} | Building | Pending |`) + .join('\n'), + '', + `[Workflow run](${runUrl})`, + ].join('\n') + } + + function replacePlatformRow(body, platformLabel, row) { + const lines = body.split('\n') + const rowIndex = lines.findIndex((line) => + line.startsWith(`| ${platformLabel} |`) + ) + if (rowIndex === -1) { + return body + } + + lines[rowIndex] = row + return lines.join('\n') + } + + function buildRows() { + switch (platformId) { + case 'macos': + return [ + [ + 'macOS Apple Silicon', + buildRow( + 'macOS Apple Silicon', + process.env.MACOS_ARM64_DMG_URL + ? `[DMG](${process.env.MACOS_ARM64_DMG_URL})` + : null + ), + ], + [ + 'macOS Intel', + buildRow( + 'macOS Intel', + process.env.MACOS_X64_DMG_URL + ? `[DMG](${process.env.MACOS_X64_DMG_URL})` + : null + ), + ], + ] + case 'linux-x64': + return [ + [ + 'Linux x64', + buildRow( + 'Linux x64', + [ + process.env.LINUX_APPIMAGE_URL + ? `[AppImage](${process.env.LINUX_APPIMAGE_URL})` + : null, + process.env.LINUX_DEB_URL + ? `[deb](${process.env.LINUX_DEB_URL})` + : null, + ] + .filter(Boolean) + .join(' / ') || null + ), + ], + ] + case 'windows-x64': + return [ + [ + 'Windows x64', + buildRow( + 'Windows x64', + process.env.WINDOWS_EXE_URL + ? `[Installer](${process.env.WINDOWS_EXE_URL})` + : null + ), + ], + ] + default: + return [[label, buildRow(label, null)]] + } + } + + function buildRow(platformLabel, artifact) { + const status = artifact ? 'Passed' : 'Failed' + return `| ${platformLabel} | ${status} | ${artifact ?? 'Unavailable'} |` + } + + - name: Prepare release assets + if: ${{ inputs.publish }} + shell: bash + env: + CHANNEL: ${{ inputs.channel }} + MATRIX_ID: ${{ matrix.id }} + run: | + set -euo pipefail + shopt -s nullglob + + mkdir -p packages/agents-desktop/publish-assets + + copy_first() { + local destination="$1" + shift + + for file in "$@"; do + if [[ -f "$file" ]]; then + cp "$file" "packages/agents-desktop/publish-assets/${destination}" + return + fi + done + + echo "No asset found for ${destination}" >&2 + exit 1 + } + + if [[ "$CHANNEL" == "canary" ]]; then + case "$MATRIX_ID" in + macos) + copy_first "Electric-Agents-canary-mac-arm64.dmg" packages/agents-desktop/release/*mac-arm64.dmg packages/agents-desktop/release/*arm64.dmg + copy_first "Electric-Agents-canary-mac-arm64.zip" packages/agents-desktop/release/*mac-arm64.zip packages/agents-desktop/release/*arm64.zip + copy_first "Electric-Agents-canary-mac-x64.dmg" packages/agents-desktop/release/*mac-x64.dmg packages/agents-desktop/release/*x64.dmg + copy_first "Electric-Agents-canary-mac-x64.zip" packages/agents-desktop/release/*mac-x64.zip packages/agents-desktop/release/*x64.zip + ;; + windows-x64) + copy_first "Electric-Agents-canary-windows-x64.exe" packages/agents-desktop/release/*.exe + ;; + linux-x64) + copy_first "Electric-Agents-canary-linux-x64.AppImage" packages/agents-desktop/release/*.AppImage + copy_first "Electric-Agents-canary-linux-x64.deb" packages/agents-desktop/release/*.deb + ;; + esac + else + cp packages/agents-desktop/release/*.{dmg,zip,exe,AppImage,deb,blockmap,yml,yaml} \ + packages/agents-desktop/publish-assets/ 2>/dev/null || true + fi + + assets=(packages/agents-desktop/publish-assets/*) + if (( ${#assets[@]} == 0 )); then + echo "No publish assets were prepared" >&2 + exit 1 + fi + + - name: Upload assets to GitHub release + if: ${{ inputs.publish }} + shell: bash + env: + GH_TOKEN: ${{ github.token }} + RELEASE_TAG: ${{ inputs.release_tag }} + run: gh release upload "$RELEASE_TAG" packages/agents-desktop/publish-assets/* --clobber + + update-pr-comment: + name: Update PR artifact comment + needs: build + if: ${{ always() && inputs.channel == 'pr' && github.event_name == 'pull_request' }} + runs-on: ubuntu-latest + steps: + - name: Update PR artifact comment + uses: actions/github-script@v7 + continue-on-error: true + with: + script: | + const marker = '' + const platforms = [ + { + id: 'macos', + label: 'macOS Apple Silicon', + jobName: 'build / Build macOS', + artifacts: [ + ['DMG', 'electric-agents-desktop-pr-macos-arm64-dmg'], + ], + }, + { + id: 'macos', + label: 'macOS Intel', + jobName: 'build / Build macOS', + artifacts: [['DMG', 'electric-agents-desktop-pr-macos-x64-dmg']], + }, + { + id: 'windows-x64', + label: 'Windows x64', + jobName: 'build / Build Windows x64', + artifacts: [ + ['Installer', 'electric-agents-desktop-pr-windows-x64-exe'], + ], + }, + { + id: 'linux-x64', + label: 'Linux x64', + jobName: 'build / Build Linux x64', + artifacts: [ + ['AppImage', 'electric-agents-desktop-pr-linux-x64-appimage'], + ['deb', 'electric-agents-desktop-pr-linux-x64-deb'], + ], + }, + ] + + const { owner, repo } = context.repo + const issue_number = context.payload.pull_request.number + const runUrl = `${context.serverUrl}/${owner}/${repo}/actions/runs/${context.runId}` + const sha = context.payload.pull_request.head.sha + const shortSha = sha.slice(0, 7) + + const [jobs, artifacts] = await Promise.all([ + github.paginate(github.rest.actions.listJobsForWorkflowRun, { + owner, + repo, + run_id: context.runId, + per_page: 100, + }), + github.paginate(github.rest.actions.listWorkflowRunArtifacts, { + owner, + repo, + run_id: context.runId, + per_page: 100, + }), + ]) + + const artifactByName = new Map( + artifacts.map((artifact) => [ + artifact.name, + `${context.serverUrl}/${owner}/${repo}/actions/runs/${context.runId}/artifacts/${artifact.id}`, + ]) + ) + + const rows = platforms + .map((platform) => { + const job = jobs.find((candidate) => candidate.name === platform.jobName) + const status = formatStatus(job) + const artifact = platform.artifacts + .map(([label, artifactName]) => { + const artifactUrl = artifactByName.get(artifactName) + return artifactUrl ? `[${label}](${artifactUrl})` : null + }) + .filter(Boolean) + .join(' / ') || 'Unavailable' + return `| ${platform.label} | ${status} | ${artifact} |` + }) + .join('\n') + + const body = [ + marker, + '## Electric Agents Desktop Builds', + '', + `Build artifacts for commit \`${shortSha}\`.`, + '', + '| Platform | Status | Artifact |', + '| --- | --- | --- |', + rows, + '', + `[Workflow run](${runUrl})`, + ].join('\n') + + const comments = await github.paginate(github.rest.issues.listComments, { + owner, + repo, + issue_number, + per_page: 100, + }) + const existing = comments.find((comment) => comment.body?.includes(marker)) + + if (existing) { + await github.rest.issues.updateComment({ + owner, + repo, + comment_id: existing.id, + body, + }) + } else { + await github.rest.issues.createComment({ + owner, + repo, + issue_number, + body, + }) + } + + function formatStatus(job) { + if (!job) return 'Unknown' + if (job.status !== 'completed') return 'Building' + + switch (job.conclusion) { + case 'success': + return 'Passed' + case 'failure': + return 'Failed' + case 'cancelled': + return 'Cancelled' + case 'skipped': + return 'Skipped' + default: + return job.conclusion || 'Completed' + } + } diff --git a/.github/workflows/agents_desktop_canary.yml b/.github/workflows/agents_desktop_canary.yml new file mode 100644 index 0000000000..3bd84e61de --- /dev/null +++ b/.github/workflows/agents_desktop_canary.yml @@ -0,0 +1,71 @@ +name: Agents Desktop Canary + +on: + push: + branches: + - main + paths: + - 'packages/agents-desktop/**' + - 'packages/agents-server-ui/**' + - 'packages/agents/**' + - 'packages/agents-mcp/**' + - 'packages/agents-runtime/**' + - '.github/workflows/agents_desktop_*.yml' + - 'scripts/ci/desktop-affected.mjs' + - '.npmrc' + - '.tool-versions' + - 'package.json' + - 'patches/**' + - 'pnpm-lock.yaml' + - 'pnpm-workspace.yaml' + - 'tsconfig.base.json' + - 'tsconfig.build.json' + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: write + +jobs: + detect: + name: Detect desktop impact + runs-on: ubuntu-latest + outputs: + should_build: ${{ steps.detect.outputs.should_build }} + reason: ${{ steps.detect.outputs.reason }} + steps: + - name: Checkout + uses: actions/checkout@v5.0.0 + with: + fetch-depth: 0 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.tool-versions' + + - name: Detect desktop impact + id: detect + env: + BASE_SHA: ${{ github.event.before }} + run: node scripts/ci/desktop-affected.mjs + + build-and-publish: + needs: detect + if: ${{ needs.detect.outputs.should_build == 'true' }} + uses: ./.github/workflows/agents_desktop_build.yml + secrets: inherit + with: + channel: canary + version: canary-${{ github.run_number }}-${{ github.sha }} + git_ref: ${{ github.sha }} + publish: true + sign: false + release_tag: agents-desktop-canary + release_name: Electric Agents Desktop Canary diff --git a/.github/workflows/agents_desktop_pr.yml b/.github/workflows/agents_desktop_pr.yml new file mode 100644 index 0000000000..9df663ddd2 --- /dev/null +++ b/.github/workflows/agents_desktop_pr.yml @@ -0,0 +1,69 @@ +name: Agents Desktop PR + +on: + pull_request: + paths: + - 'packages/agents-desktop/**' + - 'packages/agents-server-ui/**' + - 'packages/agents/**' + - 'packages/agents-mcp/**' + - 'packages/agents-runtime/**' + - '.github/workflows/agents_desktop_*.yml' + - 'scripts/ci/desktop-affected.mjs' + - '.npmrc' + - '.tool-versions' + - 'package.json' + - 'patches/**' + - 'pnpm-lock.yaml' + - 'pnpm-workspace.yaml' + - 'tsconfig.base.json' + - 'tsconfig.build.json' + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.event.number || github.ref }} + cancel-in-progress: true + +permissions: + actions: read + contents: read + issues: write + pull-requests: write + +jobs: + detect: + name: Detect desktop impact + runs-on: ubuntu-latest + outputs: + should_build: ${{ steps.detect.outputs.should_build }} + reason: ${{ steps.detect.outputs.reason }} + steps: + - name: Checkout + uses: actions/checkout@v5.0.0 + with: + fetch-depth: 0 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.tool-versions' + + - name: Detect desktop impact + id: detect + env: + BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.before }} + run: node scripts/ci/desktop-affected.mjs + + build: + needs: detect + if: ${{ needs.detect.outputs.should_build == 'true' }} + uses: ./.github/workflows/agents_desktop_build.yml + with: + channel: pr + version: pr-${{ github.event.pull_request.number || github.run_number }}-${{ github.sha }} + git_ref: ${{ github.event.pull_request.head.sha || github.sha }} + publish: false + sign: false diff --git a/.github/workflows/changesets_release.yml b/.github/workflows/changesets_release.yml index 10437e4e9c..8f6b8b8bce 100644 --- a/.github/workflows/changesets_release.yml +++ b/.github/workflows/changesets_release.yml @@ -21,6 +21,8 @@ jobs: published: ${{ steps.changesets.outputs.published }} sync_service_release_tag: ${{ steps.sync_service_release_tag.outputs.tag }} agent_server_release_tag: ${{ steps.agent_server_release_tag.outputs.tag }} + desktop_release_version: ${{ steps.desktop_release.outputs.version }} + desktop_release_tag: ${{ steps.desktop_release.outputs.tag }} steps: - uses: actions/checkout@v4 with: @@ -63,6 +65,16 @@ jobs: PUBLISHED_PACKAGES='${{ steps.changesets.outputs.publishedPackages }}' TAGS=$(echo "$PUBLISHED_PACKAGES" | jq -r '.[] | select(.name == "@electric-ax/agents-server") | .name + "@" + .version') echo "tag=$TAGS" >> "$GITHUB_OUTPUT" + - name: Capture the new agents-desktop release as an output (if any) + id: desktop_release + if: steps.changesets.outputs.published == 'true' + run: | + PUBLISHED_PACKAGES='${{ steps.changesets.outputs.publishedPackages }}' + VERSION=$(echo "$PUBLISHED_PACKAGES" | jq -r '.[] | select(.name == "@electric-ax/agents-desktop") | .version' | head -n 1) + if [ -n "$VERSION" ]; then + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + echo "tag=@electric-ax/agents-desktop@$VERSION" >> "$GITHUB_OUTPUT" + fi - name: Add latest tag to published packages if: steps.changesets.outputs.published == 'true' run: node scripts/tag-latest.mjs @@ -89,6 +101,22 @@ jobs: with: git_ref: ${{ needs.changesets.outputs.agent_server_release_tag }} + publish-agents-desktop: + needs: changesets + if: ${{ needs.changesets.outputs.published == 'true' && needs.changesets.outputs.desktop_release_tag != '' }} + uses: ./.github/workflows/agents_desktop_build.yml + permissions: + contents: write + secrets: inherit + with: + channel: stable + version: ${{ needs.changesets.outputs.desktop_release_version }} + git_ref: ${{ needs.changesets.outputs.desktop_release_tag }} + publish: true + sign: false + release_tag: ${{ needs.changesets.outputs.desktop_release_tag }} + release_name: Electric Agents Desktop v${{ needs.changesets.outputs.desktop_release_version }} + update-cloud: name: Update Electric version used by Cloud runs-on: ubuntu-latest diff --git a/DESKTOP_APP_PUBLISH_PLAN.md b/DESKTOP_APP_PUBLISH_PLAN.md new file mode 100644 index 0000000000..5dc424d2d5 --- /dev/null +++ b/DESKTOP_APP_PUBLISH_PLAN.md @@ -0,0 +1,480 @@ +# Desktop App Publish Plan + +## Goal + +Configure CI/CD for `packages/agents-desktop` so the Electric Agents desktop app +is packaged consistently, published as canary builds from `main`, attached to +full Changesets releases, and made discoverable from the website. + +## Current State + +- `packages/agents-desktop` builds the Electron main/preload bundles and reuses + the `agents-server-ui` desktop renderer build. +- The package has no desktop packager yet: no installer targets, no release + publisher, no signing/notarization, and no update metadata. +- Changesets already supports private packages via: + + ```json + "privatePackages": { "tag": true, "version": true } + ``` + +- `@electric-ax/agents-desktop` is already covered by Changesets, so full + releases can be triggered from package version/tag events rather than a + parallel release mechanism. + +## Recommended Packaging Tool + +Use `electron-builder`. + +Reasons: + +- The app is already a Vite/Electron package rather than an Electron Forge app. +- `electron-builder` can package the existing output with less restructuring. +- It has mature GitHub Releases publishing support and generates update metadata + for future auto-update work. +- It handles common desktop targets across macOS, Windows, and Linux. + +Electron Forge is viable, but adopting it would require more package reshaping. +For this repo, `electron-builder` is the lower-friction path. + +## Release Targets + +Build and publish these artifacts: + +| Platform | Architecture | Runner | Artifact | +| -------- | --------------------- | -------------------------------- | ------------------------------ | +| macOS | Apple Silicon / arm64 | `macos-14` or newer arm64 runner | signed `.dmg` and `.zip` | +| macOS | Intel / x64 | `macos-13` or x64 macOS runner | signed `.dmg` and `.zip` | +| Windows | x64 | `windows-latest` | signed `.exe` installer | +| Linux | x64 | `ubuntu-latest` | `.AppImage`, optionally `.deb` | + +macOS must be built separately for `arm64` and `x64`. Do not rely on one +architecture to cross-build the other until the native module packaging path is +proven, because the desktop app depends on native modules such as +`better-sqlite3` and `sqlite-vec`. + +Universal macOS builds can be considered later, but the first release path +should publish separate Intel and Apple Silicon downloads. This keeps signing, +notarization, and native module debugging simpler. + +## Tools + +- `electron-builder`: packages Electron apps, creates installers, publishes to + GitHub Releases, and emits update metadata for future auto-update work. +- `electron-rebuild` or `@electron/rebuild`: rebuilds native modules against the + Electron ABI during install/package preparation. +- `@electron/notarize`: used by `electron-builder` for macOS notarization when + signing secrets are present. +- GitHub Actions: runs PR builds, main canaries, and full release builds. +- GitHub Releases: stores stable and canary desktop artifacts. +- Changesets: versions `@electric-ax/agents-desktop` and decides when a stable + desktop release should run. +- `gh` CLI: creates/updates canary releases and uploads release assets when + `electron-builder` is not the best fit for a particular upload step. + +## Package Changes + +Update `packages/agents-desktop` with: + +- `electron-builder` config in either `package.json` or + `electron-builder.yml`. +- a native rebuild step for Electron: + - during packaging via `electron-builder install-app-deps`, or + - explicitly via `@electron/rebuild`. +- scripts: + - `build`: current Vite/Electron build. + - `dist`: build and package with `--publish never`. + - `dist:mac`: package macOS for the runner architecture. + - `dist:win`: package Windows. + - `dist:linux`: package Linux. + - `publish:desktop`: package and publish with `--publish always`. + +Initial `electron-builder` config should define: + +- `appId`: `com.electric-sql.agents`. +- `productName`: `Electric Agents`. +- `directories.output`: `release`. +- `files`: compiled desktop files, `package.json`, and required runtime assets. +- `extraResources`: the `agents-server-ui/dist-desktop` renderer output. +- `asarUnpack`: native modules and any runtime files that must remain unpacked. +- `publish.provider`: `github`. +- `publish.owner`: `electric-sql`. +- `publish.repo`: `electric`. +- artifact names that include channel, platform, version, and architecture. + +Fix production path resolution in `main.ts`. Today the app loads: + +```text +../agents-server-ui/dist-desktop/index.html +``` + +That path is monorepo-relative and will not be correct once packaged. The +packaged app should resolve the renderer from `process.resourcesPath` when +`app.isPackaged` is true, while keeping the current monorepo path for local +`pnpm start`/development. + +## CI Workflow Design + +Create one reusable workflow: + +```text +.github/workflows/agents_desktop_build.yml +``` + +Use `workflow_call` inputs: + +- `channel`: `pr`, `canary`, or `stable`. +- `version`: package version or canary identifier. +- `git_ref`: commit/tag to build. +- `publish`: boolean. +- `sign`: boolean. +- `release_tag`: GitHub release tag to upload to. +- `release_name`: GitHub release title. + +Use a matrix: + +```text +macos-arm64: runs-on macos-14 or arm64 macOS runner, arch arm64 +macos-x64: runs-on macos-13 or x64 macOS runner, arch x64 +windows-x64: runs-on windows-latest, arch x64 +linux-x64: runs-on ubuntu-latest, arch x64 +``` + +Each matrix job should: + +1. Check out `git_ref`. +2. Set up pnpm and Node from `.tool-versions`. +3. Install dependencies with a filter rooted at `@electric-ax/agents-desktop`. +4. Build dependency packages. +5. Run desktop typecheck. +6. Build the desktop app. +7. Rebuild Electron native modules for the target platform/arch. +8. Import signing credentials if `sign == true`. +9. Run `electron-builder` for the platform/arch. +10. Upload artifacts to GitHub Actions. +11. If `publish == true`, upload assets to the target GitHub Release. + +The reusable workflow gives PR, canary, and stable releases the same build path. +The only differences should be channel, signing, release tag, and whether assets +are published. + +## PR Build Workflow + +Create: + +```text +.github/workflows/agents_desktop_pr.yml +``` + +Trigger on `pull_request` for: + +- `packages/agents-desktop/**` +- `packages/agents-server-ui/**` +- `packages/agents/**` +- `packages/agents-runtime/**` +- `.github/workflows/agents_desktop_*.yml` +- `package.json` +- `pnpm-lock.yaml` +- `pnpm-workspace.yaml` + +Call the reusable workflow with: + +- `channel`: `pr` +- `version`: `pr-${{ github.event.pull_request.number }}-${{ github.sha }}` +- `git_ref`: pull request head SHA +- `publish`: `false` +- `sign`: `false` + +Artifacts should be unsigned and uploaded to the workflow run with short +retention, for example 7 days. These are smoke-test artifacts, not public +downloads. + +## Canary Builds From `main` + +Create: + +```text +.github/workflows/agents_desktop_canary.yml +``` + +Trigger on `push` to `main` using the same desktop path filters. + +Call the reusable workflow with: + +- `channel`: `canary` +- `version`: `canary-${{ github.run_number }}-${{ github.sha }}` +- `git_ref`: `${{ github.sha }}` +- `publish`: `true` +- `sign`: preferably `true` once secrets are configured; otherwise `false` +- `release_tag`: `agents-desktop-canary` +- `release_name`: `Electric Agents Desktop Canary` + +Before uploading assets, delete or replace the previous canary assets so URLs +remain stable. Publish fixed names such as: + +- `Electric-Agents-canary-mac-arm64.dmg` +- `Electric-Agents-canary-mac-x64.dmg` +- `Electric-Agents-canary-windows-x64.exe` +- `Electric-Agents-canary-linux-x64.AppImage` + +The canary release body should include: + +- source commit SHA; +- workflow run URL; +- build timestamp; +- package version from `packages/agents-desktop/package.json`; +- signing/notarization status; +- warning that canary builds are pre-release quality. + +## Stable Releases Through Changesets + +Keep Changesets as the source of truth for stable desktop releases. + +`changesets_release.yml` currently runs `changesets/action`, publishes packages, +captures selected package tags, and triggers follow-up release jobs such as +Docker publishing. Extend that workflow with a desktop output: + +```text +desktop_release_version +desktop_release_tag +``` + +Derive those from `steps.changesets.outputs.publishedPackages` by selecting +`@electric-ax/agents-desktop`. + +When `@electric-ax/agents-desktop` is present: + +1. Set `desktop_release_version` to the published version. +2. Set `desktop_release_tag` to the Changesets-created package tag, + `@electric-ax/agents-desktop@${version}`. +3. Create or update that GitHub Release. +4. Call `.github/workflows/agents_desktop_build.yml` with: + - `channel`: `stable` + - `version`: `${version}` + - `git_ref`: `@electric-ax/agents-desktop@${version}` + - `publish`: `true` + - `sign`: `true` + - `release_tag`: `@electric-ax/agents-desktop@${version}` + - `release_name`: `Electric Agents Desktop v${version}` +5. Upload the macOS arm64, macOS x64, Windows, and Linux artifacts. +6. Update website download metadata after successful artifact upload. + +Use the Changesets package tag for public desktop assets. This keeps stable +desktop artifacts attached to the same release event that versioned +`@electric-ax/agents-desktop`. + +The Changesets release PR should still update: + +- `packages/agents-desktop/package.json` +- `packages/agents-desktop/CHANGELOG.md`, once a changelog exists +- any linked internal package versions + +The desktop artifact build should happen only after the Changesets publish step +reports that the desktop package was included. This prevents every package +release from rebuilding desktop artifacts unnecessarily. + +## Website Download Links + +Add: + +```text +website/data/agents-desktop-downloads.json +``` + +The file should contain: + +- latest stable desktop version; +- stable release tag; +- canary release tag; +- per-platform download asset names; +- whether each channel is signed/notarized. + +The Agents landing page can render: + +- "Download for macOS Apple Silicon"; +- "Download for macOS Intel"; +- "Download for Windows"; +- "Download for Linux"; +- "Canary builds" as a secondary/pre-release section. + +For stable releases, update the website data file as part of the Changesets +release flow after desktop assets are uploaded. That update can be a direct +commit from CI or, preferably, a small automated PR if we want review on website +copy changes. + +For canaries, keep the website URLs fixed against `agents-desktop-canary`; no +website update is needed per canary. + +## Signing and Notarization + +### macOS + +macOS public releases should be signed with a Developer ID Application +certificate and notarized by Apple. + +Use `electron-builder` mac signing plus `@electron/notarize`. + +Required GitHub secrets: + +- `MACOS_DEVELOPER_ID_CERTIFICATE_BASE64`: base64-encoded `.p12` certificate. +- `MACOS_DEVELOPER_ID_CERTIFICATE_PASSWORD`: password for the `.p12`. +- `MACOS_KEYCHAIN_PASSWORD`: temporary CI keychain password. +- `APPLE_TEAM_ID`: Apple Developer Team ID. + +For notarization, prefer App Store Connect API key auth: + +- `APPLE_API_KEY_ID` +- `APPLE_API_ISSUER_ID` +- `APPLE_API_KEY_P8` + +Alternative notarization auth, if API key auth is not available: + +- `APPLE_ID` +- `APPLE_APP_SPECIFIC_PASSWORD` +- `APPLE_TEAM_ID` + +macOS signing process in CI: + +1. Decode the `.p12` certificate. +2. Create a temporary keychain. +3. Import the certificate into that keychain. +4. Configure key partition list so `codesign` can access the key non- + interactively. +5. Run `electron-builder --mac --arm64` on the arm64 runner and + `electron-builder --mac --x64` on the x64 runner. +6. Let `electron-builder` sign the app bundle. +7. Notarize the signed `.dmg`/`.zip`. +8. Staple notarization tickets where applicable. +9. Verify with `spctl` and `codesign --verify`. + +PR builds should skip this. Stable releases should require it. Canary builds can +start unsigned but should move to signed as soon as the Apple credentials are +available. + +### Windows + +Windows public releases should be Authenticode signed. + +Two viable options: + +- Use `electron-builder` certificate signing with: + - `WIN_CSC_LINK`: base64 certificate or secure URL to a `.p12`/`.pfx`. + - `WIN_CSC_KEY_PASSWORD`: certificate password. +- Use a managed signing service such as Azure Trusted Signing, with its own + OIDC/service-principal configuration. + +Pick one before public stable release. For the first implementation, +`electron-builder` certificate signing is the simplest path if we already have a +Windows code signing certificate. + +Windows signing process in CI: + +1. Make the signing certificate available only on release/canary jobs. +2. Run `electron-builder --win --x64`. +3. Let `electron-builder` sign the installer and executable. +4. Verify signatures with `signtool verify`. + +PR builds should be unsigned. + +### Linux + +Linux artifacts do not need code signing for the initial release. If we publish +`.deb`, we can later add package repository signing if we host an apt repository. + +## GitHub Permissions and Secrets + +Workflow permissions: + +- PR build workflow: + - `contents: read` +- canary and stable workflows: + - `contents: write` to create/update releases and upload assets + +Secrets used by publishing: + +- `GITHUB_TOKEN`: provided by GitHub Actions; used by `gh` and + `electron-builder` for GitHub Releases. +- macOS signing/notarization secrets listed above. +- Windows signing secrets listed above. + +Do not expose signing secrets to pull request workflows from forks. Signing +steps should run only on trusted events: `push` to `main`, Changesets stable +release jobs, or manually approved environments. + +## Auto-Update + +Do not block initial CI publishing on auto-update. + +Once signed releases are reliable: + +- use `electron-builder` generated update metadata; +- decide between GitHub Releases/update.electronjs.org and a custom update + provider; +- wire the Electron main process to check for updates. + +Because this repository is public and artifacts will live on GitHub Releases, +GitHub-based updates are the likely default. macOS updates require signed builds. + +## Implementation Plan + +### 1. Add Desktop Packaging + +Add `electron-builder`, package config, packaging scripts, native module rebuild +support, and packaged renderer path resolution. + +### 2. Add PR Build Workflow + +Add `agents_desktop_pr.yml` and call the reusable build workflow with unsigned, +unpublished artifacts for macOS arm64, macOS x64, Windows x64, and Linux x64. + +### 3. Publish Canary Builds From `main` + +Add `agents_desktop_canary.yml` to publish a moving +`agents-desktop-canary` GitHub prerelease from `main`. + +### 4. Hook Full Releases Into Changesets + +Extend `changesets_release.yml` so `@electric-ax/agents-desktop` in +`publishedPackages` triggers signed stable artifacts on the Changesets-created +package tag. + +### 5. Add Website Download Links + +Add `website/data/agents-desktop-downloads.json` and render separate download +links for macOS Apple Silicon, macOS Intel, Windows, Linux, and canary builds. + +### 6. Add Signing and Notarization + +Add macOS Developer ID signing/notarization and Windows Authenticode signing for +stable releases. Keep PR artifacts unsigned. + +### 7. Add Auto-Update Later + +Use `electron-builder` update metadata after signed releases are reliable. + +## Suggested Phasing + +1. Add `electron-builder`, native rebuilds, and packaged renderer resources. +2. Add unsigned PR artifacts for macOS arm64, macOS x64, Windows x64, and Linux + x64. +3. Add `main` canary publishing to `agents-desktop-canary`. +4. Add macOS signing/notarization and Windows signing secrets. +5. Integrate signed stable desktop artifacts into Changesets releases. +6. Add website download links for stable and canary builds. +7. Add auto-update. + +## Decisions + +- Release-blocking platforms for v1: Windows x64, macOS Apple Silicon, macOS + Intel, and Linux x64. +- Full release assets should live on the Changesets package tag rather than a + separate `agents-desktop-v${version}` alias tag. +- Unsigned canaries are acceptable on `main` while signing is being configured. + The intent is still to get signing in place before public release if possible. +- Windows signing provider is undecided. Start with the simplest + `electron-builder` path if a `.pfx` certificate is available; otherwise + evaluate managed signing such as Azure Trusted Signing. +- Do not promote canary downloads on the website before the first signed stable + desktop release. +- Keep separate macOS Apple Silicon and Intel downloads. Do not create universal + macOS builds for the initial release path. diff --git a/packages/agents-desktop/.gitignore b/packages/agents-desktop/.gitignore index 8e7dc7fcbf..2e8ce50edf 100644 --- a/packages/agents-desktop/.gitignore +++ b/packages/agents-desktop/.gitignore @@ -1,5 +1,8 @@ node_modules +build +build-mac-icon dist +release logs *.log .DS_Store diff --git a/packages/agents-desktop/assets/icon-mac.png b/packages/agents-desktop/assets/icon-mac.png new file mode 100644 index 0000000000..d9233ebd7d Binary files /dev/null and b/packages/agents-desktop/assets/icon-mac.png differ diff --git a/packages/agents-desktop/assets/icon-mark.svg b/packages/agents-desktop/assets/icon-mark.svg new file mode 100644 index 0000000000..4f02a69190 --- /dev/null +++ b/packages/agents-desktop/assets/icon-mark.svg @@ -0,0 +1,4 @@ + + + + diff --git a/packages/agents-desktop/assets/icon.png b/packages/agents-desktop/assets/icon.png index 5f47f5924d..4734273cfd 100644 Binary files a/packages/agents-desktop/assets/icon.png and b/packages/agents-desktop/assets/icon.png differ diff --git a/packages/agents-desktop/assets/icon.svg b/packages/agents-desktop/assets/icon.svg new file mode 100644 index 0000000000..561671ece7 --- /dev/null +++ b/packages/agents-desktop/assets/icon.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/packages/agents-desktop/electron-builder.yml b/packages/agents-desktop/electron-builder.yml new file mode 100644 index 0000000000..7d94dfa02c --- /dev/null +++ b/packages/agents-desktop/electron-builder.yml @@ -0,0 +1,67 @@ +appId: com.electric-sql.agents +productName: Electric Agents +artifactName: Electric-Agents-${version}-${os}-${arch}.${ext} + +directories: + buildResources: build + output: release + +files: + - dist/**/* + - assets/**/* + - package.json + +extraResources: + - from: ../agents-server-ui/dist-desktop + to: renderer + filter: + - '**/*' + - from: assets + to: assets + filter: + - '**/*' + +asar: true +asarUnpack: + - '**/*.node' + - '**/node_modules/better-sqlite3/**/*' + - '**/node_modules/sqlite-vec/**/*' + +mac: + category: public.app-category.developer-tools + hardenedRuntime: true + gatekeeperAssess: false + icon: build/icons/mac/icon.icns + target: + - target: dmg + arch: + - x64 + - arm64 + - target: zip + arch: + - x64 + - arm64 + +win: + icon: build/icons/win/icon.ico + target: + - target: nsis + arch: + - x64 + +linux: + category: Development + icon: build/icons/png + maintainer: ElectricSQL + target: + - target: AppImage + arch: + - x64 + - target: deb + arch: + - x64 + +publish: + provider: github + owner: electric-sql + repo: electric diff --git a/packages/agents-desktop/package.json b/packages/agents-desktop/package.json index 12530de927..495e500461 100644 --- a/packages/agents-desktop/package.json +++ b/packages/agents-desktop/package.json @@ -3,6 +3,9 @@ "productName": "Electric Agents", "private": true, "version": "0.0.0", + "description": "Desktop app for Electric Agents", + "author": "ElectricSQL ", + "homepage": "https://electric-sql.com", "type": "module", "main": "./dist/main.cjs", "scripts": { @@ -10,26 +13,35 @@ "dev": "pnpm --filter @electric-ax/agents build && pnpm run ensure:electron && concurrently -k -n ui,desktop -c cyan,green \"pnpm run dev:ui\" \"pnpm run dev:desktop\"", "dev:ui": "pnpm --filter @electric-ax/agents-server-ui dev:desktop", "dev:desktop": "wait-on -d 200 http-get://localhost:5183 && vite", + "build:icons": "node scripts/build-icons.mjs", + "dist": "pnpm run build && pnpm run build:icons && pnpm run rebuild:native && electron-builder --publish never", + "dist:linux": "pnpm run build && pnpm run build:icons && pnpm run rebuild:native && electron-builder --linux --publish never", + "dist:mac": "pnpm run build && pnpm run build:icons && pnpm run rebuild:native && electron-builder --mac --publish never", + "dist:win": "pnpm run build && pnpm run build:icons && pnpm run rebuild:native && electron-builder --win --publish never", "ensure:electron": "node ./node_modules/electron/install.js", + "publish:desktop": "pnpm run build && pnpm run build:icons && pnpm run rebuild:native && electron-builder --publish always", + "rebuild:native": "electron-builder install-app-deps", "start": "pnpm run ensure:electron && electron .", "coverage": "true", "typecheck": "tsc --noEmit" }, "dependencies": { - "@electric-ax/agents": "workspace:*", - "@electric-ax/agents-server-ui": "workspace:*", "@mixmark-io/domino": "^2.2.0", - "better-sqlite3": "^11.10.0", + "better-sqlite3": "^12.9.0", + "jsdom": "^28.1.0", "pino": "^10.3.1", "pino-pretty": "^13.0.0", - "turndown-plugin-gfm": "^1.0.2", - "jsdom": "^28.1.0", - "sqlite-vec": "^0.1.9" + "sqlite-vec": "^0.1.9", + "turndown-plugin-gfm": "^1.0.2" }, "devDependencies": { + "@electric-ax/agents": "workspace:*", + "@electric-ax/agents-server-ui": "workspace:*", "@types/node": "^22.19.17", "concurrently": "^8.2.2", "electron": "^41.5.0", + "electron-builder": "^26.8.1", + "electron-icon-builder": "^2.0.1", "typescript": "^5.8.3", "vite": "^7.1.7", "vite-plugin-electron": "^0.29.1", diff --git a/packages/agents-desktop/scripts/build-icons.mjs b/packages/agents-desktop/scripts/build-icons.mjs new file mode 100644 index 0000000000..d6cfad3723 --- /dev/null +++ b/packages/agents-desktop/scripts/build-icons.mjs @@ -0,0 +1,39 @@ +import { copyFileSync, rmSync } from 'node:fs' +import { dirname, join } from 'node:path' +import { fileURLToPath } from 'node:url' +import { execFileSync } from 'node:child_process' +import { createRequire } from 'node:module' + +const packageDir = dirname(dirname(fileURLToPath(import.meta.url))) +const require = createRequire(import.meta.url) +const iconBuilderBin = require.resolve(`electron-icon-builder/index.js`) +const outputDir = join(packageDir, `build`) +const baseIcon = join(packageDir, `assets`, `icon.png`) +const macIcon = join(packageDir, `assets`, `icon-mac.png`) +const macOnlyOutputDir = join(packageDir, `build-mac-icon`) + +function runIconBuilder(input, output) { + execFileSync( + process.execPath, + [iconBuilderBin, `--input`, input, `--output`, output], + { + cwd: packageDir, + stdio: `inherit`, + } + ) +} + +rmSync(outputDir, { recursive: true, force: true }) +rmSync(macOnlyOutputDir, { recursive: true, force: true }) + +// Build Windows/Linux icons from the general source icon. +runIconBuilder(baseIcon, outputDir) + +// Build macOS separately so the .icns uses the mac-specific rounded icon. +runIconBuilder(macIcon, macOnlyOutputDir) +copyFileSync( + join(macOnlyOutputDir, `icons`, `mac`, `icon.icns`), + join(outputDir, `icons`, `mac`, `icon.icns`) +) + +rmSync(macOnlyOutputDir, { recursive: true, force: true }) diff --git a/packages/agents-desktop/src/main.ts b/packages/agents-desktop/src/main.ts index 8971bb3ac6..d4f0953afb 100644 --- a/packages/agents-desktop/src/main.ts +++ b/packages/agents-desktop/src/main.ts @@ -1,5 +1,8 @@ -import { BuiltinAgentsServer } from '@electric-ax/agents' -import type { McpServerConfig, RegistrySnapshot } from '@electric-ax/agents' +import type { + BuiltinAgentsServer, + McpServerConfig, + RegistrySnapshot, +} from '@electric-ax/agents' import { openAuthorizeWindow } from './oauth-window' import { BrowserWindow, @@ -10,6 +13,7 @@ import { dialog, ipcMain, nativeImage, + nativeTheme, shell, } from 'electron' import { mkdir, readFile, writeFile } from 'node:fs/promises' @@ -102,17 +106,20 @@ type ApiKeysStatus = { const MODULE_DIR = path.dirname(fileURLToPath(import.meta.url)) const PACKAGE_DIR = path.resolve(MODULE_DIR, `..`) -const RENDERER_INDEX = path.resolve( - PACKAGE_DIR, - `../agents-server-ui/dist-desktop/index.html` -) +const RESOURCE_DIR = app.isPackaged ? process.resourcesPath : PACKAGE_DIR +const RENDERER_INDEX = app.isPackaged + ? path.join(RESOURCE_DIR, `renderer`, `index.html`) + : path.resolve(PACKAGE_DIR, `../agents-server-ui/dist-desktop/index.html`) const PRELOAD_PATH = path.resolve(MODULE_DIR, `preload.cjs`) -const TRAY_ICON_PATH = path.resolve(PACKAGE_DIR, `assets/trayTemplate.png`) -const TRAY_ICON_2X_PATH = path.resolve( - PACKAGE_DIR, - `assets/trayTemplate@2x.png` +const TRAY_ICON_PATH = path.join(RESOURCE_DIR, `assets`, `trayTemplate.png`) +const TRAY_ICON_2X_PATH = path.join( + RESOURCE_DIR, + `assets`, + `trayTemplate@2x.png` ) -const APP_ICON_PATH = path.resolve(PACKAGE_DIR, `assets/icon.png`) +const APP_ICON_FILE = + process.platform === `darwin` ? `icon-mac.png` : `icon.png` +const APP_ICON_PATH = path.join(RESOURCE_DIR, `assets`, APP_ICON_FILE) const APP_DISPLAY_NAME = `Electric Agents` const MAX_CONNECTIONS_PER_HOST = `256` @@ -156,6 +163,7 @@ type DesktopCommand = | `new-chat` | `close-tile` | `toggle-sidebar` + | `open-settings` | `open-search` | `open-find` | `find-next` @@ -164,6 +172,29 @@ type DesktopCommand = | `split-down` | `cycle-tile` +type DesktopMenuSection = `File` | `Edit` | `View` | `Window` | `Help` + +type DesktopMenuPopupBounds = { + x: number + y: number + width: number + height: number +} + +type DesktopMenuState = { + hasActiveTile: boolean + canCloseTile: boolean + canSplitTile: boolean + canCycleTile: boolean +} + +type DesktopNavigationState = { + canGoBack: boolean + canGoForward: boolean +} + +type DesktopAppearance = `light` | `dark` + type DesktopContextMenuRequest = { kind: `selection` selectionText: string @@ -213,6 +244,16 @@ let aboutWindow: BrowserWindow | null = null let isQuitting = false const windows = new Set() +function configureRuntimeEnvironment(): void { + // Packaged macOS apps can launch with cwd `/`, which makes the agents + // logger's default `./logs` path resolve to unwritable `/logs`. + process.env.ELECTRIC_AGENTS_LOG_DIR ??= path.join( + app.getPath(`userData`), + `logs` + ) +} +configureRuntimeEnvironment() + function settingsPath(): string { return path.join(app.getPath(`userData`), `settings.json`) } @@ -502,6 +543,26 @@ function broadcastState(): void { } } +function getNavigationState(win: BrowserWindow): DesktopNavigationState { + return { + canGoBack: win.webContents.canGoBack(), + canGoForward: win.webContents.canGoForward(), + } +} + +function sendNavigationState(win: BrowserWindow): void { + if (win.isDestroyed()) return + win.webContents.send( + `desktop:navigation-state-changed`, + getNavigationState(win) + ) +} + +function sendFullscreenState(win: BrowserWindow): void { + if (win.isDestroyed()) return + win.webContents.send(`desktop:fullscreen-state-changed`, win.isFullScreen()) +} + function setState(patch: Partial): void { state = { ...state, ...patch } updateTray() @@ -509,6 +570,8 @@ function setState(patch: Partial): void { } function createWindow(): BrowserWindow { + const isMac = process.platform === `darwin` + const isWindows = process.platform === `win32` const win = new BrowserWindow({ width: 1280, height: 900, @@ -519,16 +582,34 @@ function createWindow(): BrowserWindow { // overlaid on the window content. The renderer paints the toolbar // with extra left-padding so its icons sit to the right of the // traffic lights and the row reads as a single chrome strip. - // Other platforms get a frameless window with custom in-app - // title bars. - titleBarStyle: process.platform === `darwin` ? `hiddenInset` : `hidden`, - frame: process.platform === `darwin`, + // macOS keeps the native traffic lights in a hiddenInset titlebar. + // Windows/Linux use a hidden titlebar plus Electron's native + // window-controls overlay so the renderer can paint a Cursor-style + // icon/menu strip on the same row as the minimize/maximize/close + // controls. + titleBarStyle: isMac ? `hiddenInset` : `hidden`, + frame: true, + autoHideMenuBar: !isMac, + // Keep true transparent windows macOS-only. On Windows, `transparent: true` + // creates a layered window, which drops the native DWM border, rounded + // corners, and shadow. Mica is applied via `backgroundMaterial` instead. + transparent: isMac, + backgroundColor: isMac ? `#00000000` : undefined, + vibrancy: isMac ? `sidebar` : undefined, + visualEffectState: isMac ? `active` : undefined, + backgroundMaterial: isWindows ? `mica` : undefined, + titleBarOverlay: isMac + ? undefined + : { + color: isWindows ? `#00000000` : `#f7f7f7`, + symbolColor: `#1f2328`, + height: 34, + }, // Standard macOS hiddenInset traffic-light origin (top-left of the // leftmost light). The renderer matches the 44px desktop header // height so the 24px IconButton glyphs flex-center to the same y as // the light centers — the row reads as a single chrome strip. - trafficLightPosition: - process.platform === `darwin` ? { x: 16, y: 14 } : undefined, + trafficLightPosition: isMac ? { x: 16, y: 14 } : undefined, webPreferences: { preload: PRELOAD_PATH, contextIsolation: true, @@ -537,9 +618,22 @@ function createWindow(): BrowserWindow { }, }) + if (isMac) { + win.setVibrancy(`sidebar`) + } else if (isWindows) { + win.setBackgroundMaterial(`mica`) + } + windows.add(win) + if (!isMac) { + win.setMenuBarVisibility(false) + } installEditableContextMenu(win) installExternalLinkHandler(win) + installNavigationStateBridge(win) + win.on(`enter-full-screen`, () => sendFullscreenState(win)) + win.on(`leave-full-screen`, () => sendFullscreenState(win)) + win.webContents.on(`did-finish-load`, () => sendFullscreenState(win)) win.on(`closed`, () => { windows.delete(win) buildApplicationMenu() @@ -571,6 +665,13 @@ function createWindow(): BrowserWindow { return win } +function installNavigationStateBridge(win: BrowserWindow): void { + const notify = () => sendNavigationState(win) + win.webContents.on(`did-finish-load`, notify) + win.webContents.on(`did-navigate`, notify) + win.webContents.on(`did-navigate-in-page`, notify) +} + function isExternalLink(url: string): boolean { try { return EXTERNAL_LINK_PROTOCOLS.has(new URL(url).protocol) @@ -706,6 +807,74 @@ async function stopExistingRuntime(): Promise { } } +type AgentsServerHealthResult = { ok: true } | { ok: false; reason: string } + +function buildAgentsServerHealthUrl(baseUrl: string): string { + try { + return new URL(`/_electric/health`, baseUrl).toString() + } catch { + const trimmed = baseUrl.replace(/\/+$/, ``) + return `${trimmed}/_electric/health` + } +} + +function formatStartupNetworkError( + error: unknown, + activeServerUrl: string +): string | null { + if (!(error instanceof Error)) return null + if (!/fetch failed/i.test(error.message)) return null + const cause = (error as Error & { cause?: unknown }).cause + const details = + cause && typeof cause === `object` && `code` in cause + ? String((cause as { code?: unknown }).code ?? ``).trim() + : `` + const suffix = details ? ` (${details})` : `` + return [ + `Could not connect to agents-server at ${activeServerUrl}.`, + `Make sure it is running, then retry.${suffix}`, + ].join(` `) +} + +async function checkAgentsServerHealth( + baseUrl: string, + timeoutMs: number +): Promise { + const controller = new AbortController() + const timer = setTimeout(() => controller.abort(), timeoutMs) + const healthUrl = buildAgentsServerHealthUrl(baseUrl) + try { + const res = await fetch(healthUrl, { + signal: controller.signal, + headers: { accept: `application/json` }, + }) + if (!res.ok) { + return { + ok: false, + reason: `health check returned ${res.status}`, + } + } + const json = (await res.json()) as { status?: unknown } + if (json?.status !== `ok`) { + return { + ok: false, + reason: `health check returned an unexpected response`, + } + } + return { ok: true } + } catch (error) { + const reason = + error instanceof Error && error.name === `AbortError` + ? `health check timed out after ${timeoutMs}ms` + : error instanceof Error + ? error.message + : String(error) + return { ok: false, reason } + } finally { + clearTimeout(timer) + } +} + function broadcastMcpSnapshot(snapshot: RegistrySnapshot): void { lastMcpSnapshot = snapshot for (const win of windows) { @@ -747,6 +916,18 @@ async function restartRuntime(): Promise { setState({ runtimeStatus: `starting`, runtimeUrl: null, error: null }) + const serverHealth = await checkAgentsServerHealth(activeServer.url, 4_000) + if (!serverHealth.ok) { + setState({ + runtimeStatus: `error`, + runtimeUrl: null, + error: `Could not reach agents-server at ${activeServer.url}: ${serverHealth.reason}.`, + }) + return + } + + configureRuntimeEnvironment() + const { BuiltinAgentsServer } = await import(`@electric-ax/agents`) const nextRuntime = new BuiltinAgentsServer({ agentServerUrl: activeServer.url, host: `127.0.0.1`, @@ -773,7 +954,7 @@ async function restartRuntime(): Promise { // snapshot on subscribe, so renderers always see *something*. const reg = nextRuntime.mcpRegistry if (reg) { - mcpUnsubscribe = reg.subscribe((snapshot) => { + mcpUnsubscribe = reg.subscribe((snapshot: RegistrySnapshot) => { broadcastMcpSnapshot(snapshot) }) } @@ -781,10 +962,16 @@ async function restartRuntime(): Promise { if (runtime === nextRuntime) { runtime = null } + const startupNetworkError = formatStartupNetworkError( + error, + activeServer.url + ) setState({ runtimeStatus: `error`, runtimeUrl: null, - error: error instanceof Error ? error.message : String(error), + error: + startupNetworkError ?? + (error instanceof Error ? error.message : String(error)), }) } } @@ -874,21 +1061,8 @@ let discoveryTimer: NodeJS.Timeout | null = null let discoveryInFlight: Promise | null = null async function probeAgentsServer(url: string): Promise { - const controller = new AbortController() - const timer = setTimeout(() => controller.abort(), DISCOVERY_TIMEOUT_MS) - try { - const res = await fetch(`${url}/_electric/health`, { - signal: controller.signal, - headers: { accept: `application/json` }, - }) - if (!res.ok) return false - const json = (await res.json()) as { status?: unknown } - return json?.status === `ok` - } catch { - return false - } finally { - clearTimeout(timer) - } + const result = await checkAgentsServerHealth(url, DISCOVERY_TIMEOUT_MS) + return result.ok } async function runDiscovery(): Promise { @@ -946,8 +1120,27 @@ function stopDiscoveryLoop(): void { } } +function applyNativeAppearance(appearance: DesktopAppearance): void { + nativeTheme.themeSource = appearance + + const symbolColor = appearance === `dark` ? `#ededee` : `#1f2328` + for (const win of windows) { + win.setTitleBarOverlay?.({ + color: `#00000000`, + symbolColor, + height: 34, + }) + } +} + function registerIpcHandlers(): void { ipcMain.handle(`desktop:get-servers`, () => settings.servers) + ipcMain.handle( + `desktop:set-native-appearance`, + (_event, appearance: DesktopAppearance) => { + applyNativeAppearance(appearance) + } + ) ipcMain.handle( `desktop:save-servers`, async (_event, servers: Array) => { @@ -1025,6 +1218,50 @@ function registerIpcHandlers(): void { } } ) + ipcMain.handle( + `desktop:show-menu-section`, + ( + event, + section: DesktopMenuSection, + bounds: DesktopMenuPopupBounds, + menuState: DesktopMenuState + ) => { + const win = BrowserWindow.fromWebContents(event.sender) + if (!win || win.isDestroyed()) return + popupApplicationMenuSection(win, section, bounds, menuState) + } + ) + ipcMain.handle( + `desktop:show-app-menu`, + (event, bounds: DesktopMenuPopupBounds) => { + const win = BrowserWindow.fromWebContents(event.sender) + if (!win || win.isDestroyed()) return + popupAppIconMenu(win, bounds) + } + ) + ipcMain.handle(`desktop:get-navigation-state`, (event) => { + const win = BrowserWindow.fromWebContents(event.sender) + if (!win || win.isDestroyed()) { + return { + canGoBack: false, + canGoForward: false, + } satisfies DesktopNavigationState + } + return getNavigationState(win) + }) + ipcMain.handle( + `desktop:navigate-history`, + (event, direction: `back` | `forward`) => { + const win = BrowserWindow.fromWebContents(event.sender) + if (!win || win.isDestroyed()) return + if (direction === `back` && win.webContents.canGoBack()) { + win.webContents.goBack() + } else if (direction === `forward` && win.webContents.canGoForward()) { + win.webContents.goForward() + } + sendNavigationState(win) + } + ) // ── MCP registry IPC ───────────────────────────────────────────── // Renderers subscribe to `desktop:mcp-state` push events; this handler @@ -1040,7 +1277,7 @@ function registerIpcHandlers(): void { // Forces a fresh OAuth flow. The registry mutates the entry in // place rather than deleting + re-adding, so the renderer's // snapshot keeps showing the row throughout — no flicker. - await runtime?.mcpRegistry?.reauthorize(name).catch((err) => { + await runtime?.mcpRegistry?.reauthorize(name).catch((err: unknown) => { console.warn(`[agents-desktop] mcp-authorize ${name}:`, err) }) }) @@ -1048,17 +1285,17 @@ function registerIpcHandlers(): void { const reg = runtime?.mcpRegistry const entry = reg?.get(name) if (!reg || !entry) return - await reg.addServer(entry.config).catch((err) => { + await reg.addServer(entry.config).catch((err: unknown) => { console.warn(`[agents-desktop] mcp-reconnect ${name}:`, err) }) }) ipcMain.handle(`desktop:mcp-disable`, async (_event, name: string) => { - await runtime?.mcpRegistry?.disable(name).catch((err) => { + await runtime?.mcpRegistry?.disable(name).catch((err: unknown) => { console.warn(`[agents-desktop] mcp-disable ${name}:`, err) }) }) ipcMain.handle(`desktop:mcp-enable`, async (_event, name: string) => { - await runtime?.mcpRegistry?.enable(name).catch((err) => { + await runtime?.mcpRegistry?.enable(name).catch((err: unknown) => { console.warn(`[agents-desktop] mcp-enable ${name}:`, err) }) }) @@ -1214,7 +1451,7 @@ function showAboutDialog(): void { void win.loadURL(`data:text/html;charset=utf-8,${encodeURIComponent(html)}`) } -function buildApplicationMenu(): void { +function buildApplicationMenuTemplate(): Array { const isMac = process.platform === `darwin` const focused = BrowserWindow.getFocusedWindow() const liveWindows = [...windows].filter((win) => !win.isDestroyed()) @@ -1234,6 +1471,16 @@ function buildApplicationMenu(): void { accelerator: `Shift+CommandOrControl+N`, click: () => createWindow(), }, + ...(!isMac + ? ([ + { type: `separator` }, + { + label: `Settings…`, + accelerator: `CommandOrControl+,`, + click: () => sendCommand(`open-settings`), + }, + ] as Array) + : []), { type: `separator` }, { label: `Close Tile`, @@ -1247,7 +1494,7 @@ function buildApplicationMenu(): void { }, ] - const template: Array = [ + return [ ...(isMac ? [ { @@ -1255,6 +1502,12 @@ function buildApplicationMenu(): void { submenu: [ { role: `about` as const }, { type: `separator` as const }, + { + label: `Settings…`, + accelerator: `CommandOrControl+,`, + click: () => sendCommand(`open-settings`), + }, + { type: `separator` as const }, { role: `services` as const }, { type: `separator` as const }, { role: `hide` as const }, @@ -1408,10 +1661,78 @@ function buildApplicationMenu(): void { ], }, ] +} + +function buildApplicationMenu(): void { + const template = buildApplicationMenuTemplate() Menu.setApplicationMenu(Menu.buildFromTemplate(template)) } +function popupApplicationMenuSection( + win: BrowserWindow, + section: DesktopMenuSection, + bounds: DesktopMenuPopupBounds, + state: DesktopMenuState +): void { + const item = buildApplicationMenuTemplate().find( + (candidate) => candidate.label === section + ) + if (!item || !Array.isArray(item.submenu)) return + + Menu.buildFromTemplate(applyDesktopMenuState(item.submenu, state)).popup({ + window: win, + x: Math.round(bounds.x), + y: Math.round(bounds.y + bounds.height), + }) +} + +function popupAppIconMenu( + win: BrowserWindow, + bounds: DesktopMenuPopupBounds +): void { + Menu.buildFromTemplate([ + { + label: `About ${APP_DISPLAY_NAME}`, + click: () => showAboutDialog(), + }, + { + label: `Check for Updates…`, + enabled: false, + }, + ]).popup({ + window: win, + x: Math.round(bounds.x), + y: Math.round(bounds.y + bounds.height), + }) +} + +function applyDesktopMenuState( + items: Array, + state: DesktopMenuState +): Array { + const enabledByLabel = new Map([ + [`Close Tile`, state.canCloseTile], + [`Find in Pane…`, state.hasActiveTile], + [`Find Next`, state.hasActiveTile], + [`Find Previous`, state.hasActiveTile], + [`Split Right`, state.canSplitTile], + [`Split Down`, state.canSplitTile], + [`Cycle Tile`, state.canCycleTile], + ]) + + return items.map((item) => { + const next = { ...item } + if (typeof item.label === `string` && enabledByLabel.has(item.label)) { + next.enabled = enabledByLabel.get(item.label) + } + if (Array.isArray(item.submenu)) { + next.submenu = applyDesktopMenuState(item.submenu, state) + } + return next + }) +} + async function main(): Promise { // Make sure macOS shows the product name everywhere (about menu, // dock tooltip, default window title) instead of the npm package id. @@ -1446,6 +1767,7 @@ async function main(): Promise { }) await app.whenReady() + configureRuntimeEnvironment() await loadSettings() registerIpcHandlers() diff --git a/packages/agents-desktop/src/preload.ts b/packages/agents-desktop/src/preload.ts index 0f901bafda..5f2bf1c3cc 100644 --- a/packages/agents-desktop/src/preload.ts +++ b/packages/agents-desktop/src/preload.ts @@ -1,19 +1,36 @@ import { contextBridge, ipcRenderer } from 'electron' // The Vite desktop build already stamps `` -// into the index, so CSS that targets `html[data-electric-desktop='true']` -// matches from the first paint. We re-apply it here as a safety net in -// case anything (HMR, navigation, etc.) drops the attribute. Wrapped in -// try/catch so a DOM hiccup can never block `contextBridge.exposeInMainWorld` -// further down — losing `window.electronAPI` would break the whole UI. +// into the index, so CSS that targets desktop broadly matches from the first +// paint. The preload adds the runtime platform for macOS-only titlebar chrome. +// Wrapped in try/catch so a DOM hiccup can never block +// `contextBridge.exposeInMainWorld` further down — losing +// `window.electronAPI` would break the whole UI. try { + const applyFullscreenState = (fullscreen: boolean): void => { + document.documentElement.dataset.electricFullscreen = fullscreen + ? `true` + : `false` + } + if (typeof document !== `undefined` && document.documentElement) { document.documentElement.dataset.electricDesktop = `true` + document.documentElement.dataset.electricPlatform = process.platform + applyFullscreenState(false) } else if (typeof window !== `undefined`) { window.addEventListener(`DOMContentLoaded`, () => { document.documentElement.dataset.electricDesktop = `true` + document.documentElement.dataset.electricPlatform = process.platform + applyFullscreenState(false) }) } + + ipcRenderer.on( + `desktop:fullscreen-state-changed`, + (_event, fullscreen: boolean) => { + applyFullscreenState(fullscreen) + } + ) } catch { // Non-fatal — the static attribute in index.html is the source of truth. } @@ -59,6 +76,7 @@ type DesktopCommand = | `new-chat` | `close-tile` | `toggle-sidebar` + | `open-settings` | `open-search` | `open-find` | `find-next` @@ -67,6 +85,29 @@ type DesktopCommand = | `split-down` | `cycle-tile` +type DesktopMenuSection = `File` | `Edit` | `View` | `Window` | `Help` + +type DesktopMenuPopupBounds = { + x: number + y: number + width: number + height: number +} + +type DesktopMenuState = { + hasActiveTile: boolean + canCloseTile: boolean + canSplitTile: boolean + canCycleTile: boolean +} + +type DesktopNavigationState = { + canGoBack: boolean + canGoForward: boolean +} + +type DesktopAppearance = `light` | `dark` + type DesktopContextMenuRequest = { kind: `selection` selectionText: string @@ -139,6 +180,8 @@ const api = { ipcRenderer.invoke(`desktop:save-servers`, servers), getDesktopState: (): Promise => ipcRenderer.invoke(`desktop:get-state`), + setNativeAppearance: (appearance: DesktopAppearance): Promise => + ipcRenderer.invoke(`desktop:set-native-appearance`, appearance), setActiveServer: (server: ServerConfig | null): Promise => ipcRenderer.invoke(`desktop:set-active-server`, server), restartRuntime: (): Promise => @@ -156,6 +199,29 @@ const api = { ipcRenderer.invoke(`desktop:choose-working-directory`), pickDirectory: (options?: { defaultPath?: string }): Promise => ipcRenderer.invoke(`desktop:pick-directory`, options), + showMenuSection: ( + section: DesktopMenuSection, + bounds: DesktopMenuPopupBounds, + state: DesktopMenuState + ): Promise => + ipcRenderer.invoke(`desktop:show-menu-section`, section, bounds, state), + showAppMenu: (bounds: DesktopMenuPopupBounds): Promise => + ipcRenderer.invoke(`desktop:show-app-menu`, bounds), + getNavigationState: (): Promise => + ipcRenderer.invoke(`desktop:get-navigation-state`), + navigateHistory: (direction: `back` | `forward`): Promise => + ipcRenderer.invoke(`desktop:navigate-history`, direction), + onNavigationStateChanged: ( + callback: (state: DesktopNavigationState) => void + ): (() => void) => { + const listener = ( + _event: Electron.IpcRendererEvent, + state: DesktopNavigationState + ) => callback(state) + ipcRenderer.on(`desktop:navigation-state-changed`, listener) + return () => + ipcRenderer.removeListener(`desktop:navigation-state-changed`, listener) + }, onDesktopStateChanged: ( callback: (state: DesktopState) => void ): (() => void) => { diff --git a/packages/agents-mcp/src/config/watcher.ts b/packages/agents-mcp/src/config/watcher.ts index 4bba712457..1d7638aa61 100644 --- a/packages/agents-mcp/src/config/watcher.ts +++ b/packages/agents-mcp/src/config/watcher.ts @@ -1,4 +1,5 @@ import fs from 'node:fs' +import pathUtil from 'node:path' import { loadConfig, type McpConfig } from './loader' export interface WatchOpts { @@ -14,23 +15,32 @@ export interface WatchOpts { * `onChange`, or any error to `onError`. The caller is responsible * for performing the initial load — `watchConfig` only sets up the * subscription so the caller can fully await its first apply before - * subsequent change events start firing. + * subsequent change events start firing. The containing directory is + * watched so an absent `mcp.json` can be created later without making + * startup noisy. */ export async function watchConfig( path: string, opts: WatchOpts ): Promise<() => void> { const debounce = opts.debounceMs ?? 200 + const dir = pathUtil.dirname(path) + const basename = pathUtil.basename(path) let timer: NodeJS.Timeout | undefined const reload = async () => { try { const cfg = await loadConfig(path, opts.env) opts.onChange(cfg) } catch (err) { + if ((err as NodeJS.ErrnoException).code === `ENOENT`) { + opts.onChange({ servers: [], raw: { servers: {} } }) + return + } opts.onError?.(err) } } - const watcher = fs.watch(path, () => { + const watcher = fs.watch(dir, (_event, filename) => { + if (filename && filename.toString() !== basename) return if (timer) clearTimeout(timer) timer = setTimeout(reload, debounce) }) diff --git a/packages/agents-mcp/test/watcher.test.ts b/packages/agents-mcp/test/watcher.test.ts index 57d563f572..d73e89fc18 100644 --- a/packages/agents-mcp/test/watcher.test.ts +++ b/packages/agents-mcp/test/watcher.test.ts @@ -47,4 +47,41 @@ describe(`watchConfig`, () => { stop() } }) + + it(`watches a missing config file when it is created later`, async () => { + await fs.rm(file) + const onChange = vi.fn() + const onError = vi.fn() + const stop = await watchConfig(file, { onChange, onError, debounceMs: 50 }) + try { + await fs.writeFile( + file, + `{ "servers": { "created": { "transport": "stdio", "command": "true" } } }` + ) + await new Promise((r) => setTimeout(r, 200)) + expect(onError).not.toHaveBeenCalled() + expect(onChange).toHaveBeenCalled() + const cfg = onChange.mock.calls[onChange.mock.calls.length - 1]![0] + expect(cfg.servers).toHaveLength(1) + expect(cfg.servers[0]?.name).toBe(`created`) + } finally { + stop() + } + }) + + it(`treats a deleted config file as an empty config`, async () => { + const onChange = vi.fn() + const onError = vi.fn() + const stop = await watchConfig(file, { onChange, onError, debounceMs: 50 }) + try { + await fs.rm(file) + await new Promise((r) => setTimeout(r, 200)) + expect(onError).not.toHaveBeenCalled() + expect(onChange).toHaveBeenCalled() + const cfg = onChange.mock.calls[onChange.mock.calls.length - 1]![0] + expect(cfg.servers).toEqual([]) + } finally { + stop() + } + }) }) diff --git a/packages/agents-server-ui/src/App.tsx b/packages/agents-server-ui/src/App.tsx index ff65a57822..8fe4f76249 100644 --- a/packages/agents-server-ui/src/App.tsx +++ b/packages/agents-server-ui/src/App.tsx @@ -1,4 +1,5 @@ import { RouterProvider } from '@tanstack/react-router' +import { useEffect } from 'react' import { ServerConnectionProvider, useServerConnection, @@ -25,6 +26,10 @@ function ThemedApp(): React.ReactElement { const { darkMode } = useDarkModeContext() const appearance = darkMode ? `dark` : `light` + useEffect(() => { + void window.electronAPI?.setNativeAppearance?.(appearance) + }, [appearance]) + return (
diff --git a/packages/agents-server-ui/src/components/DesktopHistoryButtons.module.css b/packages/agents-server-ui/src/components/DesktopHistoryButtons.module.css new file mode 100644 index 0000000000..662e612b88 --- /dev/null +++ b/packages/agents-server-ui/src/components/DesktopHistoryButtons.module.css @@ -0,0 +1,13 @@ +.historyButtons { + display: none; + align-items: center; + gap: 2px; +} + +:global(html[data-electric-desktop='true']) .historyButtons { + display: inline-flex; +} + +.historyButton:disabled { + cursor: default; +} diff --git a/packages/agents-server-ui/src/components/DesktopHistoryButtons.tsx b/packages/agents-server-ui/src/components/DesktopHistoryButtons.tsx new file mode 100644 index 0000000000..1b52287de1 --- /dev/null +++ b/packages/agents-server-ui/src/components/DesktopHistoryButtons.tsx @@ -0,0 +1,62 @@ +import { useEffect, useState } from 'react' +import { ChevronLeft, ChevronRight } from 'lucide-react' +import { Icon, IconButton, Tooltip } from '../ui' +import { isMacPlatform } from '../hooks/useHotkey' +import type { DesktopNavigationState } from '../lib/server-connection' +import styles from './DesktopHistoryButtons.module.css' + +const INITIAL_STATE: DesktopNavigationState = { + canGoBack: false, + canGoForward: false, +} + +export function DesktopHistoryButtons(): React.ReactElement { + const [navigationState, setNavigationState] = + useState(INITIAL_STATE) + + useEffect(() => { + const api = window.electronAPI + if (!api?.getNavigationState) return + + void api.getNavigationState().then(setNavigationState) + return api.onNavigationStateChanged?.(setNavigationState) + }, []) + + const navigate = (direction: `back` | `forward`): void => { + void window.electronAPI?.navigateHistory?.(direction) + } + + const backShortcut = isMacPlatform() ? `⌘[` : `Alt+Left` + const forwardShortcut = isMacPlatform() ? `⌘]` : `Alt+Right` + + return ( + + + navigate(`back`)} + disabled={!navigationState.canGoBack} + aria-label="Back" + > + + + + + navigate(`forward`)} + disabled={!navigationState.canGoForward} + aria-label="Forward" + > + + + + + ) +} diff --git a/packages/agents-server-ui/src/components/DesktopTitleBar.module.css b/packages/agents-server-ui/src/components/DesktopTitleBar.module.css new file mode 100644 index 0000000000..e39093db06 --- /dev/null +++ b/packages/agents-server-ui/src/components/DesktopTitleBar.module.css @@ -0,0 +1,179 @@ +.titleBar { + display: none; + align-items: center; + height: 34px; + flex-shrink: 0; + background: var(--ds-chrome-bg); + color: var(--ds-text-1); + font-size: 12px; + line-height: 1; + user-select: none; + -webkit-user-select: none; + -webkit-app-region: drag; +} + +:global( + html[data-electric-desktop='true']:not([data-electric-platform='darwin']) + ) + .titleBar { + display: flex; +} + +.appMenuButton { + all: unset; + width: 24px; + height: 24px; + margin-left: 8px; + margin-right: 4px; + display: inline-flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + border-radius: var(--ds-radius-2); + cursor: default; + -webkit-app-region: no-drag; +} + +.appMenuButton:hover, +.appMenuButton:focus-visible { + background: var(--ds-bg-hover); +} + +.appMenuButton:focus-visible { + outline: 2px solid var(--ds-accent-a8); + outline-offset: 1px; +} + +.appIcon { + width: 14px; + height: 14px; + background: var(--ds-text-1); + -webkit-mask: url('../../../agents-desktop/assets/icon-mark.svg') center / + contain no-repeat; + mask: url('../../../agents-desktop/assets/icon-mark.svg') center / contain + no-repeat; +} + +:global(html[data-theme='dark']) .appIcon { + background: var(--ds-accent-9); +} + +.chrome { + display: inline-flex; + align-items: center; + gap: 2px; + margin-right: 4px; + flex-shrink: 0; + -webkit-app-region: no-drag; +} + +.menu { + display: inline-flex; + align-items: center; + gap: 2px; + height: 100%; + flex-shrink: 0; + -webkit-app-region: no-drag; +} + +.menuItem { + all: unset; + display: inline-flex; + align-items: center; + height: 24px; + padding: 0 8px; + border-radius: var(--ds-radius-2); + cursor: default; + color: var(--ds-text-2); +} + +.menuItem:hover, +.menuItem:focus-visible { + background: var(--ds-bg-hover); + color: var(--ds-text-1); +} + +.menuItem:focus-visible { + outline: 2px solid var(--ds-accent-a8); + outline-offset: 1px; +} + +.dragRegion { + flex: 1; + min-width: 24px; + height: 100%; +} + +/* In Electron the native window-controls overlay owns this space. */ +.webWindowControls { + display: inline-flex; + align-items: stretch; + height: 100%; + flex-shrink: 0; + margin-left: auto; + -webkit-app-region: no-drag; +} + +:global(html[data-electric-desktop='true']) .webWindowControls { + width: 138px; + pointer-events: none; +} + +:global(html[data-electric-desktop='true']) .webWindowControls > span { + visibility: hidden; +} + +.webWindowControls > span { + width: 46px; + height: 100%; + display: inline-flex; + align-items: center; + justify-content: center; + color: var(--ds-text-2); + position: relative; +} + +.webWindowControls > span:hover { + background: var(--ds-bg-hover); +} + +.minimize::before, +.maximize::before, +.close::before, +.close::after { + content: ''; + position: absolute; + background: currentcolor; +} + +.minimize::before { + width: 10px; + height: 1px; +} + +.maximize::before { + width: 9px; + height: 9px; + background: transparent; + border: 1px solid currentcolor; + box-sizing: border-box; +} + +.close::before, +.close::after { + width: 11px; + height: 1px; +} + +.close::before { + transform: rotate(45deg); +} + +.close::after { + transform: rotate(-45deg); +} + +.webWindowControls > span:last-child:hover { + background: #c42b1c; + color: #ffffff; +} diff --git a/packages/agents-server-ui/src/components/DesktopTitleBar.tsx b/packages/agents-server-ui/src/components/DesktopTitleBar.tsx new file mode 100644 index 0000000000..70bb1279ca --- /dev/null +++ b/packages/agents-server-ui/src/components/DesktopTitleBar.tsx @@ -0,0 +1,130 @@ +import { PanelLeft, PanelLeftClose, Search } from 'lucide-react' +import { useSearchPalette } from '../hooks/useSearchPalette' +import { useSidebarCollapsed } from '../hooks/useSidebarCollapsed' +import { listTiles, useWorkspace } from '../hooks/useWorkspace' +import { modKeyLabel } from '../lib/keyLabels' +import { Icon, IconButton, Tooltip } from '../ui' +import { DesktopHistoryButtons } from './DesktopHistoryButtons' +import styles from './DesktopTitleBar.module.css' +import type { + DesktopMenuState, + DesktopMenuPopupBounds, + DesktopMenuSection, +} from '../lib/server-connection' + +const MENU_SECTIONS: ReadonlyArray = [ + `File`, + `Edit`, + `View`, + `Window`, + `Help`, +] + +/** + * Windows/Linux desktop chrome modeled after VS Code/Cursor: a custom + * renderer-painted app icon + menu strip that shares the row with + * Electron's native window-controls overlay. + */ +export function DesktopTitleBar(): React.ReactElement { + const { workspace, helpers } = useWorkspace() + const { collapsed, toggle: toggleSidebar } = useSidebarCollapsed() + const search = useSearchPalette() + + const tiles = listTiles(workspace.root) + const menuState: DesktopMenuState = { + hasActiveTile: helpers.activeTileId !== null, + canCloseTile: tiles.length > 1 && helpers.activeTileId !== null, + canSplitTile: helpers.activeTileId !== null, + canCycleTile: tiles.length > 1, + } + + const showMenu = ( + section: DesktopMenuSection, + element: HTMLElement + ): void => { + const rect = element.getBoundingClientRect() + const bounds: DesktopMenuPopupBounds = { + x: rect.left, + y: rect.top, + width: rect.width, + height: rect.height, + } + + if (window.electronAPI?.showMenuSection) { + void window.electronAPI.showMenuSection(section, bounds, menuState) + } + } + + const showAppMenu = (element: HTMLElement): void => { + const rect = element.getBoundingClientRect() + const bounds: DesktopMenuPopupBounds = { + x: rect.left, + y: rect.top, + width: rect.width, + height: rect.height, + } + + if (window.electronAPI?.showAppMenu) { + void window.electronAPI.showAppMenu(bounds) + } + } + + return ( +
+ +
+ + + + + + + + + + + +
+ +
+ +
+ ) +} diff --git a/packages/agents-server-ui/src/components/EntityHeader.tsx b/packages/agents-server-ui/src/components/EntityHeader.tsx index f7d8925d85..4c1de0127d 100644 --- a/packages/agents-server-ui/src/components/EntityHeader.tsx +++ b/packages/agents-server-ui/src/components/EntityHeader.tsx @@ -31,6 +31,8 @@ type EntityHeaderProps = { menu?: ReactNode /** Optional leading affordance before the title, e.g. a tile drag handle. */ leading?: ReactNode + /** True for the leftmost top tile that must clear fixed titlebar controls. */ + chromeInsetTarget?: boolean /** Optional banner of error messages displayed below the strip. */ errors?: Array } @@ -50,6 +52,7 @@ export function EntityHeader({ onSetView, menu, leading, + chromeInsetTarget = false, errors, }: EntityHeaderProps): React.ReactElement | null { return ( @@ -57,6 +60,7 @@ export function EntityHeader({ } + chromeInsetTarget={chromeInsetTarget} actions={ ` and - * the strip starts directly with the title. + * The global sidebar/search controls live in the fixed titlebar controls layer + * so they stay stationary during sidebar animations. This strip only owns the + * tile title, optional leading affordance, and right-side actions. * * No border / divider — the strip shares a background with the column * body so the header reads as part of the same surface. @@ -28,38 +22,13 @@ export function MainHeader({ leading, title, actions, + chromeInsetTarget = false, }: MainHeaderProps): React.ReactElement { - const { collapsed, toggle: toggleSidebar } = useSidebarCollapsed() - const search = useSearchPalette() - return ( -
- {collapsed && ( - - - - - - - - - - - - - )} +
{leading}
{title}
{actions !== undefined &&
{actions}
} diff --git a/packages/agents-server-ui/src/components/NewSessionPage.module.css b/packages/agents-server-ui/src/components/NewSessionPage.module.css index 340454968d..3a78c83c7e 100644 --- a/packages/agents-server-ui/src/components/NewSessionPage.module.css +++ b/packages/agents-server-ui/src/components/NewSessionPage.module.css @@ -109,6 +109,10 @@ font-size: var(--ds-text-sm); } +.pickerFlow { + width: 100%; +} + .selectedFlow { width: 100%; } diff --git a/packages/agents-server-ui/src/components/Sidebar.module.css b/packages/agents-server-ui/src/components/Sidebar.module.css index 6851e50382..73ed59a4dc 100644 --- a/packages/agents-server-ui/src/components/Sidebar.module.css +++ b/packages/agents-server-ui/src/components/Sidebar.module.css @@ -1,20 +1,28 @@ .root { flex-shrink: 0; - background: var(--ds-bg-subtle); + background: var(--ds-chrome-bg); position: relative; - border-right: 1px solid var(--ds-border-1); + overflow: visible; + transition: + margin-right 180ms cubic-bezier(0.32, 0.72, 0, 1), + visibility 0s linear 0s; + will-change: margin-right; } .root::after { - content: ''; - position: absolute; - top: 0; - right: 0; - bottom: 0; - width: 4px; + display: none; +} + +.root[data-resizing='true'] { + transition: none; +} + +.root[data-state='closed']:not(.overlay) { + margin-right: calc(var(--sidebar-expanded-width, 240px) * -1); pointer-events: none; - box-shadow: inset -1px 0 2px - color-mix(in oklab, var(--ds-gray-12) 5%, transparent); - z-index: 10; + visibility: hidden; + transition: + margin-right 180ms cubic-bezier(0.32, 0.72, 0, 1), + visibility 0s linear 180ms; } /* Narrow-viewport overlay mode — see `useNarrowViewport`. The @@ -81,6 +89,7 @@ correctly because the `transform` and `opacity` rules above still apply, just without the animated interpolation. */ @media (prefers-reduced-motion: reduce) { + .root, .overlay, .backdrop { transition: none; @@ -103,6 +112,13 @@ background: var(--ds-accent-a6); } +:global( + html[data-electric-desktop='true']:not([data-electric-platform='darwin']) + ) + .resizeHandle { + top: var(--ds-radius-5); +} + .topDivider { position: relative; height: 0; @@ -131,6 +147,16 @@ padding: 0 8px 8px; } +/* When the sidebar header controls move into the Windows/Linux titlebar + there is no row above "New session", so keep the same 8px breathing + room at the top that the sidebar already has on the left. */ +:global( + html[data-electric-desktop='true']:not([data-electric-platform='darwin']) + ) + .treeRow { + padding-top: 9px; +} + /* New session row — sized to match SidebarRow geometry exactly so its pencil icon sits in the same 22px column as the status dots below and the chrome icons in SidebarHeader above. diff --git a/packages/agents-server-ui/src/components/Sidebar.tsx b/packages/agents-server-ui/src/components/Sidebar.tsx index 676c149cec..7cf030900e 100644 --- a/packages/agents-server-ui/src/components/Sidebar.tsx +++ b/packages/agents-server-ui/src/components/Sidebar.tsx @@ -1,4 +1,5 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react' +import type { CSSProperties } from 'react' import { ChevronRight, SquarePen } from 'lucide-react' import { useLiveQuery } from '@tanstack/react-db' import { eq, not } from '@tanstack/db' @@ -152,17 +153,9 @@ export function Sidebar({ // content without an extra dismiss tap. const narrow = useNarrowViewport() const { collapsed, setCollapsed } = useSidebarCollapsed() - // `data-state` drives the slide/fade transitions in CSS. - // - In wide mode the sidebar is always visible (or unmounted by - // the parent), so no transition state is needed. - // - In narrow mode the parent keeps us mounted regardless of - // `collapsed` so the exit transition can run before unmount, - // and we toggle between `open`/`closed` here. - const overlayState: `open` | `closed` | undefined = narrow - ? collapsed - ? `closed` - : `open` - : undefined + // `data-state` drives both the narrow overlay slide/fade and the + // wide-mode width collapse animation. + const sidebarState: `open` | `closed` = collapsed ? `closed` : `open` const closeIfOverlay = useCallback(() => { if (narrow) setCollapsed(true) }, [narrow, setCollapsed]) @@ -304,14 +297,16 @@ export function Sidebar({ {narrow && (
setCollapsed(true)} aria-hidden={collapsed ? `true` : undefined} /> )} {/* Resize handle is push-mode-only — dragging an overlaid sidebar wider doesn't make sense when there's no flex sibling to take the displaced space. */} - {!narrow && ( + {!narrow && !collapsed && (
` instead so the chat - * column still has a way to toggle the sidebar / open search. + * Empty sidebar header spacer. The sidebar/search controls are fixed at the + * shell level so they stay stationary while the sidebar animates under them. + * This row preserves the top gutter and macOS draggable titlebar surface. */ export function SidebarHeader(): React.ReactElement { - const { toggle: toggleSidebar } = useSidebarCollapsed() - const search = useSearchPalette() - return ( -
- - - - - - - - - - -
- ) + return @@ -62,10 +73,12 @@ function EntityTileBody({ tile, entityUrl, rootRef, + chromeInsetTarget, }: { tile: Tile entityUrl: string rootRef: React.RefObject + chromeInsetTarget: boolean }): React.ReactElement { const { activeServer } = useServerConnection() const { entitiesCollection } = useElectricAgents() @@ -127,6 +140,7 @@ function EntityTileBody({ entity={entity} currentViewId={tile.viewId} onSetView={setView} + chromeInsetTarget={chromeInsetTarget} leading={ canRearrange ? ( + chromeInsetTarget: boolean }): React.ReactElement { const { activeServer } = useServerConnection() const { workspace } = useWorkspace() @@ -199,6 +215,7 @@ function StandaloneTileBody({ ) : undefined } title={toolbarTitle} + chromeInsetTarget={chromeInsetTarget} actions={} />
diff --git a/packages/agents-server-ui/src/components/workspace/Workspace.module.css b/packages/agents-server-ui/src/components/workspace/Workspace.module.css index 5ba55ee5ff..0e9228931d 100644 --- a/packages/agents-server-ui/src/components/workspace/Workspace.module.css +++ b/packages/agents-server-ui/src/components/workspace/Workspace.module.css @@ -3,8 +3,41 @@ flex: 1; min-width: 0; min-height: 0; + position: relative; + z-index: 1; + border-left: 1px solid var(--ds-border-1); background: var(--ds-bg); + box-shadow: -1px 0 2px color-mix(in oklab, var(--ds-gray-12) 5%, transparent); overflow: hidden; + transition: border-top-left-radius 180ms cubic-bezier(0.32, 0.72, 0, 1); +} + +:global(html[data-theme='dark']) .workspace { + box-shadow: -1px 0 2px color-mix(in oklab, #000000 32%, transparent); +} + +:global([data-sidebar-state='closed']) .workspace { + margin-left: -1px; +} + +:global([data-sidebar-animation='true']) .workspace { + transition: + border-top-left-radius 180ms cubic-bezier(0.32, 0.72, 0, 1), + margin-left 180ms cubic-bezier(0.32, 0.72, 0, 1); +} + +:global( + html[data-electric-desktop='true']:not([data-electric-platform='darwin']) + ) + .workspace { + border-top: 1px solid var(--ds-border-1); +} + +:global( + html[data-electric-desktop='true']:not([data-electric-platform='darwin']) + ) + .workspace { + border-top-left-radius: var(--ds-radius-5); } .empty { diff --git a/packages/agents-server-ui/src/components/workspace/Workspace.tsx b/packages/agents-server-ui/src/components/workspace/Workspace.tsx index 8a190f855e..1381661fa3 100644 --- a/packages/agents-server-ui/src/components/workspace/Workspace.tsx +++ b/packages/agents-server-ui/src/components/workspace/Workspace.tsx @@ -235,7 +235,7 @@ export function Workspace(): React.ReactElement { return (
- +
) } diff --git a/packages/agents-server-ui/src/hooks/useSidebarCollapsed.tsx b/packages/agents-server-ui/src/hooks/useSidebarCollapsed.tsx index 537fe67060..3beed67ca9 100644 --- a/packages/agents-server-ui/src/hooks/useSidebarCollapsed.tsx +++ b/packages/agents-server-ui/src/hooks/useSidebarCollapsed.tsx @@ -4,6 +4,7 @@ import { useContext, useEffect, useMemo, + useRef, useState, type ReactNode, } from 'react' @@ -17,6 +18,7 @@ function readInitial(): boolean { type SidebarCollapsedApi = { collapsed: boolean + animating: boolean setCollapsed: (next: boolean) => void toggle: () => void } @@ -38,23 +40,44 @@ export function SidebarCollapsedProvider({ children: ReactNode }): React.ReactElement { const [collapsed, setCollapsedState] = useState(readInitial) + const [animating, setAnimating] = useState(false) + const animationTimer = useRef | null>(null) useEffect(() => { if (typeof window === `undefined`) return window.localStorage.setItem(STORAGE_KEY, collapsed ? `1` : `0`) }, [collapsed]) - const setCollapsed = useCallback((next: boolean) => { - setCollapsedState(next) + useEffect(() => { + return () => { + if (animationTimer.current) clearTimeout(animationTimer.current) + } + }, []) + + const markAnimating = useCallback(() => { + setAnimating(true) + if (animationTimer.current) clearTimeout(animationTimer.current) + animationTimer.current = setTimeout(() => setAnimating(false), 220) }, []) + const setCollapsed = useCallback( + (next: boolean) => { + setCollapsedState((prev) => { + if (prev !== next) markAnimating() + return next + }) + }, + [markAnimating] + ) + const toggle = useCallback(() => { + markAnimating() setCollapsedState((prev) => !prev) - }, []) + }, [markAnimating]) const value = useMemo( - () => ({ collapsed, setCollapsed, toggle }), - [collapsed, setCollapsed, toggle] + () => ({ collapsed, animating, setCollapsed, toggle }), + [collapsed, animating, setCollapsed, toggle] ) return {children} diff --git a/packages/agents-server-ui/src/hooks/useWorkspaceHotkeys.ts b/packages/agents-server-ui/src/hooks/useWorkspaceHotkeys.ts index f696f0c9cc..fd2ebef383 100644 --- a/packages/agents-server-ui/src/hooks/useWorkspaceHotkeys.ts +++ b/packages/agents-server-ui/src/hooks/useWorkspaceHotkeys.ts @@ -16,33 +16,53 @@ import { useWorkspace, listTiles } from './useWorkspace' * Hotkeys are skipped when focus is in a text input (handled by * `useHotkey`'s default `ignoreInputs: true` behaviour). */ -export function useWorkspaceHotkeys(): void { +export function useWorkspaceHotkeys({ + disabled = false, +}: { + disabled?: boolean +} = {}): void { const { workspace, helpers } = useWorkspace() - useHotkey(`mod+d`, (e) => { - if (!helpers.activeTile) return - e.preventDefault() - helpers.splitTile(helpers.activeTile.id, `right`) - }) + useHotkey( + `mod+d`, + (e) => { + if (!helpers.activeTile) return + e.preventDefault() + helpers.splitTile(helpers.activeTile.id, `right`) + }, + { disabled } + ) - useHotkey(`mod+shift+d`, (e) => { - if (!helpers.activeTile) return - e.preventDefault() - helpers.splitTile(helpers.activeTile.id, `down`) - }) + useHotkey( + `mod+shift+d`, + (e) => { + if (!helpers.activeTile) return + e.preventDefault() + helpers.splitTile(helpers.activeTile.id, `down`) + }, + { disabled } + ) - useHotkey(`mod+w`, (e) => { - if (!helpers.activeTile) return - e.preventDefault() - helpers.closeTile(helpers.activeTile.id) - }) + useHotkey( + `mod+w`, + (e) => { + if (!helpers.activeTile) return + e.preventDefault() + helpers.closeTile(helpers.activeTile.id) + }, + { disabled } + ) - useHotkey(`mod+\\`, (e) => { - e.preventDefault() - const tiles = listTiles(workspace.root) - if (tiles.length < 2) return - const currentIdx = tiles.findIndex((t) => t.id === workspace.activeTileId) - const next = tiles[(currentIdx + 1) % tiles.length] - helpers.setActiveTile(next.id) - }) + useHotkey( + `mod+\\`, + (e) => { + e.preventDefault() + const tiles = listTiles(workspace.root) + if (tiles.length < 2) return + const currentIdx = tiles.findIndex((t) => t.id === workspace.activeTileId) + const next = tiles[(currentIdx + 1) % tiles.length] + helpers.setActiveTile(next.id) + }, + { disabled } + ) } diff --git a/packages/agents-server-ui/src/lib/server-connection.ts b/packages/agents-server-ui/src/lib/server-connection.ts index eace83d0c8..b58c80d60c 100644 --- a/packages/agents-server-ui/src/lib/server-connection.ts +++ b/packages/agents-server-ui/src/lib/server-connection.ts @@ -68,6 +68,7 @@ export type DesktopCommand = | `new-chat` | `close-tile` | `toggle-sidebar` + | `open-settings` | `open-search` | `open-find` | `find-next` @@ -76,12 +77,36 @@ export type DesktopCommand = | `split-down` | `cycle-tile` +export type DesktopMenuSection = `File` | `Edit` | `View` | `Window` | `Help` + +export type DesktopMenuPopupBounds = { + x: number + y: number + width: number + height: number +} + +export type DesktopMenuState = { + hasActiveTile: boolean + canCloseTile: boolean + canSplitTile: boolean + canCycleTile: boolean +} + +export type DesktopNavigationState = { + canGoBack: boolean + canGoForward: boolean +} + +export type DesktopAppearance = `light` | `dark` + declare global { interface Window { electronAPI?: { getServers: () => Promise> saveServers: (servers: Array) => Promise getDesktopState?: () => Promise + setNativeAppearance?: (appearance: DesktopAppearance) => Promise setActiveServer?: (server: ServerConfig | null) => Promise restartRuntime?: () => Promise stopRuntime?: () => Promise @@ -100,6 +125,17 @@ declare global { pickDirectory?: (options?: { defaultPath?: string }) => Promise + showMenuSection?: ( + section: DesktopMenuSection, + bounds: DesktopMenuPopupBounds, + state: DesktopMenuState + ) => Promise + showAppMenu?: (bounds: DesktopMenuPopupBounds) => Promise + getNavigationState?: () => Promise + navigateHistory?: (direction: `back` | `forward`) => Promise + onNavigationStateChanged?: ( + callback: (state: DesktopNavigationState) => void + ) => () => void onDesktopStateChanged?: ( callback: (state: DesktopState) => void ) => () => void diff --git a/packages/agents-server-ui/src/router.module.css b/packages/agents-server-ui/src/router.module.css index 4f56a68971..52073942da 100644 --- a/packages/agents-server-ui/src/router.module.css +++ b/packages/agents-server-ui/src/router.module.css @@ -1,9 +1,19 @@ -.appShell { +.rootShell { + position: relative; display: flex; + flex-direction: column; height: 100vh; min-height: 0; overflow: hidden; background: var(--ds-bg); +} + +.appShell { + display: flex; + flex: 1; + min-height: 0; + overflow: hidden; + background: var(--ds-bg); /* Positioning context for the sidebar's narrow-viewport overlay (`Sidebar.module.css → .overlay` + `.backdrop`). Without this, the absolutely-positioned overlay would resolve against the @@ -11,6 +21,11 @@ position: relative; } +:global(html[data-electric-desktop='true']) .rootShell, +:global(html[data-electric-desktop='true']) .appShell { + background: transparent; +} + .entityShell { flex: 1; min-width: 0; diff --git a/packages/agents-server-ui/src/router.tsx b/packages/agents-server-ui/src/router.tsx index 7d84aef65d..18993beedd 100644 --- a/packages/agents-server-ui/src/router.tsx +++ b/packages/agents-server-ui/src/router.tsx @@ -17,7 +17,6 @@ import { SidebarCollapsedProvider, useSidebarCollapsed, } from './hooks/useSidebarCollapsed' -import { useNarrowViewport } from './hooks/useNarrowViewport' import { useHotkey } from './hooks/useHotkey' import { SearchPaletteProvider, @@ -36,6 +35,8 @@ import { Sidebar } from './components/Sidebar' import { SearchPalette } from './components/SearchPalette' import { Workspace } from './components/workspace/Workspace' import { ApiKeysModal } from './components/ApiKeysModal' +import { DesktopTitleBar } from './components/DesktopTitleBar' +import { TitlebarControls } from './components/TitlebarControls' import { SettingsSidebar, type SettingsCategoryId, @@ -70,24 +71,34 @@ function RootLayout(): React.ReactElement { function RootShell(): React.ReactElement { const { pinnedUrls, togglePin } = usePinnedEntities() const navigate = useNavigate() - const { collapsed, toggle } = useSidebarCollapsed() + const { + collapsed, + animating: sidebarAnimating, + toggle, + } = useSidebarCollapsed() const search = useSearchPalette() const { workspace, helpers } = useWorkspace() const { openFindForTile, findNextInTile, findPreviousInTile } = usePaneFindCommands() + const nativeMenuHandlesAppHotkeys = + typeof window !== `undefined` && Boolean(window.electronAPI) - useHotkey(`mod+b`, toggle) - useHotkey(`mod+k`, (e) => { - e.preventDefault() - search.toggle() - }) + useHotkey(`mod+b`, toggle, { disabled: nativeMenuHandlesAppHotkeys }) + useHotkey( + `mod+k`, + (e) => { + e.preventDefault() + search.toggle() + }, + { disabled: nativeMenuHandlesAppHotkeys } + ) useHotkey( `mod+f`, (e) => { e.preventDefault() openFindForTile(helpers.activeTileId) }, - { ignoreInputs: false } + { ignoreInputs: false, disabled: nativeMenuHandlesAppHotkeys } ) useHotkey( `mod+g`, @@ -95,7 +106,7 @@ function RootShell(): React.ReactElement { e.preventDefault() findNextInTile(helpers.activeTileId) }, - { ignoreInputs: false } + { ignoreInputs: false, disabled: nativeMenuHandlesAppHotkeys } ) useHotkey( `mod+shift+g`, @@ -103,7 +114,7 @@ function RootShell(): React.ReactElement { e.preventDefault() findPreviousInTile(helpers.activeTileId) }, - { ignoreInputs: false } + { ignoreInputs: false, disabled: nativeMenuHandlesAppHotkeys } ) // New session: bind both ⌘N / Ctrl+N (works in Electron) and // ⌘⇧O / Ctrl+Shift+O (works in browsers — `⌘N` is reserved by @@ -119,16 +130,20 @@ function RootShell(): React.ReactElement { const openNewSession = useCallback(() => { navigate({ to: `/` }) }, [navigate]) - useHotkey(`mod+n`, (e) => { - e.preventDefault() - openNewSession() - }) + useHotkey( + `mod+n`, + (e) => { + e.preventDefault() + openNewSession() + }, + { disabled: nativeMenuHandlesAppHotkeys } + ) useHotkey(`mod+shift+o`, (e) => { e.preventDefault() openNewSession() }) - useWorkspaceHotkeys() + useWorkspaceHotkeys({ disabled: nativeMenuHandlesAppHotkeys }) useWorkspacePersistence() useDocumentTitle() @@ -145,6 +160,12 @@ function RootShell(): React.ReactElement { case `toggle-sidebar`: toggle() break + case `open-settings`: + navigate({ + to: `/settings/$category`, + params: { category: `general` }, + }) + break case `open-search`: search.toggle() break @@ -189,6 +210,7 @@ function RootShell(): React.ReactElement { openNewSession, toggle, search, + navigate, helpers, workspace, openFindForTile, @@ -241,21 +263,22 @@ function RootShell(): React.ReactElement { const inSettings = settingsCategory !== null // On narrow viewports the sidebar floats over content as an - // overlay (see Sidebar.tsx + useNarrowViewport). We keep the - // component mounted regardless of `collapsed` while in overlay - // mode so the exit transition (slide-out + backdrop fade) can - // run before unmount. In wide mode we keep the existing - // mount-on-demand behaviour — there's no animation, so unmounting - // immediately on collapse is the cheapest correct option. - const narrow = useNarrowViewport() - const showWorkspaceSidebar = narrow || !collapsed + // overlay (see Sidebar.tsx + useNarrowViewport). In wide mode we + // keep it mounted too so collapse/expand can animate the width + // instead of snapping the sidebar out of the flex row. + const sidebarState = inSettings || !collapsed ? `open` : `closed` return ( -
- {inSettings ? ( - - ) : ( - showWorkspaceSidebar && ( +
+ +
+ {inSettings ? ( + + ) : ( - ) - )} - - - + )} + + + +
+ {!inSettings && }
) } diff --git a/packages/agents-server-ui/src/ui/global.css b/packages/agents-server-ui/src/ui/global.css index 7128ecbac5..d6b78a1688 100644 --- a/packages/agents-server-ui/src/ui/global.css +++ b/packages/agents-server-ui/src/ui/global.css @@ -31,11 +31,24 @@ body { * sidebars, and headers are not text-selectable unless a component * explicitly opts back into text selection. The static browser build * deliberately keeps normal web selection behaviour. */ +html[data-electric-desktop='true'], +html[data-electric-desktop='true'] body { + background: transparent; +} + html[data-electric-desktop='true'] body { user-select: none; -webkit-user-select: none; } +html[data-electric-desktop='true'][data-theme='light'] { + --ds-chrome-bg: color-mix(in oklab, var(--ds-bg-subtle) 72%, transparent); +} + +html[data-electric-desktop='true'][data-theme='dark'] { + --ds-chrome-bg: color-mix(in oklab, var(--ds-bg-subtle) 78%, transparent); +} + html[data-electric-desktop='true'] input, html[data-electric-desktop='true'] textarea, html[data-electric-desktop='true'] select, diff --git a/packages/agents-server-ui/src/ui/tokens.css b/packages/agents-server-ui/src/ui/tokens.css index e31859fb44..8f83ba2efd 100644 --- a/packages/agents-server-ui/src/ui/tokens.css +++ b/packages/agents-server-ui/src/ui/tokens.css @@ -99,6 +99,7 @@ * in dark mode it's the website's `--vp-c-bg-elv` `#22252f`. */ --ds-bg: #f7f7f5; --ds-bg-subtle: #f0efed; + --ds-chrome-bg: var(--ds-bg-subtle); --ds-surface: #ffffff; --ds-surface-raised: #ffffff; --ds-input-bg: var(--ds-surface-raised); @@ -316,6 +317,7 @@ :root[data-theme='dark'] { --ds-bg: #111318; --ds-bg-subtle: #16181f; + --ds-chrome-bg: var(--ds-bg-subtle); --ds-surface: #1a1d27; --ds-surface-raised: #22252f; /* Solid raised fill — same value the marketing site uses for its diff --git a/packages/agents-server-ui/vite.config.ts b/packages/agents-server-ui/vite.config.ts index 8cdbb94a3f..639c0f75b5 100644 --- a/packages/agents-server-ui/vite.config.ts +++ b/packages/agents-server-ui/vite.config.ts @@ -2,14 +2,14 @@ import { defineConfig, type Plugin } from 'vite' import react from '@vitejs/plugin-react' /** - * Tags the built `` element with `data-electric-desktop="true"` - * for the Electron desktop build so module-CSS rules like - * `:global(html[data-electric-desktop='true']) .header` match from the - * first paint — earlier than either preload (isolated world) or the - * renderer entry (runs after CSS is loaded) can reliably set the - * attribute. + * Tags the built `` element with `data-electric-desktop="true"` for + * the Electron desktop build so desktop-wide CSS matches from the first + * paint. Platform-specific chrome rules use `data-electric-platform`, which + * the Electron preload sets from the actual runtime platform; the static + * `darwin` default avoids flashing Windows/Linux titlebar chrome on macOS + * before preload runs. */ -function desktopHtmlMarker(): Plugin { +function desktopHtmlMarker(platform: `darwin` | `win32` = `darwin`): Plugin { return { name: `electric-desktop-html-marker`, transformIndexHtml: { @@ -17,7 +17,7 @@ function desktopHtmlMarker(): Plugin { handler(html) { return html.replace( ``, - `` + `` ) }, }, @@ -35,6 +35,17 @@ export default defineConfig(({ command, mode }) => { return { base: desktop ? (desktopServe ? `/` : `./`) : `/__agent_ui/`, plugins: [react(), ...(desktop ? [desktopHtmlMarker()] : [])], + resolve: { + dedupe: [`react`, `react-dom`], + }, + optimizeDeps: { + include: [ + `react`, + `react-dom`, + `react/jsx-runtime`, + `react/jsx-dev-runtime`, + ], + }, build: { outDir: desktop ? `dist-desktop` : `dist`, emptyOutDir: true, diff --git a/packages/agents/package.json b/packages/agents/package.json index 8fdbb6ad41..c2c7b3d235 100644 --- a/packages/agents/package.json +++ b/packages/agents/package.json @@ -47,7 +47,7 @@ "@mariozechner/pi-agent-core": "^0.70.2", "@mariozechner/pi-ai": "^0.70.2", "@sinclair/typebox": "^0.34.48", - "better-sqlite3": "^11.10.0", + "better-sqlite3": "^12.9.0", "nanoid": "^3.3.11", "pino": "^10.3.1", "pino-pretty": "^13.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f617ccbe88..84d8d50408 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -918,6 +918,34 @@ importers: specifier: ^4.18.1 version: 4.24.4 + examples/replay-loop-repro: + dependencies: + '@electric-sql/client': + specifier: workspace:* + version: link:../../packages/typescript-client + react: + specifier: ^18.3.1 + version: 18.3.1 + react-dom: + specifier: ^18.3.1 + version: 18.3.1(react@18.3.1) + devDependencies: + '@types/react': + specifier: ^18.3.3 + version: 18.3.12 + '@types/react-dom': + specifier: ^18.3.0 + version: 18.3.1 + '@vitejs/plugin-react': + specifier: ^4.3.1 + version: 4.3.3(vite@5.4.10(@types/node@25.6.0)(lightningcss@1.30.1)(terser@5.46.2)) + typescript: + specifier: ^5.5.3 + version: 5.8.3 + vite: + specifier: ^5.3.4 + version: 5.4.10(@types/node@25.6.0)(lightningcss@1.30.1)(terser@5.46.2) + examples/tanstack: dependencies: '@electric-sql/client': @@ -1016,10 +1044,10 @@ importers: version: 4.1.0 drizzle-orm: specifier: ^0.44.3 - version: 0.44.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@11.10.0)(gel@2.2.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7) + version: 0.44.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@12.9.0)(gel@2.2.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7) drizzle-zod: specifier: ^0.8.2 - version: 0.8.2(drizzle-orm@0.44.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@11.10.0)(gel@2.2.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7))(zod@4.0.10) + version: 0.8.2(drizzle-orm@0.44.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@12.9.0)(gel@2.2.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7))(zod@4.0.10) expo: specifier: 53.0.20 version: 53.0.20(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.80.1(@babel/core@7.28.0)(@types/react@19.1.17)(react@19.1.0)))(react-native@0.80.1(@babel/core@7.28.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) @@ -1125,16 +1153,16 @@ importers: version: 0.30.6 drizzle-orm: specifier: ^0.39.0 - version: 0.39.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@11.10.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7) + version: 0.39.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@12.9.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7) drizzle-zod: specifier: ^0.7.1 - version: 0.7.1(drizzle-orm@0.39.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@11.10.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7))(zod@4.1.11) + version: 0.7.1(drizzle-orm@0.39.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@12.9.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7))(zod@4.1.11) lucide-react: specifier: ^0.544.0 version: 0.544.0(react@19.2.0) nitro: specifier: 3.0.1-alpha.1 - version: 3.0.1-alpha.1(@electric-sql/pglite@0.4.5)(aws4fetch@1.0.20)(better-sqlite3@11.10.0)(chokidar@4.0.3)(drizzle-orm@0.39.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@11.10.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7))(lru-cache@11.3.5)(rollup@4.46.1)(vite@7.1.7(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.2)(tsx@4.20.3)(yaml@2.8.1))(xml2js@0.6.2) + version: 3.0.1-alpha.1(@electric-sql/pglite@0.4.5)(aws4fetch@1.0.20)(better-sqlite3@12.9.0)(chokidar@4.0.3)(drizzle-orm@0.39.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@12.9.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7))(lru-cache@11.3.5)(rollup@4.46.1)(vite@7.1.7(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.2)(tsx@4.20.3)(yaml@2.8.1))(xml2js@0.6.2) pg: specifier: ^8.16.3 version: 8.16.3 @@ -1524,8 +1552,8 @@ importers: specifier: ^0.34.48 version: 0.34.49 better-sqlite3: - specifier: ^11.10.0 - version: 11.10.0 + specifier: ^12.9.0 + version: 12.9.0 nanoid: specifier: ^3.3.11 version: 3.3.11 @@ -1569,18 +1597,12 @@ importers: packages/agents-desktop: dependencies: - '@electric-ax/agents': - specifier: workspace:* - version: link:../agents - '@electric-ax/agents-server-ui': - specifier: workspace:* - version: link:../agents-server-ui '@mixmark-io/domino': specifier: ^2.2.0 version: 2.2.0 better-sqlite3: - specifier: ^11.10.0 - version: 11.10.0 + specifier: ^12.9.0 + version: 12.9.0 jsdom: specifier: ^28.1.0 version: 28.1.0(@noble/hashes@2.0.1) @@ -1597,6 +1619,12 @@ importers: specifier: ^1.0.2 version: 1.0.2 devDependencies: + '@electric-ax/agents': + specifier: workspace:* + version: link:../agents + '@electric-ax/agents-server-ui': + specifier: workspace:* + version: link:../agents-server-ui '@types/node': specifier: ^22.19.17 version: 22.19.17 @@ -1606,6 +1634,12 @@ importers: electron: specifier: ^41.5.0 version: 41.5.0 + electron-builder: + specifier: ^26.8.1 + version: 26.8.1(electron-builder-squirrel-windows@26.8.1) + electron-icon-builder: + specifier: ^2.0.1 + version: 2.0.1 typescript: specifier: ^5.8.3 version: 5.8.3 @@ -1766,7 +1800,7 @@ importers: version: 5.5.0 drizzle-orm: specifier: ^0.44.0 - version: 0.44.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@11.10.0)(gel@2.2.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7) + version: 0.44.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@12.9.0)(gel@2.2.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7) fastq: specifier: ^1.20.1 version: 1.20.1 @@ -2398,6 +2432,9 @@ importers: packages: + 7zip-bin@5.2.0: + resolution: {integrity: sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A==} + '@0no-co/graphql.web@1.1.2': resolution: {integrity: sha512-N2NGsU5FLBhT8NZ+3l2YrzZSHITjNXNuDhC4iDiikv0IujaJ0Xc6xIxQZ/Ek3Cb+rgPjnLHYyJm11tInuJn+cw==} peerDependencies: @@ -4115,6 +4152,10 @@ packages: '@databases/validate-unicode@1.0.0': resolution: {integrity: sha512-dLKqxGcymeVwEb/6c44KjOnzaAafFf0Wxa8xcfEjx/qOl3rdijsKYBAtIGhtVtOlpPf/PFKfgTuFurSPn/3B/g==} + '@develar/schema-utils@2.6.5': + resolution: {integrity: sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==} + engines: {node: '>= 8.9.0'} + '@docsearch/css@3.7.0': resolution: {integrity: sha512-1OorbTwi1eeDmr0v5t+ckSRlt1zM5GHjm92iIl3kUu7im3GHuP+csf6E0WBg8pdXQczTWP9J9+o9n+Vg6DH5cQ==} @@ -4238,10 +4279,46 @@ packages: '@electric-sql/pglite@0.4.5': resolution: {integrity: sha512-aGG2zGEyZzGWKy8P+9ZoNUV0jxt1+hgbeTf+bVAYyxVZZLXg3/9aFlfLxb08AYZVAfAkQlQIysmWjhc5hwDG8g==} + '@electron/asar@3.4.1': + resolution: {integrity: sha512-i4/rNPRS84t0vSRa2HorerGRXWyF4vThfHesw0dmcWHp+cspK743UanA0suA5Q5y8kzY2y6YKrvbIUn69BCAiA==} + engines: {node: '>=10.12.0'} + hasBin: true + + '@electron/fuses@1.8.0': + resolution: {integrity: sha512-zx0EIq78WlY/lBb1uXlziZmDZI4ubcCXIMJ4uGjXzZW0nS19TjSPeXPAjzzTmKQlJUZm0SbmZhPKP7tuQ1SsEw==} + hasBin: true + '@electron/get@2.0.3': resolution: {integrity: sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==} engines: {node: '>=12'} + '@electron/get@3.1.0': + resolution: {integrity: sha512-F+nKc0xW+kVbBRhFzaMgPy3KwmuNTYX1fx6+FxxoSnNgwYX6LD7AKBTWkU0MQ6IBoe7dz069CNkR673sPAgkCQ==} + engines: {node: '>=14'} + + '@electron/notarize@2.5.0': + resolution: {integrity: sha512-jNT8nwH1f9X5GEITXaQ8IF/KdskvIkOFfB2CvwumsveVidzpSc+mvhhTMdAGSYF3O+Nq49lJ7y+ssODRXu06+A==} + engines: {node: '>= 10.0.0'} + + '@electron/osx-sign@1.3.3': + resolution: {integrity: sha512-KZ8mhXvWv2rIEgMbWZ4y33bDHyUKMXnx4M0sTyPNK/vcB81ImdeY9Ggdqy0SWbMDgmbqyQ+phgejh6V3R2QuSg==} + engines: {node: '>=12.0.0'} + hasBin: true + + '@electron/rebuild@4.0.4': + resolution: {integrity: sha512-Rzc39XPdk/+/wBG8MfwAHohXflep0ITUfulb6Rgz3R0NeSB1noE+E9/M/cb8ftCAiyDD9PPhLuuWgE1GaInbKg==} + engines: {node: '>=22.12.0'} + hasBin: true + + '@electron/universal@2.0.3': + resolution: {integrity: sha512-Wn9sPYIVFRFl5HmwMJkARCCf7rqK/EurkfQ/rJZ14mHP3iYTjZSIOSVonEAnhWeAXwtw7zOekGRlc6yTtZ0t+g==} + engines: {node: '>=16.4'} + + '@electron/windows-sign@1.2.2': + resolution: {integrity: sha512-dfZeox66AvdPtb2lD8OsIIQh12Tp0GNCRUDfBHIKGpbmopZto2/A8nSpYYLoedPIHpqkeblZ/k8OV0Gy7PYuyQ==} + engines: {node: '>=14.14'} + hasBin: true + '@emnapi/core@1.7.1': resolution: {integrity: sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==} @@ -5822,6 +5899,171 @@ packages: resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jimp/bmp@0.16.13': + resolution: {integrity: sha512-9edAxu7N2FX7vzkdl5Jo1BbACfycUtBQX+XBMcHA2bk62P8R0otgkHg798frgAk/WxQIzwxqOH6wMiCwrlAzdQ==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + + '@jimp/core@0.16.13': + resolution: {integrity: sha512-qXpA1tzTnlkTku9yqtuRtS/wVntvE6f3m3GNxdTdtmc+O+Wcg9Xo2ABPMh7Nc0AHbMKzwvwgB2JnjZmlmJEObg==} + + '@jimp/custom@0.16.13': + resolution: {integrity: sha512-LTATglVUPGkPf15zX1wTMlZ0+AU7cGEGF6ekVF1crA8eHUWsGjrYTB+Ht4E3HTrCok8weQG+K01rJndCp/l4XA==} + + '@jimp/gif@0.16.13': + resolution: {integrity: sha512-yFAMZGv3o+YcjXilMWWwS/bv1iSqykFahFMSO169uVMtfQVfa90kt4/kDwrXNR6Q9i6VHpFiGZMlF2UnHClBvg==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + + '@jimp/jpeg@0.16.13': + resolution: {integrity: sha512-BJHlDxzTlCqP2ThqP8J0eDrbBfod7npWCbJAcfkKqdQuFk0zBPaZ6KKaQKyKxmWJ87Z6ohANZoMKEbtvrwz1AA==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + + '@jimp/plugin-blit@0.16.13': + resolution: {integrity: sha512-8Z1k96ZFxlhK2bgrY1JNWNwvaBeI/bciLM0yDOni2+aZwfIIiC7Y6PeWHTAvjHNjphz+XCt01WQmOYWCn0ML6g==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + + '@jimp/plugin-blur@0.16.13': + resolution: {integrity: sha512-PvLrfa8vkej3qinlebyhLpksJgCF5aiysDMSVhOZqwH5nQLLtDE9WYbnsofGw4r0VVpyw3H/ANCIzYTyCtP9Cg==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + + '@jimp/plugin-circle@0.16.13': + resolution: {integrity: sha512-RNave7EFgZrb5V5EpdvJGAEHMnDAJuwv05hKscNfIYxf0kR3KhViBTDy+MoTnMlIvaKFULfwIgaZWzyhuINMzA==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + + '@jimp/plugin-color@0.16.13': + resolution: {integrity: sha512-xW+9BtEvoIkkH/Wde9ql4nAFbYLkVINhpgAE7VcBUsuuB34WUbcBl/taOuUYQrPEFQJ4jfXiAJZ2H/rvKjCVnQ==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + + '@jimp/plugin-contain@0.16.13': + resolution: {integrity: sha512-QayTXw4tXMwU6q6acNTQrTTFTXpNRBe+MgTGMDU0lk+23PjlFCO/9sacflelG8lsp7vNHhAxFeHptDMAksEYzg==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + '@jimp/plugin-blit': '>=0.3.5' + '@jimp/plugin-resize': '>=0.3.5' + '@jimp/plugin-scale': '>=0.3.5' + + '@jimp/plugin-cover@0.16.13': + resolution: {integrity: sha512-BSsP71GTNaqWRcvkbWuIVH+zK7b3TSNebbhDkFK0fVaUTzHuKMS/mgY4hDZIEVt7Rf5FjadAYtsujHN9w0iSYA==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + '@jimp/plugin-crop': '>=0.3.5' + '@jimp/plugin-resize': '>=0.3.5' + '@jimp/plugin-scale': '>=0.3.5' + + '@jimp/plugin-crop@0.16.13': + resolution: {integrity: sha512-WEl2tPVYwzYL8OKme6Go2xqiWgKsgxlMwyHabdAU4tXaRwOCnOI7v4021gCcBb9zn/oWwguHuKHmK30Fw2Z/PA==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + + '@jimp/plugin-displace@0.16.13': + resolution: {integrity: sha512-qt9WKq8vWrcjySa9DyQ0x/RBMHQeiVjdVSY1SJsMjssPUf0pS74qorcuAkGi89biN3YoGUgPkpqECnAWnYwgGA==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + + '@jimp/plugin-dither@0.16.13': + resolution: {integrity: sha512-5/N3yJggbWQTlGZHQYJPmQXEwR52qaXjEzkp1yRBbtdaekXE3BG/suo0fqeoV/csf8ooI78sJzYmIrxNoWVtgQ==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + + '@jimp/plugin-fisheye@0.16.13': + resolution: {integrity: sha512-2rZmTdFbT/cF9lEZIkXCYO0TsT114Q27AX5IAo0Sju6jVQbvIk1dFUTnwLDadTo8wkJlFzGqMQ24Cs8cHWOliA==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + + '@jimp/plugin-flip@0.16.13': + resolution: {integrity: sha512-EmcgAA74FTc5u7Z+hUO/sRjWwfPPLuOQP5O64x5g4j0T12Bd29IgsYZxoutZo/rb3579+JNa/3wsSEmyVv1EpA==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + '@jimp/plugin-rotate': '>=0.3.5' + + '@jimp/plugin-gaussian@0.16.13': + resolution: {integrity: sha512-A1XKfGQD0iDdIiKqFYi8nZMv4dDVYdxbrmgR7y/CzUHhSYdcmoljLIIsZZM3Iks/Wa353W3vtvkWLuDbQbch1w==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + + '@jimp/plugin-invert@0.16.13': + resolution: {integrity: sha512-xFMrIn7czEZbdbMzZWuaZFnlLGJDVJ82y5vlsKsXRTG2kcxRsMPXvZRWHV57nSs1YFsNqXSbrC8B98n0E32njQ==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + + '@jimp/plugin-mask@0.16.13': + resolution: {integrity: sha512-wLRYKVBXql2GAYgt6FkTnCfE+q5NomM7Dlh0oIPGAoMBWDyTx0eYutRK6PlUrRK2yMHuroAJCglICTbxqGzowQ==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + + '@jimp/plugin-normalize@0.16.13': + resolution: {integrity: sha512-3tfad0n9soRna4IfW9NzQdQ2Z3ijkmo21DREHbE6CGcMIxOSvfRdSvf1qQPApxjTSo8LTU4MCi/fidx/NZ0GqQ==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + + '@jimp/plugin-print@0.16.13': + resolution: {integrity: sha512-0m6i3p01PGRkGAK9r53hDYrkyMq+tlhLOIbsSTmZyh6HLshUKlTB7eXskF5OpVd5ZUHoltlNc6R+ggvKIzxRFw==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + '@jimp/plugin-blit': '>=0.3.5' + + '@jimp/plugin-resize@0.16.13': + resolution: {integrity: sha512-qoqtN8LDknm3fJm9nuPygJv30O3vGhSBD2TxrsCnhtOsxKAqVPJtFVdGd/qVuZ8nqQANQmTlfqTiK9mVWQ7MiQ==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + + '@jimp/plugin-rotate@0.16.13': + resolution: {integrity: sha512-Ev+Jjmj1nHYw897z9C3R9dYsPv7S2/nxdgfFb/h8hOwK0Ovd1k/+yYS46A0uj/JCKK0pQk8wOslYBkPwdnLorw==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + '@jimp/plugin-blit': '>=0.3.5' + '@jimp/plugin-crop': '>=0.3.5' + '@jimp/plugin-resize': '>=0.3.5' + + '@jimp/plugin-scale@0.16.13': + resolution: {integrity: sha512-05POQaEJVucjTiSGMoH68ZiELc7QqpIpuQlZ2JBbhCV+WCbPFUBcGSmE7w4Jd0E2GvCho/NoMODLwgcVGQA97A==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + '@jimp/plugin-resize': '>=0.3.5' + + '@jimp/plugin-shadow@0.16.13': + resolution: {integrity: sha512-nmu5VSZ9hsB1JchTKhnnCY+paRBnwzSyK5fhkhtQHHoFD5ArBQ/5wU8y6tCr7k/GQhhGq1OrixsECeMjPoc8Zw==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + '@jimp/plugin-blur': '>=0.3.5' + '@jimp/plugin-resize': '>=0.3.5' + + '@jimp/plugin-threshold@0.16.13': + resolution: {integrity: sha512-+3zArBH0OE3Rhjm4HyAokMsZlIq5gpQec33CncyoSwxtRBM2WAhUVmCUKuBo+Lr/2/4ISoY4BWpHKhMLDix6cA==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + '@jimp/plugin-color': '>=0.8.0' + '@jimp/plugin-resize': '>=0.8.0' + + '@jimp/plugins@0.16.13': + resolution: {integrity: sha512-CJLdqODEhEVs4MgWCxpWL5l95sCBlkuSLz65cxEm56X5akIsn4LOlwnKoSEZioYcZUBvHhCheH67AyPTudfnQQ==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + + '@jimp/png@0.16.13': + resolution: {integrity: sha512-8cGqINvbWJf1G0Her9zbq9I80roEX0A+U45xFby3tDWfzn+Zz8XKDF1Nv9VUwVx0N3zpcG1RPs9hfheG4Cq2kg==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + + '@jimp/tiff@0.16.13': + resolution: {integrity: sha512-oJY8d9u95SwW00VPHuCNxPap6Q1+E/xM5QThb9Hu+P6EGuu6lIeLaNBMmFZyblwFbwrH+WBOZlvIzDhi4Dm/6Q==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + + '@jimp/types@0.16.13': + resolution: {integrity: sha512-mC0yVNUobFDjoYLg4hoUwzMKgNlxynzwt3cDXzumGvRJ7Kb8qQGOWJQjQFo5OxmGExqzPphkirdbBF88RVLBCg==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + + '@jimp/utils@0.16.13': + resolution: {integrity: sha512-VyCpkZzFTHXtKgVO35iKN0sYR10psGpV6SkcSeV4oF7eSYlR8Bl6aQLCzVeFjvESF7mxTmIiI3/XrMobVrtxDA==} + '@jridgewell/gen-mapping@0.3.12': resolution: {integrity: sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==} @@ -5917,6 +6159,14 @@ packages: cpu: [x64] os: [win32] + '@malept/cross-spawn-promise@2.0.0': + resolution: {integrity: sha512-1DpKU0Z5ThltBwjNySMC14g0CkbyhCaz9FkhxqNsZI6uAPJXFS8cMXlBKo26FJ8ZuW6S9GCMcR9IO5k2X5/9Fg==} + engines: {node: '>= 12.13.0'} + + '@malept/flatpak-bundler@0.4.0': + resolution: {integrity: sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q==} + engines: {node: '>= 10.0.0'} + '@manypkg/find-root@1.1.0': resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} @@ -5932,19 +6182,23 @@ packages: '@mariozechner/pi-agent-core@0.57.1': resolution: {integrity: sha512-WXsBbkNWOObFGHkhixaT8GXJpHDd3+fn8QntYF+4R8Sa9WB90ENXWidO6b7vcKX+JX0jjO5dIsQxmzosARJKlg==} engines: {node: '>=20.0.0'} + deprecated: please use @earendil-works/pi-agent-core instead going forward '@mariozechner/pi-agent-core@0.70.2': resolution: {integrity: sha512-g1hIdKyDwmQOoBGO0R4OhpemKeMENeK0vE5FJtuQKqEcsdCAkVBgZAK6aZUARYZVxMA718JS6WPLFWoddzjD7g==} engines: {node: '>=20.0.0'} + deprecated: please use @earendil-works/pi-agent-core instead going forward '@mariozechner/pi-ai@0.57.1': resolution: {integrity: sha512-Bd/J4a3YpdzJVyHLih0vDSdB0QPL4ti0XsAwtHOK/8eVhB0fHM1CpcgIrcBFJ23TMcKXMi0qamz18ERfp8tmgg==} engines: {node: '>=20.0.0'} + deprecated: please use @earendil-works/pi-ai instead going forward hasBin: true '@mariozechner/pi-ai@0.70.2': resolution: {integrity: sha512-+30LRPjXsXF+oI96DvGWMbdPGeqoLJvadh6UPev7wx2DzhC9FEqXkQcoMZ0usbCm7E9pl8ua8a9s/pQ5ikaUbg==} engines: {node: '>=20.0.0'} + deprecated: please use @earendil-works/pi-ai instead going forward hasBin: true '@mermaid-js/parser@1.1.0': @@ -9515,6 +9769,9 @@ packages: '@types/express@5.0.3': resolution: {integrity: sha512-wGA0NX93b19/dZC1J18tKWVIYWyyF2ZjT9vin/NRu0qzzvfVzWjs04iq2rQ3H65vCTQYlRqs3YHfY7zjdV+9Kw==} + '@types/fs-extra@9.0.13': + resolution: {integrity: sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==} + '@types/geojson@7946.0.16': resolution: {integrity: sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==} @@ -9596,6 +9853,9 @@ packages: '@types/node@12.20.55': resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + '@types/node@16.9.1': + resolution: {integrity: sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==} + '@types/node@20.17.6': resolution: {integrity: sha512-VEI7OdvK2wP7XHnsuXbAJnEpEkF6NjSN45QJlL4VGqZSXsnicpesdTWsg9RISeSdYd3yeRj/y3k5KGjUXYnFwQ==} @@ -9620,6 +9880,9 @@ packages: '@types/pg@8.15.4': resolution: {integrity: sha512-I6UNVBAoYbvuWkkU3oosC8yxqH21f4/Jc4DK71JLG3dT2mdlGe1z+ep/LQGXaKaOgcvUrsQoPRqfgtMcvZiJhg==} + '@types/plist@3.0.5': + resolution: {integrity: sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA==} + '@types/prop-types@15.7.13': resolution: {integrity: sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==} @@ -9706,6 +9969,9 @@ packages: '@types/uuid@9.0.8': resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==} + '@types/verror@1.10.11': + resolution: {integrity: sha512-RlDm9K7+o5stv0Co8i8ZRGxDbrTxhJtgjqjFyVh/tXQyl/rYtTKlnTvZ88oSTeYREWurwx20Js4kTuKCsFkUtg==} + '@types/vite-plugin-react-svg@0.2.5': resolution: {integrity: sha512-p2yB779GM9G1bxgKPO+YRi+NJE/U8Di9cZacYGfjtl3XEO62mBbj54tFXCssDyhNuJc9iGUAfJipoMZvzZNPmw==} @@ -10322,6 +10588,10 @@ packages: engines: {node: '>=10.0.0'} deprecated: this version has critical issues, please update to the latest version + abbrev@4.0.0: + resolution: {integrity: sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA==} + engines: {node: ^20.17.0 || >=22.9.0} + abort-controller@3.0.0: resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} engines: {node: '>=6.5'} @@ -10362,6 +10632,10 @@ packages: resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} + aggregate-error@3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + ajv-formats@2.1.1: resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} peerDependencies: @@ -10378,6 +10652,11 @@ packages: ajv: optional: true + ajv-keywords@3.5.2: + resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} + peerDependencies: + ajv: ^6.9.1 + ajv-keywords@5.1.0: resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} peerDependencies: @@ -10421,6 +10700,10 @@ packages: resolution: {integrity: sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==} engines: {node: '>=18'} + ansi-regex@2.1.1: + resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==} + engines: {node: '>=0.10.0'} + ansi-regex@4.1.1: resolution: {integrity: sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==} engines: {node: '>=6'} @@ -10461,6 +10744,9 @@ packages: resolution: {integrity: sha512-BGcItUBWSMRgOCe+SVZJ+S7yTRG0eGt9cXAHev72yuGcY23hnLA7Bky5L/xLyPINoSN95geovfBkqoTlNZYa7w==} engines: {node: '>=14'} + any-base@1.1.0: + resolution: {integrity: sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==} + any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} @@ -10468,6 +10754,16 @@ packages: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} + app-builder-bin@5.0.0-alpha.12: + resolution: {integrity: sha512-j87o0j6LqPL3QRr8yid6c+Tt5gC7xNfYo6uQIQkorAC6MpeayVMZrEDzKmJJ/Hlv7EnOQpaRm53k6ktDYZyB6w==} + + app-builder-lib@26.8.1: + resolution: {integrity: sha512-p0Im/Dx5C4tmz8QEE1Yn4MkuPC8PrnlRneMhWJj7BBXQfNTJUshM/bp3lusdEsDbvvfJZpXWnYesgSLvwtM2Zw==} + engines: {node: '>=14.0.0'} + peerDependencies: + dmg-builder: 26.8.1 + electron-builder-squirrel-windows: 26.8.1 + arg@5.0.2: resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} @@ -10477,6 +10773,10 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + args@5.0.3: + resolution: {integrity: sha512-h6k/zfFgusnv3i5TU08KQkVKuCPBtL/PWQbWkHUxvJrZ2nAyeaUupneemcrgn1xmqxPQsPIzwkUhOpoqPDRZuA==} + engines: {node: '>= 6.0.0'} + aria-hidden@1.2.4: resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==} engines: {node: '>=10'} @@ -10534,9 +10834,16 @@ packages: asap@2.0.6: resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + asn1@0.2.6: + resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} + assert-never@1.3.0: resolution: {integrity: sha512-9Z3vxQ+berkL/JJo0dK+EY3Lp0s3NtSnP3VCLsh5HDcZPrh0M+KQRK5sWhUeyPPH+/RCxZqOxLMR+YC6vlviEQ==} + assert-plus@1.0.0: + resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} + engines: {node: '>=0.8'} + assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} @@ -10559,6 +10866,14 @@ packages: ast-v8-to-istanbul@1.0.0: resolution: {integrity: sha512-1fSfIwuDICFA4LKkCzRPO7F0hzFf0B7+Xqrl27ynQaa+Rh0e1Es0v6kWHPott3lU10AyAr7oKHa65OppjLn3Rg==} + astral-regex@2.0.0: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} + engines: {node: '>=8'} + + async-exit-hook@2.0.1: + resolution: {integrity: sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==} + engines: {node: '>=0.12.0'} + async-function@1.0.0: resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} engines: {node: '>= 0.4'} @@ -10600,6 +10915,12 @@ packages: engines: {node: '>= 10.0.0'} deprecated: The AWS SDK for JavaScript (v2) has reached end-of-support, and no longer receives updates. Please migrate your code to use AWS SDK for JavaScript (v3). More info https://a.co/cUPnyil + aws-sign2@0.7.0: + resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} + + aws4@1.13.2: + resolution: {integrity: sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==} + aws4fetch@1.0.18: resolution: {integrity: sha512-3Cf+YaUl07p24MoQ46rFwulAmiyCwH2+1zw1ZyPAX5OtJ34Hh185DwB8y/qRLb6cYYYtSFJ9pthyLc0MD4e8sQ==} @@ -10709,6 +11030,9 @@ packages: resolution: {integrity: sha512-5K9eNNn7ywHPsYnFwjKgYH8Hf8B5emh7JKcPaVjjrMJFQQwGpwowEnZNEtHs7DfR7hCZsmaK3VA4HUK0YarT+w==} engines: {node: '>=10.0.0'} + bcrypt-pbkdf@1.0.2: + resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} + better-auth@1.4.3: resolution: {integrity: sha512-cMY6PxXZ9Ep+KmLUcVEQ5RwtZtdawxTbDqUIgIIUYWJgq0KwNkQfFNimSYjHI0cNZwwAJyvbV42+uLogsDOUqQ==} peerDependencies: @@ -10749,8 +11073,9 @@ packages: resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} engines: {node: '>=4'} - better-sqlite3@11.10.0: - resolution: {integrity: sha512-EwhOpyXiOEL/lKzHz9AW1msWFNzGc/z+LzeB3/jnFJpxu+th2yqvzsSWas1v9jgs9+xiXJcD5A8CJxAG2TaghQ==} + better-sqlite3@12.9.0: + resolution: {integrity: sha512-wqUv4Gm3toFpHDQmaKD4QhZm3g1DjUBI0yzS4UBl6lElUmXFYdTQmmEDpAFa5o8FiFiymURypEnfVHzILKaxqQ==} + engines: {node: 20.x || 22.x || 23.x || 24.x || 25.x} bidi-js@1.0.3: resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==} @@ -10787,6 +11112,9 @@ packages: bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + bmp-js@0.1.0: + resolution: {integrity: sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw==} + body-parser@1.20.3: resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} @@ -10853,6 +11181,10 @@ packages: buffer-equal-constant-time@1.0.1: resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} + buffer-equal@0.0.1: + resolution: {integrity: sha512-RgSV6InVQ9ODPdLWJ5UAqBqJBOg370Nz6ZQtRzpt6nUjc8v0St97uJ4PYC6NztqIScrAXafKM3mZPMygSe1ggA==} + engines: {node: '>=0.4.0'} + buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} @@ -10865,6 +11197,13 @@ packages: buffer@6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + builder-util-runtime@9.5.1: + resolution: {integrity: sha512-qt41tMfgHTllhResqM5DcnHyDIWNgzHvuY2jDcYP9iaGpkWxTUzV6GQjDeLnlR1/DtdlcsWQbA7sByMpmJFTLQ==} + engines: {node: '>=12.0.0'} + + builder-util@26.8.1: + resolution: {integrity: sha512-pm1lTYbGyc90DHgCDO7eo8Rl4EqKLciayNbZqGziqnH9jrlKe8ZANGdityLZU+pJh16dfzjAx2xQq9McuIPEtw==} + bundle-name@4.1.0: resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} engines: {node: '>=18'} @@ -10941,6 +11280,14 @@ packages: resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} engines: {node: '>= 6'} + camelcase@3.0.0: + resolution: {integrity: sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==} + engines: {node: '>=0.10.0'} + + camelcase@5.0.0: + resolution: {integrity: sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==} + engines: {node: '>=6'} + camelcase@5.3.1: resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} engines: {node: '>=6'} @@ -10962,9 +11309,15 @@ packages: caniuse-lite@1.0.30001791: resolution: {integrity: sha512-yk0l/YSrOnFZk3UROpDLQD9+kC1l4meK/wed583AXrzoarMGJcbRi2Q4RaUYbKxYAsZ8sWmaSa/DsLmdBeI1vQ==} + caseless@0.12.0: + resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} + ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + centra@2.7.0: + resolution: {integrity: sha512-PbFMgMSrmgx6uxCdm57RUos9Tc3fclMvhLSATYN39XsDV29B89zZ3KA89jmY0vwSGazyU+uerqwa6t+KaodPcg==} + chai@5.3.3: resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} engines: {node: '>=18'} @@ -11055,6 +11408,9 @@ packages: chromium-edge-launcher@0.2.0: resolution: {integrity: sha512-JfJjUnq25y9yg4FABRRVPmBGWPZZi+AQXT4mxupb67766/0UlhG8PAZCz6xzEMXTbW3CsSoE8PcCWA49n35mKg==} + chromium-pickle-js@0.2.0: + resolution: {integrity: sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==} + ci-info@2.0.0: resolution: {integrity: sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==} @@ -11062,12 +11418,24 @@ packages: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} + ci-info@4.3.1: + resolution: {integrity: sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==} + engines: {node: '>=8'} + + ci-info@4.4.0: + resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==} + engines: {node: '>=8'} + classnames@2.3.2: resolution: {integrity: sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==} classnames@2.5.1: resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==} + clean-stack@2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + cli-boxes@3.0.0: resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} engines: {node: '>=10'} @@ -11096,6 +11464,10 @@ packages: resolution: {integrity: sha512-bXfOC4QcT1tKXGorxL3wbJm6XJPDqEnij2gQ2m7ESQuE+/z9YFIWnl/5RpTiKWbMq3EVKR4fRLJGn6DVfu0mpw==} engines: {node: '>=18.20'} + cli-truncate@2.1.0: + resolution: {integrity: sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==} + engines: {node: '>=8'} + cli-truncate@5.1.0: resolution: {integrity: sha512-7JDGG+4Zp0CsknDCedl0DYdaeOhc46QNpXi3NLQblkZpXXgA6LncLDUUyvrjSvZeF3VRQa+KiMGomazQrC1V8g==} engines: {node: '>=20'} @@ -11111,6 +11483,9 @@ packages: client-only@0.0.1: resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + cliui@3.2.0: + resolution: {integrity: sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==} + cliui@7.0.4: resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} @@ -11145,6 +11520,10 @@ packages: resolution: {integrity: sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + code-point-at@1.1.0: + resolution: {integrity: sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==} + engines: {node: '>=0.10.0'} + codemirror@6.0.1: resolution: {integrity: sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==} @@ -11208,6 +11587,14 @@ packages: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} + commander@5.1.0: + resolution: {integrity: sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==} + engines: {node: '>= 6'} + + commander@6.2.1: + resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} + engines: {node: '>= 6'} + commander@7.2.0: resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} engines: {node: '>= 10'} @@ -11216,10 +11603,18 @@ packages: resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} engines: {node: '>= 12'} + commander@9.5.0: + resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} + engines: {node: ^12.20.0 || >=14} + common-tags@1.8.2: resolution: {integrity: sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==} engines: {node: '>=4.0.0'} + compare-version@0.1.2: + resolution: {integrity: sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==} + engines: {node: '>=0.10.0'} + compare-versions@6.1.1: resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==} @@ -11234,6 +11629,10 @@ packages: concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + concat-stream@1.6.2: + resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} + engines: {'0': node >= 0.8} + concurrently@8.2.2: resolution: {integrity: sha512-1dP4gpXFhei8IOtlXRE/T/4H88ElHgTiUzh71YUmtjTEHMSRS2Z/fgOxHSxxusGHogsRfxNq1vyAwxSC+EVyDg==} engines: {node: ^14.13.0 || >=16.0.0} @@ -11311,6 +11710,9 @@ packages: core-js@3.39.0: resolution: {integrity: sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g==} + core-util-is@1.0.2: + resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} + cors@2.8.5: resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} engines: {node: '>= 0.10'} @@ -11334,6 +11736,9 @@ packages: typescript: optional: true + crc@3.8.0: + resolution: {integrity: sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==} + crelt@1.0.6: resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==} @@ -11341,6 +11746,9 @@ packages: resolution: {integrity: sha512-oML4lKUXxizYswqmxuOCpgFS8BNUJpIu6k/2HVHyaL8Ynnf3wdf9tkns0yRdJLSIjkJ+b0DXHMZEHGpMwjnPww==} engines: {node: '>=18'} + cross-dirname@0.1.0: + resolution: {integrity: sha512-+R08/oI0nl3vfPcqftZRpytksBXDzOUveBq/NBVx0sUp1axwzPQrKinNx5yd5sxPu8j1wIy8AfnVQ+5eFdha6Q==} + cross-env@10.1.0: resolution: {integrity: sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==} engines: {node: '>=20'} @@ -11596,6 +12004,10 @@ packages: dagre-d3-es@7.0.14: resolution: {integrity: sha512-P4rFMVq9ESWqmOgK+dlXvOtLwYg0i7u0HBGJER0LZDJT2VHIPAMZ/riPxqJceWMStH5+E61QxFra9kIS3AqdMg==} + dashdash@1.14.1: + resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} + engines: {node: '>=0.10'} + data-uri-to-buffer@4.0.1: resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} engines: {node: '>= 12'} @@ -11713,6 +12125,10 @@ packages: supports-color: optional: true + decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + decimal.js@10.4.3: resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} @@ -11790,6 +12206,10 @@ packages: resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==} engines: {node: '>= 14'} + del@6.1.1: + resolution: {integrity: sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==} + engines: {node: '>=10'} + delaunator@5.1.0: resolution: {integrity: sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ==} @@ -11854,6 +12274,9 @@ packages: resolution: {integrity: sha512-svtcdpS8CgJyqAjEQIXdb3OjhFVVYjzGAPO8WGCmRbrml64SPw/jJD4GoE98aR7r25A0XcgrK3F02yw9R/vhQw==} engines: {node: '>=0.3.1'} + dir-compare@4.2.0: + resolution: {integrity: sha512-2xMCmOoMrdQIPHdsTawECdNPwlVFB9zGcz3kuhmBO6U3oU+UQjsue0i8ayLKpgBcm+hcXPMVSGUN9d+pvJ6+VQ==} + dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} @@ -11864,6 +12287,15 @@ packages: dlv@1.1.3: resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + dmg-builder@26.8.1: + resolution: {integrity: sha512-glMJgnTreo8CFINujtAhCgN96QAqApDMZ8Vl1r8f0QT8QprvC1UCltV4CcWj20YoIyLZx6IUskaJZ0NV8fokcg==} + + dmg-license@1.0.11: + resolution: {integrity: sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q==} + engines: {node: '>=8'} + os: [darwin] + hasBin: true + doctrine@2.1.0: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} @@ -11878,6 +12310,9 @@ packages: dom-serializer@2.0.0: resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + dom-walk@0.1.2: + resolution: {integrity: sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==} + domelementtype@2.3.0: resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} @@ -12127,6 +12562,9 @@ packages: eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + ecc-jsbn@0.1.2: + resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} + ecdsa-sig-formatter@1.0.11: resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} @@ -12142,12 +12580,32 @@ packages: engines: {node: '>=0.10.0'} hasBin: true + electron-builder-squirrel-windows@26.8.1: + resolution: {integrity: sha512-o288fIdgPLHA76eDrFADHPoo7VyGkDCYbLV1GzndaMSAVBoZrGvM9m2IehdcVMzdAZJ2eV9bgyissQXHv5tGzA==} + + electron-builder@26.8.1: + resolution: {integrity: sha512-uWhx1r74NGpCagG0ULs/P9Nqv2nsoo+7eo4fLUOB8L8MdWltq9odW/uuLXMFCDGnPafknYLZgjNX0ZIFRzOQAw==} + engines: {node: '>=14.0.0'} + hasBin: true + + electron-icon-builder@2.0.1: + resolution: {integrity: sha512-rg9BxW2kJi3TXsMFFNXWXrwQEd5dzXmeD+w7Pj3k3z7aYRePLxE89qU4lvL/rK1X/NTY5KDn3+Dbgm1TU2dGXQ==} + engines: {node: '>= 10.0.0'} + hasBin: true + + electron-publish@26.8.1: + resolution: {integrity: sha512-q+jrSTIh/Cv4eGZa7oVR+grEJo/FoLMYBAnSL5GCtqwUpr1T+VgKB/dn1pnzxIxqD8S/jP1yilT9VrwCqINR4w==} + electron-to-chromium@1.5.344: resolution: {integrity: sha512-4MxfbmNDm+KPh066EZy+eUnkcDPcZ35wNmOWzFuh/ijvHsve6kbLTLURy88uCNK5FbpN+yk2nQY6BYh1GEt+wg==} electron-to-chromium@1.5.52: resolution: {integrity: sha512-xtoijJTZ+qeucLBDNztDOuQBE1ksqjvNjvqFoST3nGC7fSpqJ+X6BdTBaY5BHG+IhWWmpc6b/KfpeuEDupEPOQ==} + electron-winstaller@5.4.0: + resolution: {integrity: sha512-bO3y10YikuUwUuDUQRM4KfwNkKhnpVO7IPdbsrejwN9/AABJzzTQ4GeHwyzNSrVO+tEH3/Np255a3sVZpZDjvg==} + engines: {node: '>=8.0.0'} + electron@41.5.0: resolution: {integrity: sha512-x9j9//PubUA4EjDtQbZhtk3prolandqCKgit0uCIqc1jb8FTskPbnJtxcDFB1aejczJcuERgjPixBUaMwoWyJg==} engines: {node: '>= 12.20.55'} @@ -12226,6 +12684,9 @@ packages: enzyme@3.11.0: resolution: {integrity: sha512-Dw8/Gs4vRjxY6/6i9wU0V+utmQO9kvh9XLnz3LIudviOnVYDEe2ec+0k+NQoMamn1VrjKgCUOWj5jG/5M5M0Qw==} + err-code@2.0.3: + resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} + error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} @@ -12292,6 +12753,9 @@ packages: es6-promise@3.3.1: resolution: {integrity: sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==} + es6-promise@4.2.8: + resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} + esbuild-android-64@0.14.54: resolution: {integrity: sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==} engines: {node: '>=12'} @@ -12725,6 +13189,9 @@ packages: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} + exif-parser@0.1.12: + resolution: {integrity: sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw==} + expand-template@2.0.3: resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} engines: {node: '>=6'} @@ -12873,11 +13340,23 @@ packages: resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} engines: {node: '>=4'} + extract-zip@1.7.0: + resolution: {integrity: sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==} + hasBin: true + extract-zip@2.0.1: resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} engines: {node: '>= 10.17.0'} hasBin: true + extsprintf@1.3.0: + resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} + engines: {'0': node >=0.6.0} + + extsprintf@1.4.1: + resolution: {integrity: sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==} + engines: {'0': node >=0.6.0} + fast-base64-decode@1.0.0: resolution: {integrity: sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q==} @@ -12969,6 +13448,10 @@ packages: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} + file-type@16.5.4: + resolution: {integrity: sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==} + engines: {node: '>=10'} + file-type@18.7.0: resolution: {integrity: sha512-ihHtXRzXEziMrQ56VSgU7wkxh55iNchFkosu7Y9/S+tXHdKyrGjVK0ujbqNnsxzea+78MaLhN6PGmfYSAv1ACw==} engines: {node: '>=14.16'} @@ -12976,6 +13459,10 @@ packages: file-uri-to-path@1.0.0: resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + file-url@2.0.2: + resolution: {integrity: sha512-x3989K8a1jM6vulMigE8VngH7C5nci0Ks5d9kVjUXmNF28gmiZUNujk5HjwaS8dAzN2QmUfX56riJKgN00dNRw==} + engines: {node: '>=4'} + filelist@1.0.6: resolution: {integrity: sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==} @@ -12999,6 +13486,10 @@ packages: resolution: {integrity: sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==} engines: {node: '>= 0.8'} + find-up@1.1.2: + resolution: {integrity: sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==} + engines: {node: '>=0.10.0'} + find-up@4.1.0: resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} engines: {node: '>=8'} @@ -13050,6 +13541,13 @@ packages: resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} engines: {node: '>=14'} + forever-agent@0.6.1: + resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} + + form-data@2.3.3: + resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} + engines: {node: '>= 0.12'} + form-data@4.0.1: resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==} engines: {node: '>= 6'} @@ -13092,10 +13590,17 @@ packages: fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + fs-extra@1.0.0: + resolution: {integrity: sha512-VerQV6vEKuhDWD2HGOybV6v5I73syoc/cXAbKlgTC7M/oFVEtklWlp9QH2Ijw3IaWDOQcMkldSPa7zXy79Z/UQ==} + fs-extra@10.1.0: resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} engines: {node: '>=12'} + fs-extra@11.3.5: + resolution: {integrity: sha512-eKpRKAovdpZtR1WopLHxlBWvAgPny3c4gX1G5Jhwmmw4XJj0ifSD5qB5TOo8hmA0wlRKDAOAhEE1yVPgs6Fgcg==} + engines: {node: '>=14.14'} + fs-extra@7.0.1: resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} engines: {node: '>=6 <7 || >=8'} @@ -13162,6 +13667,9 @@ packages: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} + get-caller-file@1.0.3: + resolution: {integrity: sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==} + get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} @@ -13222,6 +13730,12 @@ packages: resolution: {integrity: sha512-VilgtJj/ALgGY77fiLam5iD336eSWi96Q15JSAG1zi8NRBysm3LXKdGnHb4m5cuyxvOLQQKWpBZAT6ni4FI2iQ==} engines: {node: '>=6'} + getpass@0.1.7: + resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} + + gifwrap@0.9.4: + resolution: {integrity: sha512-MDMwbhASQuVeD4JKd1fKgNgCRL3fGqMM4WaqpNhWO0JiMOAjbQdumbs4BbBZEy9/M00EHEjKN3HieVhCUlwjeQ==} + github-from-package@0.0.0: resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} @@ -13246,6 +13760,9 @@ packages: resolution: {integrity: sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==} engines: {node: '>=10.0'} + global@4.4.0: + resolution: {integrity: sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==} + globals@11.12.0: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} engines: {node: '>=4'} @@ -13330,6 +13847,15 @@ packages: engines: {node: '>=0.4.7'} hasBin: true + har-schema@2.0.0: + resolution: {integrity: sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==} + engines: {node: '>=4'} + + har-validator@5.1.5: + resolution: {integrity: sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==} + engines: {node: '>=6'} + deprecated: this library is no longer supported + has-bigints@1.0.2: resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} @@ -13360,6 +13886,10 @@ packages: resolution: {integrity: sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==} engines: {node: '>= 0.4.0'} + hasha@2.2.0: + resolution: {integrity: sha512-jZ38TU/EBiGKrmyTNNZgnvCZHNowiRI4+w/I9noMlekHTZH3KyGgvJLmhSgykeAQ9j2SYPDosM0Bg3wHfzibAQ==} + engines: {node: '>=0.10.0'} + hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} @@ -13456,6 +13986,13 @@ packages: hookable@5.5.3: resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} + hosted-git-info@2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + + hosted-git-info@4.1.0: + resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} + engines: {node: '>=10'} + hosted-git-info@7.0.2: resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} engines: {node: ^16.14.0 || >=18.0.0} @@ -13499,6 +14036,10 @@ packages: resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} engines: {node: '>= 14'} + http-signature@1.2.0: + resolution: {integrity: sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==} + engines: {node: '>=0.8', npm: '>=1.3.7'} + http2-client@1.3.5: resolution: {integrity: sha512-EC2utToWl4RKfs5zd36Mxq7nzHHBuomZboI0yYL6Y0RmBgT7Sgkq4rQ0ezFTYoIsSs7Tm9SJe+o2FcAg6GBhGA==} @@ -13529,6 +14070,16 @@ packages: hyphenate-style-name@1.1.0: resolution: {integrity: sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==} + icon-gen@2.1.0: + resolution: {integrity: sha512-rqIVvq9MJ8X7wnJW0NO8Eau/+5RWV7AH6L5vEt/U5Ajv5WefdDNDxGwJhGokyHuyBWeX7JqRMQ03tG0gAco4Eg==} + engines: {node: '>= 10'} + hasBin: true + + iconv-corefoundation@1.1.7: + resolution: {integrity: sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==} + engines: {node: ^8.11.2 || >=10} + os: [darwin] + iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} @@ -13561,6 +14112,9 @@ packages: resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} engines: {node: '>= 4'} + image-q@4.0.0: + resolution: {integrity: sha512-PfJGVgIfKQJuq3s0tTDOKtztksibuUEbJQIYT3by6wctQo+Rdlh7ef4evJ5NCdxY4CfMbvFkocEwbl4BF8RlJw==} + image-size@1.2.1: resolution: {integrity: sha512-rH+46sQJ2dlwfjfhCyNx5thzrv+dtmBIhPHk0zgRUukHzZ/kRueTJXoYYsclBaKcSMBWuGbOFXtioLpzTb5euw==} engines: {node: '>=16.x'} @@ -13578,6 +14132,10 @@ packages: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + indent-string@5.0.0: resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} engines: {node: '>=12'} @@ -13649,6 +14207,10 @@ packages: invariant@2.2.4: resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} + invert-kv@1.0.0: + resolution: {integrity: sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==} + engines: {node: '>=0.10.0'} + ip-address@10.1.0: resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==} engines: {node: '>= 12'} @@ -13757,6 +14319,10 @@ packages: resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} engines: {node: '>= 0.4'} + is-fullwidth-code-point@1.0.0: + resolution: {integrity: sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==} + engines: {node: '>=0.10.0'} + is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} @@ -13765,6 +14331,9 @@ packages: resolution: {integrity: sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==} engines: {node: '>=18'} + is-function@1.0.2: + resolution: {integrity: sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==} + is-generator-function@1.0.10: resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} engines: {node: '>= 0.4'} @@ -13827,6 +14396,10 @@ packages: resolution: {integrity: sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==} engines: {node: '>=0.10.0'} + is-path-cwd@2.2.0: + resolution: {integrity: sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==} + engines: {node: '>=6'} + is-path-inside@3.0.3: resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} engines: {node: '>=8'} @@ -13865,6 +14438,10 @@ packages: resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} engines: {node: '>= 0.4'} + is-stream@1.1.0: + resolution: {integrity: sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==} + engines: {node: '>=0.10.0'} + is-stream@2.0.1: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} @@ -13900,6 +14477,9 @@ packages: resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} engines: {node: '>= 0.4'} + is-typedarray@1.0.0: + resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} + is-unicode-supported@0.1.0: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} @@ -13908,6 +14488,9 @@ packages: resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} engines: {node: '>=18'} + is-utf8@0.2.1: + resolution: {integrity: sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==} + is-weakmap@2.0.2: resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} engines: {node: '>= 0.4'} @@ -13942,6 +14525,14 @@ packages: isarray@2.0.5: resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + isbinaryfile@4.0.10: + resolution: {integrity: sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==} + engines: {node: '>= 8.0.0'} + + isbinaryfile@5.0.7: + resolution: {integrity: sha512-gnWD14Jh3FzS3CPhF0AxNOJ8CxqeblPTADzI38r0wt8ZyQl5edpy75myt08EG2oKvpyiqSqsx+Wkz9vtkbTqYQ==} + engines: {node: '>= 18.0.0'} + isbot@5.1.28: resolution: {integrity: sha512-qrOp4g3xj8YNse4biorv6O5ZShwsJM0trsoda4y7j/Su7ZtTTfVXFzbKkpgcSoDrHS8FcTuUwcU04YimZlZOxw==} engines: {node: '>=18'} @@ -13953,9 +14544,16 @@ packages: resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==} engines: {node: '>=16'} + isexe@4.0.0: + resolution: {integrity: sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==} + engines: {node: '>=20'} + isomorphic.js@0.2.5: resolution: {integrity: sha512-PIeMbHqMt4DnUP3MA/Flc0HElYjMXArsw1qwJZcm9sqR8mq3l8NYizFMty0pWwE/tzIGH3EKK5+jes5mAr85yw==} + isstream@0.1.2: + resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} + istanbul-lib-coverage@3.2.2: resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} engines: {node: '>=8'} @@ -14039,6 +14637,9 @@ packages: jimp-compact@0.16.1: resolution: {integrity: sha512-dZ6Ra7u1G8c4Letq/B5EzAxj4tLFHL+cGtdpR+PVm4yzPDj+lCk+AbivWt1eOM+ikzkowtyV7qSqX6qr3t71Ww==} + jimp@0.16.13: + resolution: {integrity: sha512-Bxz8q7V4rnCky9A0ktTNGA9SkNFVWRHodddI/DaAWZJzF7sVUlFYKQ60y9JGqrKpi48ECA/TnfMzzc5C70VByA==} + jiti@1.21.6: resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==} hasBin: true @@ -14075,6 +14676,9 @@ packages: resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} engines: {node: '>=10'} + jpeg-js@0.4.4: + resolution: {integrity: sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==} + js-levenshtein@1.1.6: resolution: {integrity: sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==} engines: {node: '>=0.10.0'} @@ -14100,6 +14704,9 @@ packages: resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true + jsbn@0.1.1: + resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} + jsc-safe-url@0.2.4: resolution: {integrity: sha512-0wM3YBWtYePOjfyXQH5MWQ8H7sdk5EXSwZvmSLKk2RboVQ2Bu239jycHDz5J/8Blf3K0Qnoy2b6xD+z10MFB+Q==} @@ -14186,6 +14793,9 @@ packages: json-schema-typed@8.0.2: resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==} + json-schema@0.4.0: + resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} @@ -14200,6 +14810,9 @@ packages: jsonc-parser@3.3.1: resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} + jsonfile@2.4.0: + resolution: {integrity: sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==} + jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} @@ -14217,6 +14830,10 @@ packages: resolution: {integrity: sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==} engines: {node: '>=12', npm: '>=6'} + jsprim@1.4.2: + resolution: {integrity: sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==} + engines: {node: '>=0.6.0'} + jsx-ast-utils@3.3.5: resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} engines: {node: '>=4.0'} @@ -14241,6 +14858,9 @@ packages: resolution: {integrity: sha512-pQpZbdBu7wCTmQUh7ufPmLr0pFoObnGUoL/yhtwJDgmmQpbkg/0HSVti25Fu4rmd1oCR6NGWe9vqTWuWv3GcNA==} hasBin: true + kew@0.7.0: + resolution: {integrity: sha512-IG6nm0+QtAMdXt9KvbgbGdvY50RSrw+U4sGZg+KlrSKPJEwVE5JVoI3d7RWfSMdBQneRheeAOj3lIjX5VL/9RQ==} + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -14251,6 +14871,9 @@ packages: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} + klaw@1.3.1: + resolution: {integrity: sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==} + kleur@3.0.3: resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} engines: {node: '>=6'} @@ -14276,6 +14899,17 @@ packages: layout-base@2.0.1: resolution: {integrity: sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==} + lazy-val@1.0.5: + resolution: {integrity: sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==} + + lcid@1.0.0: + resolution: {integrity: sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==} + engines: {node: '>=0.10.0'} + + leven@2.1.0: + resolution: {integrity: sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==} + engines: {node: '>=0.10.0'} + leven@3.1.0: resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} engines: {node: '>=6'} @@ -14447,6 +15081,13 @@ packages: resolution: {integrity: sha512-9FKQA6G1MMtqNxfxvSBNXD/axeG2QRjYbNh0/ykRL5xYcRbCm2vXq7B9bhc7nSuKdHzr8/BHIwfPuYYH1UsXXw==} hasBin: true + load-bmfont@1.4.2: + resolution: {integrity: sha512-qElWkmjW9Oq1F9EI5Gt7aD9zcdHb9spJCW1L/dmPf7KzCCEJxq8nhHz5eCgI9aMf7vrG/wyaCqdsI+Iy9ZTlog==} + + load-json-file@1.1.0: + resolution: {integrity: sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==} + engines: {node: '>=0.10.0'} + load-tsconfig@0.2.5: resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -14943,6 +15584,11 @@ packages: engines: {node: '>=4'} hasBin: true + mime@2.6.0: + resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} + engines: {node: '>=4.0.0'} + hasBin: true + mimic-fn@1.2.0: resolution: {integrity: sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==} engines: {node: '>=4'} @@ -14963,6 +15609,9 @@ packages: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} + min-document@2.19.2: + resolution: {integrity: sha512-8S5I8db/uZN8r9HSLFVWPdJCvYOejMcEC82VIzNUc6Zkklf/d1gg2psfE79/vyhWOj4+J8MtwmoOz3TmvaGu5A==} + mini-svg-data-uri@1.4.4: resolution: {integrity: sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==} hasBin: true @@ -15004,12 +15653,20 @@ packages: resolution: {integrity: sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==} engines: {node: '>= 18'} + minizlib@3.1.0: + resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} + engines: {node: '>= 18'} + mitt@3.0.1: resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} mkdirp-classic@0.5.3: resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + mkdirp@1.0.4: resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} engines: {node: '>=10'} @@ -15055,6 +15712,10 @@ packages: moo@0.5.3: resolution: {integrity: sha512-m2fmM2dDm7GZQsY7KK2cme8agi+AAljILjQnof7p1ZMDe6dQ4bdnSMx0cPppudoeNv5hEFQirN6u+O4fDE0IWA==} + mri@1.1.4: + resolution: {integrity: sha512-6y7IjGPm8AzlvoUrwAaw1tLnUBudaS3752vcd8JtrpGGQn+rXIe63LFVHm/YMwtqAuh+LJPCFdlLYPWM1nYn6w==} + engines: {node: '>=4'} + mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} engines: {node: '>=4'} @@ -15183,9 +15844,19 @@ packages: resolution: {integrity: sha512-6u9UwL0HlAl21+agMN3YAMXcKByMqwGx+pq+P76vii5f7hTPtKDp08/H9py6DY+cfDw7kQNTGEj/rly3IgbNQA==} engines: {node: '>=10'} + node-abi@4.31.0: + resolution: {integrity: sha512-Erq5w/t3syw3s4sDsUaX4QttIdBPsGKTT1DTRsCkTonGggczhlDKm/wDX3o+HPJpQ41EjXCbcmXf0tgr5YZJXw==} + engines: {node: '>=22.12.0'} + + node-addon-api@1.7.2: + resolution: {integrity: sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==} + node-addon-api@6.1.0: resolution: {integrity: sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==} + node-api-version@0.2.1: + resolution: {integrity: sha512-2xP/IGGMmmSQpI1+O/k72jF/ykvZ89JeuKX3TLJAYPDVLUalrshrLHkeVcCCZqG/eEa635cr8IBYzgnDvM2O8Q==} + node-domexception@1.0.0: resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} engines: {node: '>=10.5.0'} @@ -15216,6 +15887,11 @@ packages: resolution: {integrity: sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==} hasBin: true + node-gyp@12.3.0: + resolution: {integrity: sha512-QNcUWM+HgJplcPzBvFBZ9VXacyGZ4+VTOb80PwWR+TlVzoHbRKULNEzpRsnaoxG3Wzr7Qh7BYxGDU3CbKib2Yg==} + engines: {node: ^20.17.0 || >=22.9.0} + hasBin: true + node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} @@ -15233,6 +15909,14 @@ packages: engines: {node: '>=10'} hasBin: true + nopt@9.0.0: + resolution: {integrity: sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw==} + engines: {node: ^20.17.0 || >=22.9.0} + hasBin: true + + normalize-package-data@2.5.0: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -15263,6 +15947,10 @@ packages: nullthrows@1.1.1: resolution: {integrity: sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==} + number-is-nan@1.0.1: + resolution: {integrity: sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==} + engines: {node: '>=0.10.0'} + nwsapi@2.2.13: resolution: {integrity: sha512-cTGB9ptp9dY9A5VbMSe7fQBcl/tt22Vcqdq8+eN93rblOuE0aCFu4aZ2vMwct/2t+lFnosm8RkQW1I0Omb1UtQ==} @@ -15285,6 +15973,9 @@ packages: oas-validator@5.0.8: resolution: {integrity: sha512-cu20/HE5N5HKqVygs3dt94eYJfBi0TsZvPVXDhbXQHiEityDN+RROTleefoKRKKJ9dFAF2JBkDHgvWj0sjKGmw==} + oauth-sign@0.9.0: + resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==} + ob1@0.82.5: resolution: {integrity: sha512-QyQQ6e66f+Ut/qUVjEce0E/wux5nAGLXYZDn1jr15JWstHsCH3l6VVrg8NKDptW9NEiBXKOJeGF/ydxeSDF3IQ==} engines: {node: '>=18.18'} @@ -15361,6 +16052,9 @@ packages: resolution: {integrity: sha512-UlU69G6Bhu0XFjw3tjFZ0qyiMUjAOR+rdzblA1nLQ8xiqFtxOVlkhM39BlgTpLFx9fxkm6rnxNNRsS5GxE/yww==} engines: {node: '>=0.8.0'} + omggif@1.0.10: + resolution: {integrity: sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==} + on-exit-leak-free@2.1.2: resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} engines: {node: '>=14.0.0'} @@ -15463,6 +16157,10 @@ packages: orderedmap@2.1.1: resolution: {integrity: sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==} + os-locale@1.4.0: + resolution: {integrity: sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==} + engines: {node: '>=0.10.0'} + os-tmpdir@1.0.2: resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} engines: {node: '>=0.10.0'} @@ -15517,6 +16215,10 @@ packages: resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} engines: {node: '>=6'} + p-map@4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + p-retry@4.6.2: resolution: {integrity: sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==} engines: {node: '>=8'} @@ -15542,6 +16244,9 @@ packages: package-manager-detector@1.6.0: resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} + pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + parameter-reducers@2.1.0: resolution: {integrity: sha512-aj9V6DUnNbj4YEmVxloPLX9duhklIC+SIOVUrVdaT3WfgEownET+TYg/JsjANQUNGe46dmOCHEKiuycL36cOnw==} @@ -15549,9 +16254,25 @@ packages: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} + parse-bmfont-ascii@1.0.6: + resolution: {integrity: sha512-U4RrVsUFCleIOBsIGYOMKjn9PavsGOXxbvYGtMOEfnId0SVNsgehXh1DxUdVPLoxd5mvcEtvmKs2Mmf0Mpa1ZA==} + + parse-bmfont-binary@1.0.6: + resolution: {integrity: sha512-GxmsRea0wdGdYthjuUeWTMWPqm2+FAd4GI8vCvhgJsFnoGhTrLhXDDupwTo7rXVAgaLIGoVHDZS9p/5XbSqeWA==} + + parse-bmfont-xml@1.1.6: + resolution: {integrity: sha512-0cEliVMZEhrFDwMh4SxIyVJpqYoOWDJ9P895tFuS+XuNzI5UBmBk5U5O4KuJdTnZpSBI4LFA2+ZiJaiwfSwlMA==} + parse-entities@4.0.1: resolution: {integrity: sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==} + parse-headers@2.0.6: + resolution: {integrity: sha512-Tz11t3uKztEW5FEVZnj1ox8GKblWn+PvHY9TmJV5Mll2uHEwRdR/5Li1OlXoECjLYkApdhWy44ocONwXLiKO5A==} + + parse-json@2.2.0: + resolution: {integrity: sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==} + engines: {node: '>=0.10.0'} + parse-json@4.0.0: resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} engines: {node: '>=4'} @@ -15599,6 +16320,10 @@ packages: path-data-parser@0.1.0: resolution: {integrity: sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==} + path-exists@2.1.0: + resolution: {integrity: sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==} + engines: {node: '>=0.10.0'} + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -15629,6 +16354,10 @@ packages: resolution: {integrity: sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==} engines: {node: '>=16'} + path-type@1.1.0: + resolution: {integrity: sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==} + engines: {node: '>=0.10.0'} + path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -15643,6 +16372,14 @@ packages: resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} engines: {node: '>= 14.16'} + pe-library@0.4.1: + resolution: {integrity: sha512-eRWB5LBz7PpDu4PUlwT0PhnQfTQJlDDdPa35urV4Osrm0t0AqQFGn+UIkU3klZvwJ8KPO3VbBFsXquA6p6kqZw==} + engines: {node: '>=12', npm: '>=6'} + + peek-readable@4.1.0: + resolution: {integrity: sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==} + engines: {node: '>=8'} + peek-readable@5.4.2: resolution: {integrity: sha512-peBp3qZyuS6cNIJ2akRNG1uo1WJ1d0wTxg/fxMdZ0BqCVhx242bSFHM9eNqflfJVS9SsgkzgT/1UgnsurBOTMg==} engines: {node: '>=14.16'} @@ -15729,6 +16466,20 @@ packages: pgpass@1.0.5: resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==} + phantomjs-prebuilt@2.1.16: + resolution: {integrity: sha512-PIiRzBhW85xco2fuj41FmsyuYHKjKuXWmhjy3A/Y+CMpN/63TV+s9uzfVhsUwFe0G77xWtHBG8xmXf5BqEUEuQ==} + deprecated: this package is now deprecated + hasBin: true + + phin@2.9.3: + resolution: {integrity: sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA==} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + + phin@3.7.1: + resolution: {integrity: sha512-GEazpTWwTZaEQ9RhL7Nyz0WwqilbqgLahDM3D0hxWwmVDI52nXEybHqiN6/elwpkJBhcuj+WbBu+QfT0uhPGfQ==} + engines: {node: '>= 8'} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -15765,6 +16516,14 @@ packages: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} engines: {node: '>=6'} + pinkie-promise@2.0.1: + resolution: {integrity: sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==} + engines: {node: '>=0.10.0'} + + pinkie@2.0.4: + resolution: {integrity: sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==} + engines: {node: '>=0.10.0'} + pino-abstract-transport@3.0.0: resolution: {integrity: sha512-wlfUczU+n7Hy/Ha5j9a/gZNy7We5+cXp8YL+X+PG8S0KXxw7n/JXA3c46Y0zQznIJ83URJiwy7Lh56WLokNuxg==} @@ -15783,6 +16542,10 @@ packages: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} + pixelmatch@4.0.2: + resolution: {integrity: sha512-J8B6xqiO37sU/gkcMglv6h5Jbd9xNER7aHzpfRdNmV4IbQBzBpe4l9XmbG+xPF/znacgu2jfEw+wHffaq/YkXA==} + hasBin: true + pkce-challenge@4.1.0: resolution: {integrity: sha512-ZBmhE1C9LcPoH9XZSdwiPtbPHZROwAnMy+kIFQVrnMCxY4Cudlz3gBOpzilgc0jOgRaiT3sIWfpMomW2ar2orQ==} engines: {node: '>=16.20.0'} @@ -15815,10 +16578,17 @@ packages: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} engines: {node: '>=4'} + pn@1.1.0: + resolution: {integrity: sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==} + pngjs@3.4.0: resolution: {integrity: sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==} engines: {node: '>=4.0.0'} + pngjs@6.0.0: + resolution: {integrity: sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==} + engines: {node: '>=12.13.0'} + pnpm@9.15.0: resolution: {integrity: sha512-duI3l2CkMo7EQVgVvNZije5yevN3mqpMkU45RBVsQpmSGon5djge4QfUHxLPpLZmgcqccY8GaPoIMe1MbYulbA==} engines: {node: '>=18.12'} @@ -15967,6 +16737,11 @@ packages: rrweb-snapshot: optional: true + postject@1.0.0-alpha.6: + resolution: {integrity: sha512-b9Eb8h2eVqNE8edvKdwqkrY6O7kAwmI8kcnBv1NScolYJbo59XUF0noFq+lxbC1yN20bmC0WBEbDC5H/7ASb0A==} + engines: {node: '>=14.0.0'} + hasBin: true + preact@10.24.3: resolution: {integrity: sha512-Z2dPnBnMUfyQfSQ+GBdsGa16hz35YmLmtTLhM169uW944hYL6xzTYkJjC07j+Wosz733pMWx0fgON3JNw1jJQA==} @@ -16029,6 +16804,13 @@ packages: resolution: {integrity: sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==} engines: {node: ^18.17.0 || >=20.5.0} + proc-log@6.1.0: + resolution: {integrity: sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==} + engines: {node: ^20.17.0 || >=22.9.0} + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + process-warning@5.0.0: resolution: {integrity: sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==} @@ -16036,10 +16818,18 @@ packages: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} engines: {node: '>= 0.6.0'} + progress@1.1.8: + resolution: {integrity: sha512-UdA8mJ4weIkUBO224tIarHzuHs4HuYiJvsuGT7j/SPQiUJVjYvNDBIPa0hAorduOfjGohB/qHWRa/lrrWX/mXw==} + engines: {node: '>=0.4.0'} + progress@2.0.3: resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} engines: {node: '>=0.4.0'} + promise-retry@2.0.1: + resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} + engines: {node: '>=10'} + promise@7.3.1: resolution: {integrity: sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==} @@ -16053,6 +16843,9 @@ packages: prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + proper-lockfile@4.1.2: + resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==} + property-information@6.5.0: resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==} @@ -16139,6 +16932,9 @@ packages: resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==} engines: {node: '>=10'} + psl@1.15.0: + resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==} + psql-describe@0.1.6: resolution: {integrity: sha512-cZqmsO1FOTmKZFnwbZxViPzEkH/Kyof/t1O2QI25oN5TEexXl6AXVFNIYpoIVBGm2Ic+ImJDR760zUgBMBv+KQ==} @@ -16178,6 +16974,10 @@ packages: resolution: {integrity: sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==} engines: {node: '>=0.6'} + qs@6.5.5: + resolution: {integrity: sha512-mzR4sElr1bfCaPJe7m8ilJ6ZXdDaGoObcYR0ZHSsktM/Lt21MVHj5De30GQH2eiZ1qGRTO7LCAzQsUeXTNexWQ==} + engines: {node: '>=0.6'} + quansync@1.0.0: resolution: {integrity: sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==} @@ -16539,6 +17339,10 @@ packages: resolution: {integrity: sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA==} engines: {node: '>=0.10.0'} + read-binary-file-arch@1.0.6: + resolution: {integrity: sha512-BNg9EN3DD3GsDXX7Aa8O4p92sryjkmzYYgmgTAc6CA4uGLEDzFfxOxugu21akOxpcXHiEgsYkC6nPsQvLLLmEg==} + hasBin: true + read-cache@1.0.0: resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} @@ -16546,10 +17350,21 @@ packages: resolution: {integrity: sha512-SEbJV7tohp3DAAILbEMPXavBjAnMN0tVnh4+9G8ihV4Pq3HYF9h8QNez9zkJ1ILkv9G2BjdzwctznGZXgu/HGw==} engines: {node: ^18.17.0 || >=20.5.0} + read-pkg-up@1.0.1: + resolution: {integrity: sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==} + engines: {node: '>=0.10.0'} + + read-pkg@1.1.0: + resolution: {integrity: sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==} + engines: {node: '>=0.10.0'} + read-yaml-file@1.1.0: resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} engines: {node: '>=6'} + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + readable-stream@3.6.2: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} @@ -16700,6 +17515,14 @@ packages: remend@1.3.0: resolution: {integrity: sha512-iIhggPkhW3hFImKtB10w0dz4EZbs28mV/dmbcYVonWEJ6UGHHpP+bFZnTh6GNWJONg5m+U56JrL+8IxZRdgWjw==} + request-progress@2.0.1: + resolution: {integrity: sha512-dxdraeZVUNEn9AvLrxkgB2k6buTlym71dJk1fk4v8j3Ou3RKNm07BcgbHdj2lLgYGfqX71F+awb1MR+tWPFJzA==} + + request@2.88.2: + resolution: {integrity: sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==} + engines: {node: '>= 6'} + deprecated: request has been deprecated, see https://github.com/request/request/issues/3142 + require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} @@ -16708,10 +17531,17 @@ packages: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} + require-main-filename@1.0.1: + resolution: {integrity: sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==} + requireg@0.2.2: resolution: {integrity: sha512-nYzyjnFcPNGR3lx9lwPPPnuQxv6JWEZd2Ci0u9opN7N5zUEPIhY/GbL3vMGOr2UXwEg9WwSyV9X9Y/kLFgPsOg==} engines: {node: '>= 4.0.0'} + resedit@1.7.2: + resolution: {integrity: sha512-vHjcY2MlAITJhC0eRD/Vv8Vlgmu9Sd3LX9zZvtGzU5ZImdTN3+d6e/4mnTyV8vEbyf1sgNIrWxhWlrys52OkEA==} + engines: {node: '>=12', npm: '>=6'} + reselect@5.1.1: resolution: {integrity: sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==} @@ -16784,6 +17614,10 @@ packages: resolution: {integrity: sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==} engines: {node: '>=0.12'} + retry@0.12.0: + resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} + engines: {node: '>= 4'} + retry@0.13.1: resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} engines: {node: '>= 4'} @@ -16795,6 +17629,11 @@ packages: rfdc@1.4.1: resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + rimraf@2.6.3: + resolution: {integrity: sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} deprecated: Rimraf versions prior to v4 are no longer supported @@ -16908,6 +17747,9 @@ packages: resolution: {integrity: sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==} engines: {node: '>=0.4'} + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} @@ -16926,6 +17768,9 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + sanitize-filename@1.6.4: + resolution: {integrity: sha512-9ZyI08PsvdQl2r/bBIGubpVdR3RR9sY6RDiWFPreA21C/EFlQhmgo20UZlNjZMMZNubusLhAQozkA0Od5J21Eg==} + sax@1.2.1: resolution: {integrity: sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==} @@ -16965,6 +17810,10 @@ packages: semver-compare@1.0.0: resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==} + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -17044,6 +17893,9 @@ packages: server-only@0.0.1: resolution: {integrity: sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==} + set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + set-cookie-parser@2.7.1: resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==} @@ -17185,6 +18037,10 @@ packages: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} + slice-ansi@3.0.0: + resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==} + engines: {node: '>=8'} + slice-ansi@7.1.2: resolution: {integrity: sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==} engines: {node: '>=18'} @@ -17270,6 +18126,18 @@ packages: spawndamnit@3.0.1: resolution: {integrity: sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==} + spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + + spdx-exceptions@2.5.0: + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} + + spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + + spdx-license-ids@3.0.23: + resolution: {integrity: sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==} + speakingurl@14.0.1: resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==} engines: {node: '>=0.10.0'} @@ -17331,6 +18199,11 @@ packages: engines: {node: '>=20.16.0'} hasBin: true + sshpk@1.18.0: + resolution: {integrity: sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==} + engines: {node: '>=0.10.0'} + hasBin: true + sst-darwin-arm64@3.13.2: resolution: {integrity: sha512-eEadOchOCc1ueIT9Qys8KlCgPjvEQ0F376BfZj+B8xZc8pXzMN1jteD8h8EWVXtehA66wPi+RDscTsRmH1iFDg==} cpu: [arm64] @@ -17432,6 +18305,10 @@ packages: resolution: {integrity: sha512-WjlahMgHmCJpqzU8bIBy4qtsZdU9lRlcZE3Lvyej6t4tuOuv1vk57OW3MBrj6hXBFx/nNoC9MPMTcr5YA7NQbg==} engines: {node: '>=6'} + stat-mode@1.0.0: + resolution: {integrity: sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==} + engines: {node: '>= 6'} + statuses@1.5.0: resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} engines: {node: '>= 0.6'} @@ -17490,6 +18367,10 @@ packages: string-ts@2.2.0: resolution: {integrity: sha512-VTP0LLZo4Jp9Gz5IiDVMS9WyLx/3IeYh0PXUn0NdPqusUFNgkHPWiEdbB9TU2Iv3myUskraD5WtYEdHUrQEIlQ==} + string-width@1.0.2: + resolution: {integrity: sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==} + engines: {node: '>=0.10.0'} + string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -17525,6 +18406,9 @@ packages: resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} engines: {node: '>= 0.4'} + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} @@ -17535,6 +18419,10 @@ packages: resolution: {integrity: sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==} engines: {node: '>=4'} + strip-ansi@3.0.1: + resolution: {integrity: sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==} + engines: {node: '>=0.10.0'} + strip-ansi@5.2.0: resolution: {integrity: sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==} engines: {node: '>=6'} @@ -17551,6 +18439,10 @@ packages: resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} engines: {node: '>=0.10.0'} + strip-bom@2.0.0: + resolution: {integrity: sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==} + engines: {node: '>=0.10.0'} + strip-bom@3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} @@ -17581,6 +18473,10 @@ packages: strnum@2.2.3: resolution: {integrity: sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg==} + strtok3@6.3.0: + resolution: {integrity: sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==} + engines: {node: '>=10'} + strtok3@7.1.1: resolution: {integrity: sha512-mKX8HA/cdBqMKUr0MMZAFssCkIGoZeSCMXgnt79yKxNFguMLVFgRe6wB+fsL0NmoHDbeyZXczy7vEPSoo3rkzg==} engines: {node: '>=16'} @@ -17670,6 +18566,10 @@ packages: svg-parser@2.0.4: resolution: {integrity: sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==} + svg2png@4.1.1: + resolution: {integrity: sha512-9tOp9Ugjlunuf1ugqkhiYboTmTaTI7p48dz5ZjNA5NQJ5xS1NLTZZ1tF8vkJOIBb/ZwxGJsKZvRWqVpo4q9z9Q==} + hasBin: true + svgo@3.3.2: resolution: {integrity: sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==} engines: {node: '>=14.0.0'} @@ -17727,6 +18627,10 @@ packages: engines: {node: '>=18'} deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + tar@7.5.15: + resolution: {integrity: sha512-dzGK0boVlC4W5QFuQN1EFSl3bIDYsk7Tj40U6eIBnK2k/8ml7TZ5agbI5j5+qnoVcAA+rNtBml8SEiLxZpNqRQ==} + engines: {node: '>=18'} + temp-dir@2.0.0: resolution: {integrity: sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==} engines: {node: '>=8'} @@ -17735,6 +18639,13 @@ packages: resolution: {integrity: sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==} engines: {node: '>=14.16'} + temp-file@3.4.0: + resolution: {integrity: sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg==} + + temp@0.9.4: + resolution: {integrity: sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==} + engines: {node: '>=6.0.0'} + tempy@0.6.0: resolution: {integrity: sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==} engines: {node: '>=10'} @@ -17790,6 +18701,15 @@ packages: throat@5.0.0: resolution: {integrity: sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==} + throttleit@1.0.1: + resolution: {integrity: sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ==} + + timm@1.7.1: + resolution: {integrity: sha512-IjZc9KIotudix8bMaBW6QvMuq64BrJWFs1+4V0lXwWGQZwH+LnX87doAYhem4caOEusRP9/g6jVDQmZ8XOk1nw==} + + tiny-async-pool@1.3.0: + resolution: {integrity: sha512-01EAw5EDrcVrdgyCLgoSPvqznC0sVxDSVeiOz09FUpjh71G79VCqneOr+xvt7T1r76CF6ZZfPjHorN2+d+3mqA==} + tiny-invariant@1.3.3: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} @@ -17799,6 +18719,9 @@ packages: tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + tinycolor2@1.6.0: + resolution: {integrity: sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==} + tinyexec@0.3.1: resolution: {integrity: sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==} @@ -17863,10 +18786,17 @@ packages: resolution: {integrity: sha512-8PWx8tvC4jDB39BQw1m4x8y5MH1BcQ5xHeL2n7UVFulMPH/3Q0uiamahFJ3lXA0zO2SUyRXuVVbWSDmstlt9YA==} hasBin: true + tmp-promise@3.0.3: + resolution: {integrity: sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==} + tmp@0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} + tmp@0.2.5: + resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==} + engines: {node: '>=14.14'} + tmpl@1.0.5: resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} @@ -17878,6 +18808,10 @@ packages: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} + token-types@4.2.1: + resolution: {integrity: sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==} + engines: {node: '>=10'} + token-types@5.0.1: resolution: {integrity: sha512-Y2fmSnZjQdDb9W4w4r1tswlMHylzWIeOKpx0aZH9BgGtACHhrk3OkT52AzwcuqTRBZtvvnTjDBh8eynMulu8Vg==} engines: {node: '>=14.16'} @@ -17889,6 +18823,10 @@ packages: resolution: {integrity: sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==} hasBin: true + tough-cookie@2.5.0: + resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==} + engines: {node: '>=0.8'} + tough-cookie@5.0.0: resolution: {integrity: sha512-FRKsF7cz96xIIeMZ82ehjC3xW2E+O2+v11udrDYewUbszngYhsGa8z6YUMMzO9QJZzzyd0nGGXnML/TReX6W8Q==} engines: {node: '>=16'} @@ -17929,6 +18867,9 @@ packages: trough@2.2.0: resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + truncate-utf8-bytes@1.0.2: + resolution: {integrity: sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==} + ts-algebra@2.0.0: resolution: {integrity: sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==} @@ -18027,6 +18968,9 @@ packages: resolution: {integrity: sha512-I8yFsfRzmzK0WV1pNNOA4A7y4RDfFxPRxb3t+e3ui14qSGOxGtiSP6GjeX+Y6CHb7HYaFj7ECUD7VE5kQMZWGQ==} engines: {node: '>=18', npm: '>=9'} + tweetnacl@0.14.5: + resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} + type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -18094,6 +19038,9 @@ packages: resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} engines: {node: '>= 0.4'} + typedarray@0.0.6: + resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} + types-react-dom@19.0.0-rc.1: resolution: {integrity: sha512-VSLZJl8VXCD0fAWp7DUTFUDCcZ8DVXOQmjhJMD03odgeFmu14ZQJHCXeETm3BEAhJqfgJaFkLnGkQv88sRx0fQ==} @@ -18170,6 +19117,10 @@ packages: resolution: {integrity: sha512-AjQF1QsmqfJys+LXfGTNum+qw4S88CojRInG/6t31W/1fk6G59s92bnAvGz5Cmur+kQv2SURXEvvudLmbrE8QA==} engines: {node: '>=18.17'} + undici@6.25.0: + resolution: {integrity: sha512-ZgpWDC5gmNiuY9CnLVXEH8rl50xhRCuLNA97fAUnKi8RRuV4E6KG31pDTsLVUKnohJE0I3XDrTeEydAXRw47xg==} + engines: {node: '>=18.17'} + undici@7.19.0: resolution: {integrity: sha512-Heho1hJD81YChi+uS2RkSjcVO+EQLmLSyUlHyp7Y/wFbxQaGb4WXVKD073JytrjXJVkSZVzoE2MCSOKugFGtOQ==} engines: {node: '>=20.18.1'} @@ -18427,6 +19378,12 @@ packages: peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + utf8-byte-length@1.0.5: + resolution: {integrity: sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==} + + utif@2.0.1: + resolution: {integrity: sha512-Z/S1fNKCicQTf375lIP9G8Sa1H/phcysstNrrSdZKj1f9g58J4NMgb5IgiEZN9/nLMPDwF0W7hdOe9Qq2IYoLg==} + util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} @@ -18446,6 +19403,11 @@ packages: resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} hasBin: true + uuid@3.4.0: + resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} + deprecated: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028). + hasBin: true + uuid@7.0.3: resolution: {integrity: sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==} deprecated: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028). @@ -18456,6 +19418,11 @@ packages: deprecated: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028). hasBin: true + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + deprecated: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028). + hasBin: true + uuid@9.0.1: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} deprecated: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028). @@ -18469,6 +19436,9 @@ packages: typescript: optional: true + validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + validate-npm-package-name@5.0.1: resolution: {integrity: sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} @@ -18489,6 +19459,14 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} + verror@1.10.0: + resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} + engines: {'0': node >=0.6.0} + + verror@1.10.1: + resolution: {integrity: sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==} + engines: {node: '>=0.6.0'} + vfile-location@5.0.3: resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} @@ -19000,6 +19978,9 @@ packages: resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} engines: {node: '>= 0.4'} + which-module@1.0.0: + resolution: {integrity: sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==} + which-typed-array@1.1.15: resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} engines: {node: '>= 0.4'} @@ -19012,6 +19993,10 @@ packages: resolution: {integrity: sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==} engines: {node: '>= 0.4'} + which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -19022,6 +20007,16 @@ packages: engines: {node: ^16.13.0 || >=18.0.0} hasBin: true + which@5.0.0: + resolution: {integrity: sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==} + engines: {node: ^18.17.0 || >=20.5.0} + hasBin: true + + which@6.0.1: + resolution: {integrity: sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==} + engines: {node: ^20.17.0 || >=22.9.0} + hasBin: true + why-is-node-running@2.3.0: resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} engines: {node: '>=8'} @@ -19090,6 +20085,10 @@ packages: workbox-window@7.3.0: resolution: {integrity: sha512-qW8PDy16OV1UBaUNGlTVcepzrlzyzNW/ZJvFQQs2j2TzGsg6IKjcpZC1RSquqQnTOafl5pCj5bGfAHlCjOOjdA==} + wrap-ansi@2.1.0: + resolution: {integrity: sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==} + engines: {node: '>=0.10.0'} + wrap-ansi@6.2.0: resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} engines: {node: '>=8'} @@ -19184,10 +20183,20 @@ packages: resolution: {integrity: sha512-kCz5k7J7XbJtjABOvkc5lJmkiDh8VhjVCGNiqdKCscmVpdVUpEAyXv1xmCLkQJ5dsHqx3IPO4XW+NTDhU/fatA==} engines: {node: '>=10.0.0'} + xhr@2.6.0: + resolution: {integrity: sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==} + xml-name-validator@5.0.0: resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} engines: {node: '>=18'} + xml-parse-from-string@1.0.1: + resolution: {integrity: sha512-ErcKwJTF54uRzzNMXq2X5sMIy88zJvfN2DmdoQvy7PAFJ+tPRU6ydWuOKNMyfmOjdyBQTFREi60s0Y0SyI0G0g==} + + xml2js@0.5.0: + resolution: {integrity: sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==} + engines: {node: '>=4.0.0'} + xml2js@0.6.0: resolution: {integrity: sha512-eLTh0kA8uHceqesPqSE+VvO1CDDJWMwlQfB6LuN6T8w6MaDJ8Txm8P7s5cHD0miF0V+GGTZrDQfxPZQVsur33w==} engines: {node: '>=4.0.0'} @@ -19234,6 +20243,9 @@ packages: peerDependencies: yjs: ^13.0.0 + y18n@3.2.2: + resolution: {integrity: sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==} + y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} @@ -19273,6 +20285,9 @@ packages: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} + yargs-parser@4.2.1: + resolution: {integrity: sha512-+QQWqC2xeL0N5/TE+TY6OGEqyNRM+g2/r712PDNYgiCdXYCApXf1vzfmDSLBxfGRwV+moTq/V8FnMI24JCm2Yg==} + yargs@17.0.1: resolution: {integrity: sha512-xBBulfCc8Y6gLFcrPvtqKz9hz8SO0l1Ni8GgDekvBX2ro0HRQImDGnikfc33cgzcYUSncapnNcZDjVFIH3f6KQ==} engines: {node: '>=12'} @@ -19281,6 +20296,9 @@ packages: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} + yargs@6.6.0: + resolution: {integrity: sha512-6/QWTdisjnu5UHUzQGst+UOEuEVwIzFVGBjq3jMTFNs5WJQsH/X6nMURSaScIdF5txylr1Ao9bvbWiKi2yXbwA==} + yauzl@2.10.0: resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} @@ -19342,6 +20360,8 @@ packages: snapshots: + 7zip-bin@5.2.0: {} + '@0no-co/graphql.web@1.1.2': {} '@acemir/cssom@0.9.24': {} @@ -22090,6 +23110,11 @@ snapshots: '@databases/validate-unicode@1.0.0': {} + '@develar/schema-utils@2.6.5': + dependencies: + ajv: 6.12.6 + ajv-keywords: 3.5.2(ajv@6.12.6) + '@docsearch/css@3.7.0': {} '@docsearch/js@3.7.0(@algolia/client-search@5.13.0)(@types/react@18.3.12)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(search-insights@2.17.2)': @@ -22301,6 +23326,18 @@ snapshots: '@electric-sql/pglite@0.4.5': {} + '@electron/asar@3.4.1': + dependencies: + commander: 5.1.0 + glob: 7.2.3 + minimatch: 3.1.2 + + '@electron/fuses@1.8.0': + dependencies: + chalk: 4.1.2 + fs-extra: 9.1.0 + minimist: 1.2.8 + '@electron/get@2.0.3': dependencies: debug: 4.4.3 @@ -22315,6 +23352,73 @@ snapshots: transitivePeerDependencies: - supports-color + '@electron/get@3.1.0': + dependencies: + debug: 4.4.3 + env-paths: 2.2.1 + fs-extra: 8.1.0 + got: 11.8.6 + progress: 2.0.3 + semver: 6.3.1 + sumchecker: 3.0.1 + optionalDependencies: + global-agent: 3.0.0 + transitivePeerDependencies: + - supports-color + + '@electron/notarize@2.5.0': + dependencies: + debug: 4.4.3 + fs-extra: 9.1.0 + promise-retry: 2.0.1 + transitivePeerDependencies: + - supports-color + + '@electron/osx-sign@1.3.3': + dependencies: + compare-version: 0.1.2 + debug: 4.4.3 + fs-extra: 10.1.0 + isbinaryfile: 4.0.10 + minimist: 1.2.8 + plist: 3.1.0 + transitivePeerDependencies: + - supports-color + + '@electron/rebuild@4.0.4': + dependencies: + '@malept/cross-spawn-promise': 2.0.0 + debug: 4.4.3 + node-abi: 4.31.0 + node-api-version: 0.2.1 + node-gyp: 12.3.0 + read-binary-file-arch: 1.0.6 + transitivePeerDependencies: + - supports-color + + '@electron/universal@2.0.3': + dependencies: + '@electron/asar': 3.4.1 + '@malept/cross-spawn-promise': 2.0.0 + debug: 4.4.3 + dir-compare: 4.2.0 + fs-extra: 11.3.5 + minimatch: 9.0.5 + plist: 3.1.0 + transitivePeerDependencies: + - supports-color + + '@electron/windows-sign@1.2.2': + dependencies: + cross-dirname: 0.1.0 + debug: 4.4.3 + fs-extra: 11.3.5 + minimist: 1.2.8 + postject: 1.0.0-alpha.6 + transitivePeerDependencies: + - supports-color + optional: true + '@emnapi/core@1.7.1': dependencies: '@emnapi/wasi-threads': 1.1.0 @@ -23652,6 +24756,255 @@ snapshots: '@types/yargs': 17.0.33 chalk: 4.1.2 + '@jimp/bmp@0.16.13(@jimp/custom@0.16.13)': + dependencies: + '@babel/runtime': 7.29.2 + '@jimp/custom': 0.16.13 + '@jimp/utils': 0.16.13 + bmp-js: 0.1.0 + + '@jimp/core@0.16.13': + dependencies: + '@babel/runtime': 7.29.2 + '@jimp/utils': 0.16.13 + any-base: 1.1.0 + buffer: 5.7.1 + exif-parser: 0.1.12 + file-type: 16.5.4 + load-bmfont: 1.4.2 + mkdirp: 0.5.6 + phin: 2.9.3 + pixelmatch: 4.0.2 + tinycolor2: 1.6.0 + transitivePeerDependencies: + - debug + + '@jimp/custom@0.16.13': + dependencies: + '@babel/runtime': 7.29.2 + '@jimp/core': 0.16.13 + transitivePeerDependencies: + - debug + + '@jimp/gif@0.16.13(@jimp/custom@0.16.13)': + dependencies: + '@babel/runtime': 7.29.2 + '@jimp/custom': 0.16.13 + '@jimp/utils': 0.16.13 + gifwrap: 0.9.4 + omggif: 1.0.10 + + '@jimp/jpeg@0.16.13(@jimp/custom@0.16.13)': + dependencies: + '@babel/runtime': 7.29.2 + '@jimp/custom': 0.16.13 + '@jimp/utils': 0.16.13 + jpeg-js: 0.4.4 + + '@jimp/plugin-blit@0.16.13(@jimp/custom@0.16.13)': + dependencies: + '@babel/runtime': 7.29.2 + '@jimp/custom': 0.16.13 + '@jimp/utils': 0.16.13 + + '@jimp/plugin-blur@0.16.13(@jimp/custom@0.16.13)': + dependencies: + '@babel/runtime': 7.29.2 + '@jimp/custom': 0.16.13 + '@jimp/utils': 0.16.13 + + '@jimp/plugin-circle@0.16.13(@jimp/custom@0.16.13)': + dependencies: + '@babel/runtime': 7.29.2 + '@jimp/custom': 0.16.13 + '@jimp/utils': 0.16.13 + + '@jimp/plugin-color@0.16.13(@jimp/custom@0.16.13)': + dependencies: + '@babel/runtime': 7.29.2 + '@jimp/custom': 0.16.13 + '@jimp/utils': 0.16.13 + tinycolor2: 1.6.0 + + '@jimp/plugin-contain@0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-blit@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-scale@0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13)))': + dependencies: + '@babel/runtime': 7.29.2 + '@jimp/custom': 0.16.13 + '@jimp/plugin-blit': 0.16.13(@jimp/custom@0.16.13) + '@jimp/plugin-resize': 0.16.13(@jimp/custom@0.16.13) + '@jimp/plugin-scale': 0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13)) + '@jimp/utils': 0.16.13 + + '@jimp/plugin-cover@0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-crop@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-scale@0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13)))': + dependencies: + '@babel/runtime': 7.29.2 + '@jimp/custom': 0.16.13 + '@jimp/plugin-crop': 0.16.13(@jimp/custom@0.16.13) + '@jimp/plugin-resize': 0.16.13(@jimp/custom@0.16.13) + '@jimp/plugin-scale': 0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13)) + '@jimp/utils': 0.16.13 + + '@jimp/plugin-crop@0.16.13(@jimp/custom@0.16.13)': + dependencies: + '@babel/runtime': 7.29.2 + '@jimp/custom': 0.16.13 + '@jimp/utils': 0.16.13 + + '@jimp/plugin-displace@0.16.13(@jimp/custom@0.16.13)': + dependencies: + '@babel/runtime': 7.29.2 + '@jimp/custom': 0.16.13 + '@jimp/utils': 0.16.13 + + '@jimp/plugin-dither@0.16.13(@jimp/custom@0.16.13)': + dependencies: + '@babel/runtime': 7.29.2 + '@jimp/custom': 0.16.13 + '@jimp/utils': 0.16.13 + + '@jimp/plugin-fisheye@0.16.13(@jimp/custom@0.16.13)': + dependencies: + '@babel/runtime': 7.29.2 + '@jimp/custom': 0.16.13 + '@jimp/utils': 0.16.13 + + '@jimp/plugin-flip@0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-rotate@0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-blit@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-crop@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13)))': + dependencies: + '@babel/runtime': 7.29.2 + '@jimp/custom': 0.16.13 + '@jimp/plugin-rotate': 0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-blit@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-crop@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13)) + '@jimp/utils': 0.16.13 + + '@jimp/plugin-gaussian@0.16.13(@jimp/custom@0.16.13)': + dependencies: + '@babel/runtime': 7.29.2 + '@jimp/custom': 0.16.13 + '@jimp/utils': 0.16.13 + + '@jimp/plugin-invert@0.16.13(@jimp/custom@0.16.13)': + dependencies: + '@babel/runtime': 7.29.2 + '@jimp/custom': 0.16.13 + '@jimp/utils': 0.16.13 + + '@jimp/plugin-mask@0.16.13(@jimp/custom@0.16.13)': + dependencies: + '@babel/runtime': 7.29.2 + '@jimp/custom': 0.16.13 + '@jimp/utils': 0.16.13 + + '@jimp/plugin-normalize@0.16.13(@jimp/custom@0.16.13)': + dependencies: + '@babel/runtime': 7.29.2 + '@jimp/custom': 0.16.13 + '@jimp/utils': 0.16.13 + + '@jimp/plugin-print@0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-blit@0.16.13(@jimp/custom@0.16.13))': + dependencies: + '@babel/runtime': 7.29.2 + '@jimp/custom': 0.16.13 + '@jimp/plugin-blit': 0.16.13(@jimp/custom@0.16.13) + '@jimp/utils': 0.16.13 + load-bmfont: 1.4.2 + transitivePeerDependencies: + - debug + + '@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13)': + dependencies: + '@babel/runtime': 7.29.2 + '@jimp/custom': 0.16.13 + '@jimp/utils': 0.16.13 + + '@jimp/plugin-rotate@0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-blit@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-crop@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13))': + dependencies: + '@babel/runtime': 7.29.2 + '@jimp/custom': 0.16.13 + '@jimp/plugin-blit': 0.16.13(@jimp/custom@0.16.13) + '@jimp/plugin-crop': 0.16.13(@jimp/custom@0.16.13) + '@jimp/plugin-resize': 0.16.13(@jimp/custom@0.16.13) + '@jimp/utils': 0.16.13 + + '@jimp/plugin-scale@0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13))': + dependencies: + '@babel/runtime': 7.29.2 + '@jimp/custom': 0.16.13 + '@jimp/plugin-resize': 0.16.13(@jimp/custom@0.16.13) + '@jimp/utils': 0.16.13 + + '@jimp/plugin-shadow@0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-blur@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13))': + dependencies: + '@babel/runtime': 7.29.2 + '@jimp/custom': 0.16.13 + '@jimp/plugin-blur': 0.16.13(@jimp/custom@0.16.13) + '@jimp/plugin-resize': 0.16.13(@jimp/custom@0.16.13) + '@jimp/utils': 0.16.13 + + '@jimp/plugin-threshold@0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-color@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13))': + dependencies: + '@babel/runtime': 7.29.2 + '@jimp/custom': 0.16.13 + '@jimp/plugin-color': 0.16.13(@jimp/custom@0.16.13) + '@jimp/plugin-resize': 0.16.13(@jimp/custom@0.16.13) + '@jimp/utils': 0.16.13 + + '@jimp/plugins@0.16.13(@jimp/custom@0.16.13)': + dependencies: + '@babel/runtime': 7.29.2 + '@jimp/custom': 0.16.13 + '@jimp/plugin-blit': 0.16.13(@jimp/custom@0.16.13) + '@jimp/plugin-blur': 0.16.13(@jimp/custom@0.16.13) + '@jimp/plugin-circle': 0.16.13(@jimp/custom@0.16.13) + '@jimp/plugin-color': 0.16.13(@jimp/custom@0.16.13) + '@jimp/plugin-contain': 0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-blit@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-scale@0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13))) + '@jimp/plugin-cover': 0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-crop@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-scale@0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13))) + '@jimp/plugin-crop': 0.16.13(@jimp/custom@0.16.13) + '@jimp/plugin-displace': 0.16.13(@jimp/custom@0.16.13) + '@jimp/plugin-dither': 0.16.13(@jimp/custom@0.16.13) + '@jimp/plugin-fisheye': 0.16.13(@jimp/custom@0.16.13) + '@jimp/plugin-flip': 0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-rotate@0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-blit@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-crop@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13))) + '@jimp/plugin-gaussian': 0.16.13(@jimp/custom@0.16.13) + '@jimp/plugin-invert': 0.16.13(@jimp/custom@0.16.13) + '@jimp/plugin-mask': 0.16.13(@jimp/custom@0.16.13) + '@jimp/plugin-normalize': 0.16.13(@jimp/custom@0.16.13) + '@jimp/plugin-print': 0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-blit@0.16.13(@jimp/custom@0.16.13)) + '@jimp/plugin-resize': 0.16.13(@jimp/custom@0.16.13) + '@jimp/plugin-rotate': 0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-blit@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-crop@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13)) + '@jimp/plugin-scale': 0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13)) + '@jimp/plugin-shadow': 0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-blur@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13)) + '@jimp/plugin-threshold': 0.16.13(@jimp/custom@0.16.13)(@jimp/plugin-color@0.16.13(@jimp/custom@0.16.13))(@jimp/plugin-resize@0.16.13(@jimp/custom@0.16.13)) + timm: 1.7.1 + transitivePeerDependencies: + - debug + + '@jimp/png@0.16.13(@jimp/custom@0.16.13)': + dependencies: + '@babel/runtime': 7.29.2 + '@jimp/custom': 0.16.13 + '@jimp/utils': 0.16.13 + pngjs: 3.4.0 + + '@jimp/tiff@0.16.13(@jimp/custom@0.16.13)': + dependencies: + '@babel/runtime': 7.29.2 + '@jimp/custom': 0.16.13 + utif: 2.0.1 + + '@jimp/types@0.16.13(@jimp/custom@0.16.13)': + dependencies: + '@babel/runtime': 7.29.2 + '@jimp/bmp': 0.16.13(@jimp/custom@0.16.13) + '@jimp/custom': 0.16.13 + '@jimp/gif': 0.16.13(@jimp/custom@0.16.13) + '@jimp/jpeg': 0.16.13(@jimp/custom@0.16.13) + '@jimp/png': 0.16.13(@jimp/custom@0.16.13) + '@jimp/tiff': 0.16.13(@jimp/custom@0.16.13) + timm: 1.7.1 + + '@jimp/utils@0.16.13': + dependencies: + '@babel/runtime': 7.29.2 + regenerator-runtime: 0.13.11 + '@jridgewell/gen-mapping@0.3.12': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -23748,6 +25101,19 @@ snapshots: '@lmdb/lmdb-win32-x64@3.5.4': optional: true + '@malept/cross-spawn-promise@2.0.0': + dependencies: + cross-spawn: 7.0.6 + + '@malept/flatpak-bundler@0.4.0': + dependencies: + debug: 4.4.3 + fs-extra: 9.1.0 + lodash: 4.18.1 + tmp-promise: 3.0.3 + transitivePeerDependencies: + - supports-color + '@manypkg/find-root@1.1.0': dependencies: '@babel/runtime': 7.29.2 @@ -27869,6 +29235,10 @@ snapshots: '@types/express-serve-static-core': 5.0.7 '@types/serve-static': 1.15.8 + '@types/fs-extra@9.0.13': + dependencies: + '@types/node': 22.19.17 + '@types/geojson@7946.0.16': {} '@types/graceful-fs@4.1.9': @@ -27958,6 +29328,8 @@ snapshots: '@types/node@12.20.55': {} + '@types/node@16.9.1': {} + '@types/node@20.17.6': dependencies: undici-types: 6.19.8 @@ -27993,6 +29365,12 @@ snapshots: pg-protocol: 1.10.3 pg-types: 2.2.0 + '@types/plist@3.0.5': + dependencies: + '@types/node': 22.19.17 + xmlbuilder: 15.1.1 + optional: true + '@types/prop-types@15.7.13': {} '@types/qs@6.14.0': {} @@ -28080,6 +29458,9 @@ snapshots: '@types/uuid@9.0.8': {} + '@types/verror@1.10.11': + optional: true + '@types/vite-plugin-react-svg@0.2.5': dependencies: '@types/node': 22.19.17 @@ -29329,6 +30710,8 @@ snapshots: '@xmldom/xmldom@0.8.10': {} + abbrev@4.0.0: {} + abort-controller@3.0.0: dependencies: event-target-shim: 5.0.1 @@ -29365,6 +30748,11 @@ snapshots: agent-base@7.1.4: {} + aggregate-error@3.1.0: + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + ajv-formats@2.1.1(ajv@8.18.0): optionalDependencies: ajv: 8.18.0 @@ -29373,6 +30761,10 @@ snapshots: optionalDependencies: ajv: 8.20.0 + ajv-keywords@3.5.2(ajv@6.12.6): + dependencies: + ajv: 6.12.6 + ajv-keywords@5.1.0(ajv@8.18.0): dependencies: ajv: 8.18.0 @@ -29435,6 +30827,8 @@ snapshots: dependencies: environment: 1.1.0 + ansi-regex@2.1.1: {} + ansi-regex@4.1.1: {} ansi-regex@5.0.1: {} @@ -29459,6 +30853,8 @@ snapshots: ansis@4.1.0: {} + any-base@1.1.0: {} + any-promise@1.3.0: {} anymatch@3.1.3: @@ -29466,6 +30862,51 @@ snapshots: normalize-path: 3.0.0 picomatch: 2.3.2 + app-builder-bin@5.0.0-alpha.12: {} + + app-builder-lib@26.8.1(dmg-builder@26.8.1)(electron-builder-squirrel-windows@26.8.1): + dependencies: + '@develar/schema-utils': 2.6.5 + '@electron/asar': 3.4.1 + '@electron/fuses': 1.8.0 + '@electron/get': 3.1.0 + '@electron/notarize': 2.5.0 + '@electron/osx-sign': 1.3.3 + '@electron/rebuild': 4.0.4 + '@electron/universal': 2.0.3 + '@malept/flatpak-bundler': 0.4.0 + '@types/fs-extra': 9.0.13 + async-exit-hook: 2.0.1 + builder-util: 26.8.1 + builder-util-runtime: 9.5.1 + chromium-pickle-js: 0.2.0 + ci-info: 4.3.1 + debug: 4.4.3 + dmg-builder: 26.8.1(electron-builder-squirrel-windows@26.8.1) + dotenv: 16.6.1 + dotenv-expand: 11.0.7 + ejs: 3.1.10 + electron-builder-squirrel-windows: 26.8.1(dmg-builder@26.8.1) + electron-publish: 26.8.1 + fs-extra: 10.1.0 + hosted-git-info: 4.1.0 + isbinaryfile: 5.0.7 + jiti: 2.6.1 + js-yaml: 4.1.1 + json5: 2.2.3 + lazy-val: 1.0.5 + minimatch: 10.2.5 + plist: 3.1.0 + proper-lockfile: 4.1.2 + resedit: 1.7.2 + semver: 7.7.4 + tar: 7.5.15 + temp-file: 3.4.0 + tiny-async-pool: 1.3.0 + which: 5.0.0 + transitivePeerDependencies: + - supports-color + arg@5.0.2: {} argparse@1.0.10: @@ -29474,6 +30915,13 @@ snapshots: argparse@2.0.1: {} + args@5.0.3: + dependencies: + camelcase: 5.0.0 + chalk: 2.4.2 + leven: 2.1.0 + mri: 1.1.4 + aria-hidden@1.2.4: dependencies: tslib: 2.8.1 @@ -29566,8 +31014,14 @@ snapshots: asap@2.0.6: {} + asn1@0.2.6: + dependencies: + safer-buffer: 2.1.2 + assert-never@1.3.0: {} + assert-plus@1.0.0: {} + assertion-error@2.0.1: {} ast-kit@1.4.3: @@ -29595,6 +31049,11 @@ snapshots: estree-walker: 3.0.3 js-tokens: 10.0.0 + astral-regex@2.0.0: + optional: true + + async-exit-hook@2.0.1: {} + async-function@1.0.0: {} async-limiter@1.0.1: {} @@ -29636,6 +31095,10 @@ snapshots: uuid: 8.0.0 xml2js: 0.6.2 + aws-sign2@0.7.0: {} + + aws4@1.13.2: {} + aws4fetch@1.0.18: {} aws4fetch@1.0.20: {} @@ -29815,6 +31278,10 @@ snapshots: basic-ftp@5.3.0: {} + bcrypt-pbkdf@1.0.2: + dependencies: + tweetnacl: 0.14.5 + better-auth@1.4.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(solid-js@1.9.7): dependencies: '@better-auth/core': 1.4.3(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.18)(better-call@1.1.0)(jose@6.1.0)(kysely@0.28.7)(nanostores@1.0.1) @@ -29850,7 +31317,7 @@ snapshots: dependencies: is-windows: 1.0.2 - better-sqlite3@11.10.0: + better-sqlite3@12.9.0: dependencies: bindings: 1.5.0 prebuild-install: 7.1.3 @@ -29891,6 +31358,8 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 + bmp-js@0.1.0: {} + body-parser@1.20.3: dependencies: bytes: 3.1.2 @@ -29995,6 +31464,8 @@ snapshots: buffer-equal-constant-time@1.0.1: {} + buffer-equal@0.0.1: {} + buffer-from@1.1.2: {} buffer@4.9.2: @@ -30013,6 +31484,34 @@ snapshots: base64-js: 1.5.1 ieee754: 1.2.1 + builder-util-runtime@9.5.1: + dependencies: + debug: 4.4.3 + sax: 1.4.1 + transitivePeerDependencies: + - supports-color + + builder-util@26.8.1: + dependencies: + 7zip-bin: 5.2.0 + '@types/debug': 4.1.12 + app-builder-bin: 5.0.0-alpha.12 + builder-util-runtime: 9.5.1 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3 + fs-extra: 10.1.0 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + js-yaml: 4.1.1 + sanitize-filename: 1.6.4 + source-map-support: 0.5.21 + stat-mode: 1.0.0 + temp-file: 3.4.0 + tiny-async-pool: 1.3.0 + transitivePeerDependencies: + - supports-color + bundle-name@4.1.0: dependencies: run-applescript: 7.1.0 @@ -30092,6 +31591,10 @@ snapshots: camelcase-css@2.0.1: {} + camelcase@3.0.0: {} + + camelcase@5.0.0: {} + camelcase@5.3.1: {} camelcase@6.3.0: {} @@ -30104,8 +31607,16 @@ snapshots: caniuse-lite@1.0.30001791: {} + caseless@0.12.0: {} + ccount@2.0.1: {} + centra@2.7.0: + dependencies: + follow-redirects: 1.16.0 + transitivePeerDependencies: + - debug + chai@5.3.3: dependencies: assertion-error: 2.0.1 @@ -30227,14 +31738,22 @@ snapshots: transitivePeerDependencies: - supports-color + chromium-pickle-js@0.2.0: {} + ci-info@2.0.0: {} ci-info@3.9.0: {} + ci-info@4.3.1: {} + + ci-info@4.4.0: {} + classnames@2.3.2: {} classnames@2.5.1: {} + clean-stack@2.2.0: {} + cli-boxes@3.0.0: {} cli-cursor@2.1.0: @@ -30257,6 +31776,12 @@ snapshots: cli-spinners@3.4.0: {} + cli-truncate@2.1.0: + dependencies: + slice-ansi: 3.0.0 + string-width: 4.2.3 + optional: true + cli-truncate@5.1.0: dependencies: slice-ansi: 7.1.2 @@ -30271,6 +31796,12 @@ snapshots: client-only@0.0.1: {} + cliui@3.2.0: + dependencies: + string-width: 1.0.2 + strip-ansi: 3.0.1 + wrap-ansi: 2.1.0 + cliui@7.0.4: dependencies: string-width: 4.2.3 @@ -30301,6 +31832,8 @@ snapshots: dependencies: convert-to-spaces: 2.0.1 + code-point-at@1.1.0: {} + codemirror@6.0.1(@lezer/common@1.2.3): dependencies: '@codemirror/autocomplete': 6.18.3(@codemirror/language@6.10.6)(@codemirror/state@6.5.0)(@codemirror/view@6.35.2)(@lezer/common@1.2.3) @@ -30371,12 +31904,21 @@ snapshots: commander@4.1.1: {} + commander@5.1.0: {} + + commander@6.2.1: {} + commander@7.2.0: {} commander@8.3.0: {} + commander@9.5.0: + optional: true + common-tags@1.8.2: {} + compare-version@0.1.2: {} + compare-versions@6.1.1: {} compressible@2.0.18: @@ -30397,6 +31939,13 @@ snapshots: concat-map@0.0.1: {} + concat-stream@1.6.2: + dependencies: + buffer-from: 1.1.2 + inherits: 2.0.4 + readable-stream: 2.3.8 + typedarray: 0.0.6 + concurrently@8.2.2: dependencies: chalk: 4.1.2 @@ -30474,6 +32023,8 @@ snapshots: core-js@3.39.0: {} + core-util-is@1.0.2: {} + cors@2.8.5: dependencies: object-assign: 4.1.1 @@ -30512,12 +32063,20 @@ snapshots: optionalDependencies: typescript: 5.7.2 + crc@3.8.0: + dependencies: + buffer: 5.7.1 + optional: true + crelt@1.0.6: {} cron-parser@5.5.0: dependencies: luxon: 3.7.2 + cross-dirname@0.1.0: + optional: true + cross-env@10.1.0: dependencies: '@epic-web/invariant': 1.0.0 @@ -30813,6 +32372,10 @@ snapshots: d3: 7.9.0 lodash-es: 4.18.1 + dashdash@1.14.1: + dependencies: + assert-plus: 1.0.0 + data-uri-to-buffer@4.0.1: {} data-uri-to-buffer@6.0.2: {} @@ -30864,11 +32427,11 @@ snapshots: dayjs@1.11.20: {} - db0@0.3.4(@electric-sql/pglite@0.4.5)(better-sqlite3@11.10.0)(drizzle-orm@0.39.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@11.10.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7)): + db0@0.3.4(@electric-sql/pglite@0.4.5)(better-sqlite3@12.9.0)(drizzle-orm@0.39.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@12.9.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7)): optionalDependencies: '@electric-sql/pglite': 0.4.5 - better-sqlite3: 11.10.0 - drizzle-orm: 0.39.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@11.10.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7) + better-sqlite3: 12.9.0 + drizzle-orm: 0.39.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@12.9.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7) de-indent@1.0.2: {} @@ -30894,6 +32457,8 @@ snapshots: dependencies: ms: 2.1.3 + decamelize@1.2.0: {} + decimal.js@10.4.3: {} decimal.js@10.6.0: {} @@ -30976,6 +32541,17 @@ snapshots: escodegen: 2.1.0 esprima: 4.0.1 + del@6.1.1: + dependencies: + globby: 11.1.0 + graceful-fs: 4.2.11 + is-glob: 4.0.3 + is-path-cwd: 2.2.0 + is-path-inside: 3.0.3 + p-map: 4.0.0 + rimraf: 3.0.2 + slash: 3.0.0 + delaunator@5.1.0: dependencies: robust-predicates: 3.0.3 @@ -31015,6 +32591,11 @@ snapshots: diff@9.0.0: {} + dir-compare@4.2.0: + dependencies: + minimatch: 3.1.2 + p-limit: 3.1.0 + dir-glob@3.0.1: dependencies: path-type: 4.0.0 @@ -31023,6 +32604,31 @@ snapshots: dlv@1.1.3: {} + dmg-builder@26.8.1(electron-builder-squirrel-windows@26.8.1): + dependencies: + app-builder-lib: 26.8.1(dmg-builder@26.8.1)(electron-builder-squirrel-windows@26.8.1) + builder-util: 26.8.1 + fs-extra: 10.1.0 + iconv-lite: 0.6.3 + js-yaml: 4.1.1 + optionalDependencies: + dmg-license: 1.0.11 + transitivePeerDependencies: + - electron-builder-squirrel-windows + - supports-color + + dmg-license@1.0.11: + dependencies: + '@types/plist': 3.0.5 + '@types/verror': 1.10.11 + ajv: 6.12.6 + crc: 3.8.0 + iconv-corefoundation: 1.1.7 + plist: 3.1.0 + smart-buffer: 4.2.0 + verror: 1.10.1 + optional: true + doctrine@2.1.0: dependencies: esutils: 2.0.3 @@ -31039,6 +32645,8 @@ snapshots: domhandler: 5.0.3 entities: 4.5.0 + dom-walk@0.1.2: {} + domelementtype@2.3.0: {} domhandler@5.0.3: @@ -31098,37 +32706,37 @@ snapshots: transitivePeerDependencies: - supports-color - drizzle-orm@0.39.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@11.10.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7): + drizzle-orm@0.39.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@12.9.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7): optionalDependencies: '@electric-sql/pglite': 0.4.5 '@opentelemetry/api': 1.9.1 '@types/better-sqlite3': 7.6.13 '@types/pg': 8.15.4 - better-sqlite3: 11.10.0 + better-sqlite3: 12.9.0 kysely: 0.28.7 pg: 8.16.3 postgres: 3.4.7 - drizzle-orm@0.44.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@11.10.0)(gel@2.2.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7): + drizzle-orm@0.44.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@12.9.0)(gel@2.2.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7): optionalDependencies: '@electric-sql/pglite': 0.4.5 '@opentelemetry/api': 1.9.1 '@types/better-sqlite3': 7.6.13 '@types/pg': 8.15.4 - better-sqlite3: 11.10.0 + better-sqlite3: 12.9.0 gel: 2.2.0 kysely: 0.28.7 pg: 8.16.3 postgres: 3.4.7 - drizzle-zod@0.7.1(drizzle-orm@0.39.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@11.10.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7))(zod@4.1.11): + drizzle-zod@0.7.1(drizzle-orm@0.39.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@12.9.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7))(zod@4.1.11): dependencies: - drizzle-orm: 0.39.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@11.10.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7) + drizzle-orm: 0.39.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@12.9.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7) zod: 4.1.11 - drizzle-zod@0.8.2(drizzle-orm@0.44.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@11.10.0)(gel@2.2.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7))(zod@4.0.10): + drizzle-zod@0.8.2(drizzle-orm@0.44.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@12.9.0)(gel@2.2.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7))(zod@4.0.10): dependencies: - drizzle-orm: 0.44.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@11.10.0)(gel@2.2.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7) + drizzle-orm: 0.44.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@12.9.0)(gel@2.2.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7) zod: 4.0.10 dts-resolver@1.2.0: @@ -31144,6 +32752,11 @@ snapshots: eastasianwidth@0.2.0: {} + ecc-jsbn@0.1.2: + dependencies: + jsbn: 0.1.1 + safer-buffer: 2.1.2 + ecdsa-sig-formatter@1.0.11: dependencies: safe-buffer: 5.2.1 @@ -31161,10 +32774,69 @@ snapshots: dependencies: jake: 10.9.4 + electron-builder-squirrel-windows@26.8.1(dmg-builder@26.8.1): + dependencies: + app-builder-lib: 26.8.1(dmg-builder@26.8.1)(electron-builder-squirrel-windows@26.8.1) + builder-util: 26.8.1 + electron-winstaller: 5.4.0 + transitivePeerDependencies: + - dmg-builder + - supports-color + + electron-builder@26.8.1(electron-builder-squirrel-windows@26.8.1): + dependencies: + app-builder-lib: 26.8.1(dmg-builder@26.8.1)(electron-builder-squirrel-windows@26.8.1) + builder-util: 26.8.1 + builder-util-runtime: 9.5.1 + chalk: 4.1.2 + ci-info: 4.4.0 + dmg-builder: 26.8.1(electron-builder-squirrel-windows@26.8.1) + fs-extra: 10.1.0 + lazy-val: 1.0.5 + simple-update-notifier: 2.0.0 + yargs: 17.7.2 + transitivePeerDependencies: + - electron-builder-squirrel-windows + - supports-color + + electron-icon-builder@2.0.1: + dependencies: + args: 5.0.3 + icon-gen: 2.1.0 + jimp: 0.16.13 + transitivePeerDependencies: + - debug + - supports-color + + electron-publish@26.8.1: + dependencies: + '@types/fs-extra': 9.0.13 + builder-util: 26.8.1 + builder-util-runtime: 9.5.1 + chalk: 4.1.2 + form-data: 4.0.5 + fs-extra: 10.1.0 + lazy-val: 1.0.5 + mime: 2.6.0 + transitivePeerDependencies: + - supports-color + electron-to-chromium@1.5.344: {} electron-to-chromium@1.5.52: {} + electron-winstaller@5.4.0: + dependencies: + '@electron/asar': 3.4.1 + debug: 4.4.3 + fs-extra: 7.0.1 + lodash: 4.18.1 + temp: 0.9.4 + optionalDependencies: + '@electron/windows-sign': 1.2.2 + transitivePeerDependencies: + - supports-color + electron@41.5.0: dependencies: '@electron/get': 2.0.3 @@ -31250,6 +32922,8 @@ snapshots: rst-selector-parser: 2.2.3 string.prototype.trim: 1.2.10 + err-code@2.0.3: {} + error-ex@1.3.2: dependencies: is-arrayish: 0.2.1 @@ -31445,6 +33119,8 @@ snapshots: es6-promise@3.3.1: {} + es6-promise@4.2.8: {} + esbuild-android-64@0.14.54: optional: true @@ -32158,6 +33834,8 @@ snapshots: signal-exit: 3.0.7 strip-final-newline: 2.0.0 + exif-parser@0.1.12: {} + expand-template@2.0.3: {} expect-type@1.3.0: {} @@ -32432,6 +34110,15 @@ snapshots: iconv-lite: 0.4.24 tmp: 0.0.33 + extract-zip@1.7.0: + dependencies: + concat-stream: 1.6.2 + debug: 2.6.9 + mkdirp: 0.5.6 + yauzl: 2.10.0 + transitivePeerDependencies: + - supports-color + extract-zip@2.0.1: dependencies: debug: 4.4.3 @@ -32442,6 +34129,10 @@ snapshots: transitivePeerDependencies: - supports-color + extsprintf@1.3.0: {} + + extsprintf@1.4.1: {} + fast-base64-decode@1.0.0: {} fast-check@4.6.0: @@ -32546,6 +34237,12 @@ snapshots: dependencies: flat-cache: 4.0.1 + file-type@16.5.4: + dependencies: + readable-web-to-node-stream: 3.0.4 + strtok3: 6.3.0 + token-types: 4.2.1 + file-type@18.7.0: dependencies: readable-web-to-node-stream: 3.0.4 @@ -32554,6 +34251,8 @@ snapshots: file-uri-to-path@1.0.0: {} + file-url@2.0.2: {} + filelist@1.0.6: dependencies: minimatch: 5.1.9 @@ -32599,6 +34298,11 @@ snapshots: transitivePeerDependencies: - supports-color + find-up@1.1.2: + dependencies: + path-exists: 2.1.0 + pinkie-promise: 2.0.1 + find-up@4.1.0: dependencies: locate-path: 5.0.0 @@ -32647,6 +34351,14 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 + forever-agent@0.6.1: {} + + form-data@2.3.3: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + form-data@4.0.1: dependencies: asynckit: 0.4.0 @@ -32681,12 +34393,24 @@ snapshots: fs-constants@1.0.0: {} + fs-extra@1.0.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 2.4.0 + klaw: 1.3.1 + fs-extra@10.1.0: dependencies: graceful-fs: 4.2.11 jsonfile: 6.1.0 universalify: 2.0.1 + fs-extra@11.3.5: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.2.1 + universalify: 2.0.1 + fs-extra@7.0.1: dependencies: graceful-fs: 4.2.11 @@ -32769,6 +34493,8 @@ snapshots: gensync@1.0.0-beta.2: {} + get-caller-file@1.0.3: {} + get-caller-file@2.0.5: {} get-east-asian-width@1.5.0: {} @@ -32831,6 +34557,15 @@ snapshots: getenv@2.0.0: {} + getpass@0.1.7: + dependencies: + assert-plus: 1.0.0 + + gifwrap@0.9.4: + dependencies: + image-q: 4.0.0 + omggif: 1.0.10 + github-from-package@0.0.0: {} glob-parent@5.1.2: @@ -32869,6 +34604,11 @@ snapshots: serialize-error: 7.0.1 optional: true + global@4.4.0: + dependencies: + min-document: 2.19.2 + process: 0.11.10 + globals@11.12.0: {} globals@13.24.0: @@ -32966,6 +34706,13 @@ snapshots: optionalDependencies: uglify-js: 3.19.3 + har-schema@2.0.0: {} + + har-validator@5.1.5: + dependencies: + ajv: 6.12.6 + har-schema: 2.0.0 + has-bigints@1.0.2: {} has-flag@3.0.0: {} @@ -32988,6 +34735,11 @@ snapshots: has@1.0.4: {} + hasha@2.2.0: + dependencies: + is-stream: 1.1.0 + pinkie-promise: 2.0.1 + hasown@2.0.2: dependencies: function-bind: 1.1.2 @@ -33170,6 +34922,12 @@ snapshots: hookable@5.5.3: {} + hosted-git-info@2.8.9: {} + + hosted-git-info@4.1.0: + dependencies: + lru-cache: 6.0.0 + hosted-git-info@7.0.2: dependencies: lru-cache: 10.4.3 @@ -33227,6 +34985,12 @@ snapshots: transitivePeerDependencies: - supports-color + http-signature@1.2.0: + dependencies: + assert-plus: 1.0.0 + jsprim: 1.4.2 + sshpk: 1.18.0 + http2-client@1.3.5: {} http2-wrapper@1.0.3: @@ -33256,6 +35020,23 @@ snapshots: hyphenate-style-name@1.1.0: {} + icon-gen@2.1.0: + dependencies: + commander: 6.2.1 + del: 6.1.1 + mkdirp: 1.0.4 + pngjs: 6.0.0 + svg2png: 4.1.1 + uuid: 8.3.2 + transitivePeerDependencies: + - supports-color + + iconv-corefoundation@1.1.7: + dependencies: + cli-truncate: 2.1.0 + node-addon-api: 1.7.2 + optional: true + iconv-lite@0.4.24: dependencies: safer-buffer: 2.1.2 @@ -33280,6 +35061,10 @@ snapshots: ignore@7.0.5: {} + image-q@4.0.0: + dependencies: + '@types/node': 16.9.1 + image-size@1.2.1: dependencies: queue: 6.0.2 @@ -33296,6 +35081,8 @@ snapshots: imurmurhash@0.1.4: {} + indent-string@4.0.0: {} + indent-string@5.0.0: {} inflight@1.0.6: @@ -33393,6 +35180,8 @@ snapshots: dependencies: loose-envify: 1.4.0 + invert-kv@1.0.0: {} + ip-address@10.1.0: {} ipaddr.js@1.9.1: {} @@ -33495,12 +35284,18 @@ snapshots: dependencies: call-bound: 1.0.4 + is-fullwidth-code-point@1.0.0: + dependencies: + number-is-nan: 1.0.1 + is-fullwidth-code-point@3.0.0: {} is-fullwidth-code-point@5.1.0: dependencies: get-east-asian-width: 1.5.0 + is-function@1.0.2: {} + is-generator-function@1.0.10: dependencies: has-tostringtag: 1.0.2 @@ -33550,6 +35345,8 @@ snapshots: is-obj@1.0.1: {} + is-path-cwd@2.2.0: {} + is-path-inside@3.0.3: {} is-plain-obj@4.1.0: {} @@ -33582,6 +35379,8 @@ snapshots: dependencies: call-bound: 1.0.4 + is-stream@1.1.0: {} + is-stream@2.0.1: {} is-stream@3.0.0: {} @@ -33615,10 +35414,14 @@ snapshots: dependencies: which-typed-array: 1.1.19 + is-typedarray@1.0.0: {} + is-unicode-supported@0.1.0: {} is-unicode-supported@2.1.0: {} + is-utf8@0.2.1: {} + is-weakmap@2.0.2: {} is-weakref@1.1.1: @@ -33646,14 +35449,22 @@ snapshots: isarray@2.0.5: {} + isbinaryfile@4.0.10: {} + + isbinaryfile@5.0.7: {} + isbot@5.1.28: {} isexe@2.0.0: {} isexe@3.1.1: {} + isexe@4.0.0: {} + isomorphic.js@0.2.5: {} + isstream@0.1.2: {} + istanbul-lib-coverage@3.2.2: {} istanbul-lib-instrument@5.2.1: @@ -33804,6 +35615,16 @@ snapshots: jimp-compact@0.16.1: {} + jimp@0.16.13: + dependencies: + '@babel/runtime': 7.29.2 + '@jimp/custom': 0.16.13 + '@jimp/plugins': 0.16.13(@jimp/custom@0.16.13) + '@jimp/types': 0.16.13(@jimp/custom@0.16.13) + regenerator-runtime: 0.13.11 + transitivePeerDependencies: + - debug + jiti@1.21.6: {} jiti@2.5.1: {} @@ -33832,6 +35653,8 @@ snapshots: joycon@3.1.1: {} + jpeg-js@0.4.4: {} + js-levenshtein@1.1.6: {} js-tokens@10.0.0: {} @@ -33853,6 +35676,8 @@ snapshots: dependencies: argparse: 2.0.1 + jsbn@0.1.1: {} + jsc-safe-url@0.2.4: {} jsdom@25.0.1: @@ -34019,15 +35844,20 @@ snapshots: json-schema-typed@8.0.2: {} + json-schema@0.4.0: {} + json-stable-stringify-without-jsonify@1.0.1: {} - json-stringify-safe@5.0.1: - optional: true + json-stringify-safe@5.0.1: {} json5@2.2.3: {} jsonc-parser@3.3.1: {} + jsonfile@2.4.0: + optionalDependencies: + graceful-fs: 4.2.11 + jsonfile@4.0.0: optionalDependencies: graceful-fs: 4.2.11 @@ -34059,6 +35889,13 @@ snapshots: ms: 2.1.3 semver: 7.6.3 + jsprim@1.4.2: + dependencies: + assert-plus: 1.0.0 + extsprintf: 1.3.0 + json-schema: 0.4.0 + verror: 1.10.0 + jsx-ast-utils@3.3.5: dependencies: array-includes: 3.1.9 @@ -34095,6 +35932,8 @@ snapshots: dependencies: commander: 8.3.0 + kew@0.7.0: {} + keyv@4.5.4: dependencies: json-buffer: 3.0.1 @@ -34103,6 +35942,10 @@ snapshots: kind-of@6.0.3: {} + klaw@1.3.1: + optionalDependencies: + graceful-fs: 4.2.11 + kleur@3.0.3: {} kysely@0.28.7: {} @@ -34127,6 +35970,14 @@ snapshots: layout-base@2.0.1: {} + lazy-val@1.0.5: {} + + lcid@1.0.0: + dependencies: + invert-kv: 1.0.0 + + leven@2.1.0: {} + leven@3.1.0: {} levn@0.4.1: @@ -34281,6 +36132,27 @@ snapshots: '@lmdb/lmdb-win32-arm64': 3.5.4 '@lmdb/lmdb-win32-x64': 3.5.4 + load-bmfont@1.4.2: + dependencies: + buffer-equal: 0.0.1 + mime: 1.6.0 + parse-bmfont-ascii: 1.0.6 + parse-bmfont-binary: 1.0.6 + parse-bmfont-xml: 1.1.6 + phin: 3.7.1 + xhr: 2.6.0 + xtend: 4.0.2 + transitivePeerDependencies: + - debug + + load-json-file@1.1.0: + dependencies: + graceful-fs: 4.2.11 + parse-json: 2.2.0 + pify: 2.3.0 + pinkie-promise: 2.0.1 + strip-bom: 2.0.0 + load-tsconfig@0.2.5: {} local-pkg@0.5.1: @@ -35102,6 +36974,8 @@ snapshots: mime@1.6.0: {} + mime@2.6.0: {} + mimic-fn@1.2.0: {} mimic-fn@2.1.0: {} @@ -35112,6 +36986,10 @@ snapshots: mimic-response@3.1.0: {} + min-document@2.19.2: + dependencies: + dom-walk: 0.1.2 + mini-svg-data-uri@1.4.4: {} minimatch@10.0.3: @@ -35149,10 +37027,18 @@ snapshots: minipass: 7.1.2 rimraf: 5.0.10 + minizlib@3.1.0: + dependencies: + minipass: 7.1.2 + mitt@3.0.1: {} mkdirp-classic@0.5.3: {} + mkdirp@0.5.6: + dependencies: + minimist: 1.2.8 + mkdirp@1.0.4: {} mkdirp@3.0.1: {} @@ -35184,6 +37070,8 @@ snapshots: moo@0.5.3: {} + mri@1.1.4: {} + mri@1.2.0: {} ms@2.0.0: {} @@ -35278,11 +37166,11 @@ snapshots: nf3@0.1.12: {} - nitro@3.0.1-alpha.1(@electric-sql/pglite@0.4.5)(aws4fetch@1.0.20)(better-sqlite3@11.10.0)(chokidar@4.0.3)(drizzle-orm@0.39.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@11.10.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7))(lru-cache@11.3.5)(rollup@4.46.1)(vite@7.1.7(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.2)(tsx@4.20.3)(yaml@2.8.1))(xml2js@0.6.2): + nitro@3.0.1-alpha.1(@electric-sql/pglite@0.4.5)(aws4fetch@1.0.20)(better-sqlite3@12.9.0)(chokidar@4.0.3)(drizzle-orm@0.39.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@12.9.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7))(lru-cache@11.3.5)(rollup@4.46.1)(vite@7.1.7(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.2)(tsx@4.20.3)(yaml@2.8.1))(xml2js@0.6.2): dependencies: consola: 3.4.2 crossws: 0.4.3(srvx@0.9.8) - db0: 0.3.4(@electric-sql/pglite@0.4.5)(better-sqlite3@11.10.0)(drizzle-orm@0.39.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@11.10.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7)) + db0: 0.3.4(@electric-sql/pglite@0.4.5)(better-sqlite3@12.9.0)(drizzle-orm@0.39.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@12.9.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7)) h3: 2.0.1-rc.5(crossws@0.4.3(srvx@0.9.8)) jiti: 2.6.1 nf3: 0.1.12 @@ -35293,7 +37181,7 @@ snapshots: srvx: 0.9.8 undici: 7.19.0 unenv: 2.0.0-rc.24 - unstorage: 2.0.0-alpha.5(aws4fetch@1.0.20)(chokidar@4.0.3)(db0@0.3.4(@electric-sql/pglite@0.4.5)(better-sqlite3@11.10.0)(drizzle-orm@0.39.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@11.10.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7)))(lru-cache@11.3.5)(ofetch@2.0.0-alpha.3) + unstorage: 2.0.0-alpha.5(aws4fetch@1.0.20)(chokidar@4.0.3)(db0@0.3.4(@electric-sql/pglite@0.4.5)(better-sqlite3@12.9.0)(drizzle-orm@0.39.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@12.9.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7)))(lru-cache@11.3.5)(ofetch@2.0.0-alpha.3) optionalDependencies: rollup: 4.46.1 vite: 7.1.7(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.2)(tsx@4.20.3)(yaml@2.8.1) @@ -35336,8 +37224,19 @@ snapshots: dependencies: semver: 7.7.4 + node-abi@4.31.0: + dependencies: + semver: 7.7.4 + + node-addon-api@1.7.2: + optional: true + node-addon-api@6.1.0: {} + node-api-version@0.2.1: + dependencies: + semver: 7.7.4 + node-domexception@1.0.0: {} node-fetch-h2@2.3.0: @@ -35360,6 +37259,19 @@ snapshots: dependencies: detect-libc: 2.0.4 + node-gyp@12.3.0: + dependencies: + env-paths: 2.2.1 + exponential-backoff: 3.1.2 + graceful-fs: 4.2.11 + nopt: 9.0.0 + proc-log: 6.1.0 + semver: 7.7.4 + tar: 7.5.15 + tinyglobby: 0.2.15 + undici: 6.25.0 + which: 6.0.1 + node-int64@0.4.0: {} node-readfiles@0.2.0: @@ -35383,6 +37295,17 @@ snapshots: touch: 3.1.1 undefsafe: 2.0.5 + nopt@9.0.0: + dependencies: + abbrev: 4.0.0 + + normalize-package-data@2.5.0: + dependencies: + hosted-git-info: 2.8.9 + resolve: 1.22.12 + semver: 5.7.2 + validate-npm-package-license: 3.0.4 + normalize-path@3.0.0: {} normalize-range@0.1.2: {} @@ -35408,6 +37331,8 @@ snapshots: nullthrows@1.1.1: {} + number-is-nan@1.0.1: {} + nwsapi@2.2.13: {} nwsapi@2.2.21: {} @@ -35443,6 +37368,8 @@ snapshots: should: 13.2.3 yaml: 1.10.2 + oauth-sign@0.9.0: {} + ob1@0.82.5: dependencies: flow-enums-runtime: 0.0.6 @@ -35515,6 +37442,8 @@ snapshots: omelette@0.4.17: {} + omggif@1.0.10: {} + on-exit-leak-free@2.1.2: {} on-finished@2.3.0: @@ -35653,6 +37582,10 @@ snapshots: orderedmap@2.1.1: {} + os-locale@1.4.0: + dependencies: + lcid: 1.0.0 + os-tmpdir@1.0.2: {} outdent@0.5.0: {} @@ -35752,6 +37685,10 @@ snapshots: p-map@2.1.0: {} + p-map@4.0.0: + dependencies: + aggregate-error: 3.1.0 + p-retry@4.6.2: dependencies: '@types/retry': 0.12.0 @@ -35783,12 +37720,23 @@ snapshots: package-manager-detector@1.6.0: {} + pako@1.0.11: {} + parameter-reducers@2.1.0: {} parent-module@1.0.1: dependencies: callsites: 3.1.0 + parse-bmfont-ascii@1.0.6: {} + + parse-bmfont-binary@1.0.6: {} + + parse-bmfont-xml@1.1.6: + dependencies: + xml-parse-from-string: 1.0.1 + xml2js: 0.5.0 + parse-entities@4.0.1: dependencies: '@types/unist': 2.0.11 @@ -35800,6 +37748,12 @@ snapshots: is-decimal: 2.0.1 is-hexadecimal: 2.0.1 + parse-headers@2.0.6: {} + + parse-json@2.2.0: + dependencies: + error-ex: 1.3.2 + parse-json@4.0.0: dependencies: error-ex: 1.3.2 @@ -35851,6 +37805,10 @@ snapshots: path-data-parser@0.1.0: {} + path-exists@2.1.0: + dependencies: + pinkie-promise: 2.0.1 + path-exists@4.0.0: {} path-expression-matcher@1.5.0: {} @@ -35870,6 +37828,12 @@ snapshots: path-to-regexp@8.2.0: {} + path-type@1.1.0: + dependencies: + graceful-fs: 4.2.11 + pify: 2.3.0 + pinkie-promise: 2.0.1 + path-type@4.0.0: {} pathe@1.1.2: {} @@ -35878,6 +37842,10 @@ snapshots: pathval@2.0.1: {} + pe-library@0.4.1: {} + + peek-readable@4.1.0: {} + peek-readable@5.4.2: {} pend@1.2.0: {} @@ -35960,6 +37928,28 @@ snapshots: dependencies: split2: 4.2.0 + phantomjs-prebuilt@2.1.16: + dependencies: + es6-promise: 4.2.8 + extract-zip: 1.7.0 + fs-extra: 1.0.0 + hasha: 2.2.0 + kew: 0.7.0 + progress: 1.1.8 + request: 2.88.2 + request-progress: 2.0.1 + which: 1.3.1 + transitivePeerDependencies: + - supports-color + + phin@2.9.3: {} + + phin@3.7.1: + dependencies: + centra: 2.7.0 + transitivePeerDependencies: + - debug + picocolors@1.1.1: {} picomatch@2.3.1: {} @@ -35978,6 +37968,12 @@ snapshots: pify@4.0.1: {} + pinkie-promise@2.0.1: + dependencies: + pinkie: 2.0.4 + + pinkie@2.0.4: {} + pino-abstract-transport@3.0.0: dependencies: split2: 4.2.0 @@ -36016,6 +38012,10 @@ snapshots: pirates@4.0.6: {} + pixelmatch@4.0.2: + dependencies: + pngjs: 3.4.0 + pkce-challenge@4.1.0: {} pkce-challenge@5.0.1: {} @@ -36048,8 +38048,12 @@ snapshots: pluralize@8.0.0: {} + pn@1.1.0: {} + pngjs@3.4.0: {} + pngjs@6.0.0: {} + pnpm@9.15.0: {} points-on-curve@0.2.0: {} @@ -36176,6 +38180,11 @@ snapshots: preact: 10.24.3 web-vitals: 4.2.4 + postject@1.0.0-alpha.6: + dependencies: + commander: 9.5.0 + optional: true + preact@10.24.3: {} preact@10.29.1: {} @@ -36229,12 +38238,23 @@ snapshots: proc-log@5.0.0: {} + proc-log@6.1.0: {} + + process-nextick-args@2.0.1: {} + process-warning@5.0.0: {} process@0.11.10: {} + progress@1.1.8: {} + progress@2.0.3: {} + promise-retry@2.0.1: + dependencies: + err-code: 2.0.3 + retry: 0.12.0 + promise@7.3.1: dependencies: asap: 2.0.6 @@ -36254,6 +38274,12 @@ snapshots: object-assign: 4.1.1 react-is: 16.13.1 + proper-lockfile@4.1.2: + dependencies: + graceful-fs: 4.2.11 + retry: 0.12.0 + signal-exit: 3.0.7 + property-information@6.5.0: {} property-information@7.1.0: {} @@ -36400,6 +38426,10 @@ snapshots: proxy-from-env@2.1.0: {} + psl@1.15.0: + dependencies: + punycode: 2.3.1 + psql-describe@0.1.6: {} pstree.remy@1.1.8: {} @@ -36431,6 +38461,8 @@ snapshots: dependencies: side-channel: 1.1.0 + qs@6.5.5: {} + quansync@1.0.0: {} query-string@7.1.3: @@ -36899,12 +38931,29 @@ snapshots: react@19.2.5: {} + read-binary-file-arch@1.0.6: + dependencies: + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + read-cache@1.0.0: dependencies: pify: 2.3.0 read-cmd-shim@5.0.0: {} + read-pkg-up@1.0.1: + dependencies: + find-up: 1.1.2 + read-pkg: 1.1.0 + + read-pkg@1.1.0: + dependencies: + load-json-file: 1.1.0 + normalize-package-data: 2.5.0 + path-type: 1.1.0 + read-yaml-file@1.1.0: dependencies: graceful-fs: 4.2.11 @@ -36912,6 +38961,16 @@ snapshots: pify: 4.0.1 strip-bom: 3.0.0 + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.2 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + readable-stream@3.6.2: dependencies: inherits: 2.0.4 @@ -37173,16 +39232,49 @@ snapshots: remend@1.3.0: {} + request-progress@2.0.1: + dependencies: + throttleit: 1.0.1 + + request@2.88.2: + dependencies: + aws-sign2: 0.7.0 + aws4: 1.13.2 + caseless: 0.12.0 + combined-stream: 1.0.8 + extend: 3.0.2 + forever-agent: 0.6.1 + form-data: 2.3.3 + har-validator: 5.1.5 + http-signature: 1.2.0 + is-typedarray: 1.0.0 + isstream: 0.1.2 + json-stringify-safe: 5.0.1 + mime-types: 2.1.35 + oauth-sign: 0.9.0 + performance-now: 2.1.0 + qs: 6.5.5 + safe-buffer: 5.2.1 + tough-cookie: 2.5.0 + tunnel-agent: 0.6.0 + uuid: 3.4.0 + require-directory@2.1.1: {} require-from-string@2.0.2: {} + require-main-filename@1.0.1: {} + requireg@0.2.2: dependencies: nested-error-stacks: 2.0.1 rc: 1.2.8 resolve: 1.7.1 + resedit@1.7.2: + dependencies: + pe-library: 0.4.1 + reselect@5.1.1: {} resolve-alpn@1.2.1: {} @@ -37254,12 +39346,18 @@ snapshots: ret@0.1.15: {} + retry@0.12.0: {} + retry@0.13.1: {} reusify@1.0.4: {} rfdc@1.4.1: {} + rimraf@2.6.3: + dependencies: + glob: 7.2.3 + rimraf@3.0.2: dependencies: glob: 7.2.3 @@ -37446,6 +39544,8 @@ snapshots: has-symbols: 1.1.0 isarray: 2.0.5 + safe-buffer@5.1.2: {} + safe-buffer@5.2.1: {} safe-push-apply@1.0.0: @@ -37463,6 +39563,10 @@ snapshots: safer-buffer@2.1.2: {} + sanitize-filename@1.6.4: + dependencies: + truncate-utf8-bytes: 1.0.2 + sax@1.2.1: {} sax@1.4.1: {} @@ -37500,6 +39604,8 @@ snapshots: semver-compare@1.0.0: optional: true + semver@5.7.2: {} + semver@6.3.1: {} semver@7.6.3: {} @@ -37591,6 +39697,8 @@ snapshots: server-only@0.0.1: {} + set-blocking@2.0.0: {} + set-cookie-parser@2.7.1: {} set-function-length@1.2.2: @@ -37811,6 +39919,13 @@ snapshots: slash@3.0.0: {} + slice-ansi@3.0.0: + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + optional: true + slice-ansi@7.1.2: dependencies: ansi-styles: 6.2.3 @@ -37889,6 +40004,20 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 + spdx-correct@3.2.0: + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.23 + + spdx-exceptions@2.5.0: {} + + spdx-expression-parse@3.0.1: + dependencies: + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.23 + + spdx-license-ids@3.0.23: {} + speakingurl@14.0.1: {} split-on-first@1.1.0: {} @@ -37931,6 +40060,18 @@ snapshots: srvx@0.9.8: {} + sshpk@1.18.0: + dependencies: + asn1: 0.2.6 + assert-plus: 1.0.0 + bcrypt-pbkdf: 1.0.2 + dashdash: 1.14.1 + ecc-jsbn: 0.1.2 + getpass: 0.1.7 + jsbn: 0.1.1 + safer-buffer: 2.1.2 + tweetnacl: 0.14.5 + sst-darwin-arm64@3.13.2: optional: true @@ -38028,6 +40169,8 @@ snapshots: dependencies: type-fest: 0.7.1 + stat-mode@1.0.0: {} + statuses@1.5.0: {} statuses@2.0.1: {} @@ -38084,6 +40227,12 @@ snapshots: string-ts@2.2.0: {} + string-width@1.0.2: + dependencies: + code-point-at: 1.1.0 + is-fullwidth-code-point: 1.0.0 + strip-ansi: 3.0.1 + string-width@4.2.3: dependencies: emoji-regex: 8.0.0 @@ -38151,6 +40300,10 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.1.1 + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + string_decoder@1.3.0: dependencies: safe-buffer: 5.2.1 @@ -38166,6 +40319,10 @@ snapshots: is-obj: 1.0.1 is-regexp: 1.0.0 + strip-ansi@3.0.1: + dependencies: + ansi-regex: 2.1.1 + strip-ansi@5.2.0: dependencies: ansi-regex: 4.1.1 @@ -38180,6 +40337,10 @@ snapshots: strip-bom-string@1.0.0: {} + strip-bom@2.0.0: + dependencies: + is-utf8: 0.2.1 + strip-bom@3.0.0: {} strip-comments@2.0.1: {} @@ -38198,6 +40359,11 @@ snapshots: strnum@2.2.3: {} + strtok3@6.3.0: + dependencies: + '@tokenizer/token': 0.3.0 + peek-readable: 4.1.0 + strtok3@7.1.1: dependencies: '@tokenizer/token': 0.3.0 @@ -38294,6 +40460,15 @@ snapshots: svg-parser@2.0.4: {} + svg2png@4.1.1: + dependencies: + file-url: 2.0.2 + phantomjs-prebuilt: 2.1.16 + pn: 1.1.0 + yargs: 6.6.0 + transitivePeerDependencies: + - supports-color + svgo@3.3.2: dependencies: '@trysound/sax': 0.2.0 @@ -38394,10 +40569,28 @@ snapshots: mkdirp: 3.0.1 yallist: 5.0.0 + tar@7.5.15: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.2 + minizlib: 3.1.0 + yallist: 5.0.0 + temp-dir@2.0.0: {} temp-dir@3.0.0: {} + temp-file@3.4.0: + dependencies: + async-exit-hook: 2.0.1 + fs-extra: 10.1.0 + + temp@0.9.4: + dependencies: + mkdirp: 0.5.6 + rimraf: 2.6.3 + tempy@0.6.0: dependencies: is-stream: 2.0.1 @@ -38463,12 +40656,22 @@ snapshots: throat@5.0.0: {} + throttleit@1.0.1: {} + + timm@1.7.1: {} + + tiny-async-pool@1.3.0: + dependencies: + semver: 5.7.2 + tiny-invariant@1.3.3: {} tiny-warning@1.0.3: {} tinybench@2.9.0: {} + tinycolor2@1.6.0: {} + tinyexec@0.3.1: {} tinyexec@0.3.2: {} @@ -38521,10 +40724,16 @@ snapshots: dependencies: tldts-core: 7.0.19 + tmp-promise@3.0.3: + dependencies: + tmp: 0.2.5 + tmp@0.0.33: dependencies: os-tmpdir: 1.0.2 + tmp@0.2.5: {} + tmpl@1.0.5: {} to-regex-range@5.0.1: @@ -38533,6 +40742,11 @@ snapshots: toidentifier@1.0.1: {} + token-types@4.2.1: + dependencies: + '@tokenizer/token': 0.3.0 + ieee754: 1.2.1 + token-types@5.0.1: dependencies: '@tokenizer/token': 0.3.0 @@ -38542,6 +40756,11 @@ snapshots: touch@3.1.1: {} + tough-cookie@2.5.0: + dependencies: + psl: 1.15.0 + punycode: 2.3.1 + tough-cookie@5.0.0: dependencies: tldts: 6.1.58 @@ -38578,6 +40797,10 @@ snapshots: trough@2.2.0: {} + truncate-utf8-bytes@1.0.2: + dependencies: + utf8-byte-length: 1.0.5 + ts-algebra@2.0.0: {} ts-api-utils@1.4.0(typescript@5.6.3): @@ -38749,6 +40972,8 @@ snapshots: dependencies: '@mixmark-io/domino': 2.2.0 + tweetnacl@0.14.5: {} + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 @@ -38820,6 +41045,8 @@ snapshots: possible-typed-array-names: 1.0.0 reflect.getprototypeof: 1.0.10 + typedarray@0.0.6: {} + types-react-dom@19.0.0-rc.1: dependencies: '@types/react': 19.2.14 @@ -38882,6 +41109,8 @@ snapshots: undici@6.20.1: {} + undici@6.25.0: {} + undici@7.19.0: {} undici@7.25.0: {} @@ -38984,11 +41213,11 @@ snapshots: picomatch: 4.0.3 webpack-virtual-modules: 0.6.2 - unstorage@2.0.0-alpha.5(aws4fetch@1.0.20)(chokidar@4.0.3)(db0@0.3.4(@electric-sql/pglite@0.4.5)(better-sqlite3@11.10.0)(drizzle-orm@0.39.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@11.10.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7)))(lru-cache@11.3.5)(ofetch@2.0.0-alpha.3): + unstorage@2.0.0-alpha.5(aws4fetch@1.0.20)(chokidar@4.0.3)(db0@0.3.4(@electric-sql/pglite@0.4.5)(better-sqlite3@12.9.0)(drizzle-orm@0.39.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@12.9.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7)))(lru-cache@11.3.5)(ofetch@2.0.0-alpha.3): optionalDependencies: aws4fetch: 1.0.20 chokidar: 4.0.3 - db0: 0.3.4(@electric-sql/pglite@0.4.5)(better-sqlite3@11.10.0)(drizzle-orm@0.39.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@11.10.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7)) + db0: 0.3.4(@electric-sql/pglite@0.4.5)(better-sqlite3@12.9.0)(drizzle-orm@0.39.3(@electric-sql/pglite@0.4.5)(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.4)(better-sqlite3@12.9.0)(kysely@0.28.7)(pg@8.16.3)(postgres@3.4.7)) lru-cache: 11.3.5 ofetch: 2.0.0-alpha.3 @@ -39081,6 +41310,12 @@ snapshots: dependencies: react: 19.2.5 + utf8-byte-length@1.0.5: {} + + utif@2.0.1: + dependencies: + pako: 1.0.11 + util-deprecate@1.0.2: {} util@0.12.5: @@ -39097,16 +41332,25 @@ snapshots: uuid@11.1.0: {} + uuid@3.4.0: {} + uuid@7.0.3: {} uuid@8.0.0: {} + uuid@8.3.2: {} + uuid@9.0.1: {} valibot@1.0.0(typescript@5.8.3): optionalDependencies: typescript: 5.8.3 + validate-npm-package-license@3.0.4: + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + validate-npm-package-name@5.0.1: {} valtio@2.1.2(react@19.0.0-rc.1)(types-react@19.0.0-rc.1): @@ -39118,6 +41362,19 @@ snapshots: vary@1.1.2: {} + verror@1.10.0: + dependencies: + assert-plus: 1.0.0 + core-util-is: 1.0.2 + extsprintf: 1.4.1 + + verror@1.10.1: + dependencies: + assert-plus: 1.0.0 + core-util-is: 1.0.2 + extsprintf: 1.4.1 + optional: true + vfile-location@5.0.3: dependencies: '@types/unist': 3.0.3 @@ -40093,6 +42350,8 @@ snapshots: is-weakmap: 2.0.2 is-weakset: 2.0.3 + which-module@1.0.0: {} + which-typed-array@1.1.15: dependencies: available-typed-arrays: 1.0.7 @@ -40121,6 +42380,10 @@ snapshots: gopd: 1.2.0 has-tostringtag: 1.0.2 + which@1.3.1: + dependencies: + isexe: 2.0.0 + which@2.0.2: dependencies: isexe: 2.0.0 @@ -40129,6 +42392,14 @@ snapshots: dependencies: isexe: 3.1.1 + which@5.0.0: + dependencies: + isexe: 3.1.1 + + which@6.0.1: + dependencies: + isexe: 4.0.0 + why-is-node-running@2.3.0: dependencies: siginfo: 2.0.0 @@ -40257,6 +42528,11 @@ snapshots: '@types/trusted-types': 2.0.7 workbox-core: 7.3.0 + wrap-ansi@2.1.0: + dependencies: + string-width: 1.0.2 + strip-ansi: 3.0.1 + wrap-ansi@6.2.0: dependencies: ansi-styles: 4.3.0 @@ -40314,8 +42590,22 @@ snapshots: simple-plist: 1.3.1 uuid: 7.0.3 + xhr@2.6.0: + dependencies: + global: 4.4.0 + is-function: 1.0.2 + parse-headers: 2.0.6 + xtend: 4.0.2 + xml-name-validator@5.0.0: {} + xml-parse-from-string@1.0.1: {} + + xml2js@0.5.0: + dependencies: + sax: 1.4.1 + xmlbuilder: 11.0.1 + xml2js@0.6.0: dependencies: sax: 1.4.1 @@ -40358,6 +42648,8 @@ snapshots: lib0: 0.2.99 yjs: 13.6.26 + y18n@3.2.2: {} + y18n@5.0.8: {} yallist@3.1.1: {} @@ -40378,6 +42670,10 @@ snapshots: yargs-parser@21.1.1: {} + yargs-parser@4.2.1: + dependencies: + camelcase: 3.0.0 + yargs@17.0.1: dependencies: cliui: 7.0.4 @@ -40398,6 +42694,22 @@ snapshots: y18n: 5.0.8 yargs-parser: 21.1.1 + yargs@6.6.0: + dependencies: + camelcase: 3.0.0 + cliui: 3.2.0 + decamelize: 1.2.0 + get-caller-file: 1.0.3 + os-locale: 1.4.0 + read-pkg-up: 1.0.1 + require-directory: 2.1.1 + require-main-filename: 1.0.1 + set-blocking: 2.0.0 + string-width: 1.0.2 + which-module: 1.0.0 + y18n: 3.2.2 + yargs-parser: 4.2.1 + yauzl@2.10.0: dependencies: buffer-crc32: 0.2.13 diff --git a/scripts/ci/desktop-affected.mjs b/scripts/ci/desktop-affected.mjs new file mode 100644 index 0000000000..151084ccc4 --- /dev/null +++ b/scripts/ci/desktop-affected.mjs @@ -0,0 +1,156 @@ +#!/usr/bin/env node + +import { execFileSync } from 'node:child_process' +import { appendFileSync } from 'node:fs' +import { relative, sep } from 'node:path' + +const repoRoot = execFileSync(`git`, [`rev-parse`, `--show-toplevel`], { + encoding: `utf8`, +}).trim() +const baseRef = process.env.BASE_SHA || process.env.GITHUB_BASE_REF || `HEAD~1` +const desktopPackage = `@electric-ax/agents-desktop` + +const globalChangePatterns = [ + `.github/workflows/agents_desktop_*.yml`, + `.npmrc`, + `.tool-versions`, + `package.json`, + `patches/**`, + `pnpm-lock.yaml`, + `pnpm-workspace.yaml`, + `tsconfig.base.json`, + `tsconfig.build.json`, +] + +const changedFiles = getChangedFiles(baseRef) +const globalChange = shouldRunForGlobalChange(baseRef, changedFiles) +const desktopClosure = listWorkspaces([`${desktopPackage}...`]) +const changedClosure = globalChange ? [] : listWorkspaces([`...[${baseRef}]`]) +const desktopClosureNames = new Set( + desktopClosure.map((workspace) => workspace.name) +) +const affectedWorkspaces = globalChange + ? desktopClosure + : changedClosure.filter((workspace) => + desktopClosureNames.has(workspace.name) + ) +const shouldBuild = globalChange || affectedWorkspaces.length > 0 + +const outputs = { + should_build: String(shouldBuild), + affected_workspaces: JSON.stringify( + affectedWorkspaces.map((workspace) => workspace.relativePath).sort() + ), + reason: globalChange + ? `global desktop build input changed` + : shouldBuild + ? `desktop package or dependency changed` + : `no desktop package dependency changed`, +} + +writeOutputs(outputs) + +console.log( + JSON.stringify( + { + baseRef, + changedFiles, + desktopClosure: desktopClosure.map((workspace) => workspace.relativePath), + ...outputs, + }, + null, + 2 + ) +) + +function listWorkspaces(filters) { + const args = [`-r`, `list`, `--depth`, `-1`, `--json`] + for (const filter of filters) { + args.push(`--filter`, filter) + } + + try { + return parsePnpmList(run(`pnpm`, args)) + } catch (error) { + console.warn( + `Falling back to building desktop because pnpm filtering failed.` + ) + console.warn(error.message) + return [{ name: desktopPackage, relativePath: `packages/agents-desktop` }] + } +} + +function parsePnpmList(output) { + return JSON.parse(output).map((workspace) => ({ + ...workspace, + relativePath: toPosixPath(relative(repoRoot, workspace.path)), + })) +} + +function getChangedFiles(base) { + if (!base || /^0+$/.test(base)) { + return [] + } + + try { + run(`git`, [`rev-parse`, `--verify`, `${base}^{commit}`]) + return run(`git`, [`diff`, `--name-only`, base, `--`, `.`]) + .split(`\n`) + .map((file) => file.trim()) + .filter(Boolean) + } catch { + return [] + } +} + +function shouldRunForGlobalChange(base, files) { + if (!base || /^0+$/.test(base) || files.length === 0) { + return true + } + + return files.some((file) => + globalChangePatterns.some((pattern) => matchesPattern(file, pattern)) + ) +} + +function matchesPattern(file, pattern) { + if (pattern.endsWith(`/**`)) { + return file.startsWith(pattern.slice(0, -3)) + } + + if (pattern.includes(`*`)) { + const escaped = pattern + .split(`*`) + .map((part) => part.replace(/[.*+?^${}()|[\]\\]/g, `\\$&`)) + .join(`.*`) + return new RegExp(`^${escaped}$`).test(file) + } + + return file === pattern +} + +function writeOutputs(outputs) { + const outputFile = process.env.GITHUB_OUTPUT + if (!outputFile) { + return + } + + appendFileSync( + outputFile, + Object.entries(outputs) + .map(([key, value]) => `${key}=${value}`) + .join(`\n`) + `\n` + ) +} + +function run(command, args) { + return execFileSync(command, args, { + cwd: repoRoot, + encoding: `utf8`, + stdio: [`ignore`, `pipe`, `pipe`], + }) +} + +function toPosixPath(value) { + return value.split(sep).join(`/`) +}