From f795e48e390d2025cd5203be69dfd20ce0980c73 Mon Sep 17 00:00:00 2001 From: yaojin3616 Date: Sat, 26 Sep 2026 01:28:50 -0700 Subject: [PATCH] feat: DSH 0.1.7 baseline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 升级 Harness 基线到 0.1.7-rc.2,包含上次 main 合入基线之后新增的变更: - chore: upgrade baseline to Harness 0.1.7-rc.2 - refactor(ppt): build bundled runtime from source on 0.1.7 baseline - fix: legacy preset migration from empty Profile patch - ci: consolidate native builds and reuse prepared runtime - fix: unpack staged PPT plugins and verify physical runtime - ci: allow platform retries alongside independent builds - ci: fetch pinned Jsign through GitHub release API - ci: download signing artifacts in verified parallel ranges - chore: normalize Undici patch context whitespace - UI plugin / sidemenu update - test: derive dependency patch hunk counts dynamically --- .github/workflows/release.yml | 443 +- .gitignore | 3 + build/dsh-desktop-safe.patch.yml | 4 + build/dsh-desktop.patch.yml | 8 +- docs/architecture.md | 6 +- docs/baseline-runtime-compatibility.md | 66 + docs/macos-window-chrome.md | 22 + docs/mobile-pairing-pin-design.zh.md | 4 +- docs/patch-compatibility-review-0.1.7.md | 60 + docs/release-runbook.md | 20 +- docs/settings-launcher-compatibility.md | 9 + docs/source-build-contract.md | 2 +- package-lock.json | 8054 +++++++++-------- package.json | 509 +- packages/dsh-desktop-client-ui/client.js | 141 +- packages/dsh-desktop-client-ui/package.json | 14 +- .../generations/installer.d.ts | 3 +- .../generations/installer.mjs | 70 +- .../generations/package-backend.d.ts | 45 + .../generations/package-backend.mjs | 286 + .../dsh-desktop-market-installer/index.js | 131 +- .../dsh-desktop-market-installer/package.json | 8 +- .../dsh-desktop-preset-transfer/package.json | 2 +- packages/dsh-image-generation/client.js | 14 +- packages/dsh-image-generation/package.json | 20 +- packages/ppt-runtime/README.md | 12 +- packages/ppt-runtime/adapter/lib/client.js | 12 +- packages/ppt-runtime/adapter/package.json | 4 +- packages/ppt-runtime/core/lib/index.js | 27 +- packages/ppt-runtime/core/package.json | 28 +- patches/@deepseek-ai+dsh+0.1.7-rc.2.patch | 36 + ...epseek-ai+dsh-api-remotes+0.1.7-rc.2.patch | 57 + ...sh-api-session-controller+0.1.7-rc.2.patch | 1229 +++ ...@deepseek-ai+dsh-app-boot+0.1.7-rc.2.patch | 190 + ...ai+dsh-client-file-upload+0.1.7-rc.2.patch | 24 + ...eek-ai+dsh-client-modules+0.1.7-rc.2.patch | 66 + ...k-ai+dsh-client-shortcuts+0.1.7-rc.2.patch | 13 + ...sh-client-ui-agent-preset+0.1.7-rc.2.patch | 215 + ...+dsh-client-ui-attachment+0.1.7-rc.2.patch | 65 + ...eek-ai+dsh-client-ui-chat+0.1.7-rc.2.patch | 252 + ...sh-client-ui-conversation+0.1.7-rc.2.patch | 287 + ...sh-client-ui-deliverables+0.1.7-rc.2.patch | 51 + ...client-ui-model-selection+0.1.7-rc.2.patch | 218 + ...lient-ui-settings-general+0.1.7-rc.2.patch | 25 + ...client-ui-settings-models+0.1.7-rc.2.patch | 909 ++ ...-ai+dsh-client-ui-sidebar+0.1.7-rc.2.patch | 38 + ...+dsh-client-ui-trajectory+0.1.7-rc.2.patch | 31 + ...i+dsh-client-ui-workspace+0.1.7-rc.2.patch | 453 + ...pseek-ai+dsh-llm-deepseek+0.1.7-rc.2.patch | 16 + ...deepseek-ai+dsh-llm-pi-ai+0.1.7-rc.2.patch | 157 + ...eek-ai+dsh-plugin-manager+0.1.7-rc.2.patch | 231 + ...i+dsh-session-persistence+0.1.7-rc.2.patch | 57 + ...session-persistence-jsonl+0.1.7-rc.2.patch | 79 + ...deepseek-ai+dsh-workspace+0.1.7-rc.2.patch | 80 + patches/undici+8.11.2.patch | 33 + scripts/build-ppt-runtime.mjs | 192 +- scripts/download-artifact-ranges.mjs | 109 + scripts/enrich-ppt-templates.mjs | 2 +- scripts/generate-ppt-templates.mjs | 2 +- scripts/generate-zara-ppt-templates.mjs | 7 +- scripts/localize-ppt-templates.mjs | 18 +- scripts/ppt-package-projection.d.mts | 14 + scripts/ppt-package-projection.mjs | 59 + scripts/prepare-ppt-runtime.mjs | 37 + scripts/verify-packaged-ppt-runtime.cjs | 90 + src/main/index.ts | 119 +- src/main/macos-window-backdrop.ts | 16 + src/main/runtime/harness-runtime.ts | 9 +- src/main/state/generation-migration.ts | 2 +- src/main/state/host-plugin-sources.ts | 18 +- src/main/state/legacy-preset-migration.ts | 121 + src/main/state/market-baseline.ts | 10 +- src/preload/index.ts | 14 +- src/preload/macos-window-chrome.ts | 27 + src/preload/windows-titlebar.ts | 49 +- test/desktop-client-ui.test.ts | 21 +- test/download-artifact-ranges.test.mjs | 51 + test/generation-installer.test.ts | 63 + test/generation-runtime-resolution.test.mjs | 51 + test/host-disabled-plugins.test.ts | 5 + test/host-plugin-sources.test.ts | 57 +- test/image-generation-settings-ui.test.mjs | 61 + test/legacy-preset-migration.test.ts | 150 + test/macos-window-backdrop.test.ts | 24 + test/macos-window-chrome.test.ts | 46 + test/market-baseline.test.ts | 38 +- test/market-installer.test.js | 4 +- test/model-selection-icons.test.mjs | 14 + test/model-selection-search-patch.test.ts | 2 +- test/model-settings-render.test.mjs | 71 + test/open-in-finder.test.ts | 73 +- test/patch-hunk-counts.test.ts | 20 +- test/patch-runtime-compatibility.test.mjs | 50 + test/pi-ai-terminal-replay.test.mjs | 28 + test/plugin-startup-failure.test.ts | 27 +- test/plugin-upgrade.test.ts | 6 +- test/plugin-version-policy.test.mjs | 45 + test/ppt-activation.test.mjs | 59 +- test/ppt-fonts.test.mjs | 2 +- test/ppt-integration.test.ts | 148 +- test/ppt-package-projection.test.ts | 52 + test/ppt-personal-templates.test.mjs | 5 +- test/ppt-source-build-contract.test.ts | 57 + test/ppt-unbound-mode.test.mjs | 58 + test/ppt-validation.test.mjs | 10 +- test/preset-toolbar.test.mjs | 41 + test/preset-transfer-patch.test.ts | 95 +- test/profile-boot-preflight.test.ts | 15 + test/release.test.ts | 101 +- test/session-delete-patch.test.ts | 41 +- test/settings-account-launcher.test.js | 23 + test/undici-legacy-headers.test.mjs | 68 + test/windows-titlebar-header.test.mjs | 32 + 113 files changed, 12490 insertions(+), 4978 deletions(-) create mode 100644 docs/baseline-runtime-compatibility.md create mode 100644 docs/macos-window-chrome.md create mode 100644 docs/patch-compatibility-review-0.1.7.md create mode 100644 docs/settings-launcher-compatibility.md create mode 100644 packages/dsh-desktop-market-installer/generations/package-backend.d.ts create mode 100644 packages/dsh-desktop-market-installer/generations/package-backend.mjs create mode 100644 patches/@deepseek-ai+dsh+0.1.7-rc.2.patch create mode 100644 patches/@deepseek-ai+dsh-api-remotes+0.1.7-rc.2.patch create mode 100644 patches/@deepseek-ai+dsh-api-session-controller+0.1.7-rc.2.patch create mode 100644 patches/@deepseek-ai+dsh-app-boot+0.1.7-rc.2.patch create mode 100644 patches/@deepseek-ai+dsh-client-file-upload+0.1.7-rc.2.patch create mode 100644 patches/@deepseek-ai+dsh-client-modules+0.1.7-rc.2.patch create mode 100644 patches/@deepseek-ai+dsh-client-shortcuts+0.1.7-rc.2.patch create mode 100644 patches/@deepseek-ai+dsh-client-ui-agent-preset+0.1.7-rc.2.patch create mode 100644 patches/@deepseek-ai+dsh-client-ui-attachment+0.1.7-rc.2.patch create mode 100644 patches/@deepseek-ai+dsh-client-ui-chat+0.1.7-rc.2.patch create mode 100644 patches/@deepseek-ai+dsh-client-ui-conversation+0.1.7-rc.2.patch create mode 100644 patches/@deepseek-ai+dsh-client-ui-deliverables+0.1.7-rc.2.patch create mode 100644 patches/@deepseek-ai+dsh-client-ui-model-selection+0.1.7-rc.2.patch create mode 100644 patches/@deepseek-ai+dsh-client-ui-settings-general+0.1.7-rc.2.patch create mode 100644 patches/@deepseek-ai+dsh-client-ui-settings-models+0.1.7-rc.2.patch create mode 100644 patches/@deepseek-ai+dsh-client-ui-sidebar+0.1.7-rc.2.patch create mode 100644 patches/@deepseek-ai+dsh-client-ui-trajectory+0.1.7-rc.2.patch create mode 100644 patches/@deepseek-ai+dsh-client-ui-workspace+0.1.7-rc.2.patch create mode 100644 patches/@deepseek-ai+dsh-llm-deepseek+0.1.7-rc.2.patch create mode 100644 patches/@deepseek-ai+dsh-llm-pi-ai+0.1.7-rc.2.patch create mode 100644 patches/@deepseek-ai+dsh-plugin-manager+0.1.7-rc.2.patch create mode 100644 patches/@deepseek-ai+dsh-session-persistence+0.1.7-rc.2.patch create mode 100644 patches/@deepseek-ai+dsh-session-persistence-jsonl+0.1.7-rc.2.patch create mode 100644 patches/@deepseek-ai+dsh-workspace+0.1.7-rc.2.patch create mode 100644 patches/undici+8.11.2.patch create mode 100644 scripts/download-artifact-ranges.mjs create mode 100644 scripts/ppt-package-projection.d.mts create mode 100644 scripts/ppt-package-projection.mjs create mode 100644 scripts/prepare-ppt-runtime.mjs create mode 100644 scripts/verify-packaged-ppt-runtime.cjs create mode 100644 src/main/macos-window-backdrop.ts create mode 100644 src/main/state/legacy-preset-migration.ts create mode 100644 src/preload/macos-window-chrome.ts create mode 100644 test/download-artifact-ranges.test.mjs create mode 100644 test/generation-runtime-resolution.test.mjs create mode 100644 test/image-generation-settings-ui.test.mjs create mode 100644 test/legacy-preset-migration.test.ts create mode 100644 test/macos-window-backdrop.test.ts create mode 100644 test/macos-window-chrome.test.ts create mode 100644 test/model-selection-icons.test.mjs create mode 100644 test/model-settings-render.test.mjs create mode 100644 test/patch-runtime-compatibility.test.mjs create mode 100644 test/pi-ai-terminal-replay.test.mjs create mode 100644 test/plugin-version-policy.test.mjs create mode 100644 test/ppt-package-projection.test.ts create mode 100644 test/ppt-source-build-contract.test.ts create mode 100644 test/preset-toolbar.test.mjs create mode 100644 test/settings-account-launcher.test.js create mode 100644 test/undici-legacy-headers.test.mjs create mode 100644 test/windows-titlebar-header.test.mjs diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 800d668f5..e12ce4e15 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,14 +20,16 @@ on: - windows - macos mode: - description: development=unsigned Dev; signed=sign only; prerelease=sign and publish + description: development=unsigned Dev; signed=sign only; resign=sign existing unsigned artifact; prerelease=publish; smoke=check signed artifact required: false default: development type: choice options: - development - signed + - resign - prerelease + - smoke prerelease_tag: description: Non-v semver tag for prerelease mode (e.g. 2.1.0-rc.1) required: false @@ -36,12 +38,21 @@ on: description: Non-v semver used only by signed mode (e.g. 0.9.2-test.1) required: false type: string + smoke_run_id: + description: Release run ID containing an existing signed windows-x64 artifact (smoke mode) + required: false + type: string + unsigned_run_id: + description: Release run ID containing an existing windows-x64-unsigned artifact (resign mode) + required: false + type: string permissions: contents: write concurrency: - group: desktop-release-${{ github.ref }} + # Platform-only retries have independent artifacts and never publish. + group: desktop-release-${{ github.ref }}-${{ inputs.target || 'all' }} cancel-in-progress: false jobs: @@ -56,6 +67,8 @@ jobs: TARGET: ${{ inputs.target }} PRERELEASE_TAG: ${{ inputs.prerelease_tag }} SIGNED_VERSION: ${{ inputs.signed_version }} + SMOKE_RUN_ID: ${{ inputs.smoke_run_id }} + UNSIGNED_RUN_ID: ${{ inputs.unsigned_run_id }} run: | set -euo pipefail semver_re='^[0-9]+\.[0-9]+\.[0-9]+([-+][0-9A-Za-z.-]+)?$' @@ -73,7 +86,7 @@ jobs: echo "::notice::target=$TARGET with prerelease mode will sign only and skip GitHub/ModelScope publish" fi ;; - signed) + signed|resign) if [ -z "${SIGNED_VERSION:-}" ]; then echo "::error::signed mode requires signed_version" exit 1 @@ -82,6 +95,16 @@ jobs: echo "::error::signed_version must be a non-v semver (e.g. 0.9.2-test.1)" exit 1 fi + if [ "$MODE" = 'resign' ] && { [ "$TARGET" != 'windows' ] || ! [[ "$UNSIGNED_RUN_ID" =~ ^[0-9]+$ ]]; }; then + echo "::error::resign mode requires target=windows and a numeric unsigned_run_id" + exit 1 + fi + ;; + smoke) + if [ "$TARGET" != 'windows' ] || ! [[ "$SMOKE_RUN_ID" =~ ^[0-9]+$ ]]; then + echo "::error::smoke mode requires target=windows and a numeric smoke_run_id" + exit 1 + fi ;; development|'') ;; @@ -94,153 +117,27 @@ jobs: if: github.event_name != 'workflow_dispatch' run: echo "No dispatch inputs to validate." - macos-apple-silicon: - name: macOS Apple Silicon - needs: validate-dispatch - if: >- - startsWith(github.ref, 'refs/tags/v') || - (github.event_name == 'workflow_dispatch' && (inputs.target == 'all' || inputs.target == 'macos')) - runs-on: macos-15 - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - uses: actions/setup-node@v4 - with: - node-version: 22 - cache: npm - - name: Set app version from release tag - if: startsWith(github.ref, 'refs/tags/v') - run: npm version --no-git-tag-version --allow-same-version "${{ github.ref_name }}" - - name: Set app version from pre-release tag - if: github.event_name == 'workflow_dispatch' && inputs.mode == 'prerelease' && inputs.prerelease_tag != '' - run: npm version --no-git-tag-version --allow-same-version "${{ inputs.prerelease_tag }}" - - name: Set app version from signed version - if: github.event_name == 'workflow_dispatch' && inputs.mode == 'signed' && inputs.signed_version != '' - run: npm version --no-git-tag-version --allow-same-version "${{ inputs.signed_version }}" - - run: npm ci - - run: npm test - - run: npm run typecheck - - name: Validate Apple release secrets - if: startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'workflow_dispatch' && (inputs.mode == 'signed' || inputs.mode == 'prerelease')) - env: - CSC_LINK: ${{ secrets.DESKTOP_CSC_LINK }} - CSC_KEY_PASSWORD: ${{ secrets.DESKTOP_CSC_KEY_PASSWORD }} - APPLE_API_KEY_CONTENT: ${{ secrets.DESKTOP_APPLE_API_KEY }} - APPLE_API_KEY_ID: ${{ secrets.DESKTOP_APPLE_API_KEY_ID }} - APPLE_API_ISSUER: ${{ secrets.DESKTOP_APPLE_API_ISSUER }} - APPLE_TEAM_ID: ${{ secrets.DESKTOP_APPLE_TEAM_ID }} - run: | - required=(CSC_LINK CSC_KEY_PASSWORD APPLE_API_KEY_CONTENT APPLE_API_KEY_ID APPLE_API_ISSUER APPLE_TEAM_ID) - for name in "${required[@]}"; do - test -n "${!name}" || { echo "::error::Missing required secret: $name"; exit 1; } - done - - name: Prepare Apple notarization key - if: startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'workflow_dispatch' && (inputs.mode == 'signed' || inputs.mode == 'prerelease')) - env: - APPLE_API_KEY_CONTENT: ${{ secrets.DESKTOP_APPLE_API_KEY }} - APPLE_API_KEY_ID: ${{ secrets.DESKTOP_APPLE_API_KEY_ID }} - APPLE_API_ISSUER: ${{ secrets.DESKTOP_APPLE_API_ISSUER }} - APPLE_TEAM_ID: ${{ secrets.DESKTOP_APPLE_TEAM_ID }} - run: | - key_path="$RUNNER_TEMP/AuthKey_${APPLE_API_KEY_ID}.p8" - printf '%s' "$APPLE_API_KEY_CONTENT" > "$key_path" - chmod 600 "$key_path" - echo "APPLE_API_KEY=$key_path" >> "$GITHUB_ENV" - echo "APPLE_API_KEY_ID=$APPLE_API_KEY_ID" >> "$GITHUB_ENV" - echo "APPLE_API_ISSUER=$APPLE_API_ISSUER" >> "$GITHUB_ENV" - echo "APPLE_TEAM_ID=$APPLE_TEAM_ID" >> "$GITHUB_ENV" - - name: Prepare macOS signing keychain - if: startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'workflow_dispatch' && (inputs.mode == 'signed' || inputs.mode == 'prerelease')) - id: signing_keychain - env: - CSC_LINK: ${{ secrets.DESKTOP_CSC_LINK }} - CSC_KEY_PASSWORD: ${{ secrets.DESKTOP_CSC_KEY_PASSWORD }} - run: node scripts/prepare-macos-signing-keychain.mjs - - name: Build signed Apple Silicon package - if: startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'workflow_dispatch' && (inputs.mode == 'signed' || inputs.mode == 'prerelease')) - env: - CSC_KEYCHAIN: ${{ steps.signing_keychain.outputs.keychain }} - run: npm run package:mac:arm64 - - name: Build isolated Apple Silicon development package - if: ${{ !startsWith(github.ref, 'refs/tags/v') && (github.event_name != 'workflow_dispatch' || inputs.mode == 'development') }} - env: - CSC_IDENTITY_AUTO_DISCOVERY: 'false' - run: npm run package:dev:mac:arm64 - - name: Preserve Apple Silicon update metadata - if: startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'workflow_dispatch' && (inputs.mode == 'signed' || inputs.mode == 'prerelease')) - run: mv dist/latest-mac.yml dist/latest-mac-arm64.yml - - name: Sign, notarize, and staple Apple Silicon DMG - if: startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'workflow_dispatch' && (inputs.mode == 'signed' || inputs.mode == 'prerelease')) - env: - CSC_KEYCHAIN: ${{ steps.signing_keychain.outputs.keychain }} - run: | - dmg_path="dist/dsh-desktop-mac-arm64.dmg" - identity="$(security find-identity -v -p codesigning "$CSC_KEYCHAIN" | awk '/Developer ID Application/ { print $2; exit }')" - test -n "$identity" || { echo "::error::Developer ID Application identity not found"; exit 1; } - codesign --keychain "$CSC_KEYCHAIN" --sign "$identity" --timestamp --force "$dmg_path" - xcrun notarytool submit "$dmg_path" \ - --key "$APPLE_API_KEY" \ - --key-id "$APPLE_API_KEY_ID" \ - --issuer "$APPLE_API_ISSUER" \ - --wait \ - --no-s3-acceleration - xcrun stapler staple "$dmg_path" - - name: Remove temporary signing keychain - if: always() && (startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'workflow_dispatch' && (inputs.mode == 'signed' || inputs.mode == 'prerelease'))) - env: - SIGNING_KEYCHAIN: ${{ steps.signing_keychain.outputs.keychain }} - SIGNING_CERTIFICATE: ${{ steps.signing_keychain.outputs.certificate }} - SIGNING_KEYCHAIN_LIST: ${{ steps.signing_keychain.outputs.keychain_list }} - run: | - if [ -n "$SIGNING_KEYCHAIN_LIST" ] && [ -f "$SIGNING_KEYCHAIN_LIST" ]; then - keychains=() - while IFS= read -r keychain; do - test -z "$keychain" || keychains+=("$keychain") - done < "$SIGNING_KEYCHAIN_LIST" - security list-keychains -d user -s "${keychains[@]}" - rm -f "$SIGNING_KEYCHAIN_LIST" - fi - test -z "$SIGNING_KEYCHAIN" || security delete-keychain "$SIGNING_KEYCHAIN" || rm -f "$SIGNING_KEYCHAIN" - test -z "$SIGNING_CERTIFICATE" || rm -f "$SIGNING_CERTIFICATE" - test -z "$APPLE_API_KEY" || rm -f "$APPLE_API_KEY" - - name: Verify signed and notarized Apple Silicon app - if: startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'workflow_dispatch' && (inputs.mode == 'signed' || inputs.mode == 'prerelease')) - run: | - app_path="dist/mac-arm64/DSH Desktop.app" - codesign --verify --deep --strict --verbose=2 "$app_path" - spctl --assess --type execute --verbose=4 "$app_path" - xcrun stapler validate "$app_path" - codesign --verify --verbose=2 dist/dsh-desktop-mac-arm64.dmg - spctl --assess --type open --context context:primary-signature --verbose=4 dist/dsh-desktop-mac-arm64.dmg - xcrun stapler validate dist/dsh-desktop-mac-arm64.dmg - - uses: actions/upload-artifact@v4 - if: startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'workflow_dispatch' && (inputs.mode == 'signed' || inputs.mode == 'prerelease')) - with: - name: macos-apple-silicon - path: | - dist/dsh-desktop-mac-arm64.dmg - dist/dsh-desktop-mac-arm64.zip - dist/dsh-desktop-mac-arm64.zip.blockmap - dist/latest-mac-arm64.yml - if-no-files-found: error - - uses: actions/upload-artifact@v4 - if: ${{ !startsWith(github.ref, 'refs/tags/v') && (github.event_name != 'workflow_dispatch' || inputs.mode == 'development') }} - with: - name: macos-apple-silicon-dev - path: | - dist-dev/dsh-desktop-dev-mac-arm64.dmg - dist-dev/dsh-desktop-dev-mac-arm64.zip - dist-dev/dsh-desktop-dev-mac-arm64.zip.blockmap - if-no-files-found: error - - macos-intel: - name: macOS Intel + macos: + name: macOS ${{ matrix.label }} needs: validate-dispatch if: >- startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'workflow_dispatch' && (inputs.target == 'all' || inputs.target == 'macos')) - runs-on: macos-15-intel + strategy: + fail-fast: false + matrix: + include: + - arch: arm64 + label: Apple Silicon + runner: macos-15 + app-directory: mac-arm64 + artifact: macos-apple-silicon + - arch: x64 + label: Intel + runner: macos-15-intel + app-directory: mac + artifact: macos-intel + runs-on: ${{ matrix.runner }} steps: - uses: actions/checkout@v4 with: @@ -259,7 +156,10 @@ jobs: if: github.event_name == 'workflow_dispatch' && inputs.mode == 'signed' && inputs.signed_version != '' run: npm version --no-git-tag-version --allow-same-version "${{ inputs.signed_version }}" - run: npm ci - - run: npm test + - run: npm run build + - run: npx --no-install vitest run + - name: Verify PPT generation leaves tracked sources clean + run: git diff --exit-code -- packages/ppt-runtime scripts/ppt - run: npm run typecheck - name: Validate Apple release secrets if: startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'workflow_dispatch' && (inputs.mode == 'signed' || inputs.mode == 'prerelease')) @@ -297,25 +197,25 @@ jobs: CSC_LINK: ${{ secrets.DESKTOP_CSC_LINK }} CSC_KEY_PASSWORD: ${{ secrets.DESKTOP_CSC_KEY_PASSWORD }} run: node scripts/prepare-macos-signing-keychain.mjs - - name: Build signed Intel package + - name: Build signed ${{ matrix.label }} package if: startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'workflow_dispatch' && (inputs.mode == 'signed' || inputs.mode == 'prerelease')) env: CSC_KEYCHAIN: ${{ steps.signing_keychain.outputs.keychain }} - run: npm run package:mac:x64 - - name: Build isolated Intel development package + run: node scripts/verify-target.mjs darwin ${{ matrix.arch }} && npx --no-install electron-builder --mac --${{ matrix.arch }} --publish never + - name: Build isolated ${{ matrix.label }} development package if: ${{ !startsWith(github.ref, 'refs/tags/v') && (github.event_name != 'workflow_dispatch' || inputs.mode == 'development') }} env: CSC_IDENTITY_AUTO_DISCOVERY: 'false' - run: npm run package:dev:mac:x64 - - name: Preserve Intel update metadata + run: node scripts/verify-target.mjs darwin ${{ matrix.arch }} && npx --no-install electron-builder --mac --${{ matrix.arch }} --publish never --config electron-builder.dev.cjs + - name: Preserve ${{ matrix.label }} update metadata if: startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'workflow_dispatch' && (inputs.mode == 'signed' || inputs.mode == 'prerelease')) - run: mv dist/latest-mac.yml dist/latest-mac-x64.yml - - name: Sign, notarize, and staple Intel DMG + run: mv dist/latest-mac.yml dist/latest-mac-${{ matrix.arch }}.yml + - name: Sign, notarize, and staple ${{ matrix.label }} DMG if: startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'workflow_dispatch' && (inputs.mode == 'signed' || inputs.mode == 'prerelease')) env: CSC_KEYCHAIN: ${{ steps.signing_keychain.outputs.keychain }} run: | - dmg_path="dist/dsh-desktop-mac-x64.dmg" + dmg_path="dist/dsh-desktop-mac-${{ matrix.arch }}.dmg" identity="$(security find-identity -v -p codesigning "$CSC_KEYCHAIN" | awk '/Developer ID Application/ { print $2; exit }')" test -n "$identity" || { echo "::error::Developer ID Application identity not found"; exit 1; } codesign --keychain "$CSC_KEYCHAIN" --sign "$identity" --timestamp --force "$dmg_path" @@ -344,34 +244,36 @@ jobs: test -z "$SIGNING_KEYCHAIN" || security delete-keychain "$SIGNING_KEYCHAIN" || rm -f "$SIGNING_KEYCHAIN" test -z "$SIGNING_CERTIFICATE" || rm -f "$SIGNING_CERTIFICATE" test -z "$APPLE_API_KEY" || rm -f "$APPLE_API_KEY" - - name: Verify signed and notarized Intel app + - name: Verify signed and notarized ${{ matrix.label }} app if: startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'workflow_dispatch' && (inputs.mode == 'signed' || inputs.mode == 'prerelease')) run: | - app_path="dist/mac/DSH Desktop.app" + app_path="dist/${{ matrix.app-directory }}/DSH Desktop.app" codesign --verify --deep --strict --verbose=2 "$app_path" spctl --assess --type execute --verbose=4 "$app_path" xcrun stapler validate "$app_path" - codesign --verify --verbose=2 dist/dsh-desktop-mac-x64.dmg - spctl --assess --type open --context context:primary-signature --verbose=4 dist/dsh-desktop-mac-x64.dmg - xcrun stapler validate dist/dsh-desktop-mac-x64.dmg + codesign --verify --verbose=2 dist/dsh-desktop-mac-${{ matrix.arch }}.dmg + spctl --assess --type open --context context:primary-signature --verbose=4 dist/dsh-desktop-mac-${{ matrix.arch }}.dmg + xcrun stapler validate dist/dsh-desktop-mac-${{ matrix.arch }}.dmg - uses: actions/upload-artifact@v4 if: startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'workflow_dispatch' && (inputs.mode == 'signed' || inputs.mode == 'prerelease')) with: - name: macos-intel + name: ${{ matrix.artifact }} path: | - dist/dsh-desktop-mac-x64.dmg - dist/dsh-desktop-mac-x64.zip - dist/dsh-desktop-mac-x64.zip.blockmap - dist/latest-mac-x64.yml + dist/dsh-desktop-mac-${{ matrix.arch }}.dmg + dist/dsh-desktop-mac-${{ matrix.arch }}.zip + dist/dsh-desktop-mac-${{ matrix.arch }}.zip.blockmap + dist/latest-mac-${{ matrix.arch }}.yml + compression-level: 0 if-no-files-found: error - uses: actions/upload-artifact@v4 if: ${{ !startsWith(github.ref, 'refs/tags/v') && (github.event_name != 'workflow_dispatch' || inputs.mode == 'development') }} with: - name: macos-intel-dev + name: ${{ matrix.artifact }}-dev path: | - dist-dev/dsh-desktop-dev-mac-x64.dmg - dist-dev/dsh-desktop-dev-mac-x64.zip - dist-dev/dsh-desktop-dev-mac-x64.zip.blockmap + dist-dev/dsh-desktop-dev-mac-${{ matrix.arch }}.dmg + dist-dev/dsh-desktop-dev-mac-${{ matrix.arch }}.zip + dist-dev/dsh-desktop-dev-mac-${{ matrix.arch }}.zip.blockmap + compression-level: 0 if-no-files-found: error windows-x64: @@ -381,6 +283,7 @@ jobs: startsWith(github.ref, 'refs/tags/v') || github.event_name == 'pull_request' || (github.event_name == 'workflow_dispatch' && + inputs.mode != 'smoke' && inputs.mode != 'resign' && (inputs.target == 'all' || inputs.target == 'windows')) runs-on: windows-2022 steps: @@ -401,9 +304,13 @@ jobs: if: github.event_name == 'workflow_dispatch' && inputs.mode == 'signed' && inputs.signed_version != '' run: npm version --no-git-tag-version --allow-same-version "${{ inputs.signed_version }}" - run: npm ci - - run: npm test - - run: npm run typecheck - run: npm run build + - name: Run Windows tests with progress + run: npx --no-install vitest run --reporter=verbose + timeout-minutes: 15 + - name: Verify PPT generation leaves tracked sources clean + run: git diff --exit-code -- packages/ppt-runtime scripts/ppt + - run: npm run typecheck - name: Check recovery UI on native Windows at three display scales run: node scripts/check-recovery-ui.mjs - uses: actions/upload-artifact@v4 @@ -416,10 +323,10 @@ jobs: if-no-files-found: warn - name: Build Windows release package if: startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'workflow_dispatch' && (inputs.mode == 'signed' || inputs.mode == 'prerelease')) - run: npm run package:win + run: node scripts/verify-target.mjs win32 x64 && node scripts/electron-builder-windows.mjs --win --x64 --publish never - name: Build isolated Windows development package if: ${{ !startsWith(github.ref, 'refs/tags/v') && (github.event_name != 'workflow_dispatch' || inputs.mode == 'development') }} - run: npm run package:dev:win + run: node scripts/verify-target.mjs win32 x64 && node scripts/electron-builder-windows.mjs --win --x64 --publish never --config electron-builder.dev.cjs - name: Smoke test packaged Windows Harness if: github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' shell: pwsh @@ -436,14 +343,17 @@ jobs: New-Item -ItemType Directory -Path $isolatedApp | Out-Null Copy-Item -Path (Join-Path $sourceExecutable.Directory.FullName '*') -Destination $isolatedApp -Recurse $executable = Join-Path $isolatedApp $sourceExecutable.Name - $packagedNode = Join-Path $isolatedApp 'resources\app\node_modules\node\bin\node.exe' + $desktopStdout = Join-Path $env:RUNNER_TEMP 'dsh-packaged-desktop.stdout.log' + $desktopStderr = Join-Path $env:RUNNER_TEMP 'dsh-packaged-desktop.stderr.log' + $packagedNode = Join-Path $isolatedApp 'resources\app.asar.unpacked\node_modules\node\bin\node.exe' if (-not (Test-Path $packagedNode)) { throw 'Packaged Windows node.exe is missing.' } # Exercise the actual native binding too; the best-effort fallback # must not hide a missing or broken packaged koffi dependency. - & $packagedNode --input-type=module -e "import { createRequire } from 'node:module'; import { pathToFileURL } from 'node:url'; const require = createRequire(pathToFileURL(process.argv[1])); const resolved = require.resolve('koffi'); if (!resolved.startsWith(process.argv[2])) throw new Error('koffi resolved outside packaged app: ' + resolved); const koffi = require('koffi'); const getCurrentProcessId = koffi.load('kernel32.dll').func('GetCurrentProcessId', 'uint32', []); if (getCurrentProcessId() !== process.pid) throw new Error('Native koffi smoke failed'); console.log('Packaged koffi native binding passed');" (Join-Path $isolatedApp 'resources\app\package.json') (Join-Path $isolatedApp 'resources\app\node_modules') + & $packagedNode --input-type=module -e "import { createRequire } from 'node:module'; import { pathToFileURL } from 'node:url'; const require = createRequire(pathToFileURL(process.argv[1])); const resolved = require.resolve('koffi'); if (!resolved.startsWith(process.argv[2])) throw new Error('koffi resolved outside packaged app: ' + resolved); const koffi = require('koffi'); const getCurrentProcessId = koffi.load('kernel32.dll').func('GetCurrentProcessId', 'uint32', []); if (getCurrentProcessId() !== process.pid) throw new Error('Native koffi smoke failed'); console.log('Packaged koffi native binding passed');" (Join-Path $isolatedApp 'resources\app.asar.unpacked\node_modules\koffi\package.json') (Join-Path $isolatedApp 'resources\app.asar.unpacked\node_modules') if ($LASTEXITCODE -ne 0) { throw 'Packaged koffi native binding failed.' } if (Test-Path $userData) { Remove-Item -Recurse -Force $userData } - $desktop = Start-Process -FilePath $executable -WorkingDirectory $isolatedApp -PassThru + $desktop = Start-Process -FilePath $executable -WorkingDirectory $isolatedApp -PassThru ` + -RedirectStandardOutput $desktopStdout -RedirectStandardError $desktopStderr try { $deadline = (Get-Date).AddSeconds(75) $ready = $false @@ -509,8 +419,11 @@ jobs: Start-Sleep -Seconds 20 $stableLog = Get-Content -Raw $logPath - if ($stableLog -match '\[stderr\]') { - throw 'Harness reported stderr after workspace and session creation.' + $readyMarker = $stableLog.LastIndexOf('[desktop] Harness is ready') + if ($readyMarker -lt 0) { throw 'Harness readiness marker is missing.' } + $postReadyLog = $stableLog.Substring($readyMarker) + if ($postReadyLog -match '\[stderr\]') { + throw 'Harness reported stderr after becoming ready.' } if ($stableLog -match '\[node\] Harness process exited') { throw 'Harness process exited after workspace and session creation.' @@ -520,6 +433,14 @@ jobs: } Write-Host 'Packaged Windows Harness smoke test passed.' } finally { + foreach ($path in @($desktopStdout, $desktopStderr)) { + if (Test-Path $path) { + Write-Host "--- $path ---" + Get-Content $path + } + } + Get-CimInstance Win32_Process -Filter "name='$($sourceExecutable.Name)'" | + Select-Object ProcessId, ParentProcessId, CommandLine | Format-List | Out-String | Write-Host if (Test-Path $logPath) { Write-Host '--- harness.log ---' Get-Content $logPath @@ -540,6 +461,7 @@ jobs: dist/win-unpacked.tar.gz dist/dsh-desktop-windows-x64-setup.exe.blockmap dist/latest.yml + compression-level: 0 if-no-files-found: error retention-days: 1 - uses: actions/upload-artifact@v4 @@ -550,15 +472,20 @@ jobs: dist-dev/dsh-desktop-dev-windows-x64-setup.exe dist-dev/dsh-desktop-dev-windows-x64-setup.exe.blockmap dist-dev/latest.yml + compression-level: 0 if-no-files-found: error sign-windows: name: Sign Windows package locally with UKey - needs: windows-x64 + needs: [validate-dispatch, windows-x64] + permissions: + actions: read + contents: read if: >- always() && - (startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'workflow_dispatch' && (inputs.mode == 'signed' || inputs.mode == 'prerelease'))) && - needs.windows-x64.result == 'success' + needs.validate-dispatch.result == 'success' && + ((startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'workflow_dispatch' && (inputs.mode == 'signed' || inputs.mode == 'prerelease'))) && needs.windows-x64.result == 'success' || + (github.event_name == 'workflow_dispatch' && inputs.mode == 'resign' && needs.windows-x64.result == 'skipped')) runs-on: [self-hosted, macOS, ARM64] env: CI: 'true' @@ -566,10 +493,10 @@ jobs: JSIGN_SHA256: '602a51c3545a6dc4fb99bd2ea7152b26d1345916d0c93ddfbd5936cb735af91c' steps: - uses: actions/checkout@v4 + # The signer only installs release tooling; skip remote npm cache restore. - uses: actions/setup-node@v4 with: node-version: 22 - cache: npm - uses: actions/setup-java@v4 with: distribution: temurin @@ -583,25 +510,47 @@ jobs: if: github.event_name == 'workflow_dispatch' && inputs.mode == 'prerelease' && inputs.prerelease_tag != '' run: npm version --no-git-tag-version --allow-same-version "${{ inputs.prerelease_tag }}" - name: Set app version from signed version - if: github.event_name == 'workflow_dispatch' && inputs.mode == 'signed' && inputs.signed_version != '' + if: github.event_name == 'workflow_dispatch' && (inputs.mode == 'signed' || inputs.mode == 'resign') && inputs.signed_version != '' run: npm version --no-git-tag-version --allow-same-version "${{ inputs.signed_version }}" - name: Prepare unsigned Windows package run: | work_dir="$RUNNER_TEMP/dsh-windows-${{ github.run_id }}" mkdir -p "$work_dir/release" echo "WINDOWS_SIGNING_WORK_DIR=$work_dir" >> "$GITHUB_ENV" - - uses: actions/download-artifact@v4 - with: - name: windows-x64-unsigned - path: ${{ runner.temp }}/dsh-windows-${{ github.run_id }}/release + - name: Bypass runner proxy for artifact transfer + run: | + # The runner exports lowercase proxy variables separately on macOS. + # A step env map cannot specify both cases in GitHub workflow YAML. + printf 'http_proxy=\nhttps_proxy=\nall_proxy=\nno_proxy=*\n' >> "$GITHUB_ENV" + - name: Download verified Windows signing inputs in parallel + env: + GH_TOKEN: ${{ github.token }} + SOURCE_RUN_ID: ${{ inputs.mode == 'resign' && inputs.unsigned_run_id || github.run_id }} + HTTP_PROXY: '' + HTTPS_PROXY: '' + ALL_PROXY: '' + run: | + node scripts/download-artifact-ranges.mjs "$GITHUB_REPOSITORY" "$SOURCE_RUN_ID" \ + windows-x64-unsigned "$WINDOWS_SIGNING_WORK_DIR/unsigned.zip" + unzip -q "$WINDOWS_SIGNING_WORK_DIR/unsigned.zip" -d "$WINDOWS_SIGNING_WORK_DIR/release" + rm "$WINDOWS_SIGNING_WORK_DIR/unsigned.zip" + - name: Check reused unsigned package version + if: github.event_name == 'workflow_dispatch' && inputs.mode == 'resign' + run: | + actual_version="$(node -e 'const fs = require("node:fs"); const yaml = require("js-yaml"); console.log(yaml.load(fs.readFileSync(process.argv[1], "utf8")).version)' "$WINDOWS_SIGNING_WORK_DIR/release/latest.yml")" + test "$actual_version" = "${{ inputs.signed_version }}" || { + echo "::error::Unsigned artifact version $actual_version does not match signed_version" + exit 1 + } - name: Download and verify Jsign + timeout-minutes: 5 + env: + GH_TOKEN: ${{ github.token }} run: | set -euo pipefail jsign_jar="$WINDOWS_SIGNING_WORK_DIR/jsign-${JSIGN_VERSION}.jar" - curl --fail-with-body --location --retry 3 --retry-all-errors \ - --connect-timeout 15 --max-time 180 \ - --output "$jsign_jar" \ - "https://github.com/ebourg/jsign/releases/download/${JSIGN_VERSION}/jsign-${JSIGN_VERSION}.jar" + gh release download "$JSIGN_VERSION" --repo ebourg/jsign \ + --pattern "jsign-${JSIGN_VERSION}.jar" --dir "$WINDOWS_SIGNING_WORK_DIR" --clobber test -s "$jsign_jar" printf '%s %s\n' "$JSIGN_SHA256" "$jsign_jar" | shasum -a 256 --check java -jar "$jsign_jar" --version @@ -610,6 +559,7 @@ jobs: env: WINDOWS_SIGNING_PIN: ${{ secrets.DESKTOP_WINDOWS_SIGNING_PIN }} run: | + set -euo pipefail test -r /usr/local/lib/libeTPkcs11.dylib test -n "$WINDOWS_SIGNING_PIN" || { echo "::error::Missing required secret: DESKTOP_WINDOWS_SIGNING_PIN"; exit 1; } pin_file="$(mktemp "$WINDOWS_SIGNING_WORK_DIR/jsign-pin.XXXXXX")" @@ -618,44 +568,17 @@ jobs: printf '%s' "$WINDOWS_SIGNING_PIN" > "$pin_file" unset WINDOWS_SIGNING_PIN - # If unpacked tree archive was uploaded, sign inner binaries and repackage NSIS installer - if [ -f "$WINDOWS_SIGNING_WORK_DIR/release/win-unpacked.tar.gz" ]; then - echo "Unpacking win-unpacked archive for inner binary signing..." - # Keep backup of original installer in case repackaging fails on self-hosted macOS runner - orig_installer="$(find "$WINDOWS_SIGNING_WORK_DIR/release" -maxdepth 1 -type f -name '*.exe' -print -quit)" - backup_installer="$RUNNER_TEMP/orig-windows-installer-$$.exe" - if [ -n "$orig_installer" ] && [ -f "$orig_installer" ]; then - cp "$orig_installer" "$backup_installer" - fi - - repackaged=false - if tar -xzf "$WINDOWS_SIGNING_WORK_DIR/release/win-unpacked.tar.gz" -C "$WINDOWS_SIGNING_WORK_DIR/release"; then - if JSIGN_JAR="$JSIGN_JAR" JSIGN_PIN_FILE="$pin_file" \ - node scripts/sign-windows-unpacked.mjs "$WINDOWS_SIGNING_WORK_DIR/release/win-unpacked"; then - echo "Removing previous unsigned installer before repackaging..." - rm -f "$WINDOWS_SIGNING_WORK_DIR/release"/*.exe "$WINDOWS_SIGNING_WORK_DIR/release"/*.blockmap - echo "Repackaging NSIS installer from signed unpacked directory..." - if npx electron-builder --win --x64 --publish never \ - --prepackaged "$WINDOWS_SIGNING_WORK_DIR/release/win-unpacked" \ - --config.directories.output="$WINDOWS_SIGNING_WORK_DIR/release"; then - repackaged=true - echo "✅ Repackaged NSIS installer successfully with signed internal binaries." - else - echo "⚠️ Repackaging with electron-builder failed. Falling back to original installer." - fi - fi - fi - - # Fallback if repackaging failed or produced no installer - current_installers="$(find "$WINDOWS_SIGNING_WORK_DIR/release" -maxdepth 1 -type f -name '*.exe' | wc -l | tr -d ' ')" - if [ "$current_installers" != '1' ] && [ -f "$backup_installer" ]; then - echo "Restoring original Windows installer from backup..." - rm -f "$WINDOWS_SIGNING_WORK_DIR/release"/*.exe - cp "$backup_installer" "$orig_installer" - fi - rm -f "$backup_installer" - rm -rf "$WINDOWS_SIGNING_WORK_DIR/release/win-unpacked" "$WINDOWS_SIGNING_WORK_DIR/release/win-unpacked.tar.gz" - fi + # A missing archive or any failed signing/repackaging step blocks publication. + test -s "$WINDOWS_SIGNING_WORK_DIR/release/win-unpacked.tar.gz" + tar -xzf "$WINDOWS_SIGNING_WORK_DIR/release/win-unpacked.tar.gz" -C "$WINDOWS_SIGNING_WORK_DIR/release" + JSIGN_JAR="$JSIGN_JAR" JSIGN_PIN_FILE="$pin_file" \ + node scripts/sign-windows-unpacked.mjs "$WINDOWS_SIGNING_WORK_DIR/release/win-unpacked" + rm -f "$WINDOWS_SIGNING_WORK_DIR/release"/*.exe "$WINDOWS_SIGNING_WORK_DIR/release"/*.blockmap + JSIGN_JAR="$JSIGN_JAR" JSIGN_PIN_FILE="$pin_file" \ + node scripts/electron-builder-windows.mjs --win --x64 --publish never \ + --prepackaged "$WINDOWS_SIGNING_WORK_DIR/release/win-unpacked" \ + --config.directories.output="$WINDOWS_SIGNING_WORK_DIR/release" + rm -rf "$WINDOWS_SIGNING_WORK_DIR/release/win-unpacked" "$WINDOWS_SIGNING_WORK_DIR/release/win-unpacked.tar.gz" installer_count="$(find "$WINDOWS_SIGNING_WORK_DIR/release" -maxdepth 1 -type f -name '*.exe' | wc -l | tr -d ' ')" test "$installer_count" = '1' @@ -702,6 +625,7 @@ jobs: ${{ runner.temp }}/dsh-windows-${{ github.run_id }}/release/dsh-desktop-windows-x64-setup.exe ${{ runner.temp }}/dsh-windows-${{ github.run_id }}/release/dsh-desktop-windows-x64-setup.exe.blockmap ${{ runner.temp }}/dsh-windows-${{ github.run_id }}/release/latest.yml + compression-level: 0 if-no-files-found: error - name: Remove local signing files if: always() @@ -712,19 +636,60 @@ jobs: *) echo "Refusing to remove unexpected signing path: $WINDOWS_SIGNING_WORK_DIR"; exit 1 ;; esac + smoke-signed-windows: + name: Smoke final signed Windows installer + needs: sign-windows + if: needs.sign-windows.result == 'success' + runs-on: windows-2022 + steps: + - uses: actions/checkout@v4 + - uses: actions/download-artifact@v4 + with: + name: windows-x64 + path: signed-windows + - name: Verify signed installation and upgrade + shell: pwsh + run: | + ./scripts/smoke-signed-windows-installer.ps1 ` + -Installer 'signed-windows/dsh-desktop-windows-x64-setup.exe' ` + -PublisherName 'Beijing Shuju Xiangsu Intelligence Technology Co., Ltd.' + + smoke-existing-signed-windows: + name: Recheck existing signed Windows installer + needs: validate-dispatch + if: github.event_name == 'workflow_dispatch' && inputs.mode == 'smoke' + runs-on: windows-2022 + permissions: + actions: read + contents: read + steps: + - uses: actions/checkout@v4 + - uses: actions/download-artifact@v4 + with: + name: windows-x64 + path: signed-windows + run-id: ${{ inputs.smoke_run_id }} + github-token: ${{ secrets.GITHUB_TOKEN }} + - name: Verify signed installation and upgrade + shell: pwsh + run: | + ./scripts/smoke-signed-windows-installer.ps1 ` + -Installer 'signed-windows/dsh-desktop-windows-x64-setup.exe' ` + -PublisherName 'Beijing Shuju Xiangsu Intelligence Technology Co., Ltd.' + publish: name: Publish GitHub Release if: >- always() && startsWith(github.ref, 'refs/tags/v') && inputs.prerelease_tag == '' && - needs.macos-apple-silicon.result == 'success' && - needs.macos-intel.result == 'success' && - needs.sign-windows.result == 'success' + needs.macos.result == 'success' && + needs.sign-windows.result == 'success' && + needs.smoke-signed-windows.result == 'success' needs: - - macos-apple-silicon - - macos-intel + - macos - sign-windows + - smoke-signed-windows runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 @@ -956,13 +921,13 @@ jobs: inputs.mode == 'prerelease' && inputs.target == 'all' && inputs.prerelease_tag != '' && - needs.macos-apple-silicon.result == 'success' && - needs.macos-intel.result == 'success' && - needs.sign-windows.result == 'success' + needs.macos.result == 'success' && + needs.sign-windows.result == 'success' && + needs.smoke-signed-windows.result == 'success' needs: - - macos-apple-silicon - - macos-intel + - macos - sign-windows + - smoke-signed-windows runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 diff --git a/.gitignore b/.gitignore index e418cc560..0323411ee 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,6 @@ docs/mobile-connection-latency.zh.md # Local pnpm content store /.pnpm-store/ +/.build/ +/packages/ppt-runtime/templates/ +/packages/ppt-bundles/ diff --git a/build/dsh-desktop-safe.patch.yml b/build/dsh-desktop-safe.patch.yml index cb1698980..cd304fc67 100644 --- a/build/dsh-desktop-safe.patch.yml +++ b/build/dsh-desktop-safe.patch.yml @@ -11,6 +11,10 @@ - id: ui-brand-official disabled: true +# Match the normal Desktop settings/model setup during recovery. +- id: ui-settings-account + disabled: true + - insert: - id: dsh-desktop-client-ui name: dsh-desktop-client-ui diff --git a/build/dsh-desktop.patch.yml b/build/dsh-desktop.patch.yml index 451007702..cd38376c7 100644 --- a/build/dsh-desktop.patch.yml +++ b/build/dsh-desktop.patch.yml @@ -7,8 +7,8 @@ # Keep the stock directory-picker (auto) row active: the native backend # serves ctx.directoryPicker, so host-side consumers (host.pickDirectory, -# plugins reading the seam) work unmodified. The client surface keeps its -# Electron-dialog bridge via the client-ui patch in patches/. +# plugins reading the seam) work unmodified. The client surface reads the +# upstream __DSH_DIRECTORY_PICKER__ bridge exposed by preload. # Disable the stock single-slot occupant before mounting Desktop's equivalent; # two occupants cannot share either brand seat. The Desktop plugin preserves @@ -18,6 +18,10 @@ - id: ui-brand-official disabled: true +# Keep the v0.9.2 settings launcher and model setup without upstream account UI. +- id: ui-settings-account + disabled: true + - insert: - id: dsh-desktop-client-ui name: dsh-desktop-client-ui diff --git a/docs/architecture.md b/docs/architecture.md index 295d29b72..0d0863f77 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -81,7 +81,9 @@ For reused or deferred legacy trees, startup reads bundle manifests and YAML lay A baseline market that cannot be installed — an offline or restricted network reports this as a pnpm fetch, 404 or EPERM failure — only blocks startup when the market already in the profile is absent, unreadable or still owned by a generation. Otherwise the boot continues on the installed market and the pending marker retries the repair on the next launch. -Safe Mode uses the installation anchor for both host plugin imports and client bundle discovery, without requiring `profiles/node_modules`. The paired `dsh-app-boot` / `dsh-client-modules` patches target Harness `0.1.5-rc.2`: `mountRootInclude` publishes the explicit host anchor on the loader using `Symbol.for("dsh.desktop.host-module-base-url")`, and client discovery consumes it for bare package names only. Configuration-relative paths and ordinary profiles keep their existing resolution. This small loader handoff is needed because the published client registry otherwise re-resolves from the Profile tree; remove both hunks when upstream propagates an equivalent resolution anchor. Regression coverage includes the actual recovery subprocess's authenticated HTML and executable bootstrap, plus path-resolution behavior tests. +Safe Mode uses the installation anchor for both host plugin imports and client bundle discovery, without requiring `profiles/node_modules`. The paired `dsh-app-boot` / `dsh-client-modules` patches target Harness `0.1.7-rc.1`: `mountRootInclude` publishes the explicit host anchor on the loader using `Symbol.for("dsh.desktop.host-module-base-url")`, and client discovery consumes it for bare package names only. Configuration-relative paths and ordinary profiles keep their existing resolution. This loader handoff is needed because client discovery otherwise re-resolves from the Profile tree; remove both hunks when upstream propagates an equivalent resolution anchor. Regression coverage includes the actual recovery subprocess's authenticated HTML and executable bootstrap, plus path-resolution behavior tests. + +Normal-profile Desktop patch insertions resolve from the actual bundled Harness entry, then use the same absolute source URLs for backend loading and client discovery. The patch file's directory is not a package anchor: installed patches live directly in `resources`, while runtime packages live in `resources/app.asar.unpacked/node_modules`. Missing host sources retain the package name, anchor and original resolution cause, and leave the previous generated patch intact. ## Mobile access boundary @@ -106,4 +108,4 @@ Update metadata and artifacts are produced by the native release workflow. macOS Most of the product UI remains upstream Harness. DSH Desktop adds native host surfaces through Electron Main and preload code, uses Harness extension slots where available, and tracks unavoidable upstream package changes as reproducible `patch-package` files. This keeps the desktop layer reviewable while making upstream upgrades an explicit compatibility exercise. -Safe Mode preset discovery and mounting also consume the explicit host anchor through the `dsh-agent-presets@0.1.5-rc.2` patch. Its own filesystem health check and `PresetTree` importer bypass the root loader import hook, so both must use the same installation base; without the Desktop anchor they retain upstream context-relative behavior. Remove this patch when upstream supports a host resolution anchor for both paths. The recovery subprocess regression creates a default-preset session through the real authenticated RPC with `profiles/node_modules` absent, catching the 24-unresolvable-plugins failure beyond frontend readiness. +Harness 0.1.7 replaces directory based `dsh-agent-presets` with Profile composition entries. Before launching the normal web Profile, Desktop converts valid user directories into those entries, backs up the original tree and Profile patch, and leaves the original directories untouched. Safe Mode continues to resolve its bundled preset and client packages from the installation anchor; the recovery subprocess regression creates a default-preset session through the authenticated RPC with `profiles/node_modules` absent. diff --git a/docs/baseline-runtime-compatibility.md b/docs/baseline-runtime-compatibility.md new file mode 100644 index 000000000..22e845615 --- /dev/null +++ b/docs/baseline-runtime-compatibility.md @@ -0,0 +1,66 @@ +# 0.1.7 baseline 兼容修复 + +## 模型配置 + +目标:`@deepseek-ai/dsh-client-ui-settings-models@0.1.7-rc.1`。 + +保留已有模型搜索、行内视觉开关、服务商选择和推理等级配置补丁。修正补丁中 5 个已移除的图标导出;DeepSeek 高级选项通过当前 `capacityInput` 契约渲染容量字段,避免调用不存在的旧 `capacityField`。 + +验证:图标导出检查、编辑器展开及容量编辑行为测试、真实 Dev 模型页和高级选项展开。未保存用户模型配置。升级时重新核对上游组件和字段契约,不机械重放旧渲染代码。 + +## generation 宿主依赖校验 + +Harness 0.1.7 可以通过运行时 resolver 将宿主依赖解析到当前安装,而旧 `profiles/node_modules` 链接仍指向另一安装。Desktop 的两条 generation 安装入口现在传入当前 DSH 入口。校验只对约定的宿主单例核对该入口提供的精确解析结果,不将整个安装目录作为普通第三方依赖的允许范围。 + +回归覆盖:旧共享链接与当前宿主不同、当前宿主可用、普通第三方依赖逃逸仍被拒绝。实际 Dev 的 `dsh-antigravity@0.0.7` 已安装并显示模型。Windows 安装包尚未验收。 + +## Undici 8 与旧 Fetch 的 HTTP/2 响应头 + +目标:`undici@8.11.0`,补丁 `patches/undici+8.11.0.patch`。 + +`Dispatcher1Wrapper` 将 `controller.rawHeaders` 原样传给旧 handler;HTTP/2 的该值是对象,旧 Fetch 要求扁平数组,因而丢失 Content-Type / Content-Encoding,gzip 数据随后被当成 JSON。修复将对象转换为原有 `toRawHeaders` 格式;HTTP/1.1 已有数组不变。同样处理 upgrade 头与 trailers。 + +这是共享网络层兼容修复,影响使用旧 Dispatcher API 的调用者,不仅是 AntiGravity。不改变代理选路、认证、请求内容或压缩协商。上游 wrapper 正式兼容对象响应头后应删除补丁,并重跑同一回归。 + +验证:内置 Fetch 的 gzip JSON、对象/数组响应头、重复 Set-Cookie、分块 SSE、HTTP/1.1 数组保持原样、trailers;在 Electron Node 24.17.0 中通过 Harness 代理向 Google OAuth token 端点发送无凭据诊断请求,修复前得到 gzip 字节且无响应头,修复后能解析预期的 HTTP 400 JSON。该检查不代表真实账号认证或模型推理验收。 + +### Windows header clearance after rc.2 + +`ConversationHeader` now owns the `
` outside `conversation.session.header`. +The old preload selector (`[data-slot="conversation.session.header"] > header`) +therefore no longer reserves space for native caption controls. The conversation +patch adds only `data-dsh-conversation-header` to the resident header; preload +uses that marker to reserve the native caption height and keeps all header slots +in normal flow below it. This covers sessionless and active views without cloning +contributions or relying on generated class names. This is window chrome, so the +layout stays in preload rather than a business plugin. Remove the marker patch +when upstream exposes an equivalent stable header/Windows clearance contract. + +Regression: `test/windows-titlebar-header.test.mjs` executes the installed rc.2 +header in both session states and verifies slot ownership/count. Local Chromium +geometry checks cover narrow/wide, light/dark and blank/active layouts; they do +not replace final Windows installer checks (DPI, zoom, maximize and clicks). + +## 插件 Harness 版本声明采用告警策略 + +目标:`dsh-app-boot` 和 `dsh-plugin-manager` 的 `0.1.7-rc.2` 补丁。 +适用于所有插件的 Harness peer 版本范围声明,不设包名白名单,也不限于 rc.1 → rc.2。 +版本范围不包含当前 Harness 时,安装检查、Profile 组合预检、运行时行预检及 manager 启用检查输出告警并继续尝试。 +告警表示兼容性未经确认,不能当作实际加载成功;不修改第三方 manifest 或自动写入版本豁免。 + +Profile 组合仍从当前 Profile 和安装 anchor 解析;普通 Profile 与 Safe Mode 的依赖解析范围不变。 +缺包、损坏的 manifest/YAML、非字符串 peer 字段及实际 import/apply/activation 错误仍保留原始诊断和恢复入口。 +仅放宽版本声明门禁,不放宽 generation 依赖闭包与宿主单例校验。 +安装告警进入安装输出和日志,启动告警按同一声明及运行时版本在每个进程中去重。 + +回归:`profile-boot-preflight.test.ts`、`plugin-startup-failure.test.ts`、`plugin-version-policy.test.mjs`。 +覆盖旧声明正常运行、实际 API 失败、损坏输入、manager 安装不回滚及 manifest 不变。 +当上游支持宿主选择同等告警策略时,改用公开配置并移除此策略补丁。 + +## CLI-only peer 校验 + +`@deepseek-ai/dsh@0.1.7-rc.2` 只提供 `bin.dsh = lib/bin.js`,没有可导入根入口。 +generation 校验不能把 `require.resolve()` 失败直接当作缺包:对于没有 main/exports 的 CLI 包,检查包内实际存在的 bin 文件,再沿用宿主目录和单例校验。 +不执行 CLI,不用 bin 掩盖损坏的 main/exports,不接受目录、缺失文件或越出包目录的 bin。 +这只影响安装后依赖校验阶段,不改变 Profile 解析基准和插件加载协议;实际 import/激活仍由 Harness 验证。 +回归位于 `test/generation-installer.test.ts`。旧 CI 安装包需重新构建后才能获得此修复。 diff --git a/docs/macos-window-chrome.md b/docs/macos-window-chrome.md new file mode 100644 index 000000000..5f838ad5a --- /dev/null +++ b/docs/macos-window-chrome.md @@ -0,0 +1,22 @@ +# macOS 窗口按钮与 Harness rc.2 布局 + +对照官方 `dsh-v0.1.7-rc.2` 的 `apps/desktop/src/preload-platform.ts`、`apps/desktop/src/main.ts`、`packages/client/ui-layout/src/client/AppFrame.module.css`: + +- preload 在客户端挂载前声明 `html[data-platform=darwin]`。 +- 使用官方 16/18 原生按钮坐标;不再混用原来的 9px 高度和旧侧栏顶部 padding。 +- 收起后由 Harness 隐藏整个侧栏并挂载 `shell.leading`;官方变量为主内容保留顶部和左侧空间。 +- main 在加载、进入/退出全屏时通知 preload,映射为 `data-fullscreen`,让官方 CSS 在全屏时回收按钮留白。 + +平台标记同时影响 shortcuts 环境检测。DSH Desktop 没有官方 `keyboard`/快捷键设置原生桥,因此显式声明 `data-dsh-desktop-web-shortcuts=true`,通过 `dsh-client-shortcuts` 最小补丁继续使用已有 Web 键盘与存储适配器。没有该标记的官方宿主仍要求自己的原生桥;这不是通用的错误吞掉或自动降级。若未来接入完整原生快捷键桥,应同时删除标记与补丁。 + +不额外复制官方侧栏/顶栏布局,不改变 Windows 的标题栏行为。行为回归覆盖 preload 首次标记、无 document root 时的全屏状态、退出全屏、监听清理和官方/自有宿主快捷键环境区分。 + +验证:全量 152 个测试文件 / 1261 项通过;typecheck 通过;两项补丁在独立临时依赖目录中 npm ci 后重放成功;真实 macOS Dev 启动、侧栏收起及展开正常,收起后顶部控件与标题留白已确认。屏幕共享指示器覆盖了原生按钮区域,按钮本体及全屏过渡尚未完成视觉验收;未验证最终安装包。 + +`npm run build` 与 `git diff --check` 通过。 + +## 完整采用官方窗口材质 + +macOS 窗口采用 `hiddenInset`、`trafficLightPosition: { x: 16, y: 18 }`、`vibrancy: sidebar`、`visualEffectState: active` 和透明窗口背景。显示时保持原生材质;隐藏/最小化时改用官方深浅底色,恢复时重新挂接 sidebar 材质,避免透明闪烁。主题同步不再把可见 macOS 窗口覆盖成不透明底色。移除旧固定拖拽覆盖条,由官方 `data-window-drag` 标记的行负责拖拽。 + +新增 backdrop 状态转换测试;完整回归 153 个文件 / 1263 项、typecheck 通过。 diff --git a/docs/mobile-pairing-pin-design.zh.md b/docs/mobile-pairing-pin-design.zh.md index 1fbe9b893..39fd3e7e7 100644 --- a/docs/mobile-pairing-pin-design.zh.md +++ b/docs/mobile-pairing-pin-design.zh.md @@ -1,7 +1,7 @@ # 手机配对:按模式拆分(扫码即连 / 隧道 PIN) -> 状态:已实现(2026-09-14)。 -> 范围:把桌面「允许 / 拒绝」改成按连接模式授权;Cloudflare 保活;免费 Pinggy 过期体验做诚实。配对中转见文末附录,**不在本次实现**。 +> 状态:已实现(2026-09-14)。 +> 范围:把桌面「允许 / 拒绝」改成按连接模式授权;Cloudflare 保活;免费 Pinggy 过期体验做诚实。配对中转见文末附录,**不在本次实现**。 > 相关代码:[`src/main/mobile/lan-mobile-bridge.ts`](../src/main/mobile/lan-mobile-bridge.ts)、[`src/main/mobile/lan-mobile-pages.ts`](../src/main/mobile/lan-mobile-pages.ts)、[`src/main/index.ts`](../src/main/index.ts)。 ## 1. 结论摘要 diff --git a/docs/patch-compatibility-review-0.1.7.md b/docs/patch-compatibility-review-0.1.7.md new file mode 100644 index 000000000..607e90993 --- /dev/null +++ b/docs/patch-compatibility-review-0.1.7.md @@ -0,0 +1,60 @@ +# 0.1.7-rc.1 补丁兼容性复核 + +范围:当前 baseline 的 25 个 patch-package 补丁,以及消费这些接缝的 Desktop 客户端插件。检查对象为实际安装的发布代码,不以补丁能应用作为运行正确的证明。 + +## 本轮发现并修复 + +1. **通用模型编辑器的未定义图标**:`ModelListEditor` 引用了已不存在的局部 `IconChevron` / `IconTrash`,会在有自定义模型行时抛错。改用当前 primitives 的 Regular 图标。新增通用编辑器展开、容量修改回归;保留搜索、视觉开关及推理配置。 +2. **遗留模型向导的未定义状态**:`DeepSeekOnboardingDialog` 修改了一半,删掉 `onboardingReadiness(state)` 却仍读取 `readiness`。恢复原有状态推导并覆盖加载、缺密钥、已就绪及错误分支。当前 Desktop 已取消该向导的 slot 注册、使用自己的向导,因此这是潜伏代码问题,不能据此认定当前 Desktop 首次启动必然白屏。 +3. **pi-ai 流式回放格式混用**:补全缺失 terminal content 时曾保存 Harness 的 `reasoning` / `tool-call`,而 `toPiReplayState` 要求原生 `thinking` / `toolCall`。改为保存原生 partial / toolCall,并保留签名;对外流式 block 仍为 Harness 格式。回归覆盖三个内容类型及回放签名。上游保证 terminal content 完整后,可删除这段补全逻辑。 + +前序已修复:模型选择器和模型配置页的旧图标导出、DeepSeek 容量编辑 helper;内置生图从旧 `settings.plugin.item` 迁到 `settings.plugins.tab`(后者属于自有插件,不是 patches 文件)。 + +## 全部补丁检查表 + +“未发现新增问题”仅表示本轮静态检查和相关源码回归范围内未发现,不表示全部平台、插件组合已验收。 + +| 包(省略 @deepseek-ai/;除特别说明外均为 0.1.7-rc.1) | 检查重点 | 结论 | +| --- | --- | --- | +| cordis-plugin-loader 1.0.5 | 超时、错误链、启动失败归属 | 未发现新增问题 | +| dsh | CLI 失败出口、宿主包依赖清单 | 未发现新增问题 | +| dsh-api-remotes | session.delete 编解码与服务映射 | 未发现新增问题 | +| dsh-api-session-controller | 文件访问、删除、预设迁移、远程事件 | 未发现新增问题 | +| dsh-app-boot | bundle 归属、禁用状态、启动审计 | 未发现新增问题 | +| dsh-client-file-upload | staged file 的 Agent 作用域 | 未发现新增问题 | +| dsh-client-modules | 客户端发现、combo 缓存、source map | 未发现新增问题 | +| dsh-client-ui-agent-preset | 导入导出、搜索、Modal 引用 | 未发现新增问题 | +| dsh-client-ui-attachment | 文件卡片回调、组件导出 | 未发现新增问题 | +| dsh-client-ui-chat | 上传文件打开链、错误提示 | 未发现新增问题 | +| dsh-client-ui-conversation | 输入区及 PPT slot 声明、props、图标 | 未发现新增接口缺失;布局改动仍由 PPT 组合测试覆盖 | +| dsh-client-ui-deliverables | 本地路径识别与文件打开 | 未发现新增问题 | +| dsh-client-ui-model-selection | 图标、搜索、推理等级 | 前序修复后未发现新增问题 | +| dsh-client-ui-settings-general | 设置入口、onboarding 条件 | 未发现新增问题 | +| dsh-client-ui-settings-models | 两类编辑器、向导状态、组件引用 | 本轮修复两项 | +| dsh-client-ui-sidebar | 品牌及平台间距接缝 | 未发现新增接口问题;不等于跨平台视觉验收 | +| dsh-client-ui-trajectory | provider 错误码展示 | 未发现新增问题 | +| dsh-client-ui-workspace | 导航接缝、未读、删除生命周期 | 未发现新增问题 | +| dsh-llm-deepseek | AUTH / QUOTA / FORBIDDEN 分类 | 未发现新增问题 | +| dsh-llm-pi-ai | 流式事件、回放、请求头 | 本轮修复内容格式混用 | +| dsh-plugin-manager | generation backend、commit/rollback 接口 | 未发现新增接口缺失;本轮不代表完成插件事务架构重写 | +| dsh-session-persistence | 可选删除接口 | 未发现新增问题 | +| dsh-session-persistence-jsonl | 删除租约及坏日志跳过 | 未发现新增问题 | +| dsh-workspace | 持久会话删除后的索引清理 | 未发现新增问题 | +| undici 8.11.0 | 新旧 Dispatcher 响应头及 trailers | 前序修复后未发现新增问题 | + +## 防止同类遗漏 + +- `patch-runtime-compatibility.test.mjs` 从 patches 动态收集已修改 JS,检查未解析的局部标识符,覆盖未执行的条件分支;仅豁免宿主提供的 `global` / `setImmediate`。 +- 同一测试核对所有被补丁修改的客户端对 primitives 的成员引用,不再只查两个包的图标。 +- 同一测试核对四个维护中的 Desktop 客户端所注入的 slot 在当前安装 Harness 中确有声明。该检查不验证贡献项可见性、容器布局及生命周期。 +- `model-settings-render.test.mjs` 执行两种模型编辑器及向导状态分支;`pi-ai-terminal-replay.test.mjs` 执行实际流转换及回放投影。 + +## 验收边界 + +干净补丁重放在独立临时项目中进行,安装 25 个补丁对应版本并通过 `npm ci --ignore-scripts` 后运行 `patch-package --error-on-fail`。该步骤验证补丁目标及重放,不等同于本仓库完整 postinstall(品牌资源、Electron 安装等)或安装包验收。 + +本轮未操作用户凭据、未保存模型设置、未发送付费模型请求。新增的通用编辑器修复仍需真实页面交互验收;pi-ai 修复仍需真实服务商的多轮推理/工具调用验收。Windows/macOS 最终安装包不在本轮已验证范围内。 + +本轮已执行:25 个补丁全部重放成功;51 个补丁目标文件与当前工作目录逐字节一致;完整回归 149 个文件 / 1251 项通过;`npm run typecheck`、`git diff --check` 通过。测试及重放均未修改真实 Profile。 + +`npm run build` 通过。该命令包含 PPT 资源构建及 Electron 编译,不包含签名或最终安装包验收。 diff --git a/docs/release-runbook.md b/docs/release-runbook.md index 30f149c6b..650624f51 100644 --- a/docs/release-runbook.md +++ b/docs/release-runbook.md @@ -6,13 +6,29 @@ The `Release desktop installers` workflow accepts a `mode` on `workflow_dispatch - `development` (default): unsigned Dev packages, no signing, no publish. - `signed`: production-identity signed packages only. Fill `signed_version` with a non-`v` semver such as `0.9.2-test.1`. Artifacts stay on the workflow run; GitHub Release, ModelScope, rollout, and Feishu do not run. These builds use the production app id and update feed, so an installed copy may later see the live `latest` channel. +- `smoke`: recheck an existing `windows-x64` signed artifact without rebuilding or signing. Set `target=windows` and `smoke_run_id` to the source release workflow run ID. The Windows runner installs that exact artifact using the current branch's smoke script. +- `resign`: sign an existing `windows-x64-unsigned` artifact without rerunning the Windows build. Set `target=windows`, `unsigned_run_id` to its source release run, and `signed_version` to the exact version used for that artifact. The self-hosted signer downloads it directly and the final signed Windows installer still runs the installation smoke. - `prerelease`: production-identity signed packages. Fill `prerelease_tag` with a non-`v` semver such as `2.1.0-rc.1`. Publish to GitHub `--prerelease` and ModelScope `releases/prerelease/` only when `target` is `all`. A single-platform prerelease signs that platform and skips publish. Official releases are still created by pushing a `v*` tag, not by filling the dispatch form. Do not put `v0.9.1` in `prerelease_tag` or `signed_version`. +## Build layout and timing + +macOS uses one matrix job with native Apple Silicon and Intel runners. Both entries retain the same signing, notarization and artifact verification gates; publishing waits for the whole matrix. Each native job builds once (including PPT previews), runs Vitest against that prepared runtime, and packages the same output with an explicit native-target check. Windows also runs recovery UI checks before packaging. Local `npm test` and `package:*` commands still prepare their own inputs. Already compressed installer artifacts use `compression-level: 0` during upload to avoid redundant compression. Compare job step durations on the same target before changing installer compression or dependency contents. + +Concurrency is grouped by ref and target: a Windows-only retry can run while an all-platform run finishes macOS notarization. Runs for the same ref and target remain serialized; publication still requires `target=all` (or a release tag), and the single local UKey runner serializes Windows signing. + +The self-hosted signer downloads artifacts in six concurrent 32 MiB ranges through `gh`, retries bounded requests, and checks the complete archive against GitHub's SHA-256 digest before extraction. A real 668,014,109-byte signing artifact downloaded and verified in 149 seconds on the signing host; the previous single stream was still incomplete after ten minutes. Throughput depends on the network. A short response, failed transfer or digest mismatch leaves an existing verified output untouched and removes temporary parts. + +PPT packages are generated under `.build/ppt-runtime/packages/` and overlaid into the Electron package. The `afterPack` gate checks the physical `dsh-ppt` and `dsh-ppt-composer` directories, including native imports and template previews. A successful source build alone does not verify the packaged paths. + ## Local Windows UKey signing runner -Windows packaging and signing run as separate jobs. The GitHub-hosted Windows runner builds an unsigned NSIS installer and uploads a short-lived workflow artifact. A local macOS ARM64 runner downloads it, signs the installer with Jsign and the SafeNet UKey, regenerates the blockmap and `latest.yml`, and uploads the signed release set. The GitHub Release job cannot start unless signing succeeds. +Windows packaging and signing run as separate jobs. The GitHub-hosted Windows runner builds an unsigned NSIS installer and uploads a short-lived workflow artifact. A local macOS ARM64 runner downloads it, scans every PE by content, preserves existing vendor signatures, and signs unsigned PEs with Jsign and the SafeNet UKey. It signs the NSIS extraction helper and generated uninstaller during repackaging, then signs the final installer, regenerates the blockmap and `latest.yml`, and uploads the signed release set. Any missing archive, invalid PE, signing failure or repackaging failure stops the run. A second Windows runner installs the final signed artifact into isolated directories, verifies every PE signature and Harness startup, repeats the same-path installation, and checks that Profile data survives. GitHub publication requires both signing and that installed-artifact smoke to pass. + +The pinned Windows NSIS template stages the application in a sibling directory before closing the old app, then renames the old directory to a backup and promotes the staged directory. A failed extraction or rename restores the previous installation. The signed installer smoke also locks the old executable to verify that a failed upgrade leaves it runnable. A user-selected different directory is an independent installation: the installer does not automatically uninstall the previous directory, which remains available until the user removes it. Keep the user-selected installation directory when changing this template; the build adapter rejects unexpected upstream template changes. + +Runtime dependencies are unpacked beside `app.asar` because Harness, pnpm, native addons, and the standalone Windows Node process need physical paths. The macOS ARM64 test package contains a 6.2 MB `app.asar` and about 588 MB of unpacked dependencies; enabling asar alone did not reduce its 256 MB DMG. Do not remove `node.exe` from Windows yet: the pinned `node-addon-require-builtin@0.1.6` rejects Electron 43.4.0 in RunAsNode mode during Harness boot, even though the Koffi native probe passes ([Windows CI evidence](https://github.com/dataelement/dsh-desktop/actions/runs/35972303467)). Repeat the packaged Windows Harness and final signed-installer gates after a loader version explicitly supports the target Electron fingerprint before revisiting that removal. Prepare the local runner once: @@ -24,4 +40,4 @@ Prepare the local runner once: The workflow pins Jsign 7.5 by SHA-256 and uses the SafeNet `ETOKEN` store, SHA-256 signing, and a DigiCert RFC 3161 timestamp. GitHub injects the PIN only into the signing step. The step copies it to a mode-`600` temporary file, removes it from the shell environment, and deletes the file when the step exits. The workflow never prints the PIN or passes it as a command-line argument. -After a tag release succeeds, verify that the Windows installer shows the expected publisher and a valid RFC 3161 timestamp in its Digital Signatures properties. Never reuse a published tag; fix the issue and release a new version. +The configured update publisher is `Beijing Shuju Xiangsu Intelligence Technology Co., Ltd.`, taken from the signed v0.9.2 installer. If the signing certificate changes, update `build.win.signtoolOptions.publisherName` only after checking the new certificate subject and the updater's signature verification on an installed Windows build. After a tag release succeeds, verify that the Windows installer shows the expected publisher and a valid RFC 3161 timestamp in its Digital Signatures properties. Never reuse a published tag; fix the issue and release a new version. diff --git a/docs/settings-launcher-compatibility.md b/docs/settings-launcher-compatibility.md new file mode 100644 index 000000000..00b37ab72 --- /dev/null +++ b/docs/settings-launcher-compatibility.md @@ -0,0 +1,9 @@ +# v0.9.2 设置入口兼容 + +Desktop 暂不使用 Harness 0.1.7-rc.1 的 `@deepseek-ai/dsh-client-ui-settings-account` 插件。普通模式和 Safe Mode 的宿主组合层均设置 `ui-settings-account` 为 disabled。 + +这会同时停用该插件的侧栏账号菜单、模型 onboarding 登录入口及账号设置页。左下角使用 `settings-general` 自带的设置按钮,模型提供方和 API 配置仍由模型设置插件承载。配置不删除账号凭据或修改用户 Profile。 + +`settings.launcher` 的声明、出口和其他插件贡献保持原样。无需第三方 JS 补丁;上一轮仅移除 AccountMenu 注册的临时补丁已删除。将来启用账号功能时可以撤销这两个组合层覆盖。 + +`test/settings-account-launcher.test.js` 使用实际上游组合层与两个 Desktop 组合层验证禁用结果,以及普通设置和模型设置保持启用。实际应用的展开/折叠侧栏、模型设置及深浅主题仍需 UI 验收。 diff --git a/docs/source-build-contract.md b/docs/source-build-contract.md index 5c64511c5..88670ed24 100644 --- a/docs/source-build-contract.md +++ b/docs/source-build-contract.md @@ -50,4 +50,4 @@ 目标是:维护代码与模板原始输入 → 构建生成预览/清单及插件分发内容 → 应用打包。开发者提交代码、输入和脚本,CI 保存和分发产物;完整性值由生成流程计算。 -本文新增开发与评审约束,尚未迁移现有 PPT 构建流程或启用上述 CI 门禁。PR #369 的业务修复与构建链路迁移应分别说明验证结果。 +后续 PPT 构建迁移将根依赖改为可在干净 checkout 安装的本地源码包;统一准备入口在忽略的 `.build/ppt-runtime/` 中生成模板、预览和完整插件目录,再投影到开发 `node_modules` 并由 Electron Builder 显式装配。仓库不再跟踪 `ppt-bundles/*.tgz`、模板生成树或 `artifacts.json`,测试同时检查生成包内容和禁止回归的 Git 跟踪边界。 diff --git a/package-lock.json b/package-lock.json index 99205be07..f2140c14c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,239 +10,241 @@ "hasInstallScript": true, "license": "MIT", "dependencies": { - "@deepseek-ai/cordis": "4.0.2", - "@deepseek-ai/cordis-plugin-group": "1.0.2", - "@deepseek-ai/cordis-plugin-hmr": "1.0.17", - "@deepseek-ai/cordis-plugin-include": "1.0.7", - "@deepseek-ai/cordis-plugin-loader": "1.0.3", - "@deepseek-ai/cordis-plugin-timer": "1.1.4", - "@deepseek-ai/cosmokit": "1.8.3", - "@deepseek-ai/dsh": "0.1.5-rc.2", - "@deepseek-ai/dsh-acp": "0.1.5-rc.2", - "@deepseek-ai/dsh-acp-app": "0.1.5-rc.2", - "@deepseek-ai/dsh-agent": "0.1.5-rc.2", - "@deepseek-ai/dsh-agent-default-model": "0.1.5-rc.2", - "@deepseek-ai/dsh-agent-instructions": "0.1.5-rc.2", - "@deepseek-ai/dsh-agent-loop": "0.1.5-rc.2", - "@deepseek-ai/dsh-agent-presets": "0.1.5-rc.2", - "@deepseek-ai/dsh-agent-tool-presentation": "0.1.5-rc.2", - "@deepseek-ai/dsh-anonymous-user-id": "0.1.5-rc.2", - "@deepseek-ai/dsh-api-gateway": "0.1.5-rc.2", - "@deepseek-ai/dsh-api-remotes": "0.1.5-rc.2", - "@deepseek-ai/dsh-api-session-controller": "0.1.5-rc.2", - "@deepseek-ai/dsh-api-settings-controller": "0.1.5-rc.2", - "@deepseek-ai/dsh-api-workspace-controller": "0.1.5-rc.2", - "@deepseek-ai/dsh-app-boot": "0.1.5-rc.2", - "@deepseek-ai/dsh-atomic-write": "0.1.5-rc.2", - "@deepseek-ai/dsh-attachment": "0.1.5-rc.2", - "@deepseek-ai/dsh-attachment-local": "0.1.5-rc.2", - "@deepseek-ai/dsh-authorization": "0.1.5-rc.2", - "@deepseek-ai/dsh-base": "0.1.5-rc.2", - "@deepseek-ai/dsh-bash-local": "0.1.5-rc.2", - "@deepseek-ai/dsh-bash-sandbox": "0.1.5-rc.2", - "@deepseek-ai/dsh-brand": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-connection": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-hmr": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-locale": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-modules": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-store": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-agent-preset": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-approval": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-attachment": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-brand-official": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-chat": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-commands": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-conversation": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-cordis": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-deliverables": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-directory-picker-browse": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-directory-picker-native": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-goal": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-input-trigger": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-jobs": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-layout": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-message-feedback": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-model-selection": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-permission-presets": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-plan": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-primitives": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-reference": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-renderer": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-schedule": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-session": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-settings": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-settings-general": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-settings-models": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-settings-plugin-inventory": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-settings-plugins": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-sidebar": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-skill": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-slots": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-subagent": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-theme": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-tool": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-trajectory": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-user-questions": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-workflow-run": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-workspace": "0.1.5-rc.2", - "@deepseek-ai/dsh-cmdline": "0.1.5-rc.2", - "@deepseek-ai/dsh-code-runtime": "0.1.5-rc.2", - "@deepseek-ai/dsh-code-runtime-worker-thread": "0.1.5-rc.2", - "@deepseek-ai/dsh-command-compact": "0.1.5-rc.2", - "@deepseek-ai/dsh-command-feedback": "0.1.5-rc.2", - "@deepseek-ai/dsh-command-goal": "0.1.5-rc.2", - "@deepseek-ai/dsh-commands": "0.1.5-rc.2", - "@deepseek-ai/dsh-compaction": "0.1.5-rc.2", - "@deepseek-ai/dsh-compaction-basic": "0.1.5-rc.2", - "@deepseek-ai/dsh-compaction-tool-result-pruner": "0.1.5-rc.2", - "@deepseek-ai/dsh-cordis-client-runner": "0.1.5-rc.2", - "@deepseek-ai/dsh-cordis-host-runner": "0.1.5-rc.2", - "@deepseek-ai/dsh-credentials": "0.1.5-rc.2", - "@deepseek-ai/dsh-credentials-local": "0.1.5-rc.2", - "@deepseek-ai/dsh-deepseek-llm-api-extensions": "0.1.5-rc.2", - "@deepseek-ai/dsh-deque": "0.1.5-rc.2", - "@deepseek-ai/dsh-file-reference": "0.1.5-rc.2", - "@deepseek-ai/dsh-file-reference-local": "0.1.5-rc.2", - "@deepseek-ai/dsh-fs": "0.1.5-rc.2", - "@deepseek-ai/dsh-fs-local": "0.1.5-rc.2", - "@deepseek-ai/dsh-fs-observation-policy": "0.1.5-rc.2", - "@deepseek-ai/dsh-fs-sandbox": "0.1.5-rc.2", - "@deepseek-ai/dsh-goal": "0.1.5-rc.2", - "@deepseek-ai/dsh-goal-round-driver": "0.1.5-rc.2", - "@deepseek-ai/dsh-headless": "0.1.5-rc.2", - "@deepseek-ai/dsh-home-paths": "0.1.5-rc.2", - "@deepseek-ai/dsh-hook-protocol": "0.1.5-rc.2", - "@deepseek-ai/dsh-hooks-claude-code": "0.1.5-rc.2", - "@deepseek-ai/dsh-hooks-codex": "0.1.5-rc.2", - "@deepseek-ai/dsh-host-directory-picker": "0.1.5-rc.2", - "@deepseek-ai/dsh-host-directory-picker-auto": "0.1.5-rc.2", - "@deepseek-ai/dsh-host-directory-picker-browse": "0.1.5-rc.2", - "@deepseek-ai/dsh-host-directory-picker-native": "0.1.5-rc.2", - "@deepseek-ai/dsh-host-frontend-static": "0.1.5-rc.2", - "@deepseek-ai/dsh-host-plugin-inventory": "0.1.5-rc.2", - "@deepseek-ai/dsh-host-webserver": "0.1.5-rc.2", - "@deepseek-ai/dsh-invariants": "0.1.5-rc.2", - "@deepseek-ai/dsh-jobs": "0.1.5-rc.2", - "@deepseek-ai/dsh-jobs-local": "0.1.5-rc.2", - "@deepseek-ai/dsh-launch-environment": "0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "0.1.5-rc.2", - "@deepseek-ai/dsh-llm-deepseek": "0.1.5-rc.2", - "@deepseek-ai/dsh-llm-pi-ai": "0.1.5-rc.2", - "@deepseek-ai/dsh-llm-retry": "0.1.5-rc.2", - "@deepseek-ai/dsh-mcp-client": "0.1.5-rc.2", - "@deepseek-ai/dsh-message-feedback": "0.1.5-rc.2", - "@deepseek-ai/dsh-native-command": "0.1.5-rc.2", - "@deepseek-ai/dsh-output-retention": "0.1.5-rc.2", - "@deepseek-ai/dsh-permission-presets": "0.1.5-rc.2", - "@deepseek-ai/dsh-persona": "0.1.5-rc.2", - "@deepseek-ai/dsh-plan-mode": "0.1.5-rc.2", - "@deepseek-ai/dsh-plugin-package-inventory-deepseek": "0.1.5-rc.2", - "@deepseek-ai/dsh-pwsh-local": "0.1.5-rc.2", - "@deepseek-ai/dsh-pwsh-sandbox": "0.1.5-rc.2", - "@deepseek-ai/dsh-repeat-tool-reminder": "0.1.5-rc.2", - "@deepseek-ai/dsh-sandbox": "0.1.5-rc.2", - "@deepseek-ai/dsh-sandbox-local": "0.1.5-rc.2", - "@deepseek-ai/dsh-sandbox-policy": "0.1.5-rc.2", - "@deepseek-ai/dsh-sandbox-windows-acl": "0.1.5-rc.2", - "@deepseek-ai/dsh-schedule": "0.1.5-rc.2", - "@deepseek-ai/dsh-scope": "0.1.5-rc.2", - "@deepseek-ai/dsh-sdk-app": "0.1.5-rc.2", - "@deepseek-ai/dsh-sdk-jsonrpc-server": "0.1.5-rc.2", - "@deepseek-ai/dsh-sdk-minimal": "0.1.5-rc.2", - "@deepseek-ai/dsh-sdk-protocol": "0.1.5-rc.2", - "@deepseek-ai/dsh-session": "0.1.5-rc.2", - "@deepseek-ai/dsh-session-checkpoint-policy": "0.1.5-rc.2", - "@deepseek-ai/dsh-session-log-deepseek": "0.1.5-rc.2", - "@deepseek-ai/dsh-session-log-export": "0.1.5-rc.2", - "@deepseek-ai/dsh-session-persistence": "0.1.5-rc.2", - "@deepseek-ai/dsh-session-persistence-jsonl": "0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection": "0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection-cache": "0.1.5-rc.2", - "@deepseek-ai/dsh-session-query": "0.1.5-rc.2", - "@deepseek-ai/dsh-session-query-sqlite": "0.1.5-rc.2", - "@deepseek-ai/dsh-session-reference": "0.1.5-rc.2", - "@deepseek-ai/dsh-session-stats": "0.1.5-rc.2", - "@deepseek-ai/dsh-session-telemetry": "0.1.5-rc.2", - "@deepseek-ai/dsh-session-telemetry-otel": "0.1.5-rc.2", - "@deepseek-ai/dsh-session-title": "0.1.5-rc.2", - "@deepseek-ai/dsh-session-title-first-prompt-llm": "0.1.5-rc.2", - "@deepseek-ai/dsh-session-title-llm": "0.1.5-rc.2", - "@deepseek-ai/dsh-session-turn-outline": "0.1.5-rc.2", - "@deepseek-ai/dsh-settings": "0.1.5-rc.2", - "@deepseek-ai/dsh-settings-file": "0.1.5-rc.2", - "@deepseek-ai/dsh-shell": "0.1.5-rc.2", - "@deepseek-ai/dsh-shell-env": "0.1.5-rc.2", - "@deepseek-ai/dsh-skill": "0.1.5-rc.2", - "@deepseek-ai/dsh-skill-badge": "0.1.5-rc.2", - "@deepseek-ai/dsh-skill-filesystem": "0.1.5-rc.2", - "@deepseek-ai/dsh-spill": "0.1.5-rc.2", - "@deepseek-ai/dsh-spill-local": "0.1.5-rc.2", - "@deepseek-ai/dsh-spill-policy": "0.1.5-rc.2", - "@deepseek-ai/dsh-storage": "0.1.5-rc.2", - "@deepseek-ai/dsh-storage-domain": "0.1.5-rc.2", - "@deepseek-ai/dsh-storage-json": "0.1.5-rc.2", - "@deepseek-ai/dsh-subagent": "0.1.5-rc.2", - "@deepseek-ai/dsh-subagent-fork-in-process": "0.1.5-rc.2", - "@deepseek-ai/dsh-subagent-in-process-driver": "0.1.5-rc.2", - "@deepseek-ai/dsh-subagent-spawn-in-process": "0.1.5-rc.2", - "@deepseek-ai/dsh-subprocess": "0.1.5-rc.2", - "@deepseek-ai/dsh-subprocess-local": "0.1.5-rc.2", - "@deepseek-ai/dsh-system-prompt": "0.1.5-rc.2", - "@deepseek-ai/dsh-terminal": "0.1.5-rc.2", - "@deepseek-ai/dsh-terminal-bash": "0.1.5-rc.2", - "@deepseek-ai/dsh-time-context": "0.1.5-rc.2", - "@deepseek-ai/dsh-timeout": "0.1.5-rc.2", - "@deepseek-ai/dsh-tmux-context": "0.1.5-rc.2", - "@deepseek-ai/dsh-token-meter": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-ask-user": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-bash": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-bash-persistent": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-call-timeout-policy": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-cordis": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-fs": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-fs-search": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-goal": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-jobs": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-pwsh": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-pwsh-persistent": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-ralph": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-skill": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-str-replace-editor": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-subagent": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-subagent-control": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-todo": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-web": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-workflow": "0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "0.1.5-rc.2", - "@deepseek-ai/dsh-typert-loader": "0.1.5-rc.2", - "@deepseek-ai/dsh-typert-protocol": "0.1.5-rc.2", - "@deepseek-ai/dsh-typert-registry": "0.1.5-rc.2", - "@deepseek-ai/dsh-user-approval": "0.1.5-rc.2", - "@deepseek-ai/dsh-user-questions": "0.1.5-rc.2", - "@deepseek-ai/dsh-util-crypto": "0.1.5-rc.2", - "@deepseek-ai/dsh-util-time": "0.1.5-rc.2", - "@deepseek-ai/dsh-util-values": "0.1.5-rc.2", - "@deepseek-ai/dsh-util-workspace-path": "0.1.5-rc.2", - "@deepseek-ai/dsh-web": "0.1.5-rc.2", - "@deepseek-ai/dsh-web-app": "0.1.5-rc.2", - "@deepseek-ai/dsh-web-fetch-http": "0.1.5-rc.2", - "@deepseek-ai/dsh-web-frontend": "0.1.5-rc.2", - "@deepseek-ai/dsh-web-search-deepseek": "0.1.5-rc.2", - "@deepseek-ai/dsh-webhook": "0.1.5-rc.2", - "@deepseek-ai/dsh-webhook-github": "0.1.5-rc.2", - "@deepseek-ai/dsh-win32-process": "0.1.5-rc.2", - "@deepseek-ai/dsh-workflow": "0.1.5-rc.2", - "@deepseek-ai/dsh-workflow-worker-thread": "0.1.5-rc.2", - "@deepseek-ai/dsh-workspace": "0.1.5-rc.2", - "@deepseek-ai/schemastery": "3.18.2", + "@deepseek-ai/cordis": "4.0.4", + "@deepseek-ai/cordis-plugin-group": "1.0.4", + "@deepseek-ai/cordis-plugin-hmr": "1.0.19", + "@deepseek-ai/cordis-plugin-include": "1.0.9", + "@deepseek-ai/cordis-plugin-loader": "1.0.5", + "@deepseek-ai/cordis-plugin-timer": "1.1.6", + "@deepseek-ai/cosmokit": "1.8.5", + "@deepseek-ai/dsh": "0.1.7-rc.2", + "@deepseek-ai/dsh-acp": "0.1.7-rc.2", + "@deepseek-ai/dsh-acp-app": "0.1.7-rc.2", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-agent-default-model": "0.1.7-rc.2", + "@deepseek-ai/dsh-agent-instructions": "0.1.7-rc.2", + "@deepseek-ai/dsh-agent-loop": "0.1.7-rc.2", + "@deepseek-ai/dsh-agent-preset": "0.1.7-rc.2", + "@deepseek-ai/dsh-agent-tool-presentation": "0.1.7-rc.2", + "@deepseek-ai/dsh-anonymous-user-id": "0.1.7-rc.2", + "@deepseek-ai/dsh-api-gateway": "0.1.7-rc.2", + "@deepseek-ai/dsh-api-remotes": "0.1.7-rc.2", + "@deepseek-ai/dsh-api-session-controller": "0.1.7-rc.2", + "@deepseek-ai/dsh-api-settings-controller": "0.1.7-rc.2", + "@deepseek-ai/dsh-api-workspace-controller": "0.1.7-rc.2", + "@deepseek-ai/dsh-app-boot": "0.1.7-rc.2", + "@deepseek-ai/dsh-atomic-write": "0.1.7-rc.2", + "@deepseek-ai/dsh-attachment": "0.1.7-rc.2", + "@deepseek-ai/dsh-attachment-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-authorization": "0.1.7-rc.2", + "@deepseek-ai/dsh-base": "0.1.7-rc.2", + "@deepseek-ai/dsh-bash-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-bash-sandbox": "0.1.7-rc.2", + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-connection": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-hmr": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-locale": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-modules": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-store": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-agent-preset": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-approval": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-attachment": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-brand-official": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-chat": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-commands": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-conversation": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-cordis": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-deliverables": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-directory-picker-browse": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-directory-picker-native": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-goal": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-input-trigger": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-jobs": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-layout": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-message-feedback": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-model-selection": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-permission-presets": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-plan": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-primitives": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-reference": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-renderer": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-schedule": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-settings": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-settings-general": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-settings-models": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-settings-plugin-inventory": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-settings-plugins": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-sidebar": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-skill": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-slots": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-subagent": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-theme": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-tool": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-trajectory": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-user-questions": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-workflow-run": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-workspace": "0.1.7-rc.2", + "@deepseek-ai/dsh-cmdline": "0.1.7-rc.2", + "@deepseek-ai/dsh-command-compact": "0.1.7-rc.2", + "@deepseek-ai/dsh-command-feedback": "0.1.7-rc.2", + "@deepseek-ai/dsh-command-goal": "0.1.7-rc.2", + "@deepseek-ai/dsh-commands": "0.1.7-rc.2", + "@deepseek-ai/dsh-compaction": "0.1.7-rc.2", + "@deepseek-ai/dsh-compaction-basic": "0.1.7-rc.2", + "@deepseek-ai/dsh-compaction-tool-result-pruner": "0.1.7-rc.2", + "@deepseek-ai/dsh-cordis-client-runner": "0.1.7-rc.2", + "@deepseek-ai/dsh-cordis-host-runner": "0.1.7-rc.2", + "@deepseek-ai/dsh-credentials": "0.1.7-rc.2", + "@deepseek-ai/dsh-credentials-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-deepseek-account": "0.1.7-rc.2", + "@deepseek-ai/dsh-deepseek-llm-api-extensions": "0.1.7-rc.2", + "@deepseek-ai/dsh-deque": "0.1.7-rc.2", + "@deepseek-ai/dsh-file-reference": "0.1.7-rc.2", + "@deepseek-ai/dsh-file-reference-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-fs": "0.1.7-rc.2", + "@deepseek-ai/dsh-fs-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-fs-observation-policy": "0.1.7-rc.2", + "@deepseek-ai/dsh-fs-sandbox": "0.1.7-rc.2", + "@deepseek-ai/dsh-goal": "0.1.7-rc.2", + "@deepseek-ai/dsh-goal-round-driver": "0.1.7-rc.2", + "@deepseek-ai/dsh-headless": "0.1.7-rc.2", + "@deepseek-ai/dsh-hmr": "0.1.7-rc.2", + "@deepseek-ai/dsh-home-paths": "0.1.7-rc.2", + "@deepseek-ai/dsh-hook-protocol": "0.1.7-rc.2", + "@deepseek-ai/dsh-hooks-claude-code": "0.1.7-rc.2", + "@deepseek-ai/dsh-hooks-codex": "0.1.7-rc.2", + "@deepseek-ai/dsh-host-directory-picker": "0.1.7-rc.2", + "@deepseek-ai/dsh-host-directory-picker-auto": "0.1.7-rc.2", + "@deepseek-ai/dsh-host-directory-picker-browse": "0.1.7-rc.2", + "@deepseek-ai/dsh-host-directory-picker-native": "0.1.7-rc.2", + "@deepseek-ai/dsh-host-frontend-static": "0.1.7-rc.2", + "@deepseek-ai/dsh-host-plugin-inventory": "0.1.7-rc.2", + "@deepseek-ai/dsh-host-webserver": "0.1.7-rc.2", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", + "@deepseek-ai/dsh-jobs": "0.1.7-rc.2", + "@deepseek-ai/dsh-jobs-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-launch-environment": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm-deepseek": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm-pi-ai": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm-retry": "0.1.7-rc.2", + "@deepseek-ai/dsh-mcp-client": "0.1.7-rc.2", + "@deepseek-ai/dsh-mcp-resources": "0.1.7-rc.2", + "@deepseek-ai/dsh-message-feedback": "0.1.7-rc.2", + "@deepseek-ai/dsh-native-command": "0.1.7-rc.2", + "@deepseek-ai/dsh-output-retention": "0.1.7-rc.2", + "@deepseek-ai/dsh-permission-presets": "0.1.7-rc.2", + "@deepseek-ai/dsh-persona": "0.1.7-rc.2", + "@deepseek-ai/dsh-plan-mode": "0.1.7-rc.2", + "@deepseek-ai/dsh-plugin-manager": "0.1.7-rc.2", + "@deepseek-ai/dsh-plugin-package-inventory-deepseek": "0.1.7-rc.2", + "@deepseek-ai/dsh-ptc-runtime": "0.1.7-rc.2", + "@deepseek-ai/dsh-pwsh-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-pwsh-sandbox": "0.1.7-rc.2", + "@deepseek-ai/dsh-repeat-tool-reminder": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox-policy": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox-windows-acl": "0.1.7-rc.2", + "@deepseek-ai/dsh-schedule": "0.1.7-rc.2", + "@deepseek-ai/dsh-scope": "0.1.7-rc.2", + "@deepseek-ai/dsh-sdk-app": "0.1.7-rc.2", + "@deepseek-ai/dsh-sdk-jsonrpc-server": "0.1.7-rc.2", + "@deepseek-ai/dsh-sdk-minimal": "0.1.7-rc.2", + "@deepseek-ai/dsh-sdk-protocol": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-checkpoint-policy": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-log-deepseek": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-log-export": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-persistence": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-persistence-jsonl": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection-cache": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-query": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-query-sqlite": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-reference": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-stats": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-telemetry": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-telemetry-otel": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-title": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-title-first-prompt-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-title-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-turn-outline": "0.1.7-rc.2", + "@deepseek-ai/dsh-settings": "0.1.7-rc.2", + "@deepseek-ai/dsh-shell": "0.1.7-rc.2", + "@deepseek-ai/dsh-shell-env": "0.1.7-rc.2", + "@deepseek-ai/dsh-skill": "0.1.7-rc.2", + "@deepseek-ai/dsh-skill-badge": "0.1.7-rc.2", + "@deepseek-ai/dsh-skill-filesystem": "0.1.7-rc.2", + "@deepseek-ai/dsh-spill": "0.1.7-rc.2", + "@deepseek-ai/dsh-spill-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-spill-policy": "0.1.7-rc.2", + "@deepseek-ai/dsh-storage": "0.1.7-rc.2", + "@deepseek-ai/dsh-storage-domain": "0.1.7-rc.2", + "@deepseek-ai/dsh-storage-json": "0.1.7-rc.2", + "@deepseek-ai/dsh-subagent": "0.1.7-rc.2", + "@deepseek-ai/dsh-subagent-fork-in-process": "0.1.7-rc.2", + "@deepseek-ai/dsh-subagent-in-process-driver": "0.1.7-rc.2", + "@deepseek-ai/dsh-subagent-spawn-in-process": "0.1.7-rc.2", + "@deepseek-ai/dsh-subprocess": "0.1.7-rc.2", + "@deepseek-ai/dsh-subprocess-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2", + "@deepseek-ai/dsh-terminal": "0.1.7-rc.2", + "@deepseek-ai/dsh-terminal-bash": "0.1.7-rc.2", + "@deepseek-ai/dsh-time-context": "0.1.7-rc.2", + "@deepseek-ai/dsh-timeout": "0.1.7-rc.2", + "@deepseek-ai/dsh-tmux-context": "0.1.7-rc.2", + "@deepseek-ai/dsh-token-meter": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-ask-user": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-bash": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-bash-persistent": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-call-timeout-policy": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-cordis": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-fs": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-fs-search": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-goal": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-jobs": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-pwsh": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-pwsh-persistent": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-ralph": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-skill": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-str-replace-editor": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-subagent": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-subagent-control": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-todo": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-web": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-workflow": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-loader": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-registry": "0.1.7-rc.2", + "@deepseek-ai/dsh-user-approval": "0.1.7-rc.2", + "@deepseek-ai/dsh-user-questions": "0.1.7-rc.2", + "@deepseek-ai/dsh-util-crypto": "0.1.7-rc.2", + "@deepseek-ai/dsh-util-time": "0.1.7-rc.2", + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2", + "@deepseek-ai/dsh-util-workspace-path": "0.1.7-rc.2", + "@deepseek-ai/dsh-web": "0.1.7-rc.2", + "@deepseek-ai/dsh-web-app": "0.1.7-rc.2", + "@deepseek-ai/dsh-web-fetch-http": "0.1.7-rc.2", + "@deepseek-ai/dsh-web-frontend": "0.1.7-rc.2", + "@deepseek-ai/dsh-web-search-deepseek": "0.1.7-rc.2", + "@deepseek-ai/dsh-webhook": "0.1.7-rc.2", + "@deepseek-ai/dsh-webhook-github": "0.1.7-rc.2", + "@deepseek-ai/dsh-win32-process": "0.1.7-rc.2", + "@deepseek-ai/dsh-workflow": "0.1.7-rc.2", + "@deepseek-ai/dsh-workflow-ptc": "0.1.7-rc.2", + "@deepseek-ai/dsh-workspace": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "3.18.4", "dsh-desktop-client-ui": "file:packages/dsh-desktop-client-ui", "dsh-desktop-hmr-fallback": "file:packages/dsh-desktop-hmr-fallback", "dsh-desktop-log-bridge": "file:packages/dsh-desktop-log-bridge", "dsh-desktop-market-installer": "file:packages/dsh-desktop-market-installer", "dsh-desktop-preset-transfer": "file:packages/dsh-desktop-preset-transfer", "dsh-image-generation": "file:packages/dsh-image-generation", - "dsh-ppt": "file:packages/ppt-bundles/dsh-ppt-0.1.1-rc.2-desktop-20260906.tgz", - "dsh-ppt-composer": "file:packages/ppt-bundles/dsh-ppt-composer-0.1.1-rc.2-desktop-20260906.tgz", + "dsh-ppt": "file:packages/ppt-runtime/core", + "dsh-ppt-composer": "file:packages/ppt-runtime/adapter", "electron-updater": "^6.8.9", "node": "24.9.0", "pnpm": "10.34.5", @@ -252,10 +254,11 @@ "ws": "^8.21.3" }, "devDependencies": { + "@types/js-yaml": "4.0.9", "@types/node": "24.10.1", "@types/qrcode": "^1.5.6", "@types/ws": "^8.18.1", - "electron": "43.4.0", + "electron": "43.0.0", "electron-builder": "26.15.3", "electron-vite": "5.0.0", "patch-package": "^8.0.1", @@ -434,17 +437,17 @@ } }, "node_modules/@aws-sdk/core": { - "version": "3.978.0", - "resolved": "https://registry.npmmirror.com/@aws-sdk/core/-/core-3.978.0.tgz", - "integrity": "sha512-2yX9LUmxPklVjSGTb8dfnWRJSiFQ3TeH2nn7G1mdKHTfnabzF0+gfrS8rYfLWmZrQ8A3mEcxMJjRc51dL5KWaA==", + "version": "3.978.1", + "resolved": "https://registry.npmmirror.com/@aws-sdk/core/-/core-3.978.1.tgz", + "integrity": "sha512-LbY9aGsEiznDWmUc30Nwv3aIX/+dbwTx8KfS0yOC3NPYMO+O91e6jkT1azf34FwjOndq8/Q+RcVVZz5xnerwdg==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.974.5", - "@aws-sdk/xml-builder": "^3.972.40", + "@aws-sdk/types": "^3.974.6", + "@aws-sdk/xml-builder": "^3.972.41", "@aws/lambda-invoke-store": "^0.3.0", - "@smithy/core": "^3.33.3", - "@smithy/signature-v4": "^5.6.12", - "@smithy/types": "^4.17.2", + "@smithy/core": "^3.35.0", + "@smithy/signature-v4": "^5.7.3", + "@smithy/types": "^4.19.0", "bowser": "^2.11.0", "tslib": "^2.6.2" }, @@ -453,15 +456,15 @@ } }, "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.972.71", - "resolved": "https://registry.npmmirror.com/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.71.tgz", - "integrity": "sha512-JN+JHruYZw3GUZB8YGAlDk4wTDPOEAEEdEzj5nS0xodWR4smzHsN7PnK2j6IeOsDIj2aqua5DSbhXl9Gtf90FQ==", + "version": "3.972.72", + "resolved": "https://registry.npmmirror.com/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.72.tgz", + "integrity": "sha512-xTKO/FWJPozTIXbozVnVGoNBhaGba8TBcx+KyUjRVeOlXE+dUc7GTR1cLvu0uTdIdmemzaFbqqCshXeZA1fZew==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.978.0", - "@aws-sdk/types": "^3.974.5", - "@smithy/core": "^3.33.3", - "@smithy/types": "^4.17.2", + "@aws-sdk/core": "^3.978.1", + "@aws-sdk/types": "^3.974.6", + "@smithy/core": "^3.35.0", + "@smithy/types": "^4.19.0", "tslib": "^2.6.2" }, "engines": { @@ -469,17 +472,17 @@ } }, "node_modules/@aws-sdk/credential-provider-http": { - "version": "3.972.73", - "resolved": "https://registry.npmmirror.com/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.73.tgz", - "integrity": "sha512-uyYYnJOnlis8uQzaYGPd7N1JoioCoNpXgnkXYixsWJXHXgXyYi8WXJSDfofxJeWfQIGWLe2Nwyq60Uc7MZdVOg==", + "version": "3.972.74", + "resolved": "https://registry.npmmirror.com/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.74.tgz", + "integrity": "sha512-u91E/hT8f4d1xy0Jl7VG4nVKJ3lxbrZkoBTeSVoJdWBiSEUMwMS/9+e0H/aJVQV//Lt5wuzP+E69v4aRSsNTmw==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.978.0", - "@aws-sdk/types": "^3.974.5", - "@smithy/core": "^3.33.3", - "@smithy/fetch-http-handler": "^5.7.2", - "@smithy/node-http-handler": "^4.11.3", - "@smithy/types": "^4.17.2", + "@aws-sdk/core": "^3.978.1", + "@aws-sdk/types": "^3.974.6", + "@smithy/core": "^3.35.0", + "@smithy/fetch-http-handler": "^5.8.0", + "@smithy/node-http-handler": "^4.12.1", + "@smithy/types": "^4.19.0", "tslib": "^2.6.2" }, "engines": { @@ -501,23 +504,23 @@ } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.973.16", - "resolved": "https://registry.npmmirror.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.973.16.tgz", - "integrity": "sha512-i++ly+0Uxa+u3ebSSyr0S/3CFhFJDxCXT3+Zj+mW2bXenEx5bKGCdTIKFu39SgXBNhWDjex/8cXUx9MUTMCrTw==", + "version": "3.973.17", + "resolved": "https://registry.npmmirror.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.973.17.tgz", + "integrity": "sha512-ged4KXdBkvIC81bLvNHHuQKdKak/VXhQTR1NWYTTqW0474nlmsxy9O/vlgTIohDDWH3xpBdtVMZRyjb+DnocDA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.978.0", - "@aws-sdk/credential-provider-env": "^3.972.71", - "@aws-sdk/credential-provider-http": "^3.972.73", - "@aws-sdk/credential-provider-login": "^3.972.78", - "@aws-sdk/credential-provider-process": "^3.972.71", - "@aws-sdk/credential-provider-sso": "^3.973.15", - "@aws-sdk/credential-provider-web-identity": "^3.972.77", - "@aws-sdk/nested-clients": "^3.997.45", - "@aws-sdk/types": "^3.974.5", - "@smithy/core": "^3.33.3", - "@smithy/credential-provider-imds": "^4.4.16", - "@smithy/types": "^4.17.2", + "@aws-sdk/core": "^3.978.1", + "@aws-sdk/credential-provider-env": "^3.972.72", + "@aws-sdk/credential-provider-http": "^3.972.74", + "@aws-sdk/credential-provider-login": "^3.972.79", + "@aws-sdk/credential-provider-process": "^3.972.72", + "@aws-sdk/credential-provider-sso": "^3.973.16", + "@aws-sdk/credential-provider-web-identity": "^3.972.78", + "@aws-sdk/nested-clients": "^3.997.46", + "@aws-sdk/types": "^3.974.6", + "@smithy/core": "^3.35.0", + "@smithy/credential-provider-imds": "^4.5.2", + "@smithy/types": "^4.19.0", "tslib": "^2.6.2" }, "engines": { @@ -525,16 +528,16 @@ } }, "node_modules/@aws-sdk/credential-provider-login": { - "version": "3.972.78", - "resolved": "https://registry.npmmirror.com/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.78.tgz", - "integrity": "sha512-eUtswnXu0+Ii9ieRK+0L7aPFV3Z/dnW2VntJzjBP9xs8s+8p5nBNuymIXtXwZ+5r5+XJP3e32nMkuZ/r0HozEA==", + "version": "3.972.79", + "resolved": "https://registry.npmmirror.com/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.79.tgz", + "integrity": "sha512-L+Z85anONJd8MaiuraO4wRxATCdEejBZ3K3eymzWI5JPXa9sOS9CkIm72PBKqXKX+Z9p9NGMX5AIMXm0LEflgw==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.978.0", - "@aws-sdk/nested-clients": "^3.997.45", - "@aws-sdk/types": "^3.974.5", - "@smithy/core": "^3.33.3", - "@smithy/types": "^4.17.2", + "@aws-sdk/core": "^3.978.1", + "@aws-sdk/nested-clients": "^3.997.46", + "@aws-sdk/types": "^3.974.6", + "@smithy/core": "^3.35.0", + "@smithy/types": "^4.19.0", "tslib": "^2.6.2" }, "engines": { @@ -542,21 +545,21 @@ } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.972.83", - "resolved": "https://registry.npmmirror.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.83.tgz", - "integrity": "sha512-jdso7ejzfRnatxMUZK4S/U6KbaDPCvfIV4XL+IQAPFDBt5rj5Fq595euqlK8Le4lNCMFR9oUpt+1l0aMgaayOQ==", + "version": "3.972.84", + "resolved": "https://registry.npmmirror.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.84.tgz", + "integrity": "sha512-oHt854odINVwzwsh+c5x69j0ajm4DbqqqVJ+O1ECsCIZeMDAbzFpXItaqP7UZstJj/ATdTk/KFSH0LaNAgV+kA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/credential-provider-env": "^3.972.71", - "@aws-sdk/credential-provider-http": "^3.972.73", - "@aws-sdk/credential-provider-ini": "^3.973.16", - "@aws-sdk/credential-provider-process": "^3.972.71", - "@aws-sdk/credential-provider-sso": "^3.973.15", - "@aws-sdk/credential-provider-web-identity": "^3.972.77", - "@aws-sdk/types": "^3.974.5", - "@smithy/core": "^3.33.3", - "@smithy/credential-provider-imds": "^4.4.16", - "@smithy/types": "^4.17.2", + "@aws-sdk/credential-provider-env": "^3.972.72", + "@aws-sdk/credential-provider-http": "^3.972.74", + "@aws-sdk/credential-provider-ini": "^3.973.17", + "@aws-sdk/credential-provider-process": "^3.972.72", + "@aws-sdk/credential-provider-sso": "^3.973.16", + "@aws-sdk/credential-provider-web-identity": "^3.972.78", + "@aws-sdk/types": "^3.974.6", + "@smithy/core": "^3.35.0", + "@smithy/credential-provider-imds": "^4.5.2", + "@smithy/types": "^4.19.0", "tslib": "^2.6.2" }, "engines": { @@ -564,15 +567,15 @@ } }, "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.972.71", - "resolved": "https://registry.npmmirror.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.71.tgz", - "integrity": "sha512-lYmXJa4gvq4xN1lrT5NiP5vIYYKcGWAdj8y+8o6dlcateB5eF3Dn8DtmjjHKfMBrTPAMr2pebIiX/UOj8c1/UA==", + "version": "3.972.72", + "resolved": "https://registry.npmmirror.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.72.tgz", + "integrity": "sha512-rLIp2xbMjX/k9/od7APpqq1ZgXXnV0pOL1Th3ZsL8Wu0TRtBsDTVS8iPqcfRFcHakFxPvR04OSTv2ka2qOb/2A==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.978.0", - "@aws-sdk/types": "^3.974.5", - "@smithy/core": "^3.33.3", - "@smithy/types": "^4.17.2", + "@aws-sdk/core": "^3.978.1", + "@aws-sdk/types": "^3.974.6", + "@smithy/core": "^3.35.0", + "@smithy/types": "^4.19.0", "tslib": "^2.6.2" }, "engines": { @@ -580,17 +583,17 @@ } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.973.15", - "resolved": "https://registry.npmmirror.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.973.15.tgz", - "integrity": "sha512-6Jhcf4v0pSFdjk1EW2kvzuEBKD+UZ2uNcHUIglKKLndD20YhvkL2kdmDOV5/j4mYuWWwe/a1FQ1aomU86/Cg5Q==", + "version": "3.973.16", + "resolved": "https://registry.npmmirror.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.973.16.tgz", + "integrity": "sha512-IGihaJfFZYacJJr/odqILCoK7W/mvrZ7cuK7ECn3sAu4vLC6u0V8bS7mCGbdugJ8Aum2tnvqmx0F2MRFp2rn9g==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.978.0", - "@aws-sdk/nested-clients": "^3.997.45", - "@aws-sdk/token-providers": "3.1129.0", - "@aws-sdk/types": "^3.974.5", - "@smithy/core": "^3.33.3", - "@smithy/types": "^4.17.2", + "@aws-sdk/core": "^3.978.1", + "@aws-sdk/nested-clients": "^3.997.46", + "@aws-sdk/token-providers": "3.1138.0", + "@aws-sdk/types": "^3.974.6", + "@smithy/core": "^3.35.0", + "@smithy/types": "^4.19.0", "tslib": "^2.6.2" }, "engines": { @@ -598,16 +601,16 @@ } }, "node_modules/@aws-sdk/credential-provider-sso/node_modules/@aws-sdk/token-providers": { - "version": "3.1129.0", - "resolved": "https://registry.npmmirror.com/@aws-sdk/token-providers/-/token-providers-3.1129.0.tgz", - "integrity": "sha512-Sbl3rpzQdsG4ZK2zh0JWUYyZPKKorJlVOddA2T0DVbKJFrsW8J6wgnslxxUH04+WaBMr4A1HzJZvZX0xUvkniA==", + "version": "3.1138.0", + "resolved": "https://registry.npmmirror.com/@aws-sdk/token-providers/-/token-providers-3.1138.0.tgz", + "integrity": "sha512-GpyAr0DD63YOEmYFM6Df+gJuIgC92MMTiBK4FTKfxii5MJ9ge20epR7LyroulscYlG89J+ZB2ivFDPjvfQhzdw==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.978.0", - "@aws-sdk/nested-clients": "^3.997.45", - "@aws-sdk/types": "^3.974.5", - "@smithy/core": "^3.33.3", - "@smithy/types": "^4.17.2", + "@aws-sdk/core": "^3.978.1", + "@aws-sdk/nested-clients": "^3.997.46", + "@aws-sdk/types": "^3.974.6", + "@smithy/core": "^3.35.0", + "@smithy/types": "^4.19.0", "tslib": "^2.6.2" }, "engines": { @@ -615,16 +618,16 @@ } }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.972.77", - "resolved": "https://registry.npmmirror.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.77.tgz", - "integrity": "sha512-uylIQSUWpfLuH2LovxEEfwzJGM/SabLOfLMg6YXu/E8jJEKUdpdILCVCQCdFvHyu/7dLJOHPMfrSwduxO56NkQ==", + "version": "3.972.78", + "resolved": "https://registry.npmmirror.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.78.tgz", + "integrity": "sha512-/y9WvNtlcPBGLR0qc1a+9J/xtYZfVczvLUOuXaVWylzttH7ewsxwHtjmiJSolNrVSDorIxHGHMU61CbonRkmwA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.978.0", - "@aws-sdk/nested-clients": "^3.997.45", - "@aws-sdk/types": "^3.974.5", - "@smithy/core": "^3.33.3", - "@smithy/types": "^4.17.2", + "@aws-sdk/core": "^3.978.1", + "@aws-sdk/nested-clients": "^3.997.46", + "@aws-sdk/types": "^3.974.6", + "@smithy/core": "^3.35.0", + "@smithy/types": "^4.19.0", "tslib": "^2.6.2" }, "engines": { @@ -632,14 +635,14 @@ } }, "node_modules/@aws-sdk/eventstream-handler-node": { - "version": "3.972.34", - "resolved": "https://registry.npmmirror.com/@aws-sdk/eventstream-handler-node/-/eventstream-handler-node-3.972.34.tgz", - "integrity": "sha512-cTeVzpu1xEAkryTZBYhGwnQ6gOGyp8ZYZvmn0Sg/nI/ABmy/CRHHxPDJDUi9PxwxUtGGaatvfRUB3FCgT/rSWw==", + "version": "3.972.35", + "resolved": "https://registry.npmmirror.com/@aws-sdk/eventstream-handler-node/-/eventstream-handler-node-3.972.35.tgz", + "integrity": "sha512-a8xilRoRaalvSPZdfrs0VY3/BPc0uYhXW56Z/k6nmZ5Vk430LHeowf9APIPq8utM3tMJSNGSSuJMlB9YrPsN+A==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.974.5", - "@smithy/core": "^3.33.3", - "@smithy/types": "^4.17.2", + "@aws-sdk/types": "^3.974.6", + "@smithy/core": "^3.35.0", + "@smithy/types": "^4.19.0", "tslib": "^2.6.2" }, "engines": { @@ -647,14 +650,14 @@ } }, "node_modules/@aws-sdk/middleware-eventstream": { - "version": "3.972.29", - "resolved": "https://registry.npmmirror.com/@aws-sdk/middleware-eventstream/-/middleware-eventstream-3.972.29.tgz", - "integrity": "sha512-dlRzHCgyB8W6hLuDC5pcT5q+ziPt00n4QGgGBE17ucLVU4zMa6lsbuUdQ2Pm75Z5VA8GF+R/+SgrRcaTdIzSIQ==", + "version": "3.972.30", + "resolved": "https://registry.npmmirror.com/@aws-sdk/middleware-eventstream/-/middleware-eventstream-3.972.30.tgz", + "integrity": "sha512-B6gvZlcnRBNWraKgyEjKsbhv+VjtbyHmpU7hmtTHzXpDSxHPpCJnYLpglEOOsF+SFne20DbZC5IVC1aNr2Pb4A==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.974.5", - "@smithy/core": "^3.33.3", - "@smithy/types": "^4.17.2", + "@aws-sdk/types": "^3.974.6", + "@smithy/core": "^3.35.0", + "@smithy/types": "^4.19.0", "tslib": "^2.6.2" }, "engines": { @@ -662,17 +665,17 @@ } }, "node_modules/@aws-sdk/middleware-websocket": { - "version": "3.972.53", - "resolved": "https://registry.npmmirror.com/@aws-sdk/middleware-websocket/-/middleware-websocket-3.972.53.tgz", - "integrity": "sha512-bIrDaMENQmYRBHntOiOheqkiw5+fhKW4Lqb+mS1uqF0VwvdWI22fW2HFgWrng66CmYd+4k8ePlpj38sEfTuMLQ==", + "version": "3.972.54", + "resolved": "https://registry.npmmirror.com/@aws-sdk/middleware-websocket/-/middleware-websocket-3.972.54.tgz", + "integrity": "sha512-bhESdru8u8KosziH8jcVta/NM/dNreeRz2+2aU86si5bfBYOiJ6IiqD+9U4URUcU5WJO3Yw+jO3GLDIHlscXMQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.978.0", - "@aws-sdk/types": "^3.974.5", - "@smithy/core": "^3.33.3", - "@smithy/fetch-http-handler": "^5.7.2", - "@smithy/signature-v4": "^5.6.12", - "@smithy/types": "^4.17.2", + "@aws-sdk/core": "^3.978.1", + "@aws-sdk/types": "^3.974.6", + "@smithy/core": "^3.35.0", + "@smithy/fetch-http-handler": "^5.8.0", + "@smithy/signature-v4": "^5.7.3", + "@smithy/types": "^4.19.0", "tslib": "^2.6.2" }, "engines": { @@ -680,18 +683,18 @@ } }, "node_modules/@aws-sdk/nested-clients": { - "version": "3.997.45", - "resolved": "https://registry.npmmirror.com/@aws-sdk/nested-clients/-/nested-clients-3.997.45.tgz", - "integrity": "sha512-mooq9Q+jLa18VoM7HouczmslZU60iiB0aKc/Ztnq/luIL1ud0z4DnYprLR/ZO1gp331S9tJctM1HZr7u6YKBXQ==", + "version": "3.997.46", + "resolved": "https://registry.npmmirror.com/@aws-sdk/nested-clients/-/nested-clients-3.997.46.tgz", + "integrity": "sha512-oRxtBcka/JGHGs9l9p9IVajGoTP8vTPmoAzdHGy4Qcy9P5vPnDf6nhIeM/COQNY9k/OahImTRaLkHftoXvfcmQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.978.0", - "@aws-sdk/signature-v4-multi-region": "^3.996.46", - "@aws-sdk/types": "^3.974.5", - "@smithy/core": "^3.33.3", - "@smithy/fetch-http-handler": "^5.7.2", - "@smithy/node-http-handler": "^4.11.3", - "@smithy/types": "^4.17.2", + "@aws-sdk/core": "^3.978.1", + "@aws-sdk/signature-v4-multi-region": "^3.996.47", + "@aws-sdk/types": "^3.974.6", + "@smithy/core": "^3.35.0", + "@smithy/fetch-http-handler": "^5.8.0", + "@smithy/node-http-handler": "^4.12.1", + "@smithy/types": "^4.19.0", "tslib": "^2.6.2" }, "engines": { @@ -713,14 +716,14 @@ } }, "node_modules/@aws-sdk/signature-v4-multi-region": { - "version": "3.996.46", - "resolved": "https://registry.npmmirror.com/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.46.tgz", - "integrity": "sha512-L+2xZTye/2T96f3lwCws0Zw6GG2JHZW9e8FpVgGBeeExSKyeoZ6CWRpBml/7DNiK/O26jrgPM9F+Ay8VkgzUWQ==", + "version": "3.996.47", + "resolved": "https://registry.npmmirror.com/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.47.tgz", + "integrity": "sha512-Zk08macMvQTHzQJCLJVkOlviVoqwYMrpXv4lmLN7b7sAbiMoOK7Go0NYdR5UeF+MW8LIbRmwrNy9u/5VvX1U5g==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.974.5", - "@smithy/signature-v4": "^5.6.12", - "@smithy/types": "^4.17.2", + "@aws-sdk/types": "^3.974.6", + "@smithy/signature-v4": "^5.7.3", + "@smithy/types": "^4.19.0", "tslib": "^2.6.2" }, "engines": { @@ -745,12 +748,12 @@ } }, "node_modules/@aws-sdk/types": { - "version": "3.974.5", - "resolved": "https://registry.npmmirror.com/@aws-sdk/types/-/types-3.974.5.tgz", - "integrity": "sha512-LkwLL2BLbC6wNNm4JaH9mbEqBMdOZCct6VAYqhdN4U1xrWM+fUJQEfbHwQgDypapOWTRtlk25akb5afM0P8CIQ==", + "version": "3.974.6", + "resolved": "https://registry.npmmirror.com/@aws-sdk/types/-/types-3.974.6.tgz", + "integrity": "sha512-v/clNZzZnDxGyvpHMOGpJKVXFAExJzUNAAjaWGdcx8QAcXLGwTaOkw33p5SHAi0YAioK32xB3hWwOekRVfmfKg==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.17.2", + "@smithy/types": "^4.19.0", "tslib": "^2.6.2" }, "engines": { @@ -770,12 +773,12 @@ } }, "node_modules/@aws-sdk/xml-builder": { - "version": "3.972.40", - "resolved": "https://registry.npmmirror.com/@aws-sdk/xml-builder/-/xml-builder-3.972.40.tgz", - "integrity": "sha512-wlFmCIGUlwF4zx/kncw+bmxTQh1HeSJq4mYV/V5cZUSJadDP3kXvGW8Rn21cimj/7y9ju+47oYWXi97vF7czaA==", + "version": "3.972.41", + "resolved": "https://registry.npmmirror.com/@aws-sdk/xml-builder/-/xml-builder-3.972.41.tgz", + "integrity": "sha512-ctjVSyCMegrWfXlx6VqzSBFI6UqmQ5ZlnfMhdLIiWmhoH8UAQxSCP5N3OpG7X3k4LnS7ou74C4mt20+bfTW2aQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.17.2", + "@smithy/types": "^4.19.0", "tslib": "^2.6.2" }, "engines": { @@ -1281,20 +1284,20 @@ } }, "node_modules/@deepseek-ai/cordis": { - "version": "4.0.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/cordis/-/cordis-4.0.2.tgz", - "integrity": "sha512-asOnXP1TzFSFQlHb1iegDZp0z/8WD1c7YNrwJR/Tx2bzNuMXfcekE/I67Iv6SQXeLB4csxqCngzQKANP7gdw0g==", + "version": "4.0.4", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/cordis/-/cordis-4.0.4.tgz", + "integrity": "sha512-obgyxqWAmFn3Re8kvsuUnyW+ihrz6eJCnJO4fh1cQzDtmPYz/zzVeUkH9R94I0OwSVOocK67Kgakm04j/oQXzg==", "license": "MIT", "dependencies": { - "@deepseek-ai/cosmokit": "^1.8.3", + "@deepseek-ai/cosmokit": "~1.8.5", "@standard-schema/spec": "^1.1.0" }, "bin": { "cordis": "bin.js" }, "peerDependencies": { - "@deepseek-ai/cordis-plugin-include": "^1.0.7", - "@deepseek-ai/cordis-plugin-loader": "^1.0.3" + "@deepseek-ai/cordis-plugin-include": "~1.0.9", + "@deepseek-ai/cordis-plugin-loader": "~1.0.5" }, "peerDependenciesMeta": { "@deepseek-ai/cordis-plugin-include": { @@ -1306,57 +1309,58 @@ } }, "node_modules/@deepseek-ai/cordis-plugin-group": { - "version": "1.0.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/cordis-plugin-group/-/cordis-plugin-group-1.0.2.tgz", - "integrity": "sha512-OeGiPD793Mhma9+rGIox95neuufwOFTqQ5jooFgrMK/Mn7Fp7Hkv/d7VKMXZz40iks2fZCbiFE6p9WjTVTQRdg==", + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/cordis-plugin-group/-/cordis-plugin-group-1.0.4.tgz", + "integrity": "sha512-/7tuY5pMQetHava4v6QUeOa4CwZA+mleNvbIoj+iqEmzkYUtlXbLqhzJIcbnDa/Hxgr1jaCwROrI77nuLyeCFg==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/cordis-plugin-loader": "^1.0.3" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/cordis-plugin-loader": "~1.0.5" } }, "node_modules/@deepseek-ai/cordis-plugin-hmr": { - "version": "1.0.17", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/cordis-plugin-hmr/-/cordis-plugin-hmr-1.0.17.tgz", - "integrity": "sha512-o1BooaJpwd+C80Tn5+B48MGqrfNZydlfRVQjmCrrULA4nCmlMqBKjDF2FmcZoNP+L2uX9m/6DdGKVtFpQRQVUQ==", + "version": "1.0.19", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/cordis-plugin-hmr/-/cordis-plugin-hmr-1.0.19.tgz", + "integrity": "sha512-ZDleX6NlbtACFJI8mANn/TQj9OuACeIY9ctzfSGlfhAwOWL88EXowCh5lXvHZl5v6ClL7pPhG1fsZaihLs7pqQ==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.29.0", - "@deepseek-ai/cosmokit": "^1.8.3", - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/cosmokit": "~1.8.5", + "@deepseek-ai/schemastery": "~3.18.4", "chokidar": "^4.0.3", "picomatch": "^4.0.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/cordis-plugin-timer": "^1.1.4" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/cordis-plugin-timer": "~1.1.6" } }, "node_modules/@deepseek-ai/cordis-plugin-include": { - "version": "1.0.7", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/cordis-plugin-include/-/cordis-plugin-include-1.0.7.tgz", - "integrity": "sha512-bZ4S1YuOmwOeE97HnslQ6ggVQbaWz4GejJ8OcY4P/DIyc1Qhu/3Szt1XSw6c/pd37kRkxxJXGwt4cmCxWSBBuw==", + "version": "1.0.9", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/cordis-plugin-include/-/cordis-plugin-include-1.0.9.tgz", + "integrity": "sha512-Xmekm7u5Kpeym6nABL4T1/Mg6aQYFZxsipB0WycmCctvX1DqAv8nCFwRmg2XMx/f7EbZgNEbXQwJfabcMu8zxQ==", "license": "MIT", "dependencies": { - "@deepseek-ai/cosmokit": "^1.8.3", + "@deepseek-ai/cosmokit": "~1.8.5", "js-yaml": "^4.1.0" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/cordis-plugin-loader": "^1.0.3" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/cordis-plugin-loader": "~1.0.5" } }, "node_modules/@deepseek-ai/cordis-plugin-loader": { - "version": "1.0.3", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/cordis-plugin-loader/-/cordis-plugin-loader-1.0.3.tgz", - "integrity": "sha512-YNcHiH7TRFrgnRbQU7qdS1spABUFFHg04QpB9DdboPEjgKLTFfeEAvr6Y7qll3/nGgqywDQdk1tYshqKO0p1WQ==", + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/cordis-plugin-loader/-/cordis-plugin-loader-1.0.5.tgz", + "integrity": "sha512-200huL2ttWcjyeYllvPYn+qMR7I89qy8MhZasbHltPzB/KMrSfsyoCYKdCGc5KqPGj5iJugcmibQzjINMO9I+Q==", "license": "MIT", "dependencies": { - "@deepseek-ai/cosmokit": "^1.8.3" + "@deepseek-ai/cosmokit": "~1.8.5", + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "node-addon-require-builtin": "^0.1.4" + "@deepseek-ai/cordis": "~4.0.4", + "node-addon-require-builtin": "^0.1.6" }, "peerDependenciesMeta": { "node-addon-require-builtin": { @@ -1365,126 +1369,135 @@ } }, "node_modules/@deepseek-ai/cordis-plugin-timer": { - "version": "1.1.4", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/cordis-plugin-timer/-/cordis-plugin-timer-1.1.4.tgz", - "integrity": "sha512-GhxOiU+TF2BbNBKlV2N24zvfv2Kh7RxkFW1hjML6s+DOb+y2zomzbeC5zHIIjsc/rpRwbKpDNucPGSwkH0ChXw==", + "version": "1.1.6", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/cordis-plugin-timer/-/cordis-plugin-timer-1.1.6.tgz", + "integrity": "sha512-/nZC7G637LIDF8G+lhF4OSXl1uFRuNAZqv1x11CDGLSjUpmIayePfzABEGTDEKAY+IBivg2DIXBr/sjjaLZxqg==", "license": "MIT", "dependencies": { - "@deepseek-ai/cosmokit": "^1.8.3" + "@deepseek-ai/cosmokit": "~1.8.5" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/cosmokit": { - "version": "1.8.3", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/cosmokit/-/cosmokit-1.8.3.tgz", - "integrity": "sha512-qBo+ronVM6Eu2WNVJXi8JcMiqZ19T9BRIpV+5qJUFPXjGH/Z0QKcQMC/IZJ7L394YTOtJgcovbk9qP0w2GsBXQ==", + "version": "1.8.5", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/cosmokit/-/cosmokit-1.8.5.tgz", + "integrity": "sha512-LXsrlem9z8dq4sLflj2yuCuYX7KqhdzF5hZly3eZyuTo8d6oDSOXuEgC5DbQWKW+lksm6zmOutQLsP/ma6wR6A==", "license": "MIT" }, "node_modules/@deepseek-ai/dsh": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh/-/dsh-0.1.5-rc.2.tgz", - "integrity": "sha512-8Xc8hCQHcIWRmTCVU/xZdp6/qMsWMeAd2ObChKDEsfhUPJFXx6H0lgeb1DxUMD86HZrrVN+1bCvn1ppjZ/fOxw==", - "license": "MIT", - "dependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/cordis-plugin-hmr": "^1.0.17", - "@deepseek-ai/cordis-plugin-include": "^1.0.7", - "@deepseek-ai/cordis-plugin-loader": "^1.0.3", - "@deepseek-ai/cordis-plugin-timer": "^1.1.4", - "@deepseek-ai/dsh-acp-app": "^0.1.5-rc.2", - "@deepseek-ai/dsh-agent-instructions": "^0.1.5-rc.2", - "@deepseek-ai/dsh-agent-tool-presentation": "^0.1.5-rc.2", - "@deepseek-ai/dsh-app-boot": "^0.1.5-rc.2", - "@deepseek-ai/dsh-base": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-agent-preset": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-cordis": "^0.1.5-rc.2", - "@deepseek-ai/dsh-cmdline": "^0.1.5-rc.2", - "@deepseek-ai/dsh-command-compact": "^0.1.5-rc.2", - "@deepseek-ai/dsh-command-goal": "^0.1.5-rc.2", - "@deepseek-ai/dsh-compaction-basic": "^0.1.5-rc.2", - "@deepseek-ai/dsh-compaction-tool-result-pruner": "^0.1.5-rc.2", - "@deepseek-ai/dsh-cordis-client-runner": "^0.1.5-rc.2", - "@deepseek-ai/dsh-fs-local": "^0.1.5-rc.2", - "@deepseek-ai/dsh-goal": "^0.1.5-rc.2", - "@deepseek-ai/dsh-goal-round-driver": "^0.1.5-rc.2", - "@deepseek-ai/dsh-headless": "^0.1.5-rc.2", - "@deepseek-ai/dsh-home-paths": "^0.1.5-rc.2", - "@deepseek-ai/dsh-hooks-claude-code": "^0.1.5-rc.2", - "@deepseek-ai/dsh-hooks-codex": "^0.1.5-rc.2", - "@deepseek-ai/dsh-http-proxy": "^0.1.5-rc.2", - "@deepseek-ai/dsh-jobs-local": "^0.1.5-rc.2", - "@deepseek-ai/dsh-launch-environment": "^0.1.5-rc.2", - "@deepseek-ai/dsh-mcp-client": "^0.1.5-rc.2", - "@deepseek-ai/dsh-persona": "^0.1.5-rc.2", - "@deepseek-ai/dsh-plan-mode": "^0.1.5-rc.2", - "@deepseek-ai/dsh-pwsh-local": "^0.1.5-rc.2", - "@deepseek-ai/dsh-pwsh-sandbox": "^0.1.5-rc.2", - "@deepseek-ai/dsh-schedule": "^0.1.5-rc.2", - "@deepseek-ai/dsh-sdk-app": "^0.1.5-rc.2", - "@deepseek-ai/dsh-sdk-minimal": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-reference": "^0.1.5-rc.2", - "@deepseek-ai/dsh-skill": "^0.1.5-rc.2", - "@deepseek-ai/dsh-skill-filesystem": "^0.1.5-rc.2", - "@deepseek-ai/dsh-terminal": "^0.1.5-rc.2", - "@deepseek-ai/dsh-terminal-bash": "^0.1.5-rc.2", - "@deepseek-ai/dsh-time-context": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tmux-context": "^0.1.5-rc.2", - "@deepseek-ai/dsh-token-meter": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-ask-user": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-bash": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-bash-persistent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-cordis": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-fs": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-fs-search": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-goal": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-jobs": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-present": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-pwsh": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-pwsh-persistent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-ralph": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-skill": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-str-replace-editor": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-subagent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-subagent-control": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-todo": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-web": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-workflow": "^0.1.5-rc.2", - "@deepseek-ai/dsh-web-app": "^0.1.5-rc.2", - "@deepseek-ai/dsh-webhook": "^0.1.5-rc.2", - "@deepseek-ai/dsh-webhook-github": "^0.1.5-rc.2", - "@deepseek-ai/dsh-workflow-worker-thread": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh/-/dsh-0.1.7-rc.2.tgz", + "integrity": "sha512-SQFhriLvza8GnFApnC5/32AgpcyKxrWnYXhvwDOLJdgWpkCX2EexyR9c8kCkMITJXnFLEN3Qb2CEh0W36vkLyw==", + "license": "MIT", + "dependencies": { + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/cordis-plugin-include": "~1.0.9", + "@deepseek-ai/cordis-plugin-loader": "~1.0.5", + "@deepseek-ai/cordis-plugin-timer": "~1.1.6", + "@deepseek-ai/dsh-acp-app": "0.1.7-rc.2", + "@deepseek-ai/dsh-agent-instructions": "0.1.7-rc.2", + "@deepseek-ai/dsh-agent-preset": "0.1.7-rc.2", + "@deepseek-ai/dsh-agent-tool-presentation": "0.1.7-rc.2", + "@deepseek-ai/dsh-app-boot": "0.1.7-rc.2", + "@deepseek-ai/dsh-atomic-write": "0.1.7-rc.2", + "@deepseek-ai/dsh-base": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-agent-preset": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-cordis": "0.1.7-rc.2", + "@deepseek-ai/dsh-cmdline": "0.1.7-rc.2", + "@deepseek-ai/dsh-command-compact": "0.1.7-rc.2", + "@deepseek-ai/dsh-command-goal": "0.1.7-rc.2", + "@deepseek-ai/dsh-compaction-basic": "0.1.7-rc.2", + "@deepseek-ai/dsh-compaction-tool-result-pruner": "0.1.7-rc.2", + "@deepseek-ai/dsh-cordis-client-runner": "0.1.7-rc.2", + "@deepseek-ai/dsh-experimental-agent-team-profile": "0.1.7-rc.2", + "@deepseek-ai/dsh-experimental-auto-review": "0.1.7-rc.2", + "@deepseek-ai/dsh-experimental-voice-input-bundle": "0.1.7-rc.2", + "@deepseek-ai/dsh-fs-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-goal": "0.1.7-rc.2", + "@deepseek-ai/dsh-goal-round-driver": "0.1.7-rc.2", + "@deepseek-ai/dsh-headless": "0.1.7-rc.2", + "@deepseek-ai/dsh-hmr": "0.1.7-rc.2", + "@deepseek-ai/dsh-home-paths": "0.1.7-rc.2", + "@deepseek-ai/dsh-hooks-claude-code": "0.1.7-rc.2", + "@deepseek-ai/dsh-hooks-codex": "0.1.7-rc.2", + "@deepseek-ai/dsh-http-proxy": "0.1.7-rc.2", + "@deepseek-ai/dsh-jobs-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-launch-environment": "0.1.7-rc.2", + "@deepseek-ai/dsh-mcp-client": "0.1.7-rc.2", + "@deepseek-ai/dsh-mcp-resources": "0.1.7-rc.2", + "@deepseek-ai/dsh-persona": "0.1.7-rc.2", + "@deepseek-ai/dsh-plan-mode": "0.1.7-rc.2", + "@deepseek-ai/dsh-plugin-manager": "0.1.7-rc.2", + "@deepseek-ai/dsh-pwsh-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-pwsh-sandbox": "0.1.7-rc.2", + "@deepseek-ai/dsh-schedule": "0.1.7-rc.2", + "@deepseek-ai/dsh-sdk-app": "0.1.7-rc.2", + "@deepseek-ai/dsh-sdk-minimal": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-reference": "0.1.7-rc.2", + "@deepseek-ai/dsh-skill": "0.1.7-rc.2", + "@deepseek-ai/dsh-skill-filesystem": "0.1.7-rc.2", + "@deepseek-ai/dsh-skill-office": "0.1.7-rc.2", + "@deepseek-ai/dsh-terminal": "0.1.7-rc.2", + "@deepseek-ai/dsh-terminal-bash": "0.1.7-rc.2", + "@deepseek-ai/dsh-time-context": "0.1.7-rc.2", + "@deepseek-ai/dsh-tmux-context": "0.1.7-rc.2", + "@deepseek-ai/dsh-token-meter": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-ask-user": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-bash": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-bash-persistent": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-cordis": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-fs": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-fs-search": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-goal": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-jobs": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-present": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-pwsh": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-pwsh-persistent": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-ralph": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-skill": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-str-replace-editor": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-subagent": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-subagent-control": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-todo": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-web": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-workflow": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-workspace-dependencies": "0.1.7-rc.2", + "@deepseek-ai/dsh-web-app": "0.1.7-rc.2", + "@deepseek-ai/dsh-webhook": "0.1.7-rc.2", + "@deepseek-ai/dsh-webhook-github": "0.1.7-rc.2", + "@deepseek-ai/dsh-workflow-ptc": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4", "commander": "^15.0.0", "js-yaml": "^4.2.0", - "node-addon-require-builtin": "^0.1.4" + "node-addon-require-builtin": "^0.1.6" }, "bin": { "dsh": "lib/bin.js" } }, "node_modules/@deepseek-ai/dsh-acp": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-acp/-/dsh-acp-0.1.5-rc.2.tgz", - "integrity": "sha512-0lmDF2qyy136fTFN7jowBVBRVQ00YASi1umgnFSVpHQ0rDKh32tpl7xWaoOTlh6mmKh04A93qt92QhPLIzkcSg==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-acp/-/dsh-acp-0.1.7-rc.2.tgz", + "integrity": "sha512-pYA/KH4ks/q/S82PEwdpGQ+Bdmyx8G4aspd2N0BVM9KAfupEszrgZyfNX7L0+hvy4sYTjP5LyUr6/2QmQVhXiw==", "license": "MIT", "dependencies": { "@agentclientprotocol/sdk": "1.4.0", - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-attachment": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-mcp-client": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-persistence": "^0.1.5-rc.2", - "@deepseek-ai/dsh-token-meter": "^0.1.5-rc.2", - "@deepseek-ai/dsh-user-approval": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-attachment": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-mcp-client": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-persistence": "0.1.7-rc.2", + "@deepseek-ai/dsh-token-meter": "0.1.7-rc.2", + "@deepseek-ai/dsh-user-approval": "0.1.7-rc.2" }, "peerDependenciesMeta": { "@deepseek-ai/dsh-token-meter": { @@ -1493,1114 +1506,1279 @@ } }, "node_modules/@deepseek-ai/dsh-acp-app": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-acp-app/-/dsh-acp-app-0.1.5-rc.2.tgz", - "integrity": "sha512-90SRAmF6haHARulVllv6uh88n+zubdrgDfxvTzmi9+p3ktt7o6oZ6+yKO7I7e04bSskT+Pz/1J0FLugi9l39dw==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-acp-app/-/dsh-acp-app-0.1.7-rc.2.tgz", + "integrity": "sha512-7Km0Fchvx/PoL3/By4M6ykKkrmmIgelXq/1l0624Ixt3JgTtFNSgko3dpL/32Hv/a5Fn/wEsuujBHzmcBBcZ7Q==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-acp": "^0.1.5-rc.2", - "@deepseek-ai/dsh-cmdline": "^0.1.5-rc.2", + "@deepseek-ai/dsh-acp": "0.1.7-rc.2", + "@deepseek-ai/dsh-cmdline": "0.1.7-rc.2", "commander": "^15.0.0" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-agent": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-agent/-/dsh-agent-0.1.5-rc.2.tgz", - "integrity": "sha512-SlUL1riZmVLwMUR3jo9CP/R1cxov9dHkCJDh6JQW3fSZJVCIdPygBRlAweCUDvHxAEmPpFHxE/U3NmSUbX+vQQ==", - "license": "MIT", - "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-scope": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.2", - "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2", - "@deepseek-ai/dsh-typert-protocol": "^0.1.5-rc.2", - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2" + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-agent/-/dsh-agent-0.1.7-rc.2.tgz", + "integrity": "sha512-9U/zHZvZqRR5S2FD9fjjAuoMh+WfDan+bE/cLBLSLpqftjZ0FhIlEBK99yonUkNkGemyHiH/lL3jCKYw35ahJA==", + "license": "MIT", + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-scope": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2", + "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2", + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2", + "@deepseek-ai/dsh-workspace": "0.1.7-rc.2" + }, + "peerDependenciesMeta": { + "@deepseek-ai/dsh-workspace": { + "optional": true + } } }, "node_modules/@deepseek-ai/dsh-agent-default-model": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-agent-default-model/-/dsh-agent-default-model-0.1.5-rc.2.tgz", - "integrity": "sha512-B2e3e1iT+iSE2Pf7bnrKmsbOPiD+ZXplVhL98K35y0IGX7yUdqATsyKVPEHjgfCGooNKjGlSBB42kUk3s7Iv/A==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-agent-default-model/-/dsh-agent-default-model-0.1.7-rc.2.tgz", + "integrity": "sha512-Ilvgi3Dsogn6X3GTd6ke8MrWV1jBTLIVep7xji7own/TVdhtu7pP7Zs0mFYDTuuP1INGGrcnS/dHEPayNyRm+A==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/dsh-config-editor": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-settings": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-agent-instructions": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-agent-instructions/-/dsh-agent-instructions-0.1.5-rc.2.tgz", - "integrity": "sha512-735wmeuRDr/fB9vCnBALEHE7z04Lmhx6WX3KJLE3DjWMGbmTudU5i0iYSYst2mZh7C/igV5wXBveIGKLPIrL+A==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-agent-instructions/-/dsh-agent-instructions-0.1.7-rc.2.tgz", + "integrity": "sha512-q6V4d4XIEmLiHgNg/z3jYV5K0f1qHvpuq1fatEHaLjTCZPXy4p3O7ge+PKQSoB8I/Gxy8HGXthZ4oJPXro5Klw==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-fs": "^0.1.5-rc.2", - "@deepseek-ai/dsh-home-paths": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-fs": "0.1.7-rc.2", + "@deepseek-ai/dsh-home-paths": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-agent-loop": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-agent-loop/-/dsh-agent-loop-0.1.5-rc.2.tgz", - "integrity": "sha512-24wvqVlqFmdqJ2Bhcku/vKeNy+qWSmeEeN7lvcUB+WkhcF0/Ra2G3WwcVmnahJA4+w0AKdW3W7v+YYcO/jKJpg==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-agent-loop/-/dsh-agent-loop-0.1.7-rc.2.tgz", + "integrity": "sha512-X+fegYY7yITQ5kAIayFrylMY9Vg6zHFLnP83rJVZ89juF9EBRm8soGAJHvyjat+mdk5a1WViWYdIPM0t9g/glA==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4", "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-scope": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-persistence": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.2", - "@deepseek-ai/dsh-settings": "^0.1.5-rc.2", - "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-scope": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-persistence": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2", + "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2" } }, - "node_modules/@deepseek-ai/dsh-agent-presets": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-agent-presets/-/dsh-agent-presets-0.1.5-rc.2.tgz", - "integrity": "sha512-h0j7IfuHPYh/oJR7SDxh6pzSgUeaHwaaAIg5X0RNL6Z2oQrq0oUmjtArCVVw7nkgt48DjdBwx4EwJ9IdNrHxug==", + "node_modules/@deepseek-ai/dsh-agent-preset": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-agent-preset/-/dsh-agent-preset-0.1.7-rc.2.tgz", + "integrity": "sha512-T3HKwuNf9S+FxZilyHw34bXilX+a8GqXfaoL8QqShghUyNYLLuAI9lUDdNpADf7huuTvBA1TO+ulUmVXAN/QhA==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2", - "js-yaml": "^4.1.0", + "@deepseek-ai/schemastery": "~3.18.4" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/cordis-plugin-loader": "~1.0.5", + "@deepseek-ai/dsh-agent-preset-registry": "0.1.7-rc.2" + } + }, + "node_modules/@deepseek-ai/dsh-agent-preset-registry": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-agent-preset-registry/-/dsh-agent-preset-registry-0.1.7-rc.2.tgz", + "integrity": "sha512-qpB4H6uWuPx/Jqm2sLbNJPrWOtVhk3FLK+5PdqLBHqEDfCmpBZCBm6lUdSWsmnKmPnHiBeHSVZO9AZl9qJJlHQ==", + "license": "MIT", + "dependencies": { + "@deepseek-ai/dsh-app-boot": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4", + "js-yaml": "^4.2.0", "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/cordis-plugin-include": "^1.0.7", - "@deepseek-ai/cordis-plugin-loader": "^1.0.3", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-atomic-write": "^0.1.5-rc.2", - "@deepseek-ai/dsh-home-paths": "^0.1.5-rc.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2", - "@deepseek-ai/dsh-scope": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.2", - "@deepseek-ai/dsh-settings": "^0.1.5-rc.2", - "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2", - "@deepseek-ai/dsh-typert-protocol": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/cordis-plugin-include": "~1.0.9", + "@deepseek-ai/cordis-plugin-loader": "~1.0.5", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", + "@deepseek-ai/dsh-scope": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2", + "@deepseek-ai/dsh-settings": "0.1.7-rc.2", + "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-agent-tool-presentation": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-agent-tool-presentation/-/dsh-agent-tool-presentation-0.1.5-rc.2.tgz", - "integrity": "sha512-XA4Z3zm73SQw4VmWdo2Z/HdRr3YCWL7SseO70wIuYbcjfar1BdMC0S6/KXTgvshn1lCuCqf7I47B1e5oxoHKhg==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-agent-tool-presentation/-/dsh-agent-tool-presentation-0.1.7-rc.2.tgz", + "integrity": "sha512-xKfJLdNhh91bO52qCAl9qCGJkEbuZdHg7sWGfY5dB+RsXxOGXxZwXQUOnPgbKS54f3Ydks93SmphzYKJHBSdxA==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-anonymous-user-id": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-anonymous-user-id/-/dsh-anonymous-user-id-0.1.5-rc.2.tgz", - "integrity": "sha512-YIpZoi8mY/d+BjnPOryDYR7lkwr2uWh5KJWjIqm2sGN+C6imc66lDiSi5wy91JMRzefFWJf26fCiYXAF7ErQAw==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-anonymous-user-id/-/dsh-anonymous-user-id-0.1.7-rc.2.tgz", + "integrity": "sha512-krpu7wg/5+5MjeYml8TfViV6nXm3hzPvTBIa70tjcUTyLJidXmchwDr65HqYE2Mv+tRlrkGKZr6a+iOpdscEug==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/dsh-home-paths": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-home-paths": "0.1.7-rc.2" + } + }, + "node_modules/@deepseek-ai/dsh-api-account-controller": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-api-account-controller/-/dsh-api-account-controller-0.1.7-rc.2.tgz", + "integrity": "sha512-0dQuFlmeoOcxvVg9UooR5ZztCZlLBq7V/APVTErIgZaMTbwV5myJSxlftc92Y3gxAM6lCpyjYa2eAq1mT09oww==", + "license": "MIT", + "dependencies": { + "zod": "^4.4.3" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-deepseek-account": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-api-gateway": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-api-gateway/-/dsh-api-gateway-0.1.5-rc.2.tgz", - "integrity": "sha512-jYDsxVyRnRI++f+hXqBJemOk6ASTvly1sO8ZRuoI77RR22r0nfTFiifxevbmUcavl6j9fgB/LL3X7BpXMy5QQg==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-api-gateway/-/dsh-api-gateway-0.1.7-rc.2.tgz", + "integrity": "sha512-CnM2kk7UQc/7MSEgNUG6V1CeWYoG7cS1b/IF7tpYEQihuswXGaBVPBsQSMZMAiU8uMyUFTBKm4POSJ/J6QiT2Q==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-deque": "^0.1.5-rc.2", - "@deepseek-ai/dsh-timeout": "^0.1.5-rc.2", - "@deepseek-ai/dsh-typert-protocol": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/dsh-deque": "0.1.7-rc.2", + "@deepseek-ai/dsh-timeout": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4", "ws": "^8.21.0" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-client-connection": "0.1.7-rc.2" + } + }, + "node_modules/@deepseek-ai/dsh-api-job-controller": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-api-job-controller/-/dsh-api-job-controller-0.1.7-rc.2.tgz", + "integrity": "sha512-yO3bQ3fQ5G/SG3Mm/3kQHIB7YaXjSRufIvOtBWV321SN1NOrCuhncIWBzE7UmsnaqxhGGzNQ5lIUILtIxy1aGQ==", + "license": "MIT", + "dependencies": { + "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4", + "zod": "^4.4.3" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-api-remotes": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-api-remotes/-/dsh-api-remotes-0.1.5-rc.2.tgz", - "integrity": "sha512-O8t/aJiHatgzlQIgXx6xdmpy+iAXJ/Zab1xMHIx7Noo6mzSYUIxwfJkoYgPv9G0Yfx06FPoRTUtLiZ8IADqUOA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-api-remotes/-/dsh-api-remotes-0.1.7-rc.2.tgz", + "integrity": "sha512-MYPFy7wb9wJE3CkeFum2aEHDaDTy8YIkRSJWIpkpsYTKSEFr2IZTU6TH8dFQf8eF58WAHr0YUCA0t7p/uQJPow==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-deque": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2" + "@deepseek-ai/dsh-deque": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-scope": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-scope": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-api-session-controller": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-api-session-controller/-/dsh-api-session-controller-0.1.5-rc.2.tgz", - "integrity": "sha512-rwOxS6piZ9EuLgE/pbq4cUlRCGv98IKgdFnK5v8WNwZYKug3rUpvYODDU9vE42ydmClgjFd/KIAaEDFPatcDpA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-api-session-controller/-/dsh-api-session-controller-0.1.7-rc.2.tgz", + "integrity": "sha512-PB6Sk3h9g0ZGeIxUNcnZJIdWQxvhV4dh9g7KOd+Wu2YyqnA7TqweU9JRKitrDb4hYB1TFTDImGmdcAhiiMhbEw==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/dsh-deque": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-deque": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4", "mime-types": "^3.0.2", "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-agent-default-model": "^0.1.5-rc.2", - "@deepseek-ai/dsh-agent-presets": "^0.1.5-rc.2", - "@deepseek-ai/dsh-api-gateway": "^0.1.5-rc.2", - "@deepseek-ai/dsh-attachment": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-connection": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-file-upload": "^0.1.5-rc.2", - "@deepseek-ai/dsh-commands": "^0.1.5-rc.2", - "@deepseek-ai/dsh-file-reference": "^0.1.5-rc.2", - "@deepseek-ai/dsh-fs": "^0.1.5-rc.2", - "@deepseek-ai/dsh-jobs": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-native-command": "^0.1.5-rc.2", - "@deepseek-ai/dsh-scope": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-persistence": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection-cache": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-query": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-title": "^0.1.5-rc.2", - "@deepseek-ai/dsh-skill": "^0.1.5-rc.2", - "@deepseek-ai/dsh-subagent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-typert-protocol": "^0.1.5-rc.2", - "@deepseek-ai/dsh-typert-registry": "^0.1.5-rc.2", - "@deepseek-ai/dsh-util-time": "^0.1.5-rc.2", - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2", - "@deepseek-ai/dsh-util-workspace-path": "^0.1.5-rc.2", - "@deepseek-ai/dsh-workspace": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-agent-default-model": "0.1.7-rc.2", + "@deepseek-ai/dsh-agent-preset-registry": "0.1.7-rc.2", + "@deepseek-ai/dsh-api-gateway": "0.1.7-rc.2", + "@deepseek-ai/dsh-attachment": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-connection": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-file-upload": "0.1.7-rc.2", + "@deepseek-ai/dsh-commands": "0.1.7-rc.2", + "@deepseek-ai/dsh-credentials": "0.1.7-rc.2", + "@deepseek-ai/dsh-file-reference": "0.1.7-rc.2", + "@deepseek-ai/dsh-fs": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-native-command": "0.1.7-rc.2", + "@deepseek-ai/dsh-scope": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-persistence": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection-cache": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-query": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-title": "0.1.7-rc.2", + "@deepseek-ai/dsh-settings": "0.1.7-rc.2", + "@deepseek-ai/dsh-skill": "0.1.7-rc.2", + "@deepseek-ai/dsh-subagent": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-registry": "0.1.7-rc.2", + "@deepseek-ai/dsh-util-time": "0.1.7-rc.2", + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2", + "@deepseek-ai/dsh-util-workspace-path": "0.1.7-rc.2", + "@deepseek-ai/dsh-workspace": "0.1.7-rc.2" }, "peerDependenciesMeta": { - "@deepseek-ai/dsh-jobs": { - "optional": true - }, "@deepseek-ai/dsh-session-persistence": { "optional": true }, "@deepseek-ai/dsh-session-projection-cache": { "optional": true + }, + "@deepseek-ai/dsh-settings": { + "optional": true } } }, "node_modules/@deepseek-ai/dsh-api-settings-controller": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-api-settings-controller/-/dsh-api-settings-controller-0.1.5-rc.2.tgz", - "integrity": "sha512-HcnffXfBLi8Xaq3i8DZDDMZHkekW3RjRvA1XqnG/1SLR2w9OEt5P3oY2VzO0UuhyBlYCjS61BwGxDa5zWLCPlw==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-api-settings-controller/-/dsh-api-settings-controller-0.1.7-rc.2.tgz", + "integrity": "sha512-6CWdSCOSjNx07WTlat3Oq2UIMlT/tqtMC9CHqIbLFEmumQcoFFIyr34IFEMyWxN8Lwf0yL5s5wJ6KcF9UOLb5Q==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/schemastery": "~3.18.4", "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent-presets": "^0.1.5-rc.2", - "@deepseek-ai/dsh-credentials": "^0.1.5-rc.2", - "@deepseek-ai/dsh-native-command": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-settings": "^0.1.5-rc.2", - "@deepseek-ai/dsh-typert-protocol": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent-preset-registry": "0.1.7-rc.2", + "@deepseek-ai/dsh-credentials": "0.1.7-rc.2", + "@deepseek-ai/dsh-native-command": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-settings": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2" + } + }, + "node_modules/@deepseek-ai/dsh-api-terminal-controller": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-api-terminal-controller/-/dsh-api-terminal-controller-0.1.7-rc.2.tgz", + "integrity": "sha512-SxsRrFEbi6uEmu3QHnus/pDPIUzlh40hwKonjomLZoZeceW9AjAo7G0kvU2xNQDX6RpieayOhYdSVyQjBRIQHQ==", + "license": "MIT", + "dependencies": { + "@deepseek-ai/dsh-deque": "0.1.7-rc.2", + "@deepseek-ai/dsh-lazy-require": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4", + "@xterm/addon-serialize": "^0.14.0", + "@xterm/headless": "^6.0.0", + "zod": "^4.4.3" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-subprocess": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-api-workspace-controller": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-api-workspace-controller/-/dsh-api-workspace-controller-0.1.5-rc.2.tgz", - "integrity": "sha512-95USICv+Ds+BS4Bjf27gVneXc/ZuhlYvTsdfjx/S+MMSutjgV2eZDKkQOxVn8u8KMZw3FG0X5Era47qa3kg01Q==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-api-workspace-controller/-/dsh-api-workspace-controller-0.1.7-rc.2.tgz", + "integrity": "sha512-BUeoGq1didny2GqiGsCDfQTp9QF+oeAzRCG3z6gjbkQ4AGzOWw5QoSS7eknI+BU5vUq0zrJoVPR1gOaKK/9fbg==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-deque": "^0.1.5-rc.2", + "@deepseek-ai/dsh-deque": "0.1.7-rc.2", + "@deepseek-ai/dsh-native-command": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4", "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-api-gateway": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-connection": "^0.1.5-rc.2", - "@deepseek-ai/dsh-host-directory-picker": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-storage-domain": "^0.1.5-rc.2", - "@deepseek-ai/dsh-typert-protocol": "^0.1.5-rc.2", - "@deepseek-ai/dsh-workspace": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-api-gateway": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-connection": "0.1.7-rc.2", + "@deepseek-ai/dsh-host-directory-picker": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-storage-domain": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2", + "@deepseek-ai/dsh-workspace": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-api-workspace-files": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-api-workspace-files/-/dsh-api-workspace-files-0.1.5-rc.2.tgz", - "integrity": "sha512-Kx4ksBWQhN2Sbj48TPwC9cM0cxltIKzjyzanYog0d1WRnzxtqPDHthi6fx1I6RYA+k6257/xLi/Vx/ThYJ1ppQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-api-workspace-files/-/dsh-api-workspace-files-0.1.7-rc.2.tgz", + "integrity": "sha512-ImRQDxH7s4imG+G3EgT3nNepUomobwriGZtf+V39hlimytIdFcV9lZjzMkx9sQgz/V+3ExovAcvr7TEnu8EA6A==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-deque": "^0.1.5-rc.2", - "@deepseek-ai/dsh-typert-protocol": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/dsh-deque": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4", "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-app-boot": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-app-boot/-/dsh-app-boot-0.1.5-rc.2.tgz", - "integrity": "sha512-beM+ULhjr2mGoyrWta3F6HOQ9OD+i5tKG8BU0RtgVGmXDjA57cVEAiEkkgPLMTxbbzU+xsFP61I5SApna4Cz5A==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-app-boot/-/dsh-app-boot-0.1.7-rc.2.tgz", + "integrity": "sha512-d0QWMMXxT6kICO9QRrXTqJRKP6bWNes7SVGJK6OOEzX6Ua9mzCx1KghPIf7tjW/ZmX0b8n1FoySr4IHElBkrOg==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-atomic-write": "^0.1.5-rc.2", - "@deepseek-ai/dsh-package-manifest": "^0.1.5-rc.2", + "@deepseek-ai/dsh-atomic-write": "0.1.7-rc.2", + "@deepseek-ai/dsh-package-manifest": "0.1.7-rc.2", + "@eslint-community/regexpp": "^4.12.2", + "ajv": "^8.20.0", "js-yaml": "^4.2.0", - "resolve.exports": "^2.0.3" + "node-addon-require-builtin": "^0.1.6", + "resolve.exports": "^2.0.3", + "semver": "^7.8.5" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/cordis-plugin-group": "^1.0.2", - "@deepseek-ai/cordis-plugin-hmr": "^1.0.17", - "@deepseek-ai/cordis-plugin-include": "^1.0.7", - "@deepseek-ai/cordis-plugin-loader": "^1.0.3", - "@deepseek-ai/dsh-home-paths": "^0.1.5-rc.2", - "@deepseek-ai/dsh-launch-environment": "^0.1.5-rc.2", - "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2" - }, - "peerDependenciesMeta": { - "@deepseek-ai/cordis-plugin-hmr": { - "optional": true - } + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/cordis-plugin-group": "~1.0.4", + "@deepseek-ai/cordis-plugin-include": "~1.0.9", + "@deepseek-ai/cordis-plugin-loader": "~1.0.5", + "@deepseek-ai/dsh-home-paths": "0.1.7-rc.2", + "@deepseek-ai/dsh-launch-environment": "0.1.7-rc.2", + "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-atomic-write": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-atomic-write/-/dsh-atomic-write-0.1.5-rc.2.tgz", - "integrity": "sha512-9bCOLkug83IGuoEBPHUxgfJ/IxsHg/UigGi8Oj0agibcGVq2WdL/fbU8KA3KU5H49KDOxq2/AA3XUI3RiAEtYA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-atomic-write/-/dsh-atomic-write-0.1.7-rc.2.tgz", + "integrity": "sha512-gdUVkVv5DXBgnEDB1Dh/lL+HV/8mKR3AGUqNjLhQJSEqE9MIYyiHC+3zwzaWjeWhiTdLXd5rkA4HVCiS3KIcUg==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-attachment": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-attachment/-/dsh-attachment-0.1.5-rc.2.tgz", - "integrity": "sha512-S6b8/WjqzGw+dMDLRXnq+tbijDGkQh38yE+zpQytX2/w/mPR3VzGj5r6McS01WwD76vXR8WFoheSCLyCAro8WQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-attachment/-/dsh-attachment-0.1.7-rc.2.tgz", + "integrity": "sha512-g2SQ12Ki1l28T/H+fZKtSWDFF5Y1gavcKVBb2X4eOVX5uT5Jwumx+9Svelp1pHaknuAE1N2Yt9tMwj2quMkhDg==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-brand": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-attachment-local": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-attachment-local/-/dsh-attachment-local-0.1.5-rc.2.tgz", - "integrity": "sha512-UN9Zw6oBqHl/SQxFQCGUp8OcARQkPzZo4BGNkSQHqSsEo3d59Mv7H5mSFHmKl4NogSMwksjN3SF0FocN7xyF2A==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-attachment-local/-/dsh-attachment-local-0.1.7-rc.2.tgz", + "integrity": "sha512-Z50ktA9dTTR6DfjwoRQac7BBfkCvyE+FUcbj68u3R0d4lZpYQ9a9r4uYrSF57wrxZCVjYw48HbTYegxvyFh5mw==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/dsh-lazy-require": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4", "sharp": "^0.35.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-attachment": "^0.1.5-rc.2", - "@deepseek-ai/dsh-home-paths": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-attachment": "0.1.7-rc.2", + "@deepseek-ai/dsh-home-paths": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-authorization": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-authorization/-/dsh-authorization-0.1.5-rc.2.tgz", - "integrity": "sha512-1AtUlo72eYUwiiYL728E4oLgGfP3Kq1yiftiKv0hZ9AYzwZRMIGxv1659UymViNQ/m3BIEPlfiv+vWIDHkqMgQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-authorization/-/dsh-authorization-0.1.7-rc.2.tgz", + "integrity": "sha512-20hFGce+wzzWQ9qG2BfLeO26550HVVEe5ApELvmA6J7QUVsHkGWQsldKsYUzZ6AkgzgeUz4mwuOFYDf0r4timQ==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-credentials": "^0.1.5-rc.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-credentials": "0.1.7-rc.2", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-base": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-base/-/dsh-base-0.1.5-rc.2.tgz", - "integrity": "sha512-a4QqqqnN/qmWmIvFdCsXXlPerI3IhyIXh0UdLX1Wo1Q6P+blCIkQDG4LLLNS4RoWjhDURoKm2t51NBjotD6BVg==", - "license": "MIT", - "dependencies": { - "@deepseek-ai/cordis-plugin-hmr": "^1.0.17", - "@deepseek-ai/cordis-plugin-timer": "^1.1.4", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-agent-default-model": "^0.1.5-rc.2", - "@deepseek-ai/dsh-agent-instructions": "^0.1.5-rc.2", - "@deepseek-ai/dsh-agent-loop": "^0.1.5-rc.2", - "@deepseek-ai/dsh-api-gateway": "^0.1.5-rc.2", - "@deepseek-ai/dsh-attachment-local": "^0.1.5-rc.2", - "@deepseek-ai/dsh-bash-sandbox": "^0.1.5-rc.2", - "@deepseek-ai/dsh-command-compact": "^0.1.5-rc.2", - "@deepseek-ai/dsh-command-feedback": "^0.1.5-rc.2", - "@deepseek-ai/dsh-command-goal": "^0.1.5-rc.2", - "@deepseek-ai/dsh-commands": "^0.1.5-rc.2", - "@deepseek-ai/dsh-compaction-basic": "^0.1.5-rc.2", - "@deepseek-ai/dsh-compaction-tool-result-pruner": "^0.1.5-rc.2", - "@deepseek-ai/dsh-credentials-local": "^0.1.5-rc.2", - "@deepseek-ai/dsh-deepseek-llm-api-extensions": "^0.1.5-rc.2", - "@deepseek-ai/dsh-fs-local": "^0.1.5-rc.2", - "@deepseek-ai/dsh-fs-observation-policy": "^0.1.5-rc.2", - "@deepseek-ai/dsh-fs-sandbox": "^0.1.5-rc.2", - "@deepseek-ai/dsh-goal": "^0.1.5-rc.2", - "@deepseek-ai/dsh-goal-round-driver": "^0.1.5-rc.2", - "@deepseek-ai/dsh-jobs-local": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm-deepseek": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm-pi-ai": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm-retry": "^0.1.5-rc.2", - "@deepseek-ai/dsh-permission-presets": "^0.1.5-rc.2", - "@deepseek-ai/dsh-plan-mode": "^0.1.5-rc.2", - "@deepseek-ai/dsh-plugin-package-inventory-deepseek": "^0.1.5-rc.2", - "@deepseek-ai/dsh-pwsh-sandbox": "^0.1.5-rc.2", - "@deepseek-ai/dsh-repeat-tool-reminder": "^0.1.5-rc.2", - "@deepseek-ai/dsh-sandbox-local": "^0.1.5-rc.2", - "@deepseek-ai/dsh-sandbox-policy": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-checkpoint-policy": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-log-deepseek": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-persistence-jsonl": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection-cache": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-query-sqlite": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-telemetry-otel": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-title": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-title-first-prompt-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-settings-file": "^0.1.5-rc.2", - "@deepseek-ai/dsh-shell-env": "^0.1.5-rc.2", - "@deepseek-ai/dsh-skill": "^0.1.5-rc.2", - "@deepseek-ai/dsh-skill-badge": "^0.1.5-rc.2", - "@deepseek-ai/dsh-skill-filesystem": "^0.1.5-rc.2", - "@deepseek-ai/dsh-spill-local": "^0.1.5-rc.2", - "@deepseek-ai/dsh-spill-policy": "^0.1.5-rc.2", - "@deepseek-ai/dsh-storage": "^0.1.5-rc.2", - "@deepseek-ai/dsh-storage-domain": "^0.1.5-rc.2", - "@deepseek-ai/dsh-storage-json": "^0.1.5-rc.2", - "@deepseek-ai/dsh-subagent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-subagent-fork-in-process": "^0.1.5-rc.2", - "@deepseek-ai/dsh-subagent-spawn-in-process": "^0.1.5-rc.2", - "@deepseek-ai/dsh-subprocess-local": "^0.1.5-rc.2", - "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2", - "@deepseek-ai/dsh-token-meter": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-bash": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-call-timeout-policy": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-fs": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-fs-search": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-goal": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-jobs": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-present": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-pwsh": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-ralph": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-skill": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-subagent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-subagent-control": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-todo": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-web": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-workflow": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2", - "@deepseek-ai/dsh-typert-loader": "^0.1.5-rc.2", - "@deepseek-ai/dsh-typert-registry": "^0.1.5-rc.2", - "@deepseek-ai/dsh-user-approval": "^0.1.5-rc.2", - "@deepseek-ai/dsh-user-questions": "^0.1.5-rc.2", - "@deepseek-ai/dsh-web": "^0.1.5-rc.2", - "@deepseek-ai/dsh-web-fetch-http": "^0.1.5-rc.2", - "@deepseek-ai/dsh-web-search-deepseek": "^0.1.5-rc.2", - "@deepseek-ai/dsh-workflow-worker-thread": "^0.1.5-rc.2" - }, - "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-base/-/dsh-base-0.1.7-rc.2.tgz", + "integrity": "sha512-LYwclGWi0SEZh0ZjnlJT/kHaOV0JDuI1mCHFCOQthYlabPp90Ohba+7wdIRX1oqcQN6erFzsQrrV1WFf+NhRYg==", + "license": "MIT", + "dependencies": { + "@deepseek-ai/cordis-plugin-timer": "~1.1.6", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-agent-default-model": "0.1.7-rc.2", + "@deepseek-ai/dsh-agent-instructions": "0.1.7-rc.2", + "@deepseek-ai/dsh-agent-loop": "0.1.7-rc.2", + "@deepseek-ai/dsh-api-gateway": "0.1.7-rc.2", + "@deepseek-ai/dsh-attachment-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-authorization": "0.1.7-rc.2", + "@deepseek-ai/dsh-bash-sandbox": "0.1.7-rc.2", + "@deepseek-ai/dsh-command-compact": "0.1.7-rc.2", + "@deepseek-ai/dsh-command-feedback": "0.1.7-rc.2", + "@deepseek-ai/dsh-command-goal": "0.1.7-rc.2", + "@deepseek-ai/dsh-commands": "0.1.7-rc.2", + "@deepseek-ai/dsh-compaction-basic": "0.1.7-rc.2", + "@deepseek-ai/dsh-compaction-image-offload": "0.1.7-rc.2", + "@deepseek-ai/dsh-compaction-tool-result-pruner": "0.1.7-rc.2", + "@deepseek-ai/dsh-config-editor": "0.1.7-rc.2", + "@deepseek-ai/dsh-credentials-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-deepseek-account-platform": "0.1.7-rc.2", + "@deepseek-ai/dsh-deepseek-llm-api-extensions": "0.1.7-rc.2", + "@deepseek-ai/dsh-fs-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-fs-observation-policy": "0.1.7-rc.2", + "@deepseek-ai/dsh-fs-sandbox": "0.1.7-rc.2", + "@deepseek-ai/dsh-goal": "0.1.7-rc.2", + "@deepseek-ai/dsh-goal-round-driver": "0.1.7-rc.2", + "@deepseek-ai/dsh-hmr": "0.1.7-rc.2", + "@deepseek-ai/dsh-jobs-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm-deepseek-account": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm-deepseek-api-key": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm-pi-ai": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm-retry": "0.1.7-rc.2", + "@deepseek-ai/dsh-mcp-resources": "0.1.7-rc.2", + "@deepseek-ai/dsh-permission-presets": "0.1.7-rc.2", + "@deepseek-ai/dsh-plan-mode": "0.1.7-rc.2", + "@deepseek-ai/dsh-plugin-manager": "0.1.7-rc.2", + "@deepseek-ai/dsh-plugin-package-inventory-deepseek": "0.1.7-rc.2", + "@deepseek-ai/dsh-ptc-runtime-node": "0.1.7-rc.2", + "@deepseek-ai/dsh-pwsh-sandbox": "0.1.7-rc.2", + "@deepseek-ai/dsh-repeat-tool-reminder": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox-policy": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-checkpoint-policy": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-log-deepseek": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-persistence-jsonl": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection-cache": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-query-sqlite": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-telemetry-otel": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-title": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-title-first-prompt-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-settings": "0.1.7-rc.2", + "@deepseek-ai/dsh-shell-env": "0.1.7-rc.2", + "@deepseek-ai/dsh-skill": "0.1.7-rc.2", + "@deepseek-ai/dsh-skill-badge": "0.1.7-rc.2", + "@deepseek-ai/dsh-skill-filesystem": "0.1.7-rc.2", + "@deepseek-ai/dsh-spill-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-spill-policy": "0.1.7-rc.2", + "@deepseek-ai/dsh-storage": "0.1.7-rc.2", + "@deepseek-ai/dsh-storage-domain": "0.1.7-rc.2", + "@deepseek-ai/dsh-storage-json": "0.1.7-rc.2", + "@deepseek-ai/dsh-subagent": "0.1.7-rc.2", + "@deepseek-ai/dsh-subagent-fork-in-process": "0.1.7-rc.2", + "@deepseek-ai/dsh-subagent-spawn-in-process": "0.1.7-rc.2", + "@deepseek-ai/dsh-subprocess-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2", + "@deepseek-ai/dsh-token-meter": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-bash": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-call-timeout-policy": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-fs": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-fs-search": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-goal": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-jobs": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-present": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-pwsh": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-ralph": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-skill": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-subagent": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-subagent-control": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-todo": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-web": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-workflow": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-loader": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-registry": "0.1.7-rc.2", + "@deepseek-ai/dsh-user-approval": "0.1.7-rc.2", + "@deepseek-ai/dsh-user-questions": "0.1.7-rc.2", + "@deepseek-ai/dsh-web": "0.1.7-rc.2", + "@deepseek-ai/dsh-web-fetch-http": "0.1.7-rc.2", + "@deepseek-ai/dsh-web-search-deepseek": "0.1.7-rc.2", + "@deepseek-ai/dsh-workflow-ptc": "0.1.7-rc.2" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-bash-local": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-bash-local/-/dsh-bash-local-0.1.5-rc.2.tgz", - "integrity": "sha512-a/FTpYUKY0Sorn4GlY2HjuQh7+gjU8XQ2+HRDN0tuqMQyO1RIzJi62FjtZSZ6+qV4EJJ8o8h0+8URHsVrzro+Q==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-bash-local/-/dsh-bash-local-0.1.7-rc.2.tgz", + "integrity": "sha512-8InocMSTIzUGuKXnSp05pTBfeQmUdC+L5T1I+2iESzPtrNh/F9jLQeCPknWZ7ren/XwDki79J9EqYaLE1vNiUg==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-settings": "^0.1.5-rc.2", - "@deepseek-ai/dsh-shell": "^0.1.5-rc.2", - "@deepseek-ai/dsh-subprocess": "^0.1.5-rc.2", - "@deepseek-ai/dsh-timeout": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-shell": "0.1.7-rc.2", + "@deepseek-ai/dsh-subprocess": "0.1.7-rc.2", + "@deepseek-ai/dsh-timeout": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-bash-sandbox": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-bash-sandbox/-/dsh-bash-sandbox-0.1.5-rc.2.tgz", - "integrity": "sha512-y8vwK6jf4gPq8mG71zWure803NjfqJ66Nvzr1FTB8An+IF68hT2eU+hHJCByvP0u6FuiLPRptuX/im2CxcNo1g==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-bash-sandbox/-/dsh-bash-sandbox-0.1.7-rc.2.tgz", + "integrity": "sha512-M4laxtYLPkXlvbtMpLm4hTWKmBb1xJuNMma/eA+xYTNdjHtV/ZJPxiKMVe1crjBp/dKuMTJR42p8rizLM1vkNg==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-bash-local": "^0.1.5-rc.2", - "@deepseek-ai/dsh-sandbox": "^0.1.5-rc.2", - "@deepseek-ai/dsh-sandbox-policy": "^0.1.5-rc.2", - "@deepseek-ai/dsh-shell": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-bash-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox-policy": "0.1.7-rc.2", + "@deepseek-ai/dsh-shell": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-brand": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-brand/-/dsh-brand-0.1.5-rc.2.tgz", - "integrity": "sha512-/+3TzQRYT4M8NINZ9OrsL5VWNyQSXof8mFLx3txiosWA7Bt0H6UcxUdKGXVwj6gCXhsQ74mzEHm2ucsflG0mYA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-brand/-/dsh-brand-0.1.7-rc.2.tgz", + "integrity": "sha512-cvcvlNRuiFqZNNqyxdu7wcpiBjd9xa/0MpuhRvee43zBp9uED2p5JolZr5/2EKJf57gYx9k9bedb+Zbyiqnpkw==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-chunked-list": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-chunked-list/-/dsh-chunked-list-0.1.5-rc.2.tgz", - "integrity": "sha512-XPr311bleMyOh9SzhTMmc1mC6qx2Tty8315MNYYyzIOLAns0h27PReFa9axy8I0soBaE7gfp6eQI1ZriVkI68g==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-chunked-list/-/dsh-chunked-list-0.1.7-rc.2.tgz", + "integrity": "sha512-fMpkkFPG9I9/wlQygbyPAdGKMK/RnD1p7/czm2hbzyAZtr/kDz+RThOWtlV1VDZ23NWkps98qTwlhM3NJ3LkXg==", "license": "MIT", "dependencies": { "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-connection": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-connection/-/dsh-client-connection-0.1.5-rc.2.tgz", - "integrity": "sha512-W0GAZX01hAfrfjoZbtwEJ5ik3dG20Hy/0TFYJ6dnvwxtcacGYNIwi3f2oHpZgLcEw+PWwq1Y9IV1iKG+yDOytg==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-connection/-/dsh-client-connection-0.1.7-rc.2.tgz", + "integrity": "sha512-Wc2ANM5NO3Ri+p8wBoVnPxTYxz++zYSuEoVOhd498WMY779w0RCgWfRzHekPY5ftJX/G02qzWNHe0yBIoTpXXw==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-credentials": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/dsh-credentials": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4", "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-scope": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-client-file-upload": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-file-upload/-/dsh-client-file-upload-0.1.5-rc.2.tgz", - "integrity": "sha512-Y0v4pr1btn1fY8ox1cxIuxDhm2RKHrztfIDMhzj2Z1xRCdSdfbZYtkYvOdWS4uAbpZWQKs5gDMGgASvwTCJ+lg==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-file-upload/-/dsh-client-file-upload-0.1.7-rc.2.tgz", + "integrity": "sha512-jjXlNn0pANLGO+VzW1ABmtGgM/9z6rvg/Dj4y1LVliGQD5bQBw+xCp2faKjpe3C/LEu2lAv9FMjUjB9YrukzVw==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/dsh-typert-protocol": "^0.1.5-rc.2", + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2", "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-scope": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-scope": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-client-hmr": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-hmr/-/dsh-client-hmr-0.1.5-rc.2.tgz", - "integrity": "sha512-Ra1JziRbpV5CiIaYUT4FbBKko1m+PONCGJjmKM7PyHSAv00v53/xKREHVB1SNqu/QT9cGs688ID2KHuwFxbHSA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-hmr/-/dsh-client-hmr-0.1.7-rc.2.tgz", + "integrity": "sha512-5Qx01rqP8uq3l2hKW3bCNPzvNZ0KdAQHM/KDGSX24LCgYQRejV4BC7VOacMRCZFZAOLVU+RlFnPXIucF6v0C9g==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-locale": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-locale/-/dsh-client-locale-0.1.5-rc.2.tgz", - "integrity": "sha512-kv56ki/WQWagsHt94wJAPzsiKnxa8KlmM33bZGgl2SgF4atlQ3iRCdkwJ3fQARXF4Ocnfutivoj5fu5usks1Sw==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-locale/-/dsh-client-locale-0.1.7-rc.2.tgz", + "integrity": "sha512-zkRt/JrBvS7w1TPi/dOo0QCqjkcAApq7nNoeIL2lX0VlzwHD86Hrg/n/YJJlg1i0nvOEtZDibR9FGwa/X2wpvA==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-modules": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-modules/-/dsh-client-modules-0.1.5-rc.2.tgz", - "integrity": "sha512-034DxLlGvX4GgkqqFN2SGcQx8hKdicj5IrgENclBXXbyMDlpF9xADiWi5DxPms+iOBcL/5LLe84q/GCTWOrA2g==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-modules/-/dsh-client-modules-0.1.7-rc.2.tgz", + "integrity": "sha512-+ePHhpZr3H7bWbbQxiYq/B4oINmot11O2A+IeVMmkwMGClGi2ZumO5BWuIYZLlS1Aof9ANSez+uoX5BeVjqAdg==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-resources": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-resources/-/dsh-client-resources-0.1.5-rc.2.tgz", - "integrity": "sha512-fl0saN8LKcAZ/YUSqxBeAbzVj6ZSBWnWrKGFUqhuq5N0XHWu4CpswFIruKxkvgl7lwAsdTtbL3wMtsKIupSmNQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-resources/-/dsh-client-resources-0.1.7-rc.2.tgz", + "integrity": "sha512-gbfYcakpo6BhOH4/XAiNVYrpHroH3xJhSb0LUOwPLhZEOFBgDAyAy1dtlBj+o+CNPraI3j+8SCt/oHVOu5y6mw==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" + } + }, + "node_modules/@deepseek-ai/dsh-client-shortcuts": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-shortcuts/-/dsh-client-shortcuts-0.1.7-rc.2.tgz", + "integrity": "sha512-yM52NmuHZcDkV1pbvD9f+Me5W+SgMz2jc1K8Iu9VZOgL5sy4EtMre6kPoHYMT4g1kcYpbVaqyygDXjA/guRW/A==", + "license": "MIT", + "dependencies": { + "@deepseek-ai/dsh-util-crypto": "0.1.7-rc.2", + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-store": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-store/-/dsh-client-store-0.1.5-rc.2.tgz", - "integrity": "sha512-lY7F/CTx9kdX+vN17jzOq+/Mwdw0A5oXrJcLV5OOMago/Kc/6nNl5WLnJTBx+qSAVII2tBKKGLmfrRi5D8y6Tg==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-store/-/dsh-client-store-0.1.7-rc.2.tgz", + "integrity": "sha512-8nF4gqy/3yvSN3KsuHX61DVP1Z2YjC93wkB2uGVS5xg4iyD1KgCqWB2S+fVAdQ7END9PDzWhZTk71AYnkSh7LA==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-agent-preset": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-agent-preset/-/dsh-client-ui-agent-preset-0.1.5-rc.2.tgz", - "integrity": "sha512-BMhRU54q7/8E/JoksXm9TW1rCBBg2V64XsDwltYWmCLcZuLCVBc3GX7t/11WMERNi8Do+0ZM6khslwrhbT5QLw==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-agent-preset/-/dsh-client-ui-agent-preset-0.1.7-rc.2.tgz", + "integrity": "sha512-dE0Ua4Ke8yDo31BPEdTK+a3mrbuTRPLbdEK3LDWwUYQ9L0V2vYjHikQle4p/Asmx2Z/g2P87Wyx/016CnXHFNw==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-approval": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-approval/-/dsh-client-ui-approval-0.1.5-rc.2.tgz", - "integrity": "sha512-jrlEBEYfYq04HuKYBxD1yI5Z9btJ4fnuWbz3xtK8M/gvsTye8PrhCMxaNARMznGiUFoXmwv9CRhl/KAqbbfE/g==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-approval/-/dsh-client-ui-approval-0.1.7-rc.2.tgz", + "integrity": "sha512-zM8k2o504kLz9jDzqKze36W6Opb1voDwsO+YgWFmTrGQIjMXLmxdyuLxbMco9ER4cygUeJf8weH92FKQDw5CeA==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-attachment": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-attachment/-/dsh-client-ui-attachment-0.1.5-rc.2.tgz", - "integrity": "sha512-+i98BXfTpz9HX0G7m7k9ka1R5Tekd0tBIljFtKMmiXWju5MW1u+dngpmGCwoSHenEuZGZDC8K/qgw7MIOcbRnw==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-attachment/-/dsh-client-ui-attachment-0.1.7-rc.2.tgz", + "integrity": "sha512-PG5bsHJ6WioVegi8K7GuXsoPZ3wd4rQBZ9OwSPjB4L6G2Zzln3UuBlNuAVpaTJL8lvxB5IBnUdw++4yQ8DvAWw==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-brand-official": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-brand-official/-/dsh-client-ui-brand-official-0.1.5-rc.2.tgz", - "integrity": "sha512-VESOQ7N8MmUNyy5H1A099Zx3NW1DTTcFIdN/zYVTXWKukmSR6xanShJMai6e69ibDmUfh0YmRgwOvHOVd2K0Uw==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-brand-official/-/dsh-client-ui-brand-official-0.1.7-rc.2.tgz", + "integrity": "sha512-pdWYHX/xRFMIWkT+IfemhTTOZVAJiA3CAlesUJpTDhbu6MEXQcPeBnsd3iPKswzCiVSPanvaj9Vv/057oXWfUA==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-chat": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-chat/-/dsh-client-ui-chat-0.1.5-rc.2.tgz", - "integrity": "sha512-ywvtoJUgd/vkfETuFDIgqrvdR5yzfvBDqpuyw0pFDHaHwLzRtk/xPjraI9blNoLWQ8x/Sp42aS4Pr7XQPfjIvQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-chat/-/dsh-client-ui-chat-0.1.7-rc.2.tgz", + "integrity": "sha512-mH4Womiv1jFMdhNQQvvlF2t8T7rcQNDuR5e2YSJvJdVpZ2+9CxZOd/56hBURTciYX9p8QnCe+Qb1zj/A0ilWqA==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-commands": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-commands/-/dsh-client-ui-commands-0.1.5-rc.2.tgz", - "integrity": "sha512-wXSTOM4DHogdXZp8tp5RhEvpRJbNey/lN7yjCNN5Qg+BjSu6BAVwKLRKiriCmKIKJcEEpq4BFQb9Di4c1GMm1w==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-commands/-/dsh-client-ui-commands-0.1.7-rc.2.tgz", + "integrity": "sha512-bw6+g4uSNYMoRtkzE8gqzRK6F38Qxa5HQonGf1KcAGWkQ79k8MtTcE9MOS++SBEr4pxokuwRncjPH+Ywjh/m2w==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-conversation": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-conversation/-/dsh-client-ui-conversation-0.1.5-rc.2.tgz", - "integrity": "sha512-VnZ0VrmI7+1JH/iMYV6+FaxCsZrVk4CZIuG+k1HkeevHgUPHe3ghLo8u1Qt9cx00MEH5i3bLOY5Nka3w4mbA6g==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-conversation/-/dsh-client-ui-conversation-0.1.7-rc.2.tgz", + "integrity": "sha512-bPC3RNBF2TgMwoueaRuFLMIrRVA/k9iqZQ6Lre8GPpn5c8uhmtTV5D1TlKNHQPNtnKv/Gn5BGw2Kh16ItbY83Q==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-cordis": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-cordis/-/dsh-client-ui-cordis-0.1.5-rc.2.tgz", - "integrity": "sha512-wLolxQURdqIXNLcoGmiXb6tE7dPD5v5eBBu7WtUn/w7FNlp4QambxpCfX/ytGy8LtKO42LwhYk9uPPr51COorQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-cordis/-/dsh-client-ui-cordis-0.1.7-rc.2.tgz", + "integrity": "sha512-v1ktLqwVQJq1Mjcml4jZpFeN0VcbePH2Pg7IkI25bAHaF2fn2afsf8hRYJdR2nfL9Us0mIwlo6/M/EkkfUGIXA==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-deliverables": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-deliverables/-/dsh-client-ui-deliverables-0.1.5-rc.2.tgz", - "integrity": "sha512-RO2XqjCOZfCSkMzlZf1rgg1ZYhLO6Uy2FUsTwkPContjKCGnGWUMtcaRS8LTs1lYgH8+hP50LIf67o/6z8FJxA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-deliverables/-/dsh-client-ui-deliverables-0.1.7-rc.2.tgz", + "integrity": "sha512-/7eOaMsDJQgOYtPRHFHoyY9wwDOgM0af8Ihy8EtvnQjr7VqeluJvX2B3L55wOW0aBnCp0llHL4MZlYa+f7Z3SA==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-typert-protocol": "^0.1.5-rc.2" + "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-directory-picker-browse": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-directory-picker-browse/-/dsh-client-ui-directory-picker-browse-0.1.5-rc.2.tgz", - "integrity": "sha512-DrrcPERnA50Il/1Roc6T3goodqANi0u+nVtQShw2P3FHBwVqdlfUURMQgZgKdHO4JFv2dGnikwf+XhiE41icWw==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-directory-picker-browse/-/dsh-client-ui-directory-picker-browse-0.1.7-rc.2.tgz", + "integrity": "sha512-rpUbd6d2ZJs/uVa36ATa2y+QlX5i/RQ+24VZTWmz70hj/UhxiRWq3E6hXc2trOHIpHnXI8I3cfKYdP9BJPBb7w==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-directory-picker-native": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-directory-picker-native/-/dsh-client-ui-directory-picker-native-0.1.5-rc.2.tgz", - "integrity": "sha512-bH3VBqhlXcmkEcnPrnRLecDW9uOdvsaTzfZ8zTUh5ZtexwNhBs6Wv3lN6gZNw457jbP4BnQoEar5fq+rIC5RTw==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-directory-picker-native/-/dsh-client-ui-directory-picker-native-0.1.7-rc.2.tgz", + "integrity": "sha512-zEK/4cg6HKjqOabLRtcXWyPxsB0Q34RKulg6bYuOh58eQBEYBLlY6inyFESEVjP30fVkYx2qvrBuzBEVZ1A6Mg==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-goal": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-goal/-/dsh-client-ui-goal-0.1.5-rc.2.tgz", - "integrity": "sha512-38+k8tQq61nQjHYLwYfrwOoju+Jlg2hB0xWJrMvPfcZlB5Shjtthm50lW362tK6iJ9GMSfOGIPGuC+nooBD/Yw==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-goal/-/dsh-client-ui-goal-0.1.7-rc.2.tgz", + "integrity": "sha512-1h3u/5FNEuui+31lCklla2q+Df7EAribAwuY/O3lv8Gf/kT9seQfrJNkxwaZMoLh/9wnx/mAAnQT6K7v4OWmMg==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-input-trigger": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-input-trigger/-/dsh-client-ui-input-trigger-0.1.5-rc.2.tgz", - "integrity": "sha512-Am7qlXQX+Kf3IddzoJDy2/kgtHm3R5hcUFjDQ8tespSWXswPEX+9wsPFugUvjHJkqdpfeE9OTI3jnd8K6sT/BA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-input-trigger/-/dsh-client-ui-input-trigger-0.1.7-rc.2.tgz", + "integrity": "sha512-m2uKSOFijUI7gW66LjsThuPbHt67ezvL+nfKL+IpoBSc5596/WFcj6HysFdiGBv0bv7Gd0pNXUVTOJ2Z6Jhg4Q==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-jobs": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-jobs/-/dsh-client-ui-jobs-0.1.5-rc.2.tgz", - "integrity": "sha512-/ygltqocItoM+Jh+tnyYJwIpAPTSu6bAWfEkyBunHpHllCjONuFmnpPcLPZTOxKwkjTdQT6XTRdMhmxU7Sageg==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-jobs/-/dsh-client-ui-jobs-0.1.7-rc.2.tgz", + "integrity": "sha512-QIFavpfsmMjmD/lb2nAoJNHpuaf7TQyWlpN3BNUVe2iBURu0+KviSnRQLOR8PxBztobo0AYtrAMNrmAACfLnuA==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-layout": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-layout/-/dsh-client-ui-layout-0.1.5-rc.2.tgz", - "integrity": "sha512-N5+kH1W6UjzOuagJEKDenm/Gbs8Y2sz6btdmVKW5dypEEUgVWsQGV0auTC37gsWKWDaWGpfYOpeAa3Ybk6DYbQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-layout/-/dsh-client-ui-layout-0.1.7-rc.2.tgz", + "integrity": "sha512-od2Q5A3SxiOO5V1Mi35lmm64LQLNjew+HgigjTC9oLpCkb+es739VQeWPdUnzWP/+4WVIyQ2+SbHMLZiyB5jVg==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-message-feedback": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-message-feedback/-/dsh-client-ui-message-feedback-0.1.5-rc.2.tgz", - "integrity": "sha512-LSp6c87DLMiO4B0JCpp00QEHI6VEKSLWydAx7DBjWTma397HLGLwKoaOT7kHZ8ZSkei970LmdBCUxcwo2Mc4tQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-message-feedback/-/dsh-client-ui-message-feedback-0.1.7-rc.2.tgz", + "integrity": "sha512-6WbWPtxFc3NpFqsGlU02z+UzLaAaKZkOeD046T+DG3WXf9eAjWHs7nwyxo//kYtWOGYVFyvXI+To9knby78TXw==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-model-selection": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-model-selection/-/dsh-client-ui-model-selection-0.1.5-rc.2.tgz", - "integrity": "sha512-AlYjgwb40OOe5InaAFsQEu/KZr5+vYTItXMkFhkP5myzo5fOea0H0xdF29UV12BZ0SaRItacs8GE1kbDB9n5Ew==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-model-selection/-/dsh-client-ui-model-selection-0.1.7-rc.2.tgz", + "integrity": "sha512-kazoUL2VstZZs1Pvd+IliHIHqgNVKOHPmiXehUCBxc4pqwUV6v84X+aH4W6dxFCFojd1zqzgfp7dA2RwkNBfsA==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-open-in-app": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-open-in-app/-/dsh-client-ui-open-in-app-0.1.5-rc.2.tgz", - "integrity": "sha512-UqLrgiNa48kTGJuMHo/f1er8ti3vcktkseUgFVW2WfWiV3ES1CQTyKF3+4gH3ub7RYFN8VteTQ5QKuOZe5WgPg==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-open-in-app/-/dsh-client-ui-open-in-app-0.1.7-rc.2.tgz", + "integrity": "sha512-cIZ8Q1v/HdPMSe1fouJMNTyIYRz9VKtN96I5Q8PwgRHKUIwoIQ1qDIxMaeCaOkYBnDftmafDVGxNSsvQ7XjfDg==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-permission-presets": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-permission-presets/-/dsh-client-ui-permission-presets-0.1.5-rc.2.tgz", - "integrity": "sha512-2iDWBqr8bfhvzuxNW03JptdPtqQs6kHjh4GdBfgudUhFszaJZOBETx83+PfazYqV4daT4N0cE696l8tqqsS5Ow==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-permission-presets/-/dsh-client-ui-permission-presets-0.1.7-rc.2.tgz", + "integrity": "sha512-RUt06rwzQ1oYX74I5Va/y+nGOJC0l0i29EL5UEzfnz1RH26OGMw11PZnVDFQZbDE6QFpp44Rh8RF6H0MBlKttA==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-plan": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-plan/-/dsh-client-ui-plan-0.1.5-rc.2.tgz", - "integrity": "sha512-3lbKHZA+9gPSXlMpEFA9xVbn7FOTCgP78Tf3buAjTmOnwSF3PRwBQoMeaANro2SoTn4ZuJZjJkpxqe3YDEOc/w==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-plan/-/dsh-client-ui-plan-0.1.7-rc.2.tgz", + "integrity": "sha512-IYw6lMWvMZ0gCHStZYAKqUuimSIgns1iShTOqNJBsyL82u99iRLUCOjTePRNVcn+OPSD0MpJEUPA4wPa1t3byw==", + "license": "MIT", + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4" + } + }, + "node_modules/@deepseek-ai/dsh-client-ui-plugin-manager": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-plugin-manager/-/dsh-client-ui-plugin-manager-0.1.7-rc.2.tgz", + "integrity": "sha512-y2BlSTNqiFKxvtx86r/xaskWhjc6OYfHmtbJGI6BVfquqrHBhKeHJ7D1vNURamOFdouJjurWdc6UclrM/6D4OA==", "license": "MIT", + "dependencies": { + "@deepseek-ai/dsh-timeout": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4", + "zod": "^4.4.3" + }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-primitives": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-primitives/-/dsh-client-ui-primitives-0.1.5-rc.2.tgz", - "integrity": "sha512-APWho69VlEmbLGqzBLiybTtjun93tEbxMMJlm+Q129Cx7ZGJak3DNfQtW3OPzBCf3Gzs2PGEz8fKbunTpea2jQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-primitives/-/dsh-client-ui-primitives-0.1.7-rc.2.tgz", + "integrity": "sha512-ymIUil9ivHcIDgaAmF88lOygC7dJ0UsUgdbIvXT5bymPZDzvDJIoorOKhlMsCqPEG1ZawCMVhUatnIPi4xdlMQ==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-reference": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-reference/-/dsh-client-ui-reference-0.1.5-rc.2.tgz", - "integrity": "sha512-9zNSMWIhG0txbpwbUdHfkPTHYR44rBVl2aKPIcqr8JSUhI+8y8+QZwoykYTnbZXCKo2Ircdm5IXYbMXTbrGCGQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-reference/-/dsh-client-ui-reference-0.1.7-rc.2.tgz", + "integrity": "sha512-6gfOeDM/Z9hJRDP+m777VPgiFvjhVvbjnCxkXlG8rsXQBcdO4SSqCBWX0ioQ+2tIGMuMypfVNdFPOk8pxoR7FA==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-renderer": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-renderer/-/dsh-client-ui-renderer-0.1.5-rc.2.tgz", - "integrity": "sha512-otUJ72f1UfL8b/UL+tMdSE+FHqJWErPmHs2AWbad9nHXghNoZjL2bxumOhI3b+Hb1eezhhM+KanlWzIulTIkvw==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-renderer/-/dsh-client-ui-renderer-0.1.7-rc.2.tgz", + "integrity": "sha512-GdOE1zyespclxrcCGPTWk8+TQKQy3tUNC2Ch+4eoAyzp1GD4hmQNyzwFIiQDLB6Bwc7kv+8cWc51sbjr5/2vNg==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-schedule": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-schedule/-/dsh-client-ui-schedule-0.1.5-rc.2.tgz", - "integrity": "sha512-DjBRHytIkcntXs93cpDSiDCiA6eEegc26ht+ZuE9sdCHNh3eu2GxLihMoKBiVFbepwIsdfuWO2mf40iFH/w82A==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-schedule/-/dsh-client-ui-schedule-0.1.7-rc.2.tgz", + "integrity": "sha512-MIdo7fTNZ+kNOO0fp9oiw3D6qJ1O8xyjnYyJlZ1gqDFjuT+IdH65BEOoeGyT5atYYJnwMDWD7vL3sUMh5l5lqw==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-session": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-session/-/dsh-client-ui-session-0.1.5-rc.2.tgz", - "integrity": "sha512-EGCG4Ik95obEM1MA3ZVSsPuK7nknQyhfV/qgNg035jn6gtZJxAguuck9qBNuSOC0upx1xTbh+gSJ6bAmS4ugcQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-session/-/dsh-client-ui-session-0.1.7-rc.2.tgz", + "integrity": "sha512-gr7hwtWpgqU1mJwFFtugxH2QOYw+j/RvU/h8719mGYjkmBbOxzy3wgTL00tf0WFHLZh8pPMKQMg/eG3bEb0Z/w==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-settings": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-settings/-/dsh-client-ui-settings-0.1.5-rc.2.tgz", - "integrity": "sha512-NsnZLRI2ZDzJJylx9KATuDwrTdJ0FSP93dU5SL5k2G2W4FLUspNvlAmk7bha5Miopfzmfd+h5/NvMdWe8PVVjQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-settings/-/dsh-client-ui-settings-0.1.7-rc.2.tgz", + "integrity": "sha512-RAZXUt25mVibi2fnZyHhRArAtmNYIbyEUcAx/nc0i01V8dabnZkUCuGDRLjUeB4X6aPAOrlqLCliNcATuHD+hw==", + "license": "MIT", + "dependencies": { + "@deepseek-ai/schemastery": "~3.18.4" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4" + } + }, + "node_modules/@deepseek-ai/dsh-client-ui-settings-account": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-settings-account/-/dsh-client-ui-settings-account-0.1.7-rc.2.tgz", + "integrity": "sha512-bMrSAJjkGGW1NCRS5I7rYFpUrTtl+6d3rUGWAJQlFRB3GCBDICfyAd2ZjLC+8NtklqyG8sXlmKPZr29N5mh61A==", + "license": "MIT", + "dependencies": { + "@deepseek-ai/schemastery": "~3.18.4" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4" + } + }, + "node_modules/@deepseek-ai/dsh-client-ui-settings-agent-loop": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-settings-agent-loop/-/dsh-client-ui-settings-agent-loop-0.1.7-rc.2.tgz", + "integrity": "sha512-qD0C+CK8KJ02B7URv7lsnddT1exlv9imvt7e6wAb5nkmzIdptXfLs2MfL5CXoH+b7NGx9sGYFHR9hRqKU3OMUA==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-settings-general": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-settings-general/-/dsh-client-ui-settings-general-0.1.5-rc.2.tgz", - "integrity": "sha512-Y/UNa3iwrqLesUVSPLts1xZotenWyybnpU0/oABUt6rkvhDuxVz2w8HltnrVD3ytKzPBSrmlK2vP2YyUaK4z2g==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-settings-general/-/dsh-client-ui-settings-general-0.1.7-rc.2.tgz", + "integrity": "sha512-Qy7nobyQqUuXoTwe0QckrikCAFmX8JJ5RT5Wt7J2ZZ+soesDnaEkMkAfO1ZTxJi6MKzntuwwMwjF+Z330FFmAw==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-settings-models": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-settings-models/-/dsh-client-ui-settings-models-0.1.5-rc.2.tgz", - "integrity": "sha512-L1vxfbVZEDmGlVuEaJcQb60E36l7BMZoICLJf+D7r8Gwcy8kFckGWKS0fbxsz+3Jvm2L0+lINJESzSMC9pMGNA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-settings-models/-/dsh-client-ui-settings-models-0.1.7-rc.2.tgz", + "integrity": "sha512-WDHuCh0cVJiSUyaa31OiXSSgpwWD9TAW2gEWBWUrF8eO+hyQEA8Q5f3wzVvea1ltiOmjqU0IBFMQRtpSckyDPw==", "license": "MIT", + "dependencies": { + "@deepseek-ai/schemastery": "~3.18.4" + }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-settings-plugin-inventory": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-settings-plugin-inventory/-/dsh-client-ui-settings-plugin-inventory-0.1.5-rc.2.tgz", - "integrity": "sha512-lpa6KZA/wqYRNi0zHQVrdUEbt4UGHKfughUSpew4sWvd4HymGGyuKF1ksVrioRUdRGAM+f8/VYpXd0ySk4wQ5A==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-settings-plugin-inventory/-/dsh-client-ui-settings-plugin-inventory-0.1.7-rc.2.tgz", + "integrity": "sha512-TweCas4hY0NPl6m4TFeE9OVNSNGH6BjRCSzRfKVddZ6qm54aCW3pxy0fprJLLRVIkVckushjbfl+vaxyYGHoFA==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-settings-plugins": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-settings-plugins/-/dsh-client-ui-settings-plugins-0.1.5-rc.2.tgz", - "integrity": "sha512-MRErIAbG1GjrIDN/ULFEMrBA5rHUfg55+uY2P51UVmLdI5UC3B6I5QQYNo9pPcqHSVnT8EZFz7ZWz4Yi5DTAuQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-settings-plugins/-/dsh-client-ui-settings-plugins-0.1.7-rc.2.tgz", + "integrity": "sha512-eLljHiQ6fR0K/yXDiHeyiWkCsmg1eQucoMAKcwerh8sjtyKPTpqLFQDmOn/O7znJz+b/V89yshkyyHw8ZvC38Q==", + "license": "MIT", + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4" + } + }, + "node_modules/@deepseek-ai/dsh-client-ui-settings-shell": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-settings-shell/-/dsh-client-ui-settings-shell-0.1.7-rc.2.tgz", + "integrity": "sha512-+N2RZaN/WCA9vVqCdf4PnvuzmtGnzyacnlOe37g5NSpZGrg2MpPnUTuv9vJnygsQhYLHZxkJOojAnxEJ/dOgfQ==", + "license": "MIT", + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4" + } + }, + "node_modules/@deepseek-ai/dsh-client-ui-settings-subagent": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-settings-subagent/-/dsh-client-ui-settings-subagent-0.1.7-rc.2.tgz", + "integrity": "sha512-c93MFjtSoffOCeVAUBOL9oTul1Hd5MhyUngGetBUv7APixG5zN6X13NjnS20mqOKRidSMc0xyizYiS30ygz2fQ==", + "license": "MIT", + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4" + } + }, + "node_modules/@deepseek-ai/dsh-client-ui-settings-web-search": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-settings-web-search/-/dsh-client-ui-settings-web-search-0.1.7-rc.2.tgz", + "integrity": "sha512-/EwngqLFH4tBnF8GXMVRDpR0Lfwk3uhJ103UFSLq+p4E46yv2zxH6S3AcKIWR8YdntB8i0nj2Xr/5Cs4IbK+yQ==", + "license": "MIT", + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4" + } + }, + "node_modules/@deepseek-ai/dsh-client-ui-shortcuts": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-shortcuts/-/dsh-client-ui-shortcuts-0.1.7-rc.2.tgz", + "integrity": "sha512-Bo5Z0j6Xcm5NHWmrgJwMP9vehsfUcNQvZ0IT6WAT5z51cEza3iIXfpfEa/3GTos68cv9R5i14wjAJL9a3Go7Ow==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-sidebar": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-sidebar/-/dsh-client-ui-sidebar-0.1.5-rc.2.tgz", - "integrity": "sha512-52PGlC4e9zkD6MQOjDo2TakxsWi4f5QigmdNsHluhDMBUfwMYl8ppWGD3uuHyAkK95yh0D1eKI5UPdQ5kikn+A==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-sidebar/-/dsh-client-ui-sidebar-0.1.7-rc.2.tgz", + "integrity": "sha512-/rzmtzk5Wg89zkT03nPGD/yYx9x1MD2ircBb9zIaLB9+DMBUFNjHJh5htYmYFxN7ldNEa6zDnmcx0N6jg1xnPg==", + "license": "MIT", + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4" + } + }, + "node_modules/@deepseek-ai/dsh-client-ui-sidebar-browser": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-sidebar-browser/-/dsh-client-ui-sidebar-browser-0.1.7-rc.2.tgz", + "integrity": "sha512-Mnn+EVIy2YGIEyHcJf5ifAhLKUdeYjhv1XA4fMhfGUmadq0QYGMN+K9j0mWb6eBCSXoujBzfwiClhCT11dN+3w==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-sidebar-documentpreview": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-sidebar-documentpreview/-/dsh-client-ui-sidebar-documentpreview-0.1.5-rc.2.tgz", - "integrity": "sha512-HeaqHwOyCg6/3ppFP7///G8C4vmVrhRBP8R0w31PLWIv9dcpnULKuFLFO7UemeBsi8K7uQ5zwN7V25DoT05X7w==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-sidebar-documentpreview/-/dsh-client-ui-sidebar-documentpreview-0.1.7-rc.2.tgz", + "integrity": "sha512-5SRZ9SgYIq0GB4q9PQPY7uInG+WKaVLv7V9kQn58YWjwzzEVDDcGMDbgCP5lBLq/Hj+fZ7jI70na1M8hMCjf1g==", "license": "MIT", + "dependencies": { + "@deepseek-ai/schemastery": "~3.18.4" + }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-sidebar-files": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-sidebar-files/-/dsh-client-ui-sidebar-files-0.1.5-rc.2.tgz", - "integrity": "sha512-ZJCpQNruk1Sm29wce30+ATjFkvnuhd55yB3wb+9WpeN+hW6jPmBnAmvUGbS4JsWqpimHLL4y8xYUd5AzAe7+sQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-sidebar-files/-/dsh-client-ui-sidebar-files-0.1.7-rc.2.tgz", + "integrity": "sha512-5H9kFhSFoZDj19YE8BYue3Ux1anPOGC4JNAYZJI9cmYLXB/Onb8nndFUxt+9HKJhQaRaLXgYBMrBQxg+Wig6Bg==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-sidebar-right": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-sidebar-right/-/dsh-client-ui-sidebar-right-0.1.5-rc.2.tgz", - "integrity": "sha512-EqKZ5JuyM+yCd6TVe7NwTmZf9y7dyhcLczpnu5rG87RuwVufEz1ARqO9TBXf32ApXCeYOJQGVeJjR/VsYzVMgA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-sidebar-right/-/dsh-client-ui-sidebar-right-0.1.7-rc.2.tgz", + "integrity": "sha512-CXTONIEGrMJA7Aj9OK5K7XSv6Qa/f+yK8UqKHvrT03m1FAqLJZGVqj2OUUbCgoB6Yf3wBTrNh5D4RqTE0rLpVw==", + "license": "MIT", + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4" + } + }, + "node_modules/@deepseek-ai/dsh-client-ui-sidebar-terminal": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-sidebar-terminal/-/dsh-client-ui-sidebar-terminal-0.1.7-rc.2.tgz", + "integrity": "sha512-1nr+HVNXkxnJ1eSxkIt2NnIaotyjTHvX2tHNaV6Fy7T/KoxcDecCW3sFFqIFnhZqR61SsQ8yNIP79DV65xWfog==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-skill": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-skill/-/dsh-client-ui-skill-0.1.5-rc.2.tgz", - "integrity": "sha512-aVBAA4cp79MRE98yVyFjosz8BAn4W5U2DFGF7BxmDYKNmFEp7Ae0THGNn9VXZg5wfmTH6fTAzQKw1THSv+EVWA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-skill/-/dsh-client-ui-skill-0.1.7-rc.2.tgz", + "integrity": "sha512-DQhYOWGid/KIX9Pg4vCngO5vIOrtxxaL6v12RIV3PWJlZQ70JB2j8UEfayN3qtfHpbmWo15UTDJ56sA71lf/Mg==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-slots": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-slots/-/dsh-client-ui-slots-0.1.5-rc.2.tgz", - "integrity": "sha512-uUKIHBcNzWmJFtTlPkgn7hprsE5uU8lJf8Fw7jKwUouZWIwGnLdxuunrm1LOZWr7G+b4UfjVwD4LV12rhF/WLg==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-slots/-/dsh-client-ui-slots-0.1.7-rc.2.tgz", + "integrity": "sha512-83cd5owHfNMGIc5THEkMw1L6iKj/tl2m3thQhVGWp2p3Y+QAPh2hIrIQCNI+i97cH+7SsIsUIoCIoB0mu51aqQ==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-subagent": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-subagent/-/dsh-client-ui-subagent-0.1.5-rc.2.tgz", - "integrity": "sha512-/SWymLiSOzYswhikUo+VAuTc4dYkTecw+8vtex0H5IsCsRHlDaTnHgcxXnlvgeqFFifjanr4JzVhwzg9Ope2dA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-subagent/-/dsh-client-ui-subagent-0.1.7-rc.2.tgz", + "integrity": "sha512-iXO910+1CQ+AMrRkrzuG6XYDH/lH3iIXIU0YvEt844Vmp3r3GJ+HrEQAo5E1CXgctBwQtMDmocyhIUQNlYV7iA==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-theme": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-theme/-/dsh-client-ui-theme-0.1.5-rc.2.tgz", - "integrity": "sha512-qLR/6E/AzHUpTgKn8P0TiHiWg69qXYFfbpfHWM+HpQ66K7lyRQUXC+WKEJf2ZStCF4/enkx/rhMdXzRDlPVO3A==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-theme/-/dsh-client-ui-theme-0.1.7-rc.2.tgz", + "integrity": "sha512-sgI50PPgGwhxXR+xEUa0zTAg80S2RaQOLsuuVdfliZPbVLjodme7/bbc8cnPQ+ZV9oU5Q3to+yXxAQByuIKjRQ==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-tool": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-tool/-/dsh-client-ui-tool-0.1.5-rc.2.tgz", - "integrity": "sha512-ncGDBvf7EpuDkq8KteGqQoUCcYkLWlGWNHPZScF8B92zdftYjlnsiQJZCkFbDiyRju3z7PAV3qdY0WO9hOTs3Q==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-tool/-/dsh-client-ui-tool-0.1.7-rc.2.tgz", + "integrity": "sha512-0HDXXfaqw6u2tB0HES+XvOO+QRKGHP2gRUU5+9gE0uDcJWawj7SXX6Dj27hJ3rztT2xAAu4W2fA2S9vjxzw8MA==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-trajectory": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-trajectory/-/dsh-client-ui-trajectory-0.1.5-rc.2.tgz", - "integrity": "sha512-QiCP1h1bgHG05vlJL5hde3hZPfTuSdwRrszgfY7Jy2NfkuIX6wqv8TI5zsZsEkS2/ha3Ebp3nhjDfkXsGZpgbQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-trajectory/-/dsh-client-ui-trajectory-0.1.7-rc.2.tgz", + "integrity": "sha512-RteqWWQuqj/2VGQYeNo+nKkuPPd/bv7ejJxHnMRtHEuYrnwObkBUqhZ4+7CbhZuM9m0Jv26+tg9SxIp7GzO03Q==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-user-questions": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-user-questions/-/dsh-client-ui-user-questions-0.1.5-rc.2.tgz", - "integrity": "sha512-vJzqgAIAlGX7oth3a4qVq3pyyBRc4paL7ENOnt1kfmY+XoPTGF+/CUXwe/Lep5Xjo+95K2HPq7tMxeryKJj72g==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-user-questions/-/dsh-client-ui-user-questions-0.1.7-rc.2.tgz", + "integrity": "sha512-cmZOeVspzKrD2r87xvXSGbQ7j18VwznKKkvA1lukBCpsHYfFYKdqg5vt3tbW4UJYPGa9Ch0j8qX0zpRGD0YBUg==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-workflow-run": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-workflow-run/-/dsh-client-ui-workflow-run-0.1.5-rc.2.tgz", - "integrity": "sha512-dFpAilctrJhwwZY/XXVvTy73v9UhAPqbuEMIK3sMBFtoAg+S/gCQsiVX/WV5/WCADWdjHLtBoEVAsZgrnImbHQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-workflow-run/-/dsh-client-ui-workflow-run-0.1.7-rc.2.tgz", + "integrity": "sha512-241DeEeaF8vp8vC54rrENDNA0R2n+nRRPvUCg4OYNi5MKLp0p7jgbeQ1lIcTaCuabRr1wYM0AZdoMyBaCkpaCQ==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-client-ui-workspace": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-workspace/-/dsh-client-ui-workspace-0.1.5-rc.2.tgz", - "integrity": "sha512-BRe/RDIJJblCECYLwVroy8h4+cXrf3eXSfLjJ6BdpnW2fI3CBJuEKlFaBPGtKAFTTain0rQ+dP6SscZNrXm5Gw==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-client-ui-workspace/-/dsh-client-ui-workspace-0.1.7-rc.2.tgz", + "integrity": "sha512-iaf28XLl3+1WTgVMsykV8HVvGPH8VXv+CQD7Z5koejk0EJZVXtMB9nosUKX810qF+CVJKL04en9a8mOm8dIsFg==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-cmdline": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-cmdline/-/dsh-cmdline-0.1.5-rc.2.tgz", - "integrity": "sha512-sfjqgFojZRprFx0oKCI2J1GX2BZ+mgWq8bYX9CktFt3OGlLgmFE5JJ/nNSLKtCjRoXok7KXhsYFcH0dZGlkUsQ==", - "license": "MIT", - "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/cordis-plugin-loader": "^1.0.3" - } - }, - "node_modules/@deepseek-ai/dsh-code-runtime": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-code-runtime/-/dsh-code-runtime-0.1.5-rc.2.tgz", - "integrity": "sha512-qex3bvQNBkv1eapi8iTyNq+c52q1kxfdv5+8Nkswv4/kwrkvcDa4n4iiCbEgKS+K5U4DiVIprnyIv8Nx7il7Nw==", - "license": "MIT", - "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" - } - }, - "node_modules/@deepseek-ai/dsh-code-runtime-worker-thread": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-code-runtime-worker-thread/-/dsh-code-runtime-worker-thread-0.1.5-rc.2.tgz", - "integrity": "sha512-eXrkDTWlc/ZH2A6S1bP1An2AgfQjmaMRmCKJU1mUzvENO7sLTo++GFR6L1CRLRkFxB8VGZo1TYFKtBxNKsdbaA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-cmdline/-/dsh-cmdline-0.1.7-rc.2.tgz", + "integrity": "sha512-IULzGaZowx/xNJkWDwGTFTEP2wdjPZ7FT1uCW0gwvQdkN4MWEsbC9B1BMCenAoER1n6rs+GqIWmj3z8celngWQ==", "license": "MIT", - "dependencies": { - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2" - }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-code-runtime": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-timeout": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/cordis-plugin-loader": "~1.0.5" } }, "node_modules/@deepseek-ai/dsh-command-compact": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-command-compact/-/dsh-command-compact-0.1.5-rc.2.tgz", - "integrity": "sha512-TBvpsgCLLXvnyuVYV+eiAyL/xkl0dG2j1GUVC2mxwPov1jLiKgLqneZClJpo9gT192HAkGIs8a7wXCoID2ryag==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-command-compact/-/dsh-command-compact-0.1.7-rc.2.tgz", + "integrity": "sha512-vSDXWGW9Gh7hFrCCkfdMwut2kseS6HYOD89X5X43cnIxBayofenKfnMb/ZuN+NTGIWRr74FihtAe6mg0FxTtSw==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-commands": "^0.1.5-rc.2", - "@deepseek-ai/dsh-compaction": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-commands": "0.1.7-rc.2", + "@deepseek-ai/dsh-compaction": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-command-feedback": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-command-feedback/-/dsh-command-feedback-0.1.5-rc.2.tgz", - "integrity": "sha512-7bXJ5IiSzaCbNUffWboAvMXze4N/GTID7O8loSsKBbeAo4CIS6lOWxyx8ZSrcQv/Gnd4onxizN6WqIMxW6i5Qw==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-command-feedback/-/dsh-command-feedback-0.1.7-rc.2.tgz", + "integrity": "sha512-BczHqimHOdWQYNfpGfVtMPEBhFh1AhDia88cVDxLENfSXfaF8xUagSb2cJKXxS4iG8Xco6lz8lnnZAGOdLX2JA==", "license": "MIT", "dependencies": { "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-anonymous-user-id": "^0.1.5-rc.2", - "@deepseek-ai/dsh-commands": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-typert-protocol": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-anonymous-user-id": "0.1.7-rc.2", + "@deepseek-ai/dsh-commands": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-command-goal": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-command-goal/-/dsh-command-goal-0.1.5-rc.2.tgz", - "integrity": "sha512-wNxZKEBC6bAHd92fzKJjyPnYsZJ7yq13p+5wLufNPZrty7y1nlJ8lm7SwxuPZyXYJ9+/5njYlMnZNNZFmitJCA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-command-goal/-/dsh-command-goal-0.1.7-rc.2.tgz", + "integrity": "sha512-NSBwTXaU3eFiOjHFHdxllLE2h5CJSWBcIeKIONBMZqYW2q1myAdldTv9NHY5uPSYDQU1ew4hMt47OigpJ8Vicg==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-commands": "^0.1.5-rc.2", - "@deepseek-ai/dsh-goal": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-commands": "0.1.7-rc.2", + "@deepseek-ai/dsh-goal": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-commands": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-commands/-/dsh-commands-0.1.5-rc.2.tgz", - "integrity": "sha512-ODc9h2Jig+Lo4XLdxqHpHjSXsBFeUCth6Y/rToor4KVRWQMedUARlq5otPyB1lYHyQh2DonNs2uf7g3mvag57A==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-commands/-/dsh-commands-0.1.7-rc.2.tgz", + "integrity": "sha512-wVAHwHNDLDNBKXJZU2rHnwc+e3mhi6EuazAfJmqtbzU/ldQVEoJ9f5eXqesBcdQbRIrWQlpjfjdlw3nCJfK2HQ==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-util-crypto": "^0.1.5-rc.2", + "@deepseek-ai/dsh-util-crypto": "0.1.7-rc.2", "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-attachment": "^0.1.5-rc.2", - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-scope": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-typert-protocol": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-attachment": "0.1.7-rc.2", + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-scope": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-compaction": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-compaction/-/dsh-compaction-0.1.5-rc.2.tgz", - "integrity": "sha512-aYCBBcmodNycKjaX9hWChxi2+YYMKlfiIfrNaL9QwtXs0BLvsv2/ttZqGxCebLGv6XdHWozNadC+opFpUCeZAA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-compaction/-/dsh-compaction-0.1.7-rc.2.tgz", + "integrity": "sha512-NOrFYDM6EdvO+UBioNcpiZ+Klv5v2xvOxLXDWKtA0rjKKW8IvW7Rui2hBnOpchsWe5So5vwBvu4lNjTdl5/2CA==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/dsh-commands": "^0.1.5-rc.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-commands": "0.1.7-rc.2", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-compaction-basic": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-compaction-basic/-/dsh-compaction-basic-0.1.5-rc.2.tgz", - "integrity": "sha512-Tz6aEvPunsp+SXQruXTldxnZIMLPwXL3ZkWWiWnCM+83r1PglVBWABrxjaRkMaIEype/R16OjxodzR4k7GNA1A==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-compaction-basic/-/dsh-compaction-basic-0.1.7-rc.2.tgz", + "integrity": "sha512-8I2TzEDZA9MhbjmSTanw4nM4Ud6mZTUy0Xe9Zy8oQ7GCbYpVhAe3grb5MHnpS0WYisrW1ws063Kj8hHZerdaEQ==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-commands": "^0.1.5-rc.2", - "@deepseek-ai/dsh-compaction": "^0.1.5-rc.2", - "@deepseek-ai/dsh-compaction-tool-result-pruner": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-token-meter": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-commands": "0.1.7-rc.2", + "@deepseek-ai/dsh-compaction": "0.1.7-rc.2", + "@deepseek-ai/dsh-compaction-tool-result-pruner": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-token-meter": "0.1.7-rc.2" }, "peerDependenciesMeta": { "@deepseek-ai/dsh-compaction-tool-result-pruner": { @@ -2608,680 +2786,1072 @@ } } }, + "node_modules/@deepseek-ai/dsh-compaction-image-offload": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-compaction-image-offload/-/dsh-compaction-image-offload-0.1.7-rc.2.tgz", + "integrity": "sha512-IraXZq6uR88RbJcxkK7vfDViIB4WCxm8Kf9s43VWoias9Tr//w0s8oHZWTfNuy8kVgpw4cBze6DeExZooMALrw==", + "license": "MIT", + "dependencies": { + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-compaction": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2" + } + }, "node_modules/@deepseek-ai/dsh-compaction-tool-result-pruner": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-compaction-tool-result-pruner/-/dsh-compaction-tool-result-pruner-0.1.5-rc.2.tgz", - "integrity": "sha512-JsCZrbStt2EehHSLXU4CFKJW8idc0xefqCOh101bW4El26JShEKoJKTUwIMvRPq7AQh9RBWk25Pf9N1yAjKuDw==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-compaction-tool-result-pruner/-/dsh-compaction-tool-result-pruner-0.1.7-rc.2.tgz", + "integrity": "sha512-ih1YpOuUNTZQR1epsZ2SgfT7+VsBrTBypl37DTbCqWZo3nO7LvTHILvdd+Kd2B/DkV1gKpXpBt4H493UNtXJOw==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-compaction": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-token-meter": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-compaction": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-token-meter": "0.1.7-rc.2" + } + }, + "node_modules/@deepseek-ai/dsh-config-editor": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-config-editor/-/dsh-config-editor-0.1.7-rc.2.tgz", + "integrity": "sha512-UgNqOUqI9ZNABnb7TvoJ9d6EbaScVymL54YV/s8rU06cl4bTKuz/ahA8uLclyutCoRANkwh/eMiA+othLyhooA==", + "license": "MIT", + "dependencies": { + "@deepseek-ai/dsh-atomic-write": "0.1.7-rc.2", + "js-yaml": "^4.1.0", + "yaml": "^2.8.1" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/cordis-plugin-include": "~1.0.9", + "@deepseek-ai/cordis-plugin-loader": "~1.0.5", + "@deepseek-ai/dsh-app-boot": "0.1.7-rc.2", + "@deepseek-ai/dsh-hmr": "0.1.7-rc.2" + }, + "peerDependenciesMeta": { + "@deepseek-ai/dsh-hmr": { + "optional": true + } } }, "node_modules/@deepseek-ai/dsh-cordis-client-runner": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-cordis-client-runner/-/dsh-cordis-client-runner-0.1.5-rc.2.tgz", - "integrity": "sha512-RFzivtNX2Zx5wTR+9XnawzoxDViti44QoGEamhLP5+Jc0X8BMPVemYB9755UL3YRqgASNQ2x0IrJgBoc813jAg==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-cordis-client-runner/-/dsh-cordis-client-runner-0.1.7-rc.2.tgz", + "integrity": "sha512-cYRPl4Ftu8Gwbi7gDmAB11wgRvt4hiqdkRNCLq+988jU6q7p9h6lRYpvR4G/5YodP0Bs0fSdyRaZgHrpF2LOoA==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-cordis-host-runner": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-cordis-host-runner/-/dsh-cordis-host-runner-0.1.5-rc.2.tgz", - "integrity": "sha512-VUvOt3L7D7EJEMO2Cetlv0UMY1haIzI401W5kO1AKgOHktGr5SC+wFk83SHX7v2/CS0g1N3PbQ3D+RslutqPjg==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-cordis-host-runner/-/dsh-cordis-host-runner-0.1.7-rc.2.tgz", + "integrity": "sha512-Rts8lOjeJyVAkth7ezDpDPAXOjr0GHplqUz1BmWcAotErQWZGkVxJK6hqiVMlFKB24JMQwr/UWH4474iZUiZKw==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4", "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-scope": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2", - "@deepseek-ai/dsh-typert-protocol": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-scope": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-credentials": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-credentials/-/dsh-credentials-0.1.5-rc.2.tgz", - "integrity": "sha512-TfX5MYLlyw0BFERj3dGxVfP9QGcKZUE5eXDSaY7ZfJbfQgK51VfxV5tP899OxIDRD3Bw94K5Rzx+dbUTSWJBtA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-credentials/-/dsh-credentials-0.1.7-rc.2.tgz", + "integrity": "sha512-Zi5MCL+o2bphuvWcfFsaRmg6eIafkjCa758+DVB2ac2tt5hzXLoKhwSku4YVhvhZYJan8TP87abIzyGr5z1X5g==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2" + "@deepseek-ai/dsh-brand": "0.1.7-rc.2" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-credentials-local": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-credentials-local/-/dsh-credentials-local-0.1.5-rc.2.tgz", - "integrity": "sha512-Xaz/giXBtfwWP/jd/o1QwKDCurGjZVfVXEfFZvXfzGJ1pdQiMFdt/1nfCnIkktHO2fHhtxEE4MBg10PBLtmp7A==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-credentials-local/-/dsh-credentials-local-0.1.7-rc.2.tgz", + "integrity": "sha512-pl3PRh+y9iLpwxZZmtxZzRTahiNGO6xNVC9nsN9h3eLu0ECetUkqRl2ByxLY/3ZcahSRzsad4eHjwKH5Prt7/w==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/schemastery": "~3.18.4", "chokidar": "^4.0.3", "yaml": "^2.9.0" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-atomic-write": "^0.1.5-rc.2", - "@deepseek-ai/dsh-credentials": "^0.1.5-rc.2", - "@deepseek-ai/dsh-home-paths": "^0.1.5-rc.2", - "@deepseek-ai/dsh-launch-environment": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-atomic-write": "0.1.7-rc.2", + "@deepseek-ai/dsh-credentials": "0.1.7-rc.2", + "@deepseek-ai/dsh-home-paths": "0.1.7-rc.2", + "@deepseek-ai/dsh-launch-environment": "0.1.7-rc.2" + } + }, + "node_modules/@deepseek-ai/dsh-deepseek-account": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-deepseek-account/-/dsh-deepseek-account-0.1.7-rc.2.tgz", + "integrity": "sha512-nJ142OEH8XPF2j9vCLBba9aQAQbO/eb3kfkZr/YdtXr3soYeConxveNFFXgIVLqevItKJReo0sa0P0l5E1xZiQ==", + "license": "MIT", + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2" + }, + "peerDependenciesMeta": { + "@deepseek-ai/dsh-agent": { + "optional": true + } + } + }, + "node_modules/@deepseek-ai/dsh-deepseek-account-platform": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-deepseek-account-platform/-/dsh-deepseek-account-platform-0.1.7-rc.2.tgz", + "integrity": "sha512-ppvmTdigUDtljfuZZkPkElscjOB3EA9C2hpgBMY1Y58j7F/8pYAD1OCiuFot4C+lb6uk90NbZE2M3th7NxP5mQ==", + "license": "MIT", + "dependencies": { + "@deepseek-ai/schemastery": "~3.18.4", + "zod": "^4.4.3" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-authorization": "0.1.7-rc.2", + "@deepseek-ai/dsh-credentials": "0.1.7-rc.2", + "@deepseek-ai/dsh-deepseek-account": "0.1.7-rc.2", + "@deepseek-ai/dsh-host-webserver": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-deepseek-llm-api-extensions": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-deepseek-llm-api-extensions/-/dsh-deepseek-llm-api-extensions-0.1.5-rc.2.tgz", - "integrity": "sha512-zue4FWkj7Srg8mAwA6XNqT560NkraILiYtAwIcpT4mmt1Nlim+m55x7ACNkwA5Es0uCkEFAU1H6wHSnR7l2EfQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-deepseek-llm-api-extensions/-/dsh-deepseek-llm-api-extensions-0.1.7-rc.2.tgz", + "integrity": "sha512-RCUarjaYUQDuyQzQ47qDyngMKbOkALMa7P8i3jZd5SsGK67eZd49O72ClFGd/r6CeO7JNQK4s1/W+C0orosUuw==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-deque": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-deque/-/dsh-deque-0.1.5-rc.2.tgz", - "integrity": "sha512-j1dINwK5XU8f+GPdzx22o2GvsAEhCvnLxqZfEqaLGYImbvdLkToVuU7M2nVcNSU+B7v+kl39lWf3E5u6tzG8RQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-deque/-/dsh-deque-0.1.7-rc.2.tgz", + "integrity": "sha512-a4zFfo+D7+BhV7hQzFQgIMtD65Hm3DQTLGRRd1EkI2O5TjrvBgVHOanyGJYK6VAgj07eIxIira8ws1KKNbbT+w==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, - "node_modules/@deepseek-ai/dsh-file-reference": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-file-reference/-/dsh-file-reference-0.1.5-rc.2.tgz", - "integrity": "sha512-vJIHFFn3YmipM5X9SgPglnUO4jpvlCh3Yr3JQYITRtpBkL4hBbleayICP8cCmrfN0prstJ8dtIuXkUANu7decw==", + "node_modules/@deepseek-ai/dsh-experimental-agent-team": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-experimental-agent-team/-/dsh-experimental-agent-team-0.1.7-rc.2.tgz", + "integrity": "sha512-N3/M+Wc1p50jKNF4fxJIP4m3iL4T4MiZelpIneVwwxVxoCTPlzdz0E5tKyN+p5x318aOxsibsa98D4N13Q4uoA==", "license": "MIT", + "dependencies": { + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4", + "zod": "^4.4.3" + }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-persistence": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2", + "@deepseek-ai/dsh-subagent": "0.1.7-rc.2" } }, - "node_modules/@deepseek-ai/dsh-file-reference-local": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-file-reference-local/-/dsh-file-reference-local-0.1.5-rc.2.tgz", - "integrity": "sha512-WYTbwUD5TFWExRttqeNRPBk0EF6xfngevyQyNMRu3fgWYVrHHW9vtR7iGAs/mxAqCgTwZw4vAhCnw1HxaYYLqw==", + "node_modules/@deepseek-ai/dsh-experimental-agent-team-profile": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-experimental-agent-team-profile/-/dsh-experimental-agent-team-profile-0.1.7-rc.2.tgz", + "integrity": "sha512-WdcCnmEflVTWK4HRtJGnLDZxZFd00cCqB2kNc80XA60SB71/r+umYU2JACtTbslLlThD5OzADG0c/3LAYuW1vQ==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/dsh-experimental-agent-team": "0.1.7-rc.2", + "@deepseek-ai/dsh-experimental-client-ui-agent-team": "0.1.7-rc.2", + "@deepseek-ai/dsh-experimental-tool-agent-team": "0.1.7-rc.2" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-file-reference": "^0.1.5-rc.2", - "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4" } }, - "node_modules/@deepseek-ai/dsh-fs": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-fs/-/dsh-fs-0.1.5-rc.2.tgz", - "integrity": "sha512-6DHTquXPbpYdykGayqYaXSI9t668tDCoswH/bDezV+nwj4LxjrfY/smEtgp7nC4ubyoKf1hmjpNfUonGC9e7aA==", + "node_modules/@deepseek-ai/dsh-experimental-api-speech-to-text": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-experimental-api-speech-to-text/-/dsh-experimental-api-speech-to-text-0.1.7-rc.2.tgz", + "integrity": "sha512-OWvVO1iG1ypxR3XKvAU8HH3To7NU9dt5AAI+g9Xb9QJ2AIbmI2qXklbm3vvrYaJyxW24p9pnEkuwuTJWcIBbWQ==", "license": "MIT", + "dependencies": { + "@deepseek-ai/schemastery": "~3.18.4", + "zod": "^4.4.3" + }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-sandbox": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-experimental-speech-to-text": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2" } }, - "node_modules/@deepseek-ai/dsh-fs-local": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-fs-local/-/dsh-fs-local-0.1.5-rc.2.tgz", - "integrity": "sha512-akUTz9D/N0ruSOzytZ8SZ330SdzG75fd7DzHsJ7KJzSif/QM0Y+RpOmGMnjlJzit4HDV2A4Etn80wSzstyp82A==", + "node_modules/@deepseek-ai/dsh-experimental-auto-review": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-experimental-auto-review/-/dsh-experimental-auto-review-0.1.7-rc.2.tgz", + "integrity": "sha512-qycXHx0+rxiu15vN3d5VOK5mIsKxk6yFteISHaMrEd7A+Y7aLAnJBhnKtBV0GObEfpuUjAsEbB0/N6htIxSMLA==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2", - "koffi": "^3.1.0" + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-fs": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-agent-instructions": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-permission-presets": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2" } }, - "node_modules/@deepseek-ai/dsh-fs-observation-policy": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-fs-observation-policy/-/dsh-fs-observation-policy-0.1.5-rc.2.tgz", - "integrity": "sha512-AntY5dfkTL8WugNGHkJxCEffaTFHqdXaYm7ZrerexnLiZQscDRRjf9zI00JwOmlFM/IrioCuLf5cERfhZN5GYw==", + "node_modules/@deepseek-ai/dsh-experimental-client-ui-agent-team": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-experimental-client-ui-agent-team/-/dsh-experimental-client-ui-agent-team-0.1.7-rc.2.tgz", + "integrity": "sha512-K74WkKbc5ctqjVYxO3HHdBnINWvlVM39aMFIZntIH7PMK9HVRzzD0D51keigWAZhdvUVWwcX1IO7VW5ALg9TPg==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-fs": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-api-session-controller": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-locale": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-conversation": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-primitives": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-renderer": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-slots": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-workspace": "0.1.7-rc.2", + "@deepseek-ai/dsh-experimental-agent-team": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2" } }, - "node_modules/@deepseek-ai/dsh-fs-sandbox": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-fs-sandbox/-/dsh-fs-sandbox-0.1.5-rc.2.tgz", - "integrity": "sha512-eUxNsnM+TsjGw5OleOIcAhMnFhmQ4OAZoBYeiRMSeOMuCKWEjhxUGN8S8Hg1HxPaZVeIrUV7qFsNQzhehKj7wg==", + "node_modules/@deepseek-ai/dsh-experimental-client-ui-voice-input": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-experimental-client-ui-voice-input/-/dsh-experimental-client-ui-voice-input-0.1.7-rc.2.tgz", + "integrity": "sha512-JuFJgrCoG+4gePKZlJjmCAgZN4l7TGMT7xnGEY8jr4cnKHjdyB5buMRGqNo6gF6Bu6UCJVtc1+oqsFuCz2vbHA==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-fs": "^0.1.5-rc.2", - "@deepseek-ai/dsh-fs-local": "^0.1.5-rc.2", - "@deepseek-ai/dsh-sandbox": "^0.1.5-rc.2", - "@deepseek-ai/dsh-sandbox-policy": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-api-gateway": "0.1.7-rc.2", + "@deepseek-ai/dsh-api-remotes": "0.1.7-rc.2", + "@deepseek-ai/dsh-api-session-controller": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-locale": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-store": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-conversation": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-plugin-manager": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-primitives": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-renderer": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-slots": "0.1.7-rc.2", + "@deepseek-ai/dsh-experimental-api-speech-to-text": "0.1.7-rc.2", + "@deepseek-ai/dsh-experimental-speech-to-text": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2" + } + }, + "node_modules/@deepseek-ai/dsh-experimental-speech-to-text": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-experimental-speech-to-text/-/dsh-experimental-speech-to-text-0.1.7-rc.2.tgz", + "integrity": "sha512-AYsU6xhb/Y2lBoHU+qBB4X3NKYnCOmJhP6lLhh8xl2hAxY8UPcOKMeUFatTQtMUXD3lL2flg4UwXM7vJAApj0Q==", + "license": "MIT", + "dependencies": { + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/cordis-plugin-loader": "~1.0.5", + "@deepseek-ai/dsh-settings": "0.1.7-rc.2" + }, + "peerDependenciesMeta": { + "@deepseek-ai/cordis-plugin-loader": { + "optional": true + } + } + }, + "node_modules/@deepseek-ai/dsh-experimental-speech-to-text-sensevoice": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-experimental-speech-to-text-sensevoice/-/dsh-experimental-speech-to-text-sensevoice-0.1.7-rc.2.tgz", + "integrity": "sha512-SVg4+Bz1QnP4bRr6lBmV39fxyDPiy6mg5f9loAM+RUI4mC6suKjDnt3A0VLhJ5TTIziFe5r5tfPRsCH6Ts2zzg==", + "license": "MIT", + "dependencies": { + "@deepseek-ai/dsh-timeout": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4", + "sherpa-onnx-node": "1.13.8", + "zod": "^4.4.3" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-experimental-speech-to-text": "0.1.7-rc.2", + "@deepseek-ai/dsh-subprocess": "0.1.7-rc.2" + } + }, + "node_modules/@deepseek-ai/dsh-experimental-tool-agent-team": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-experimental-tool-agent-team/-/dsh-experimental-tool-agent-team-0.1.7-rc.2.tgz", + "integrity": "sha512-WQ4NkWo6c1WPv5D6VP3wIhWyEkFk5+ShsBk+ecwhzNKWi4Q8v92rqwoIBy0xtPiCkHdVcrjlD37H3PS8oAUQYQ==", + "license": "MIT", + "dependencies": { + "@deepseek-ai/schemastery": "~3.18.4" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-experimental-agent-team": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2" + } + }, + "node_modules/@deepseek-ai/dsh-experimental-voice-input-bundle": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-experimental-voice-input-bundle/-/dsh-experimental-voice-input-bundle-0.1.7-rc.2.tgz", + "integrity": "sha512-IoaMPoVxuTFx+SRrXWeuClKCBlpeQGUKFiNozmRLM63/EzZmTqB8yLxzSkHtL3TYfnx6gMU6m31RRKUYbdjimQ==", + "license": "MIT", + "dependencies": { + "@deepseek-ai/dsh-experimental-api-speech-to-text": "0.1.7-rc.2", + "@deepseek-ai/dsh-experimental-client-ui-voice-input": "0.1.7-rc.2", + "@deepseek-ai/dsh-experimental-speech-to-text": "0.1.7-rc.2", + "@deepseek-ai/dsh-experimental-speech-to-text-sensevoice": "0.1.7-rc.2" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4" + } + }, + "node_modules/@deepseek-ai/dsh-file-reference": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-file-reference/-/dsh-file-reference-0.1.7-rc.2.tgz", + "integrity": "sha512-kjtnauKgQSnoQ6acOhVrRFFsIiIb2NnLXV08Inow34is6oANH0Ti2EqJmOVFlt/7mqcEYHxBvJUbh/DY6h/vmQ==", + "license": "MIT", + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2" + } + }, + "node_modules/@deepseek-ai/dsh-file-reference-local": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-file-reference-local/-/dsh-file-reference-local-0.1.7-rc.2.tgz", + "integrity": "sha512-DRsbWY4NCWIeyhnnGpbGKsbiXf0m/FB51SI/4xdGL/TLZbZjIdROtBzXthL2IYG62QDtQMzEVs+jsg9zaBAuUw==", + "license": "MIT", + "dependencies": { + "@deepseek-ai/schemastery": "~3.18.4" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-file-reference": "0.1.7-rc.2", + "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2" + } + }, + "node_modules/@deepseek-ai/dsh-fs": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-fs/-/dsh-fs-0.1.7-rc.2.tgz", + "integrity": "sha512-3ES1FKLM4asLvFS+yBcatzRNGINfUx/Cl+x+JzGhEK5QWX3aCxpH8Oa9Z4T9k0McBStWg1CTfHziRR8trHPYyw==", + "license": "MIT", + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox": "0.1.7-rc.2" + } + }, + "node_modules/@deepseek-ai/dsh-fs-local": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-fs-local/-/dsh-fs-local-0.1.7-rc.2.tgz", + "integrity": "sha512-7XlSqUY2nk1S0GQNU7f7rimhBnYZYdtOtW5xr3oApHuaiWyP2Qj9D2Y0Xq5+jyFz7kQ9hoNHq3gA+g5IK1Dofw==", + "license": "MIT", + "dependencies": { + "@deepseek-ai/schemastery": "~3.18.4", + "chokidar": "^4.0.3", + "koffi": "^3.1.0" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-fs": "0.1.7-rc.2" + } + }, + "node_modules/@deepseek-ai/dsh-fs-observation-policy": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-fs-observation-policy/-/dsh-fs-observation-policy-0.1.7-rc.2.tgz", + "integrity": "sha512-htzbOb2krclujHcSMu4eLiMxE1zl1fNlQylN7RReU3ais5J08pJPzenNLH+M18zecRWr7IljxI/mrGAXlH0Upw==", + "license": "MIT", + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-fs": "0.1.7-rc.2" + } + }, + "node_modules/@deepseek-ai/dsh-fs-sandbox": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-fs-sandbox/-/dsh-fs-sandbox-0.1.7-rc.2.tgz", + "integrity": "sha512-E1f+stkuTefmMeOQ1lEQJum42igtOeg+V5J5P92dZp5QObt3VT1EcIkywe9zFHtEJ+jExVzACLIxj8XNmisiiA==", + "license": "MIT", + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-fs": "0.1.7-rc.2", + "@deepseek-ai/dsh-fs-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox-policy": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-goal": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-goal/-/dsh-goal-0.1.5-rc.2.tgz", - "integrity": "sha512-atFJaoijwAz5yZ119f82I7jMx3tGCwXOz6qoY0Likb2c5DpumWZTJgs5L19OhKbhvEW+r2MAC4MYKaUxtrbb0Q==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-goal/-/dsh-goal-0.1.7-rc.2.tgz", + "integrity": "sha512-9ULU4IMWGBkUTzOoQC+3tuyy7J/oFq5J05rv2PyxpLZyJGf5lRRDfhNjm/PAfbKzuXAPGEB2aOQ8eAdZ1RCnHA==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/schemastery": "~3.18.4", "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-scope": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.2", - "@deepseek-ai/dsh-typert-protocol": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-scope": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-goal-round-driver": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-goal-round-driver/-/dsh-goal-round-driver-0.1.5-rc.2.tgz", - "integrity": "sha512-9uEhBTqIVxJklNkxCvDDD9upyEa6mIYlB5kfan37zixGDfKSgj83VSwXjJhVqN0b/2CLQDuPxtXgFuSdItoR0g==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-goal-round-driver/-/dsh-goal-round-driver-0.1.7-rc.2.tgz", + "integrity": "sha512-pIIDOhEGMr/BMLsRa+L7Q+qZgQupeAcT5wA7z3GEoZB/ABH4KTsepg0BZadZyuGEen4t0x6AG2pK2K+evonJLQ==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-goal": "^0.1.5-rc.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-goal": "0.1.7-rc.2", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-headless": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-headless/-/dsh-headless-0.1.5-rc.2.tgz", - "integrity": "sha512-EJ0QCWo+0WCTq2SFFRZpbMcGwkSh/uBRNJmE6nx9Eh1Qlt4y3I4G3k+p2mn276ujPbGfEadaI5KLciLOHsZQXQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-headless/-/dsh-headless-0.1.7-rc.2.tgz", + "integrity": "sha512-3M2QA46ATJNwdz2AYB5MpQMZot1ehwH36AqRBU2mNu9Iv8kC9cjsSST0eBnk1EyjF4jTqh5h6PZAkgLOBOExyA==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/dsh-cmdline": "^0.1.5-rc.2", - "@deepseek-ai/dsh-code-runtime-worker-thread": "^0.1.5-rc.2", - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-cmdline": "0.1.7-rc.2", + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4", "commander": "^15.0.0" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/cordis-plugin-loader": "^1.0.3", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-agent-default-model": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/cordis-plugin-loader": "~1.0.5", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-agent-default-model": "0.1.7-rc.2", + "@deepseek-ai/dsh-fs": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-query": "0.1.7-rc.2" + } + }, + "node_modules/@deepseek-ai/dsh-hmr": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-hmr/-/dsh-hmr-0.1.7-rc.2.tgz", + "integrity": "sha512-+Zz8Fz9wwaOQ1h2KYc8BHPsCNIifRZVb+mPMRgl8N2ECByO8ZlarN0He4NjwWR9T/zgMEOvvhRf1aumPLs6TIw==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@deepseek-ai/schemastery": "~3.18.4", + "chokidar": "^4.0.3", + "picomatch": "^4.0.3" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/cordis-plugin-include": "~1.0.9", + "@deepseek-ai/cordis-plugin-loader": "~1.0.5", + "@deepseek-ai/cordis-plugin-timer": "~1.1.6", + "@deepseek-ai/dsh-app-boot": "0.1.7-rc.2", + "@deepseek-ai/dsh-cmdline": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-home-paths": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-home-paths/-/dsh-home-paths-0.1.5-rc.2.tgz", - "integrity": "sha512-Ek+DH9+MTiulfWDMKo5r335k4I9XIItk+jq8YaPihpK3klSeiKLW/SpKJhFodRnW1CwEyjIlt2XriycRvceIiw==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-home-paths/-/dsh-home-paths-0.1.7-rc.2.tgz", + "integrity": "sha512-LafnefS9IttUziet9cQfCNfyBVce+aCPBGFrZGxsQJZYZXvkDQH94QHzDIxOIJfwwHuKC36fP5riD+Eajpx5jw==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-hook-protocol": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-hook-protocol/-/dsh-hook-protocol-0.1.5-rc.2.tgz", - "integrity": "sha512-qJ0AlRhLsj31tro0vzubhXarigq8EDi3PwyOxxhoSxZUbGqOBWx+QLNEOC5E5tuob6DYA64Qbmgh7Cbz8vYgiA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-hook-protocol/-/dsh-hook-protocol-0.1.7-rc.2.tgz", + "integrity": "sha512-MoTAuM84wpxOQX5N56PQFgWYS8mqxjJ7CbIvP+3KSa//+z6Ob7MWQAwi36S5VLGvywFMbzxpImCz9EawRuE5fQ==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-shell": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-shell": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-hooks-claude-code": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-hooks-claude-code/-/dsh-hooks-claude-code-0.1.5-rc.2.tgz", - "integrity": "sha512-wdsl+A8tvAk66N5ozqyxmJ5t30AQQ5byBaKYL60Vx1jFoWXaD83piPcD1BAPZ+hVoWI1a9PCUDowFzAzq/PnwQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-hooks-claude-code/-/dsh-hooks-claude-code-0.1.7-rc.2.tgz", + "integrity": "sha512-TJx0FUFm6GZEjJKz4o8HiuBfk3qbOEAAEoIfEIy0Kgo2JDWgl04o/c7ZOf9KgurdZt/WpfVt2dG6nEQg6UJ7mA==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-hook-protocol": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.2", - "@deepseek-ai/dsh-subagent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-hook-protocol": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2", + "@deepseek-ai/dsh-subagent": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-hooks-codex": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-hooks-codex/-/dsh-hooks-codex-0.1.5-rc.2.tgz", - "integrity": "sha512-WVmZIWJJ04A7rpe80wcd4+O4MfJbBJdtiPwM99B2DASpm/Igyz3t0mNzNfbWe3zmznRKTHFz1imqhaPdceY1Ng==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-hooks-codex/-/dsh-hooks-codex-0.1.7-rc.2.tgz", + "integrity": "sha512-xsGEcQOvt42vdkCQtJgV4/w136EJKALjs7TkljeeWKkQKJyEWvPjaUV3vJtJetd/wdqcv2vof1eNxfRzRybIRQ==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-hook-protocol": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-hook-protocol": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-host-directory-picker": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-host-directory-picker/-/dsh-host-directory-picker-0.1.5-rc.2.tgz", - "integrity": "sha512-a0fVQTX0tM7Zl+1WWkCO3Pd+64CW1CwfOJrNxpTuz7EOp6wOtsYDRHlDyJUSKAOMJArS4xN2qkkt8n3eIkNkbQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-host-directory-picker/-/dsh-host-directory-picker-0.1.7-rc.2.tgz", + "integrity": "sha512-J/by0v0yRI5LHPPaHCokDXEJNKNEPCaDziJueGI+fxpXfXwFvpoHp3hjwdWiN+bLPDdZL6DSQLh1evC46wobtQ==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-host-directory-picker-auto": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-host-directory-picker-auto/-/dsh-host-directory-picker-auto-0.1.5-rc.2.tgz", - "integrity": "sha512-R6nl8L/xAd1kmlCZc8xOl4jxp69HMmZ75vWdRswM3MXrM3GIgNiF7AKwK0JlNIKPc6M4vsC3sGMR4yR0XtdhrA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-host-directory-picker-auto/-/dsh-host-directory-picker-auto-0.1.7-rc.2.tgz", + "integrity": "sha512-o2YCHr3uioc4HyB/s24gKDr1ZktEAHsuhqQocfTWPLivwe2Uozdvh/Kjq1LU9pBNeBGTHzUvtkhgVMTCpQXedg==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-launch-environment": "^0.1.5-rc.2" + "@deepseek-ai/dsh-launch-environment": "0.1.7-rc.2" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/cordis-plugin-loader": "^1.0.3", - "@deepseek-ai/dsh-client-ui-directory-picker-browse": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-directory-picker-native": "^0.1.5-rc.2", - "@deepseek-ai/dsh-host-directory-picker-browse": "^0.1.5-rc.2", - "@deepseek-ai/dsh-host-directory-picker-native": "^0.1.5-rc.2", - "@deepseek-ai/dsh-host-webserver": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/cordis-plugin-loader": "~1.0.5", + "@deepseek-ai/dsh-client-ui-directory-picker-browse": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-directory-picker-native": "0.1.7-rc.2", + "@deepseek-ai/dsh-host-directory-picker-browse": "0.1.7-rc.2", + "@deepseek-ai/dsh-host-directory-picker-native": "0.1.7-rc.2", + "@deepseek-ai/dsh-host-webserver": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-host-directory-picker-browse": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-host-directory-picker-browse/-/dsh-host-directory-picker-browse-0.1.5-rc.2.tgz", - "integrity": "sha512-8xnMfNt5XcO81qshrC/zzD2NYfLKYEQjVzcu7r+u/ymro7jLypRAp7DQFGuRZiQV4jIF9bdTTT2gcCYaXkWi5A==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-host-directory-picker-browse/-/dsh-host-directory-picker-browse-0.1.7-rc.2.tgz", + "integrity": "sha512-XV+iP2MXbeQ6nRKCiTGLE7ntDX6/SbJJ7hK0f8UO7WbC6TrbaCWtLTiCQ3xgqC314Zc3YpOVZPs7LGUS3P013w==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-host-directory-picker": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/dsh-host-directory-picker": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-host-directory-picker-native": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-host-directory-picker-native/-/dsh-host-directory-picker-native-0.1.5-rc.2.tgz", - "integrity": "sha512-bBsGBR+tE/w9Dw9rM2Lh/4umjYtGnEmQ9YEss7vrKzo/KFuMfgNPkXHKb6A+AoCfSVd7L7PqkocoA5qVRQND2g==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-host-directory-picker-native/-/dsh-host-directory-picker-native-0.1.7-rc.2.tgz", + "integrity": "sha512-97pxHwk3bhMRgBlTH36W3fEyLI6JeuG6oaKLEVCyS8xduhAeWGVAv3M3JxmeTAQsKvIxaqwlVJ18bgHc7Qw6tQ==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-host-directory-picker": "^0.1.5-rc.2", - "@deepseek-ai/dsh-native-command": "^0.1.5-rc.2", + "@deepseek-ai/dsh-host-directory-picker": "0.1.7-rc.2", + "@deepseek-ai/dsh-native-command": "0.1.7-rc.2", "koffi": "^3.1.0" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-host-frontend-static": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-host-frontend-static/-/dsh-host-frontend-static-0.1.5-rc.2.tgz", - "integrity": "sha512-cTc0vTyejoYBE0XWOXw/nEDTcveAF9ucYEcaUVintvoo4b4WGG8fuTZSJX9EVkvXggAvxvFjSiYAQ8o2zP7qrA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-host-frontend-static/-/dsh-host-frontend-static-0.1.7-rc.2.tgz", + "integrity": "sha512-G1DHZONOfyxiPyvEMyJns3EFPANz5svjxh+gRK0PDC7WJv6fivvJ0agR3D2wa0RIRhQLML7FMw9C1MD2Hzrfxw==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-client-connection": "^0.1.5-rc.2", - "@deepseek-ai/dsh-host-webserver": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-client-connection": "0.1.7-rc.2", + "@deepseek-ai/dsh-host-webserver": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-host-open-in-app": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-host-open-in-app/-/dsh-host-open-in-app-0.1.5-rc.2.tgz", - "integrity": "sha512-8CBzeDQYMmz4IG7xp7a8mp0xeQ9v6FS9qcN2pOdfRBTXmMk8zHroBpiuW+26yEQmP4HsAi1BECgcWQ03eNoOCg==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-host-open-in-app/-/dsh-host-open-in-app-0.1.7-rc.2.tgz", + "integrity": "sha512-bozNEbEAeCmk6fny4qaDioLYLvX9xLmHPYVAeXdXoLRML7qiwIP88BbH8NxpibreCcFKFi9uMpx/GdoiwK2bMw==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-launch-environment": "^0.1.5-rc.2", - "@deepseek-ai/dsh-native-command": "^0.1.5-rc.2", - "@deepseek-ai/dsh-subprocess": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/dsh-launch-environment": "0.1.7-rc.2", + "@deepseek-ai/dsh-native-command": "0.1.7-rc.2", + "@deepseek-ai/dsh-subprocess": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-host-plugin-inventory": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-host-plugin-inventory/-/dsh-host-plugin-inventory-0.1.5-rc.2.tgz", - "integrity": "sha512-U7RTRLRs+O18ru6KzUy7LvMk/IgXnkWSalogg0abfA+QU020XZi+UpwZqM567RzC7MtpxijQk8bulGunu0lifw==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-host-plugin-inventory/-/dsh-host-plugin-inventory-0.1.7-rc.2.tgz", + "integrity": "sha512-krS/FKI7cacoUtjpIaZnFQZy4cM2DnshsP//jafFdC1LyKyh5gG97MPmQ37jRM5Gm4VDJfDj3ojqWzx3BrP1sQ==", "license": "MIT", "dependencies": { "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/cordis-plugin-loader": "^1.0.3", - "@deepseek-ai/dsh-agent-presets": "^0.1.5-rc.2", - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/dsh-typert-protocol": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/cordis-plugin-loader": "~1.0.5", + "@deepseek-ai/dsh-agent-preset-registry": "0.1.7-rc.2", + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2" }, "peerDependenciesMeta": { - "@deepseek-ai/dsh-agent-presets": { + "@deepseek-ai/dsh-agent-preset-registry": { "optional": true } } }, "node_modules/@deepseek-ai/dsh-host-webserver": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-host-webserver/-/dsh-host-webserver-0.1.5-rc.2.tgz", - "integrity": "sha512-lFgGm9wDrHiTBANzsdoWzdfPSjWYuDFwCoNQ4Uko57Fo5XASL2unfRHGm1xZ828rwEYuGwRvJHMOuoP/17VmlA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-host-webserver/-/dsh-host-webserver-0.1.7-rc.2.tgz", + "integrity": "sha512-0ex5NsJFvpqchfnar/IPtNOG5Tx7PmtUO3/zVptT4MJs5OOrvtjNYHpZ6DGntmnpupgXnci1cUsQJIfG3D+U+Q==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/schemastery": "~3.18.4", "compression": "^1.8.1", "negotiator": "^1.0.0" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-http-proxy": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-http-proxy/-/dsh-http-proxy-0.1.5-rc.2.tgz", - "integrity": "sha512-dRK8SMoxyY1F1ulzfnslI++9RDvXLGkPxahUwrnSQl8gTL9R69ZEh6P9dtcIVWMbstaYcq4CqWvo2/qUHSYRhA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-http-proxy/-/dsh-http-proxy-0.1.7-rc.2.tgz", + "integrity": "sha512-sG0bj5U6CX54BLWizf/6QtqYgtbv56qSe7wW/0B+DxmN+TtOr4s+6TRWLLMUxH2SCR9th20SwiEDHvuLf17Q7Q==", "license": "MIT", "dependencies": { "undici": "^8.10.0" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-invariants": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-invariants/-/dsh-invariants-0.1.5-rc.2.tgz", - "integrity": "sha512-oUxttB2yjAgkk47AiXOCxk9GwnfGvIEGsQfnMD7fukwIdD3KLJObU7+nz63tbFN80rjwMI8rg+p9QBQ10KU5+g==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-invariants/-/dsh-invariants-0.1.7-rc.2.tgz", + "integrity": "sha512-GY2lY2TUUH2Qk1ZnrB3Q5+lXSh4webn1kbt5nQfhojVmNbist/f3dJC8JJa7XXOUNvqAgqRN9IZ4egbDZ9LLxQ==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-jobs": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-jobs/-/dsh-jobs-0.1.5-rc.2.tgz", - "integrity": "sha512-C3rBEuWhtDBlxMeKykFvSfBwjSPxkLsvKCFq8BrFdjDmZC1lI9GooMjPZkPxXVbogVrcOBaYVtJdOYJ4+rIpQg==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-jobs/-/dsh-jobs-0.1.7-rc.2.tgz", + "integrity": "sha512-bzbdcQ1dzCAGjYDs2J+YiwG58cDpASecJ4N6euUJNl0CCmnDETwCUhCpyMKDKCWcExdG3XcHmCjaCnL2hZIC0g==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-workspace": "0.1.7-rc.2" + }, + "peerDependenciesMeta": { + "@deepseek-ai/dsh-workspace": { + "optional": true + } } }, "node_modules/@deepseek-ai/dsh-jobs-local": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-jobs-local/-/dsh-jobs-local-0.1.5-rc.2.tgz", - "integrity": "sha512-PCDLSktONJ+If3QCcPlRskVLXIa8hG/l0pBIgKNllz4mb7CmYlJ5w1H9pWyrFZllMO0Wm94ZS9aP3SnUcJ8R1g==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-jobs-local/-/dsh-jobs-local-0.1.7-rc.2.tgz", + "integrity": "sha512-DE0HLEuI15Vw1ncXLDESUIBTdWhrXgKWV3g/jupEGCwmm6GCqC9W9cjJPmbLP7JQGB7UPkui5DrIft+8MYL6Nw==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-jobs": "^0.1.5-rc.2", - "@deepseek-ai/dsh-scope": "^0.1.5-rc.2", - "@deepseek-ai/dsh-timeout": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-jobs": "0.1.7-rc.2", + "@deepseek-ai/dsh-scope": "0.1.7-rc.2", + "@deepseek-ai/dsh-timeout": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-launch-environment": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-launch-environment/-/dsh-launch-environment-0.1.5-rc.2.tgz", - "integrity": "sha512-Cr35kPA3W7skJsPLJhUExLDAjVKCmvJgkog0m8EZ+XdK8RlBDsWiH2peRWFtFOjt8QOOeEkupPs1VDpWORIRyw==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-launch-environment/-/dsh-launch-environment-0.1.7-rc.2.tgz", + "integrity": "sha512-i8U15ebCS4tWtL2mnuhfl0h5XXBagtbiGO63/OMeHpfWb5sHUvTYBNWTDxmlMjLDkTNQgPsXmRl0UrbWKCSJwg==", + "license": "MIT", + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4" + } + }, + "node_modules/@deepseek-ai/dsh-lazy-require": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-lazy-require/-/dsh-lazy-require-0.1.7-rc.2.tgz", + "integrity": "sha512-tJGmGfJzr+zXK9ZoDLFF9r8ZI5X5ARz945rl+tHTEDcgtm2NavkRbx4qjOg3kXoBasYGXtp18RGlBB2rWT7vGQ==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-llm": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-llm/-/dsh-llm-0.1.5-rc.2.tgz", - "integrity": "sha512-Z7BVsBkK24SE4EItQeow8PHms/9GP0DSTi337vTAa/RY7tNg2Snz3INcXUj6CPZfvntQr1in9op9wLI+rfNsqA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-llm/-/dsh-llm-0.1.7-rc.2.tgz", + "integrity": "sha512-hNT3ovFnbNDQ8g544bh2Q9ORX40aI6Y+jhjer1lETeHS4g0jTjqUUVfARCTA7uAFvHucSBg2rFgbisIktmJCxw==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/dsh-timeout": "^0.1.5-rc.2", - "@deepseek-ai/dsh-typert-protocol": "^0.1.5-rc.2", - "@deepseek-ai/dsh-util-crypto": "^0.1.5-rc.2", - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-timeout": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2", + "@deepseek-ai/dsh-util-crypto": "0.1.7-rc.2", + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4", "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-llm-deepseek": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-llm-deepseek/-/dsh-llm-deepseek-0.1.5-rc.2.tgz", - "integrity": "sha512-qNRbLsE2ro+AfD7NgJwTukQLG82gIkbAISjDHgv0au7TocfPkNkUWSu20mTaBcuLGXzfSgBVn4oYx5N3ws6KVg==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-llm-deepseek/-/dsh-llm-deepseek-0.1.7-rc.2.tgz", + "integrity": "sha512-bFHhDxegsawOI2uqGHAbPoYiRM9Lpq5g31TeqVYAMcMCpa5qbk1wGUsAzCP+eJM/Sbb19VHJpsJj/Op6UbBESQ==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/cosmokit": "~1.8.5", + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4", "eventsource-parser": "^3.1.0" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-anonymous-user-id": "^0.1.5-rc.2", - "@deepseek-ai/dsh-atomic-write": "^0.1.5-rc.2", - "@deepseek-ai/dsh-attachment": "^0.1.5-rc.2", - "@deepseek-ai/dsh-credentials": "^0.1.5-rc.2", - "@deepseek-ai/dsh-deepseek-llm-api-extensions": "^0.1.5-rc.2", - "@deepseek-ai/dsh-fs": "^0.1.5-rc.2", - "@deepseek-ai/dsh-home-paths": "^0.1.5-rc.2", - "@deepseek-ai/dsh-launch-environment": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-settings": "^0.1.5-rc.2", - "@deepseek-ai/dsh-timeout": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/cordis-plugin-loader": "~1.0.5", + "@deepseek-ai/dsh-anonymous-user-id": "0.1.7-rc.2", + "@deepseek-ai/dsh-atomic-write": "0.1.7-rc.2", + "@deepseek-ai/dsh-attachment": "0.1.7-rc.2", + "@deepseek-ai/dsh-deepseek-llm-api-extensions": "0.1.7-rc.2", + "@deepseek-ai/dsh-fs": "0.1.7-rc.2", + "@deepseek-ai/dsh-home-paths": "0.1.7-rc.2", + "@deepseek-ai/dsh-launch-environment": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-timeout": "0.1.7-rc.2" + }, + "peerDependenciesMeta": { + "@deepseek-ai/cordis-plugin-loader": { + "optional": true + } + } + }, + "node_modules/@deepseek-ai/dsh-llm-deepseek-account": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-llm-deepseek-account/-/dsh-llm-deepseek-account-0.1.7-rc.2.tgz", + "integrity": "sha512-Yq3oVAYih7b+kvb4S82fqcKkOmVtoT1WoxCQ7Y27SYbir2gO6g/QqVk3CsLS0Xqnq1CwBAH4xU3r2m+siq2o6A==", + "license": "MIT", + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/cordis-plugin-loader": "~1.0.5", + "@deepseek-ai/dsh-deepseek-account": "0.1.7-rc.2", + "@deepseek-ai/dsh-launch-environment": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm-deepseek": "0.1.7-rc.2" + }, + "peerDependenciesMeta": { + "@deepseek-ai/cordis-plugin-loader": { + "optional": true + }, + "@deepseek-ai/dsh-deepseek-account": { + "optional": true + } + } + }, + "node_modules/@deepseek-ai/dsh-llm-deepseek-api-key": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-llm-deepseek-api-key/-/dsh-llm-deepseek-api-key-0.1.7-rc.2.tgz", + "integrity": "sha512-Djc3LE0fZ73U+T75P81obElk9c5Fd7G25uNubtcFcSDKuo+tuJi8qEqvSTScCQVvTAsCPRQh7Ti5YjPKQdO29g==", + "license": "MIT", + "dependencies": { + "@deepseek-ai/schemastery": "~3.18.4" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/cordis-plugin-loader": "~1.0.5", + "@deepseek-ai/dsh-credentials": "0.1.7-rc.2", + "@deepseek-ai/dsh-launch-environment": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm-deepseek": "0.1.7-rc.2" + }, + "peerDependenciesMeta": { + "@deepseek-ai/cordis-plugin-loader": { + "optional": true + } } }, "node_modules/@deepseek-ai/dsh-llm-pi-ai": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-llm-pi-ai/-/dsh-llm-pi-ai-0.1.5-rc.2.tgz", - "integrity": "sha512-56/TRc857HqapiAia0OyWsKtWPaPOfivx1OMzWYsexhTsIvxIOetrj5IMF+tW6geeSm38vfOffn18gOb97NgEg==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-llm-pi-ai/-/dsh-llm-pi-ai-0.1.7-rc.2.tgz", + "integrity": "sha512-pkRHMAAu9v7Ko2yo+UzZmGg0rNlVymF3KjTch/z6kT9BfIxpI4dtNDkeibamszRvjqz3Oywm8uGm+Iwz0zW2sA==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4", "@earendil-works/pi-ai": "^0.85.1" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-attachment": "^0.1.5-rc.2", - "@deepseek-ai/dsh-authorization": "^0.1.5-rc.2", - "@deepseek-ai/dsh-credentials": "^0.1.5-rc.2", - "@deepseek-ai/dsh-fs": "^0.1.5-rc.2", - "@deepseek-ai/dsh-launch-environment": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-settings": "^0.1.5-rc.2", - "@deepseek-ai/dsh-timeout": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/cordis-plugin-loader": "~1.0.5", + "@deepseek-ai/dsh-attachment": "0.1.7-rc.2", + "@deepseek-ai/dsh-authorization": "0.1.7-rc.2", + "@deepseek-ai/dsh-credentials": "0.1.7-rc.2", + "@deepseek-ai/dsh-fs": "0.1.7-rc.2", + "@deepseek-ai/dsh-launch-environment": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-timeout": "0.1.7-rc.2" + }, + "peerDependenciesMeta": { + "@deepseek-ai/cordis-plugin-loader": { + "optional": true + } } }, "node_modules/@deepseek-ai/dsh-llm-retry": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-llm-retry/-/dsh-llm-retry-0.1.5-rc.2.tgz", - "integrity": "sha512-6jyxD9tdzePZMdA4BdvrbdnqSkNYv2M1Nac84urkOcc3D8Jc+QYMnXrpeDB4fZRWg/l7FoKXtfUdn4Mj3kY5ow==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-llm-retry/-/dsh-llm-retry-0.1.7-rc.2.tgz", + "integrity": "sha512-t3RP8ftkHFUXPRnpUGLogKsgXykJWPDad251qk8PvOHpWw/ex6HY8GqXm5YWSgbLHpEKHz+0gR7u6MyIdpqtxA==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/schemastery": "~3.18.4", "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.2", - "@deepseek-ai/dsh-timeout": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2", + "@deepseek-ai/dsh-timeout": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-mcp-client": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-mcp-client/-/dsh-mcp-client-0.1.5-rc.2.tgz", - "integrity": "sha512-L1uhXptzs63bne3fpe8By30xUu2KzC9bbo8t1RdasnRNxhevNJA/5/Z9ZenuMRh26XZh9THF+DVuudEH8PFIsQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-mcp-client/-/dsh-mcp-client-0.1.7-rc.2.tgz", + "integrity": "sha512-AUEhxqk8rPl41cIfi07/9dbIKKDOT0LWifX3K7xRki57X3Hd3XCT4PRiYekqt9sOJ7863d2t/knWk4pryieZtQ==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2", - "@modelcontextprotocol/sdk": "^1.12.0", - "zod": "^4.4.3" + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4", + "@modelcontextprotocol/client": "2.0.0" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-attachment": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-scope": "^0.1.5-rc.2", - "@deepseek-ai/dsh-subprocess": "^0.1.5-rc.2", - "@deepseek-ai/dsh-timeout": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-attachment": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-mcp-resources": "0.1.7-rc.2", + "@deepseek-ai/dsh-scope": "0.1.7-rc.2", + "@deepseek-ai/dsh-subprocess": "0.1.7-rc.2", + "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2", + "@deepseek-ai/dsh-timeout": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2" + }, + "peerDependenciesMeta": { + "@deepseek-ai/dsh-mcp-resources": { + "optional": true + }, + "@deepseek-ai/dsh-system-prompt": { + "optional": true + } + } + }, + "node_modules/@deepseek-ai/dsh-mcp-resources": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-mcp-resources/-/dsh-mcp-resources-0.1.7-rc.2.tgz", + "integrity": "sha512-V6G8Hdmh5gtvzzvlV8RgM43LbTOnoQnfmMdd8dBNoHKZLvv0XvcpmqZWNZVqpDP8NUx3/PGjo9SQK7R3gwROYg==", + "license": "MIT", + "dependencies": { + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-scope": "0.1.7-rc.2", + "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2" + }, + "peerDependenciesMeta": { + "@deepseek-ai/dsh-system-prompt": { + "optional": true + } } }, "node_modules/@deepseek-ai/dsh-message-feedback": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-message-feedback/-/dsh-message-feedback-0.1.5-rc.2.tgz", - "integrity": "sha512-oNLajqBpv5bkebQrzByUpNTlQPcCoLoreMKzYN0s6STwtHpTzOqj9vSzwk964TfFAYutcmfQoCHNY7j9jmw6iw==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-message-feedback/-/dsh-message-feedback-0.1.7-rc.2.tgz", + "integrity": "sha512-XYgpXXr9iqgiuCzpFzdoNR55tT+kyZ7xEYC0DuxdcK9JNHpQdQcckOZkJU8+MzJ1FjoYGijTSV+y5jSuhX2UlQ==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/schemastery": "~3.18.4", "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/dsh-command-feedback": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-persistence": "^0.1.5-rc.2", - "@deepseek-ai/dsh-typert-protocol": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-command-feedback": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-persistence": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-native-command": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-native-command/-/dsh-native-command-0.1.5-rc.2.tgz", - "integrity": "sha512-FFkiS4Izm5VC1l0bHuw3yExNDmqW0/ypSLt+RtH24GG/W5ofpFvwjGclYDUzSDa0MP5uPzhTMN6qgM76BAA40g==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-native-command/-/dsh-native-command-0.1.7-rc.2.tgz", + "integrity": "sha512-XObRF7I6fVAXWSWvAK0HVp+nT9ZLR6g6mPss6j2ciovW6wBiAm71O2wzi2S1YqmQXYNaGwvudolqJyMRtCSCxg==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" + } + }, + "node_modules/@deepseek-ai/dsh-office-to-pdf": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-office-to-pdf/-/dsh-office-to-pdf-0.1.7-rc.2.tgz", + "integrity": "sha512-4FQi4gTiSgPg6oCYcYv5eT8hewoOK1Y3sYBAMGmYwBcJXuy7e37qOGOAu9bKaowhTAc1bi0yofdNruBm7595eg==", + "license": "MIT", + "dependencies": { + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2", + "@deepseek-ai/libreoffice-kit": "^0.1.1", + "@deepseek-ai/schemastery": "~3.18.4", + "zod": "^4.4.3" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-output-retention": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-output-retention/-/dsh-output-retention-0.1.5-rc.2.tgz", - "integrity": "sha512-3eOx7EmMkttMcJfF/BT6e8A8b0SzWuLCxU+AdY9jBcU8ffZFspIPtMgJ86yNCMLdoZctbrmeSVwEdweMJWRhLA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-output-retention/-/dsh-output-retention-0.1.7-rc.2.tgz", + "integrity": "sha512-hQodzFmVrANIiDw3i662XkA++Jmj0TCFW2aG3/9RYpiR+wkxmEx1bmWv5MuTX9t5QZ7vdyaAUn3t8c11OGyxhw==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-package-manifest": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-package-manifest/-/dsh-package-manifest-0.1.5-rc.2.tgz", - "integrity": "sha512-PTieT+tXdV8TNK718JZCd9dpVZR52UMYu5i1nXPDPBpoq1fTP7lLSlgHvDEs6SpoJtdFPGNTe8+7KjELyUDDvw==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-package-manifest/-/dsh-package-manifest-0.1.7-rc.2.tgz", + "integrity": "sha512-oS6OD0emk+HD25B8FomvuAkqCg0aEooQEs/Tk7sZj9ww0uMXwYtU69Wnh4rFBQzp8pkZBYv9HeIzw67iBwDH0w==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-permission-presets": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-permission-presets/-/dsh-permission-presets-0.1.5-rc.2.tgz", - "integrity": "sha512-WeQ3a+mcWfGjv6PLJGvMIgIZNBiR9mCA+wsjFZvxjtuPdu8p8uILxnaodlXhWpSDQ+8oimRO3eBxNVuJdtX1eQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-permission-presets/-/dsh-permission-presets-0.1.7-rc.2.tgz", + "integrity": "sha512-ci5LzPdhsaxUSMq43a1LOF5wixuFWECf3BzrUSlnOHp4q+cssd6Pf50LADe/CukHJkP7yf+ns8EXhT20iDwvrg==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/schemastery": "~3.18.4", "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-commands": "^0.1.5-rc.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2", - "@deepseek-ai/dsh-sandbox": "^0.1.5-rc.2", - "@deepseek-ai/dsh-sandbox-policy": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.2", - "@deepseek-ai/dsh-settings": "^0.1.5-rc.2", - "@deepseek-ai/dsh-shell": "^0.1.5-rc.2", - "@deepseek-ai/dsh-user-approval": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-commands": "0.1.7-rc.2", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox-policy": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2", + "@deepseek-ai/dsh-shell": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2", + "@deepseek-ai/dsh-user-approval": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-persona": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-persona/-/dsh-persona-0.1.5-rc.2.tgz", - "integrity": "sha512-VYAoj8tmSmwBr8SzDfjoG+t0v4Y/clu7BIWjZB5rnyNXLl5RNiY8kVTttnYRBQE+2jLLXlcR7PBJlYkfig3Kiw==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-persona/-/dsh-persona-0.1.7-rc.2.tgz", + "integrity": "sha512-1PceaaPx/xlZpCOJmcHVs2nAxdtgGTNo4mpytrmeEstxxc1ZEno7AoDKeTuZcnC4HIdSXBsTZHTWndNUW+SeDQ==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-plan-mode": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-plan-mode/-/dsh-plan-mode-0.1.5-rc.2.tgz", - "integrity": "sha512-veJCNJ8qL1vTG5F1GBpBa+lmtBVm+P3kgXpHBCJbYGmZKyrmHj3kbkiVgqxDdxTwnOoQiVco1OcBQUIO/ofGxA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-plan-mode/-/dsh-plan-mode-0.1.7-rc.2.tgz", + "integrity": "sha512-Lj4btqbwnSaXC2mQkk8VHnOPqx/HFNQyuLLB/n6RgeEjbAVDeGzDWcjEy3vpT+7K9YY1zU0FxMwp7ON3cGDX7A==", "license": "MIT", "dependencies": { + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-commands": "^0.1.5-rc.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.2", - "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2", - "@deepseek-ai/dsh-user-questions": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-commands": "0.1.7-rc.2", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2", + "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2", + "@deepseek-ai/dsh-user-questions": "0.1.7-rc.2" }, "peerDependenciesMeta": { "@deepseek-ai/dsh-commands": { @@ -3289,465 +3859,559 @@ } } }, + "node_modules/@deepseek-ai/dsh-plugin-manager": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-plugin-manager/-/dsh-plugin-manager-0.1.7-rc.2.tgz", + "integrity": "sha512-jYMEyz8fJWa099wvs7meXCOC+W9n2N5mxDL4hze/GDU+t9+brMrpnif6Ind8ENTu/RXVx8O40iCCsPcUXGwa2Q==", + "license": "MIT", + "dependencies": { + "@deepseek-ai/dsh-app-boot": "0.1.7-rc.2", + "@deepseek-ai/dsh-atomic-write": "0.1.7-rc.2", + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4", + "execa": "^10.0.0", + "yaml": "^2.9.0", + "zod": "^4.4.3" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/cordis-plugin-loader": "~1.0.5", + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-hmr": "0.1.7-rc.2", + "@deepseek-ai/dsh-host-plugin-inventory": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox-policy": "0.1.7-rc.2", + "@deepseek-ai/dsh-subprocess": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2", + "@deepseek-ai/dsh-user-approval": "0.1.7-rc.2" + }, + "peerDependenciesMeta": { + "@deepseek-ai/dsh-hmr": { + "optional": true + }, + "@deepseek-ai/dsh-user-approval": { + "optional": true + } + } + }, "node_modules/@deepseek-ai/dsh-plugin-package-inventory-deepseek": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-plugin-package-inventory-deepseek/-/dsh-plugin-package-inventory-deepseek-0.1.5-rc.2.tgz", - "integrity": "sha512-X/6mHIXFoFj6KSj0NBA2RC1xQaHtKnj1QS703AypNaq9+rxn3su3oFnZeWulLx0Tex4URfSmIo8SD1pkJkgUeg==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-plugin-package-inventory-deepseek/-/dsh-plugin-package-inventory-deepseek-0.1.7-rc.2.tgz", + "integrity": "sha512-Y+3VG3feOpjrwFupkr6jAncASs4As82VswGclr7FzqnzGz6GS2YIlALe3EaQ4sBygN1gE3cnXPFLFUhFXOzEtw==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/cordis-plugin-loader": "^1.0.3", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-agent-presets": "^0.1.5-rc.2", - "@deepseek-ai/dsh-deepseek-llm-api-extensions": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/cordis-plugin-loader": "~1.0.5", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-agent-preset-registry": "0.1.7-rc.2", + "@deepseek-ai/dsh-deepseek-llm-api-extensions": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2" }, "peerDependenciesMeta": { - "@deepseek-ai/dsh-agent-presets": { + "@deepseek-ai/dsh-agent-preset-registry": { "optional": true } } }, + "node_modules/@deepseek-ai/dsh-ptc-runtime": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-ptc-runtime/-/dsh-ptc-runtime-0.1.7-rc.2.tgz", + "integrity": "sha512-zRFwSSUgTpKuFQTVwnuNO4067Gyi//4C4RRLaUntXaHkZv3z1S07f1fTaYwX4+ubIIAuAVeEsczxf6tPgZ8P5g==", + "license": "MIT", + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-sandbox": "0.1.7-rc.2" + } + }, + "node_modules/@deepseek-ai/dsh-ptc-runtime-node": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-ptc-runtime-node/-/dsh-ptc-runtime-node-0.1.7-rc.2.tgz", + "integrity": "sha512-E+c60QE0Lh4GCw7yDkvO56E17uRqbiT1ehJxdmFMmpu7hg3wbTT4rNB+w6qVsy5RUs8LSW7bsoSIk9ibW4R9ow==", + "license": "MIT", + "dependencies": { + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-fs": "0.1.7-rc.2", + "@deepseek-ai/dsh-ptc-runtime": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox-policy": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-subprocess": "0.1.7-rc.2", + "@deepseek-ai/dsh-timeout": "0.1.7-rc.2" + } + }, "node_modules/@deepseek-ai/dsh-pwsh-local": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-pwsh-local/-/dsh-pwsh-local-0.1.5-rc.2.tgz", - "integrity": "sha512-TwH/xwDRtgk3LyQraG4VoaIaItFSuorTTqyJ3nzuyLOsXq0I8nNYQr/wuaoRjkiDyzFTDeEVMCKq6zEEoLLz1Q==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-pwsh-local/-/dsh-pwsh-local-0.1.7-rc.2.tgz", + "integrity": "sha512-OJlGS7JLJe5CcLMvVdbxryS6bKW5pfYN2emIeTYhSu+tBsKAiah8kdD+2EOwC0XMq24NcwgKO7xlNmS8oIrurQ==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-settings": "^0.1.5-rc.2", - "@deepseek-ai/dsh-shell": "^0.1.5-rc.2", - "@deepseek-ai/dsh-subprocess": "^0.1.5-rc.2", - "@deepseek-ai/dsh-timeout": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-shell": "0.1.7-rc.2", + "@deepseek-ai/dsh-subprocess": "0.1.7-rc.2", + "@deepseek-ai/dsh-timeout": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-pwsh-sandbox": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-pwsh-sandbox/-/dsh-pwsh-sandbox-0.1.5-rc.2.tgz", - "integrity": "sha512-AYTAiy8wQwVoHO47e+hnG73GvHdmg+bKy3bFnrPDANCqnRZh9TJIbkxHxtJnfpBnNCcs2fhhCo6yHtGFYl7KHg==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-pwsh-sandbox/-/dsh-pwsh-sandbox-0.1.7-rc.2.tgz", + "integrity": "sha512-c3kXLNhf8fNL7nt8NfJwcHU0jPvRiy6IPF+DHtT/Tp7+NhytHwj8vR3Ln7GIwsXGNU2hJbaD63S2IStjWLaylQ==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-pwsh-local": "^0.1.5-rc.2", - "@deepseek-ai/dsh-sandbox": "^0.1.5-rc.2", - "@deepseek-ai/dsh-sandbox-policy": "^0.1.5-rc.2", - "@deepseek-ai/dsh-shell": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-pwsh-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox-policy": "0.1.7-rc.2", + "@deepseek-ai/dsh-shell": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-repeat-tool-reminder": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-repeat-tool-reminder/-/dsh-repeat-tool-reminder-0.1.5-rc.2.tgz", - "integrity": "sha512-ZDK8AJOP/hdpCKLfbKbfwgj/flICKEPdJbtdoYsTR5A+BGfq8RIy0BWux0IczDenzNSNa8FXq3gbnwQGTPAJ1Q==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-repeat-tool-reminder/-/dsh-repeat-tool-reminder-0.1.7-rc.2.tgz", + "integrity": "sha512-tuG5xgqXth+CfNJiEMhsW+HTXfy14vMkuKx+J+47792P9AdxHr/a/Gi8qj6Err7TRU+Tz+d/VdzfsY+6+oWkkQ==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-sandbox": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-sandbox/-/dsh-sandbox-0.1.5-rc.2.tgz", - "integrity": "sha512-OTOR6Jj9cey5YkhALG0TBwZ/Z3t986aczH6fLbzoIIegix+gwNaEBOqCWs+exVJ0Z2QuN/ItXzn+xHxW8Y0dcA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-sandbox/-/dsh-sandbox-0.1.7-rc.2.tgz", + "integrity": "sha512-7aP893mtTvnuZfCKD6hUN5gYchi6Wogn4W3mg/rGMvogmhbWgrCs00boJx/eHK4KvVJmEW1e8kO5N+GtsesptA==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2" + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-sandbox-local": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-sandbox-local/-/dsh-sandbox-local-0.1.5-rc.2.tgz", - "integrity": "sha512-qlbg0X7sR9BE90sfHMuOl0t29XG859jJK8xwf5x8yI9Du0zcmviTlQtvlsT7MgDC9OOw8TEDfRTgbm3VDSXCdg==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-sandbox-local/-/dsh-sandbox-local-0.1.7-rc.2.tgz", + "integrity": "sha512-Xfyj+z5QZbbAU3nGU5JMpoJpL+mHkNCueMO8nzbBPiDvJBNeHvNefEvKmBRgtQmaxeHrpG9NRU6P/81KfqajlA==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-sandbox-windows-acl": "^0.1.5-rc.2", - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2", - "@deepseek-ai/node-addon-system": "^0.1.2", - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/dsh-sandbox-windows-acl": "0.1.7-rc.2", + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2", + "@deepseek-ai/node-addon-system": "~0.1.2", + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-sandbox": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-sandbox-policy": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-sandbox-policy/-/dsh-sandbox-policy-0.1.5-rc.2.tgz", - "integrity": "sha512-QyQSCyLFxljkvmsVWJG0xUrYTiXr1DVOxHWURf7EHnbmvYZgg2B+nFcI58+IeUB2qbB35B1ClW5NQsKjOgDm2g==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-sandbox-policy/-/dsh-sandbox-policy-0.1.7-rc.2.tgz", + "integrity": "sha512-pIhCaOEqYjNoKy/c7dYYgYzK+zp8/FxnEeaBA5e6fTmNROb+/qSFsC4hY3Qu+PVU9IdbH/4fa6TbT2jnqoDPQw==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/schemastery": "~3.18.4", "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2", - "@deepseek-ai/dsh-sandbox": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.2", - "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2", + "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-sandbox-windows-acl": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-sandbox-windows-acl/-/dsh-sandbox-windows-acl-0.1.5-rc.2.tgz", - "integrity": "sha512-GPig5OcIBSYtE5YwVzXqV+ICG68FMI1Fo+ZgyH4Jc73Qlze6A4uZqtCyH/xsmiZfzOZiOLyFB9+gc8lu4tZv3g==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-sandbox-windows-acl/-/dsh-sandbox-windows-acl-0.1.7-rc.2.tgz", + "integrity": "sha512-QOi5DSTDdEXTI2qhfx/uRZ+2zo3ssDG+r8uHWCor8Hg3VK28JICO1nWNbl3SDevvHqcKsM2oxNdwr5XTSC14jg==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-win32-process": "^0.1.5-rc.2", + "@deepseek-ai/dsh-lazy-require": "0.1.7-rc.2", + "@deepseek-ai/dsh-win32-process": "0.1.7-rc.2", "koffi": "^3.1.0" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-subprocess": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-schedule": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-schedule/-/dsh-schedule-0.1.5-rc.2.tgz", - "integrity": "sha512-SjVt6miSlSX1WQdAyvLf0KyQULIds+bLihr3nIvUAhrVSmoRDzbu2jNrNA5jGCo923+dgjGfLn6iUT6aNDJO3w==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-schedule/-/dsh-schedule-0.1.7-rc.2.tgz", + "integrity": "sha512-GR9m2V923qZkgvkEGcF/XN47hxs5By/3XahtJjqSRnqnUdMjUZ1k2C0XL4dDsluJLefrpFAK3sRx0LPJXxer3A==", "license": "MIT", "dependencies": { + "@deepseek-ai/schemastery": "~3.18.4", + "@js-temporal/polyfill": "0.5.1", "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-persistence": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-api-session-controller": "0.1.7-rc.2", + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-persistence": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2", + "@deepseek-ai/dsh-storage-domain": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2", + "@deepseek-ai/dsh-workspace": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-scope": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-scope/-/dsh-scope-0.1.5-rc.2.tgz", - "integrity": "sha512-JwItISje52iVIjlGMNayRVMZrvZU/0i3Gr0s+coND5nBp5lS+pOj9Zf1RQzA5cWjHYCWKmDuQc+m6zGlwmtAeQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-scope/-/dsh-scope-0.1.7-rc.2.tgz", + "integrity": "sha512-rk/OM5ej6/V8pCNczEqQ3BkKx3DuPeFGzNUsEZo8hF+tnkF/EhsxMWSXC/yP/uLKeNkSsVHzjFpaQR0qr0J3gQ==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-sdk-app": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-sdk-app/-/dsh-sdk-app-0.1.5-rc.2.tgz", - "integrity": "sha512-WamfPr7CctpoICsT32UpnLlAZavaEno2zwa3icqqpGdSHY0H+BL8yx/4mmRROIX1/ovMyxTcC5urjptDKy34KQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-sdk-app/-/dsh-sdk-app-0.1.7-rc.2.tgz", + "integrity": "sha512-H+SUCfCrHAIHUSSM3jnxUqUf3frSdtsUDBDcQ0SjybfyWuq4P3w/L3hfmvVK26EitireKOYkhoOpEB5I/PzXlg==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-cmdline": "^0.1.5-rc.2", - "@deepseek-ai/dsh-sdk-jsonrpc-server": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/dsh-cmdline": "0.1.7-rc.2", + "@deepseek-ai/dsh-sdk-jsonrpc-server": "0.1.7-rc.2", + "@deepseek-ai/dsh-skill-office": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-workspace-dependencies": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4", "commander": "^15.0.0" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-sdk-jsonrpc-server": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-sdk-jsonrpc-server/-/dsh-sdk-jsonrpc-server-0.1.5-rc.2.tgz", - "integrity": "sha512-TRVkUngQPKlpHvqS5AZi63zwa+5eG0zp1NwZXzJjdiYhjV2LPICiWVM6EuSbmIRB6tUZMB1MXf4ZSj2OFQWn/Q==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-sdk-jsonrpc-server/-/dsh-sdk-jsonrpc-server-0.1.7-rc.2.tgz", + "integrity": "sha512-2eOJZ/Ml3p4LnASEGydxUq+qTild9E6mcbBQmMElRfmiy0Po5b42L0Ds+8V0uRxVKZbvKooq8XNhDywQ4ZCcQg==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-attachment": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm-deepseek": "^0.1.5-rc.2", - "@deepseek-ai/dsh-scope": "^0.1.5-rc.2", - "@deepseek-ai/dsh-sdk-protocol": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-subagent": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-attachment": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm-deepseek-api-key": "0.1.7-rc.2", + "@deepseek-ai/dsh-scope": "0.1.7-rc.2", + "@deepseek-ai/dsh-sdk-protocol": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-subagent": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-sdk-minimal": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-sdk-minimal/-/dsh-sdk-minimal-0.1.5-rc.2.tgz", - "integrity": "sha512-mWdnFnz+MGU1+xgg4GExF+OkkYxEdaNQdAPFq30m0oP67cWQV0Om+pNBHDeGeguf8MVGLNLJB+iRP3/63LQV/Q==", - "license": "MIT", - "dependencies": { - "@deepseek-ai/cordis-plugin-timer": "^1.1.4", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-agent-loop": "^0.1.5-rc.2", - "@deepseek-ai/dsh-deepseek-llm-api-extensions": "^0.1.5-rc.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2", - "@deepseek-ai/dsh-jobs-local": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm-deepseek": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm-retry": "^0.1.5-rc.2", - "@deepseek-ai/dsh-plugin-package-inventory-deepseek": "^0.1.5-rc.2", - "@deepseek-ai/dsh-sandbox-local": "^0.1.5-rc.2", - "@deepseek-ai/dsh-sandbox-policy": "^0.1.5-rc.2", - "@deepseek-ai/dsh-scope": "^0.1.5-rc.2", - "@deepseek-ai/dsh-sdk-app": "^0.1.5-rc.2", - "@deepseek-ai/dsh-sdk-jsonrpc-server": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-log-deepseek": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-persistence-jsonl": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-title": "^0.1.5-rc.2", - "@deepseek-ai/dsh-subprocess-local": "^0.1.5-rc.2", - "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2", - "@deepseek-ai/dsh-terminal": "^0.1.5-rc.2", - "@deepseek-ai/dsh-terminal-bash": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-bash-persistent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-pwsh-persistent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2" - }, - "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-sdk-minimal/-/dsh-sdk-minimal-0.1.7-rc.2.tgz", + "integrity": "sha512-nxvJQXkrA9PvgGh96GAel2mpW4XCR6D9VTgYb1UzVTX6ja6kJT+IR2SIRHf9BnqWdDHxQXw7kGdcxd9GywE2WQ==", + "license": "MIT", + "dependencies": { + "@deepseek-ai/cordis-plugin-timer": "~1.1.6", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-agent-loop": "0.1.7-rc.2", + "@deepseek-ai/dsh-deepseek-llm-api-extensions": "0.1.7-rc.2", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", + "@deepseek-ai/dsh-jobs-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm-deepseek-api-key": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm-retry": "0.1.7-rc.2", + "@deepseek-ai/dsh-mcp-resources": "0.1.7-rc.2", + "@deepseek-ai/dsh-plugin-package-inventory-deepseek": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox-policy": "0.1.7-rc.2", + "@deepseek-ai/dsh-scope": "0.1.7-rc.2", + "@deepseek-ai/dsh-sdk-app": "0.1.7-rc.2", + "@deepseek-ai/dsh-sdk-jsonrpc-server": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-log-deepseek": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-persistence-jsonl": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-title": "0.1.7-rc.2", + "@deepseek-ai/dsh-subprocess-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2", + "@deepseek-ai/dsh-terminal": "0.1.7-rc.2", + "@deepseek-ai/dsh-terminal-bash": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-bash-persistent": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-pwsh-persistent": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-sdk-protocol": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-sdk-protocol/-/dsh-sdk-protocol-0.1.5-rc.2.tgz", - "integrity": "sha512-ewWYU+2tkcm5rTQtM5F6pYP5S6ox/7j/Gc/xCpXBtVOfUNchI8IUYbVNuea/lGX6XYGCBxpdG1jxV51W1YyWkg==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-sdk-protocol/-/dsh-sdk-protocol-0.1.7-rc.2.tgz", + "integrity": "sha512-jt75g7h8cxypjL6uXGiWlsvSpO8dY/aUo5Me4wnxpeslVyItYQurkIk35rYBlVG4fdlFep9/FAy+pRhnK/TKUA==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-subagent": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-subagent": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-session": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session/-/dsh-session-0.1.5-rc.2.tgz", - "integrity": "sha512-y+klWiGAWR4m4cc4ylurA0cW63673B4N8cr2ANMimweDZAfxL4XVBC7WiD/5DT2DtIhYmVZhz/niyS/WbniUTA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session/-/dsh-session-0.1.7-rc.2.tgz", + "integrity": "sha512-0dXv1t4Zox/yHkZ4PfPNSBWJfIc72PDqOvjz43EMoHpbmoKTVpit2UpUI+yTtX01e4MVBbDMxBZ95oJW/Oydnw==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2" + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-scope": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-scope": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-session-checkpoint-policy": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-checkpoint-policy/-/dsh-session-checkpoint-policy-0.1.5-rc.2.tgz", - "integrity": "sha512-RDaGTq4c49nFfVNq0AiL71z07OhtxoxfXESWppyegxotcdZTpdJTk4wIUto56SuaXi+kNCAP2PEjHC+VM0Z30A==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-checkpoint-policy/-/dsh-session-checkpoint-policy-0.1.7-rc.2.tgz", + "integrity": "sha512-2V+o25gPkQNeBXD2E9zSTCxZzEnIKmClnQwhXEMKFWwS6Ibm99GFc51DFjIvhdu/I0/YawOS637KsrPznHILpQ==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-persistence": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-persistence": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-session-format": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-format/-/dsh-session-format-0.1.5-rc.2.tgz", - "integrity": "sha512-Bih+d4wQ8ea+sZ1+Hws+ZBG3XpExrSQAtNMJRueFVzfTALhbnzpS5uLYw9qDapdfYYyHURlotQPRImBEpIVGFQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-format/-/dsh-session-format-0.1.7-rc.2.tgz", + "integrity": "sha512-ayk2VoX3r7m8U9rVc+F70qx76Eq3Mi3ToLySi29hDZPFLy8ujjSOO5LVCC1xmon8uukfcnScvElNPoP/mKTkBg==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2" + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-session-format-catalog": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-format-catalog/-/dsh-session-format-catalog-0.1.5-rc.2.tgz", - "integrity": "sha512-UKKVXS551VuTA5hH0cz9s9GjBb8HKdQcM+8Xa4uiviavTy4SOkVO3zmo2Wx43jzgdmChtNiUhc+w9RDOZLc7gQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-format-catalog/-/dsh-session-format-catalog-0.1.7-rc.2.tgz", + "integrity": "sha512-PMwm6M713ZWMqV0NVRFGeP0eYoBBCe0n4l5k8g1sRI+e2wD5xVoTEn8ZduG0vxnrVrGneJRDPQjZ4TiMi/fgDw==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-session-format": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-format-v0-to-v1": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-format-v1-to-v2": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-format-v2-to-v3": "^0.1.5-rc.2" + "@deepseek-ai/dsh-compaction-image-offload": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-format": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-format-v0-to-v1": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-format-v1-to-v2": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-format-v2-to-v3": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-format-v3-to-v4": "0.1.7-rc.2" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-session": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-session-format-v0-to-v1": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-format-v0-to-v1/-/dsh-session-format-v0-to-v1-0.1.5-rc.2.tgz", - "integrity": "sha512-0ff7Rl5JsUHGv223XMRFv0adfy7nV2mUQSRf3N1MZviblnp2c65dArq+ieRGISw6JQL4FAz4LSt6A6zV/D6o0A==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-format-v0-to-v1/-/dsh-session-format-v0-to-v1-0.1.7-rc.2.tgz", + "integrity": "sha512-2JjUnl5+00N8/eda1s47VXP8wEl0HFqLRKk3MgEcRb6PEH3NH3Mvxb6jmkF6EeH0mMLLvzYHbpfDazOhECkXRg==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-session-format": "^0.1.5-rc.2", - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2" + "@deepseek-ai/dsh-session-format": "0.1.7-rc.2", + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-session-format-v1-to-v2": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-format-v1-to-v2/-/dsh-session-format-v1-to-v2-0.1.5-rc.2.tgz", - "integrity": "sha512-VI15vcRCFfzmPpUg+BXSqgB9Kd99sVVXbfxGXo/gYRgjCY3JqClRh1CYhj1BDUvL91l7LsLv9Oa63kYXXbCaIw==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-format-v1-to-v2/-/dsh-session-format-v1-to-v2-0.1.7-rc.2.tgz", + "integrity": "sha512-a7Rsv7z2zeIyWpwRWkdtbi1T8r9zBGvbcoQVQEPpmpMFH9qu5hZmzYUGNFS1qRW5KW2cZoOU+qRxHwRoKI0dcQ==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-format": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-format-v0-to-v1": "^0.1.5-rc.2", - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2" + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-format": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-format-v0-to-v1": "0.1.7-rc.2", + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-session-format-v2-to-v3": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-format-v2-to-v3/-/dsh-session-format-v2-to-v3-0.1.5-rc.2.tgz", - "integrity": "sha512-BO9N4O3HhBrUhyO1ucuk1xa5r1+wYCUPnMTryIrasVnOHI3ndb9ITnPhTEc2m6OXJa3c+wuEWrxc7DJHM1Cx6g==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-format-v2-to-v3/-/dsh-session-format-v2-to-v3-0.1.7-rc.2.tgz", + "integrity": "sha512-che+x4X57f4MPWYWjj3UkcDs4qU0sQspUvy0Ie8w+iMFPkH0C7f/629l6ubZXRFrGF/k6djbyLR/NYH7nArZaA==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-session-format": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-format-v0-to-v1": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-format-v1-to-v2": "^0.1.5-rc.2" + "@deepseek-ai/dsh-session-format": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-format-v0-to-v1": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-format-v1-to-v2": "0.1.7-rc.2" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" + } + }, + "node_modules/@deepseek-ai/dsh-session-format-v3-to-v4": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-format-v3-to-v4/-/dsh-session-format-v3-to-v4-0.1.7-rc.2.tgz", + "integrity": "sha512-PpGsFntVbc6HEnIlTRMluk55YPAFGmbz7SSyYMXDaz7N+jzWTa54AuMg9gUthHxPwZyj7KF2QtJAJnSQ2+GPGw==", + "license": "MIT", + "dependencies": { + "@deepseek-ai/dsh-session-format": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-format-v2-to-v3": "0.1.7-rc.2" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-session-log-deepseek": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-log-deepseek/-/dsh-session-log-deepseek-0.1.5-rc.2.tgz", - "integrity": "sha512-d/PJ5/vsJcbv6ZOOD3pBXH58rBWhhSmWHlfLqH7wDq2wA25e1va290OVKv1wwR05/mZBBQZZXxc7qwT4xnsiyg==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-log-deepseek/-/dsh-session-log-deepseek-0.1.7-rc.2.tgz", + "integrity": "sha512-DOSb50EoF9ZGojLyCf+WCgHgz98aHXjQR7fX22EN7g7jDaOF7iFkFyBxJr7cHkkCwMGXgGXqvVlVb2r/Xmsyiw==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-deepseek-llm-api-extensions": "^0.1.5-rc.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-deepseek-llm-api-extensions": "0.1.7-rc.2", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-session-log-export": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-log-export/-/dsh-session-log-export-0.1.5-rc.2.tgz", - "integrity": "sha512-eoJWiv/oZQA2S61PpDpkU6kovoN5rQ1ZvOmp3HfKLKqfWzi6La1YP5VyiXi/g0qFjZ3ttZC0N+ckmWjNcGUjzw==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-log-export/-/dsh-session-log-export-0.1.7-rc.2.tgz", + "integrity": "sha512-y7Gt5ud52yFZM+v9sdmNyxUWEbGh3xIlXg5MWo9+159KBqyLyfO9yfA8MkTL8PouqNNvHwvN3Ea5ZZm9gWFthA==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-format": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-format": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4", "fflate": "^0.8.2" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-persistence": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-persistence": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-session-persistence": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-persistence/-/dsh-session-persistence-0.1.5-rc.2.tgz", - "integrity": "sha512-0nDeM+H+3YR0CH/IVlhjNL9bDx2G4QbliaLekVxY0jdZHM7RqdN/fWPKjeCKbXcRq6qdn9QcmvXU3uWZdErlIw==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-persistence/-/dsh-session-persistence-0.1.7-rc.2.tgz", + "integrity": "sha512-xZXMo8hYMnh96UyxpkmDqvfxpmVNWbTlXqSuJray7S2kW8AkugKDc+FMy2+/znoBHhZsi+2/uKJRPj6dwDBIsg==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2" + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-timeout": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-timeout": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-session-persistence-jsonl": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-persistence-jsonl/-/dsh-session-persistence-jsonl-0.1.5-rc.2.tgz", - "integrity": "sha512-nkIXdb5oOV6a05Of+3Wywe3gEB77uQOH1U0M+/SRVziSLX4JkE+us7dbWczOOloZjuUsEV7Il8kZ3R9JLsGqjA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-persistence-jsonl/-/dsh-session-persistence-jsonl-0.1.7-rc.2.tgz", + "integrity": "sha512-Dymapt+M11rJKQgsisfod2LSf0HvyUN/8QTv+g3BAXlRh5YFXvRcSVsY3XWj5NnUs3tlbU2aauBE7OXbMSP4vQ==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-format": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-format-catalog": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-format-v2-to-v3": "^0.1.5-rc.2", - "@deepseek-ai/node-addon-system": "^0.1.2", - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-format": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-format-catalog": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-format-v3-to-v4": "0.1.7-rc.2", + "@deepseek-ai/node-addon-system": "~0.1.2", + "@deepseek-ai/schemastery": "~3.18.4", "koffi": "^3.1.0" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-persistence": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-persistence": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-session-projection": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-projection/-/dsh-session-projection-0.1.5-rc.2.tgz", - "integrity": "sha512-WMXGBdbxD1FO1Eu7Qs2FKDXq/kl+z+5b7zGLHdra66eEnShSnQmdF9bXSFQu1sJwba2yF7ueMcBJpWy76gtgQQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-projection/-/dsh-session-projection-0.1.7-rc.2.tgz", + "integrity": "sha512-s5T8oHBEh+GeOTJ+wehD4CGZkTiWgczZZA+NDbfbqUO0k5L+dk0kk3fN+/srAg77rhR7UeeDSR8ZNcpYx/VUdw==", "license": "MIT", "dependencies": { "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-session": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-session-projection-cache": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-projection-cache/-/dsh-session-projection-cache-0.1.5-rc.2.tgz", - "integrity": "sha512-dS4GGlgZBBHv0U7C4+pQssApxao8Jbt3tMSGQeRU3xpmR5wP8PucR20wTiFThNrsUjdIs2Q/2IKw5bcnkaHwCw==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-projection-cache/-/dsh-session-projection-cache-0.1.7-rc.2.tgz", + "integrity": "sha512-7SRuNDAzOVMbKoXyK0GAA8xMYVRAHUCoYiR56+4hHUkU7YQ5JuRjQiHxG6dEtYqibp3AI8E+oXgOJhkpB5Gl8A==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4", "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.2", - "@deepseek-ai/dsh-storage-domain": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2", + "@deepseek-ai/dsh-storage-domain": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-session-query": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-query/-/dsh-session-query-0.1.5-rc.2.tgz", - "integrity": "sha512-Ntv/yYwhRhhXO3UkRKc1RIIk4RMLVR6jR8mdphRILEZoxPGjZxMJR95RuZg8TuLERbmGH8AkPAEKD6HWHqWh1g==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-query/-/dsh-session-query-0.1.7-rc.2.tgz", + "integrity": "sha512-dS9+GFdXBS0UWiSMiloD6IpSb7cDy7ig//h0LaGZAro8xcfs+rY+78Eu5JKrTObTCTL4p6x70cxAJdbRaIxzGw==", "license": "MIT", + "dependencies": { + "@deepseek-ai/dsh-session-format-catalog": "0.1.7-rc.2" + }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-persistence": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection-cache": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-title": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-todo": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-persistence": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection-cache": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-title": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-todo": "0.1.7-rc.2" }, "peerDependenciesMeta": { "@deepseek-ai/dsh-session-persistence": { @@ -3762,18 +4426,18 @@ } }, "node_modules/@deepseek-ai/dsh-session-query-sqlite": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-query-sqlite/-/dsh-session-query-sqlite-0.1.5-rc.2.tgz", - "integrity": "sha512-7xqyRvcaXfPzK6T96QFTdfEVbYIOz69qcghBoDMwSo66MQ+3DSdH3yTPlvrf3a8Nd9Jek375Upz1h12//FB5Ew==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-query-sqlite/-/dsh-session-query-sqlite-0.1.7-rc.2.tgz", + "integrity": "sha512-Yxer7MvfvJ6mi9Gkvl+NZyKLZkVuA8eMwhQW8O7EL6AK4I+Xb8tCJymvgD4ev/EFzuoQJHgtlwtD4x86qQp/GA==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-persistence": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-query": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-persistence": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-query": "0.1.7-rc.2" }, "peerDependenciesMeta": { "@deepseek-ai/dsh-session-persistence": { @@ -3782,30 +4446,31 @@ } }, "node_modules/@deepseek-ai/dsh-session-reference": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-reference/-/dsh-session-reference-0.1.5-rc.2.tgz", - "integrity": "sha512-SpkwyQp0o28bxc01xwid+s+nVCo1Xs8OGsOqyuPRky4WhZtbuI3HN0q/M7+8EcH+kN/SbUzrDD45Q4FAiiHzbQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-reference/-/dsh-session-reference-0.1.7-rc.2.tgz", + "integrity": "sha512-Yo+/foHDI5JitZl/+Pt76QpwytkkDjv5vwSKtMQBXXLXPRJSuXz+xtSkEqQCQ1667RbksGZz8mVzWSZWb0IpYg==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4", "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-compaction": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-output-retention": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection-cache": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-query": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-title": "^0.1.5-rc.2", - "@deepseek-ai/dsh-spill": "^0.1.5-rc.2", - "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2", - "@deepseek-ai/dsh-typert-protocol": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-compaction": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-output-retention": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection-cache": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-query": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-title": "0.1.7-rc.2", + "@deepseek-ai/dsh-spill": "0.1.7-rc.2", + "@deepseek-ai/dsh-subagent": "0.1.7-rc.2", + "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2" }, "peerDependenciesMeta": { "@deepseek-ai/dsh-session-projection-cache": { @@ -3817,38 +4482,38 @@ } }, "node_modules/@deepseek-ai/dsh-session-stats": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-stats/-/dsh-session-stats-0.1.5-rc.2.tgz", - "integrity": "sha512-p0C+g31Xcq5w4FWxS+V2hMfLtb97sHpaHNTaAT1UeVTqpSVHt21qC0PnqfFfOe/OsVkMkWDKWDbLb1cA9SnQ5Q==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-stats/-/dsh-session-stats-0.1.7-rc.2.tgz", + "integrity": "sha512-BT3X9w6REGTkc5bRH5jLiQ6Hv+jkiqhxzSQnnwJKmskowthLwsigN9cn760IBBCPZNyPNGghixAMxm9pl0/yIQ==", "license": "MIT", "dependencies": { "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-session-telemetry": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-telemetry/-/dsh-session-telemetry-0.1.5-rc.2.tgz", - "integrity": "sha512-HCTlVFiyWHNqewD1wLow3kf6dbDBU8GqjHlLO6Es9viYW4GCAALO8FXxdqbWMSLOkwMNMM5xqWrXedjfSmRehA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-telemetry/-/dsh-session-telemetry-0.1.7-rc.2.tgz", + "integrity": "sha512-JyCrRnTlA5tKU+8MVP3+byoA3ducZjZpSJp/2t0GofbvyAhYdvQVoR3hb4h4OxUxPiW+dPUtC95gCr+snM42Ug==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-session-telemetry-otel": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-telemetry-otel/-/dsh-session-telemetry-otel-0.1.5-rc.2.tgz", - "integrity": "sha512-T2gH6xJ9NNTnEjQG3od1vVIieT3htMShlqTTfOzxIR8YoGf/92KpCq6xVtYx3URm6aJysRpIbtRmoYzVq8Ln7w==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-telemetry-otel/-/dsh-session-telemetry-otel-0.1.7-rc.2.tgz", + "integrity": "sha512-rgWtlx4Wc+F9grOeun9tt9R0u6HSbToxapkxEeJFtkSIm4TFAUKRP7osv2I7LEleUNmc7dpQtp87aHrWpnXXKg==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/schemastery": "~3.18.4", "@opentelemetry/api": "^1.9.1", "@opentelemetry/api-logs": "^0.220.0", "@opentelemetry/exporter-logs-otlp-http": "^0.220.0", @@ -3857,184 +4522,170 @@ "@opentelemetry/sdk-logs": "^0.220.0" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-anonymous-user-id": "^0.1.5-rc.2", - "@deepseek-ai/dsh-command-feedback": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-message-feedback": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-telemetry": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-anonymous-user-id": "0.1.7-rc.2", + "@deepseek-ai/dsh-command-feedback": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-message-feedback": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-telemetry": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-session-title": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-title/-/dsh-session-title-0.1.5-rc.2.tgz", - "integrity": "sha512-lQ1PzIdySxANbhVM9blxCSlqR0iF2GVCiE9R1Qm0VJJue/G9ZUasz+jGQJeAVZi7PHjVWCALljtqpcnaOZq+6g==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-title/-/dsh-session-title-0.1.7-rc.2.tgz", + "integrity": "sha512-UsbFH2ESc8lY2YgSb9OPsXOBryOc7qq0f57FYccb3yOAez27afERWwvcPGZY8D9YTJKZCf0Q3ae/NZMQU15AJA==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4", "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-session-title-first-prompt-llm": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-title-first-prompt-llm/-/dsh-session-title-first-prompt-llm-0.1.5-rc.2.tgz", - "integrity": "sha512-D+eMbKUadK/9QTkk00TItqvE0ealZek8Tc17HJgdGP7Ya0pSYL3hI03q0U6m7SXJQAAFjENMof3xHS+HmyPhdQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-title-first-prompt-llm/-/dsh-session-title-first-prompt-llm-0.1.7-rc.2.tgz", + "integrity": "sha512-I7O64gk/HLoBjPWu1ikDd6kEz7QZKfI+njyLGaGapLITycRMYWDaSCQGKXqPvTlMPTNQL8ym/kKXbFrG61j/Vg==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-title": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-title-llm": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-title": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-title-llm": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-session-title-llm": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-title-llm/-/dsh-session-title-llm-0.1.5-rc.2.tgz", - "integrity": "sha512-IO80OEJ88AUX6S3c5hgjmrrOAgqvTwg9S/4o40H2btAFPCefj+ioHg9qa6KyMZaaZBe8dGjjdngpsaOvC/QPIQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-title-llm/-/dsh-session-title-llm-0.1.7-rc.2.tgz", + "integrity": "sha512-KmHI4hvuY5lpeMJLq2sR8vxTXvakgSA96DbqmqX3zbE8neCM+pojZBcUeDKdYwV6TfiT2oWJno1n7QGwoT9fdw==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-title": "^0.1.5-rc.2", - "@deepseek-ai/dsh-timeout": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-title": "0.1.7-rc.2", + "@deepseek-ai/dsh-timeout": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-session-turn-outline": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-turn-outline/-/dsh-session-turn-outline-0.1.5-rc.2.tgz", - "integrity": "sha512-z3kVLSv/dqwtOM4ii8FfzmmLuEvp9NJORMvm2MQPkYzBxLrQvfxIRPm5Q6uqmTowFrEcYWu1bQCdg6EdnZJDgg==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-session-turn-outline/-/dsh-session-turn-outline-0.1.7-rc.2.tgz", + "integrity": "sha512-Ouag8143h3+exBd8Q7iQ4XI22VcR+0rfDgOjzsVC3WMq6ckHLeo3SrxLFLXMuLn+UpBTBnjy1b2q6uaLemQsIA==", "license": "MIT", "dependencies": { "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-settings": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-settings/-/dsh-settings-0.1.5-rc.2.tgz", - "integrity": "sha512-LI2Y6GkEs9ALMW+7S9jHPeEZDXHtG5X6cix1HdJ1rRxTEO5427QlYhMiz45rk7hqZ8ca2O4XFMW8IWXFZQLxmw==", - "license": "MIT", - "dependencies": { - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2" - }, - "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2" - } - }, - "node_modules/@deepseek-ai/dsh-settings-file": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-settings-file/-/dsh-settings-file-0.1.5-rc.2.tgz", - "integrity": "sha512-5bdcCyDLMQyo4sm1g8l4mNjIrsyfn1mu3+9tvGYrDWIw0f1n1YEIWuHp2reyoZpRCMAco9S5N4mDoKF2mc9T/Q==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-settings/-/dsh-settings-0.1.7-rc.2.tgz", + "integrity": "sha512-xS48//SMs3xp5qI+brj0T4BsJ1vgcv2LteZO6lW4X0YZVUOIe6H9aS2sRPh2OAWTFHrzPep4NwVkAOCD8NvBzQ==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2", - "chokidar": "^4.0.3", - "yaml": "^2.9.0" + "@deepseek-ai/cordis-plugin-loader": "~1.0.5", + "@deepseek-ai/cosmokit": "~1.8.5", + "@deepseek-ai/dsh-config-editor": "0.1.7-rc.2", + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2", + "yaml": "^2.8.1" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-atomic-write": "^0.1.5-rc.2", - "@deepseek-ai/dsh-home-paths": "^0.1.5-rc.2", - "@deepseek-ai/dsh-settings": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4" } }, "node_modules/@deepseek-ai/dsh-shell": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-shell/-/dsh-shell-0.1.5-rc.2.tgz", - "integrity": "sha512-BfmNN6X0NHN2XleW0fCbtFXedXEppeDQ2oa3WsOTuhvnBftl6QWMWWMM59weE4xXker5fzqOnoJdeBR8D9qR9Q==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-shell/-/dsh-shell-0.1.7-rc.2.tgz", + "integrity": "sha512-l/CdrpqFG3SNPKBm7/zJkqn8gODxMLcTOg57zSqyDi5VdJXb8dlRQNHH4KfhxfWM9rZSH5AC94g6Il2n3sOQ+w==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-sandbox": "^0.1.5-rc.2", - "@deepseek-ai/dsh-settings": "^0.1.5-rc.2", - "@deepseek-ai/dsh-subprocess": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-sandbox": "0.1.7-rc.2", + "@deepseek-ai/dsh-subprocess": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-shell-env": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-shell-env/-/dsh-shell-env-0.1.5-rc.2.tgz", - "integrity": "sha512-fFSrfhxfvVYfDxsOuV0cjAeC/PWweW+86uOJWT+2paHXOSgM6MSDe3eTd5DHRDYnjb5XutTYu32pR49cVBHMug==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-shell-env/-/dsh-shell-env-0.1.7-rc.2.tgz", + "integrity": "sha512-Zu31yhGgnB+WMah0Qb/+adZTeUr1MQLmNMU8lV6YVt20tCnbA+HFI/akPTIoc9Ux8+Lqf6/fyv4e63OniPXaRw==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-home-paths": "^0.1.5-rc.2", - "@deepseek-ai/dsh-shell": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-app-boot": "0.1.7-rc.2", + "@deepseek-ai/dsh-home-paths": "0.1.7-rc.2", + "@deepseek-ai/dsh-shell": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-skill": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-skill/-/dsh-skill-0.1.5-rc.2.tgz", - "integrity": "sha512-Z1mouW3vTzmYk9OAGUp7S9oOB4k9+qr8BpD7KPAR0nAPX1XOxyKA7zQA/6P0tMS69/aS7UsyLZNz9+RG8ZZ8Wg==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-skill/-/dsh-skill-0.1.7-rc.2.tgz", + "integrity": "sha512-m1SFnBjx8F4upZObk13d3MC6QsiNA3kWHJ5dOZu+Z9oB5BudzNnFJWXZf2gcZclWai9lOiKxCb1ibPio1inwUg==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-scope": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-scope": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-skill-badge": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-skill-badge/-/dsh-skill-badge-0.1.5-rc.2.tgz", - "integrity": "sha512-piOjH/WNjv0If4P3IQLuAsOh0WWbmWBv/06IXd1x7emet/d62nnnAp2gl75pqpYDR6qyavvRLNCqhqBJIudKTw==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-skill-badge/-/dsh-skill-badge-0.1.7-rc.2.tgz", + "integrity": "sha512-l3jIjc7m9xqARMO3uGp/exH7S76T5A7y4e33dAFeFdIdJgy4D37pLWfy1UY8drIP91TgaIniqz4RO1jfWjPg1A==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-skill": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-skill": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-skill-filesystem": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-skill-filesystem/-/dsh-skill-filesystem-0.1.5-rc.2.tgz", - "integrity": "sha512-lEZ9KojaIc24vKCa5mp8LBHUDoXpNRSR/vlMsWONc9Tc1wwfn9kEotIjj0HD4PjIRcnc+Lma1nk4G/oNED8A9Q==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-skill-filesystem/-/dsh-skill-filesystem-0.1.7-rc.2.tgz", + "integrity": "sha512-k+I8mictkO+g8JMm8EM13yDtG4MqeES88DJq7TJNKRT4o7tD2vkDqr8Ep3KN4EYH5KDGd0h6HabIwvEqhbx37A==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/schemastery": "~3.18.4", "chokidar": "^5.0.0", "yaml": "^2.4.2" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-fs": "^0.1.5-rc.2", - "@deepseek-ai/dsh-home-paths": "^0.1.5-rc.2", - "@deepseek-ai/dsh-skill": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-fs": "0.1.7-rc.2", + "@deepseek-ai/dsh-home-paths": "0.1.7-rc.2", + "@deepseek-ai/dsh-skill": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-skill-filesystem/node_modules/chokidar": { @@ -4065,125 +4716,148 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/@deepseek-ai/dsh-skill-office": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-skill-office/-/dsh-skill-office-0.1.7-rc.2.tgz", + "integrity": "sha512-kU6bggLhVzqxYYXZHS2dCVRxa3MlofoLbtT1cdLC0D8qmJ2S8juja4PEm7HI8100PH9y7WSsAkQLqcsJgVsJGA==", + "license": "MIT", + "dependencies": { + "@deepseek-ai/libreoffice-kit": "^0.1.1", + "@deepseek-ai/schemastery": "~3.18.4", + "yaml": "^2.4.2" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-skill": "0.1.7-rc.2" + } + }, "node_modules/@deepseek-ai/dsh-spill": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-spill/-/dsh-spill-0.1.5-rc.2.tgz", - "integrity": "sha512-djiz5HH1xtuxiBAPT6ODlwEPUQz/SR/Q6SCUiEud7x90nmTsfLLxGUQmNETdiRC3juBLZeoDV1Xgmjf54P4y+A==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-spill/-/dsh-spill-0.1.7-rc.2.tgz", + "integrity": "sha512-OV3T73WDjz9x8Zc/Qwfjui1I/bVWO7UVWNK4FjujZABJi/61PMyUYmrWMBjF22VGS4V1f2foSJ0TVzd/1mq+gQ==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-spill-local": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-spill-local/-/dsh-spill-local-0.1.5-rc.2.tgz", - "integrity": "sha512-HrTEyP/KJh9YudGYmXBZvu54x022JWIlVX96d2UkHKICSB1NJy3AUIO0zyYCOk1PX+4iC77oD6zdOAyyxX21QA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-spill-local/-/dsh-spill-local-0.1.7-rc.2.tgz", + "integrity": "sha512-ls6vTHb2GHUbi2Es2/sBdtS0A3k3Wrfyq2uVbMI5XNARoMnftezcIcxyGME+s/7cCtAof7Sy5LK6BnY2vOWuUQ==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-spill": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-spill": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-spill-policy": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-spill-policy/-/dsh-spill-policy-0.1.5-rc.2.tgz", - "integrity": "sha512-XDtIEF7eeErjf0HS6ASkquXZIorv96+A3kuSZs9ZoWqI6eHVxUBrTebHhNc59P9Cp6LeumLUhPIb+SEP3ITgYA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-spill-policy/-/dsh-spill-policy-0.1.7-rc.2.tgz", + "integrity": "sha512-n4CrVMlS/kK4bQMHBlhrr9V9z3UuZdynwpXKKq1j+7Wl0GbqIyimGyzfVCVd0u5L84geVbI825ltleBqirwNFg==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-output-retention": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-spill": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-attachment": "0.1.7-rc.2", + "@deepseek-ai/dsh-fs": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-output-retention": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-spill": "0.1.7-rc.2", + "@deepseek-ai/dsh-token-meter": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-storage": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-storage/-/dsh-storage-0.1.5-rc.2.tgz", - "integrity": "sha512-mYt6+JSRxA5fSUcYnI3JFvYw9/TKUyykz5JWoZZ3MxWudItfhw+CV6T3kn3/bpTbWIQnGesSeY+0pJJVz0xBAA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-storage/-/dsh-storage-0.1.7-rc.2.tgz", + "integrity": "sha512-BZ5MZY44KCUoQEy8FJTpSOXfGGPQ3sJS3xrwxF9rARIqHwtsR5WR6rXY/JmsFNc3nI0djGmJ0bF81U0q7EbDLA==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-storage-domain": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-storage-domain/-/dsh-storage-domain-0.1.5-rc.2.tgz", - "integrity": "sha512-NZ9U14kqcCnF4F+ynrTlBLb+S9FEOwSLkfdjDgdfrFdHh4c2WsRKWxyeYbL8AME1rB+XxLp4YQBx8LQ0Kiy62A==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-storage-domain/-/dsh-storage-domain-0.1.7-rc.2.tgz", + "integrity": "sha512-Ch+k8iYvxMtmxxcVFZQ75griJMdj7RX49mbgRXLbr0s5IvCY2RYPNVDLyB1e/2wXysT1rP08FsH8nH7PoVABRg==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/schemastery": "~3.18.4", "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2", - "@deepseek-ai/dsh-storage": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", + "@deepseek-ai/dsh-storage": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-storage-json": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-storage-json/-/dsh-storage-json-0.1.5-rc.2.tgz", - "integrity": "sha512-vIdKeI6BUQpqneD/+oTZ2YNotNSGXZX0VbFbhdvgMSgamOrExIjl4cRsEJttcNr8zSvB8PjmuX2wPFvkMoeAlQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-storage-json/-/dsh-storage-json-0.1.7-rc.2.tgz", + "integrity": "sha512-dmzUEcCPkvCppdZFv4TC9OlVNbb+oJdl20ybtENbIy967/kYVnJryyRBtAR6ajm2hQ2MmK9XyOD/XTZpZHy+Fw==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-storage": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-storage": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-subagent": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-subagent/-/dsh-subagent-0.1.5-rc.2.tgz", - "integrity": "sha512-f2wbfB1M2P8RpcApp5eDpDQR4V5ElvEkeK6su7tor1U06uJadJ+JuIVXP3MrCnT7yjg/IM2tTacYFMOg62BOfg==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-subagent/-/dsh-subagent-0.1.7-rc.2.tgz", + "integrity": "sha512-wIl53frMLSQI+QXfKTHBdyKT/hslFH9LT0DUDeiNyShGkiewYG1wSY1rnmv+p57Q+zS/SfDYjt0s0MGK1tUL0Q==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/dsh-chunked-list": "^0.1.5-rc.2", - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2", + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-chunked-list": "0.1.7-rc.2", + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4", "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-agent-presets": "^0.1.5-rc.2", - "@deepseek-ai/dsh-attachment": "^0.1.5-rc.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2", - "@deepseek-ai/dsh-jobs": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-sandbox": "^0.1.5-rc.2", - "@deepseek-ai/dsh-sandbox-policy": "^0.1.5-rc.2", - "@deepseek-ai/dsh-scope": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-persistence": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection-cache": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-query": "^0.1.5-rc.2", - "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2", - "@deepseek-ai/dsh-typert-protocol": "^0.1.5-rc.2", - "@deepseek-ai/dsh-user-approval": "^0.1.5-rc.2", - "@deepseek-ai/dsh-util-time": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-agent-preset-registry": "0.1.7-rc.2", + "@deepseek-ai/dsh-attachment": "0.1.7-rc.2", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", + "@deepseek-ai/dsh-jobs": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-permission-presets": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox-policy": "0.1.7-rc.2", + "@deepseek-ai/dsh-scope": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-persistence": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-query": "0.1.7-rc.2", + "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2", + "@deepseek-ai/dsh-user-approval": "0.1.7-rc.2", + "@deepseek-ai/dsh-util-time": "0.1.7-rc.2", + "@deepseek-ai/dsh-workspace": "0.1.7-rc.2" }, "peerDependenciesMeta": { - "@deepseek-ai/dsh-agent-presets": { + "@deepseek-ai/dsh-agent-preset-registry": { "optional": true }, "@deepseek-ai/dsh-jobs": { "optional": true }, + "@deepseek-ai/dsh-permission-presets": { + "optional": true + }, "@deepseek-ai/dsh-sandbox": { "optional": true }, @@ -4196,941 +4870,1150 @@ "@deepseek-ai/dsh-session-projection": { "optional": true }, - "@deepseek-ai/dsh-session-projection-cache": { + "@deepseek-ai/dsh-session-query": { "optional": true }, - "@deepseek-ai/dsh-session-query": { + "@deepseek-ai/dsh-settings": { "optional": true }, "@deepseek-ai/dsh-user-approval": { "optional": true + }, + "@deepseek-ai/dsh-workspace": { + "optional": true } } }, "node_modules/@deepseek-ai/dsh-subagent-fork-in-process": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-subagent-fork-in-process/-/dsh-subagent-fork-in-process-0.1.5-rc.2.tgz", - "integrity": "sha512-9VHI9pA1FX7mEOUx8Iw7Q6Sqk76rJGsOCQ0jwsaE+7YvQxV8YhOFe9gBzkmk+ChRNag5ToBVLFuUFROpboo+Xw==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-subagent-fork-in-process/-/dsh-subagent-fork-in-process-0.1.7-rc.2.tgz", + "integrity": "sha512-tGJ06AG1JXXTLQBdskJRaggA/gg601+lr52kxvuT1sx/L404hRdw18OdPOebDh9wrj8gt2zxeVEkHA0QY6Hkhg==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-subagent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-subagent-in-process-driver": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-subagent": "0.1.7-rc.2", + "@deepseek-ai/dsh-subagent-in-process-driver": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-subagent-in-process-driver": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-subagent-in-process-driver/-/dsh-subagent-in-process-driver-0.1.5-rc.2.tgz", - "integrity": "sha512-IBwRQHVX4hi3YO2vUYmTtDxKM2B0lIwAuiAG3hsvljmaF66z2snyLYezKszLZeTPphr2QHgt2CJNxNP1LlhUJg==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-subagent-in-process-driver/-/dsh-subagent-in-process-driver-0.1.7-rc.2.tgz", + "integrity": "sha512-4NroGWZydU4INXIyPGFKL4Zy1XfMphGDqAJyz/bVTNdrMi6M/8XdRASzTKvsud8TP6IMklAGxcEyEw0pD+AKmg==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2" + "@deepseek-ai/dsh-brand": "0.1.7-rc.2" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-subagent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-subagent": "0.1.7-rc.2", + "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-subagent-spawn-in-process": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-subagent-spawn-in-process/-/dsh-subagent-spawn-in-process-0.1.5-rc.2.tgz", - "integrity": "sha512-/FJxY+dBc8AVWFmSYcQPWapuTd3ATGQpAb9Z2cQEZjFRXy8ySuZnh2MrnAa/r00FX6Lz0G8BfvUurr4K+uKHSw==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-subagent-spawn-in-process/-/dsh-subagent-spawn-in-process-0.1.7-rc.2.tgz", + "integrity": "sha512-xEWjgl/wMalKHGlckmTZ8B0UuwPUGAUathXaeVvs/stqLgmX5IFa1t2/KAN/guLOfeK0rHYvqQGSQhBJkCGxxg==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-subagent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-subagent-in-process-driver": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-subagent": "0.1.7-rc.2", + "@deepseek-ai/dsh-subagent-in-process-driver": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-subprocess": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-subprocess/-/dsh-subprocess-0.1.5-rc.2.tgz", - "integrity": "sha512-Bbxg5/dlbK09qNu4/BVuicUAYnC+b/YGhtkUBsxa9/+KRfvloeJcJ9Ug6dKAeJeluzEXnFIh08+MNweO7hn7ig==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-subprocess/-/dsh-subprocess-0.1.7-rc.2.tgz", + "integrity": "sha512-HgELZIXAEDvlqI4ThbaJ7bJi2ytotxjcaAoXgiKstFGyyf9EAHOSmLkmJZ1G4nunF7cop2YclSEpAvGNTofBTg==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-http-proxy": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-http-proxy": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-subprocess-local": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-subprocess-local/-/dsh-subprocess-local-0.1.5-rc.2.tgz", - "integrity": "sha512-DmG3lcQlAh8bTKfeyYM44cfRyJktbLL8drXrVfOvGrFk0zSs5eTSLcfhIKLT3jFJ5CKFriHYZPLdRT6Alvyy4w==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-subprocess-local/-/dsh-subprocess-local-0.1.7-rc.2.tgz", + "integrity": "sha512-1JKUC4YriYbuyNsDcOwb+WQVaxy6I8CWeTVP/UoEc6uXPSMQdS3GJArDYyFdC2NzjOEmAxpTr4awTNNrpA6Gmw==", "hasInstallScript": true, "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-win32-process": "^0.1.5-rc.2", + "@deepseek-ai/dsh-lazy-require": "0.1.7-rc.2", + "@deepseek-ai/dsh-win32-process": "0.1.7-rc.2", "koffi": "^3.1.0", "node-pty": "1.2.0-beta.15" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-subprocess": "^0.1.5-rc.2", - "@deepseek-ai/dsh-timeout": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-subprocess": "0.1.7-rc.2", + "@deepseek-ai/dsh-timeout": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-system-prompt": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-system-prompt/-/dsh-system-prompt-0.1.5-rc.2.tgz", - "integrity": "sha512-VtmZVKqBMJ7kzskHu0jY+Jth7jSuKMG8QB3MBPzJe9M0LL4YPMWsGKt9gGky9RXolk/ugAy4YZEv1gUqouVofA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-system-prompt/-/dsh-system-prompt-0.1.7-rc.2.tgz", + "integrity": "sha512-vxKcADh7XOuWJOfa0WeEOhvFiUbMOdoK4w6M7KVCI0S99c9ktxrgY4wKdmAxap+nQjwTEPme3QuOlY3Na+cz9w==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-scope": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-scope": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-terminal": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-terminal/-/dsh-terminal-0.1.5-rc.2.tgz", - "integrity": "sha512-ALDjWfRMWvRmk/HfM7z5sXfQ1DSarJcjkzL8bT1KV01WlJB1KHVbXKlLI29tQH1Zu92uXk9g0JaFQKNycqT9yQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-terminal/-/dsh-terminal-0.1.7-rc.2.tgz", + "integrity": "sha512-8C7Ua0DZY2dikN1zPthvlYcxWAmB2bPMup/LJXsnD+2CK3D1QSGEsxkjIUtpGZo0HnapJY1JixzgOU3/fab5Og==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-brand": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-terminal-bash": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-terminal-bash/-/dsh-terminal-bash-0.1.5-rc.2.tgz", - "integrity": "sha512-UJVx058VgMNjwptwlGPBsMCmAs/ljgQwW9RNDZCpxvKxtc6D4RqEm675/f4uMPnGEKhPCJFKCGZy3ltqHvUPdg==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-terminal-bash/-/dsh-terminal-bash-0.1.7-rc.2.tgz", + "integrity": "sha512-6dlzgzSoClNcW/th0iapYjWq7gGfSQqIUTqHxZXKwvOR2g1x51uagRctQ7AamNw4iOStQzLFGQ3ctLDg8WSQfw==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-pwsh-local": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/dsh-lazy-require": "0.1.7-rc.2", + "@deepseek-ai/dsh-pwsh-local": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4", "@xterm/headless": "^6.0.0" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-sandbox": "^0.1.5-rc.2", - "@deepseek-ai/dsh-sandbox-policy": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.2", - "@deepseek-ai/dsh-subprocess": "^0.1.5-rc.2", - "@deepseek-ai/dsh-terminal": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox-policy": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2", + "@deepseek-ai/dsh-subprocess": "0.1.7-rc.2", + "@deepseek-ai/dsh-terminal": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-time-context": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-time-context/-/dsh-time-context-0.1.5-rc.2.tgz", - "integrity": "sha512-XClt8a3ijmELHrMuPG8F+P7uLbi+ZBcjulTdeMq7UB4yRSmTHNcQ1rJLyPjPajSDsR6F81x6z6xT842PC4u1kQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-time-context/-/dsh-time-context-0.1.7-rc.2.tgz", + "integrity": "sha512-YemKiNNbS+y7H80aHDSahYlgwlgQR1UU/8SabAbFLepWqrGH07O0HdSoZ8WVmXD3wBX+X+hAJyWw3zTT52jDMw==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4", "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-timeout": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-timeout/-/dsh-timeout-0.1.5-rc.2.tgz", - "integrity": "sha512-FgfaAw8Zt5X4Y6Ljh833B8Hy7h96FeR+yjNKI3iSyZSqREqOBgvDGXFfQlSu6V3Buvw/cbI/CJUQJvfRBKXOiA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-timeout/-/dsh-timeout-0.1.7-rc.2.tgz", + "integrity": "sha512-YunLoLZSF8Ld9eYwyvKoBnxgy3GZrIQpw98HfFS15ZfZlqcFiZcchFhYmStLtUbtX+gjhoeXc8Xz913YbVifNA==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-tmux-context": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tmux-context/-/dsh-tmux-context-0.1.5-rc.2.tgz", - "integrity": "sha512-gocDAjUDx80DkbS92/WZJqx+NJkTfuGnSBglDXdUZRFj5O38Ggl9ywSKxTISk/Yhj3SbjRab9UfNjBZ1M8Nlxg==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tmux-context/-/dsh-tmux-context-0.1.7-rc.2.tgz", + "integrity": "sha512-DYRsMMTgQicntevipFcV6k5LyTMm+UDmo46b9MRK0hc34y5RXCSdX9uIrC0GErDm1K8N1OufPjTXwJIgMe65MA==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/schemastery": "~3.18.4", "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.2", - "@deepseek-ai/dsh-shell": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2", + "@deepseek-ai/dsh-shell": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-token-meter": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-token-meter/-/dsh-token-meter-0.1.5-rc.2.tgz", - "integrity": "sha512-GS13T/USWa8pFBsahLGQCTQ31ktIa5iBqUYyFFrDPKhvUZFk7dTgltqIo9BxpsU5op0Lwj1LFyCnhNnuYbzvaw==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-token-meter/-/dsh-token-meter-0.1.7-rc.2.tgz", + "integrity": "sha512-9Ig2EI16amhKyiitkWqMzvCocTc8O7Z1bHZbHEQUMeKRlp7F0t1l3hUT/JSd9DQ7UzRcjSAhVavXGwke5lWYGQ==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4", "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-compaction": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm-retry": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-compaction": "0.1.7-rc.2", + "@deepseek-ai/dsh-compaction-image-offload": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm-retry": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-tool-ask-user": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-ask-user/-/dsh-tool-ask-user-0.1.5-rc.2.tgz", - "integrity": "sha512-M+ha4uty4SM/nEfkOeIMw7vxj3Ez6lZin6oQqgw5hWXNrmf5C9SfF8VH6KZYuPhsmxPiyTUr5SyULxgn2eTUGA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-ask-user/-/dsh-tool-ask-user-0.1.7-rc.2.tgz", + "integrity": "sha512-qOdhDY9GD6ibSKFNNcRN3i/FHj1csnStK3DHg/5Gagz4W4i3YmpfK+5bOPp/wrhPgzRDCh/wLYjRo4SiyKujWA==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2", - "@deepseek-ai/dsh-user-questions": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2", + "@deepseek-ai/dsh-user-questions": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-tool-bash": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-bash/-/dsh-tool-bash-0.1.5-rc.2.tgz", - "integrity": "sha512-f4LmiZkZSfJfvBcEzV4q5J83VL79l/+ncLkwnJyHzsjvJbW5qFxzCy4p5FXfY/CflG0taG14/p42UJzb9qEhrQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-bash/-/dsh-tool-bash-0.1.7-rc.2.tgz", + "integrity": "sha512-pdFYrdnX2OlMN9nI0XT5MZwMkR58x4Z5j9qyTfMYLvtbuZxHwxcdHq2PJU3vAuVQj14F7TJiFEan2EXq+X1mFg==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-jobs": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-sandbox": "^0.1.5-rc.2", - "@deepseek-ai/dsh-sandbox-policy": "^0.1.5-rc.2", - "@deepseek-ai/dsh-shell": "^0.1.5-rc.2", - "@deepseek-ai/dsh-shell-env": "^0.1.5-rc.2", - "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2", - "@deepseek-ai/dsh-user-approval": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-jobs": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox-policy": "0.1.7-rc.2", + "@deepseek-ai/dsh-shell": "0.1.7-rc.2", + "@deepseek-ai/dsh-shell-env": "0.1.7-rc.2", + "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2", + "@deepseek-ai/dsh-user-approval": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-tool-bash-persistent": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-bash-persistent/-/dsh-tool-bash-persistent-0.1.5-rc.2.tgz", - "integrity": "sha512-OCfqQijK/eo+ILLatQntWnKJ7hFwUUOLpxdbkgmN8zjvD3o3LPRnnt9IerCid4YjGwc69jSTBX0Zk2jW2n/rhQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-bash-persistent/-/dsh-tool-bash-persistent-0.1.7-rc.2.tgz", + "integrity": "sha512-aFNJWg2MW+cpyv7yOOl3sfpE7q4e9hE+DmODYiBxXtdTEKfDuKMnIY7Z8TT9sb/wonmUNaneG6LpNUzz6lV+og==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-terminal": "^0.1.5-rc.2", - "@deepseek-ai/dsh-timeout": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-output-retention": "0.1.7-rc.2", + "@deepseek-ai/dsh-terminal": "0.1.7-rc.2", + "@deepseek-ai/dsh-timeout": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-tool-call-timeout-policy": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-call-timeout-policy/-/dsh-tool-call-timeout-policy-0.1.5-rc.2.tgz", - "integrity": "sha512-B8lBJ6FHT3eqfQupHANU6JGwSvqp4EGYSGgOiNh1EVwXNn5MeX1AztQO+sNqWl69nof9d7/7vxXmTeS7rmIFXw==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-call-timeout-policy/-/dsh-tool-call-timeout-policy-0.1.7-rc.2.tgz", + "integrity": "sha512-k8UaAZqeeYmcY2G03o8mD6ks8LL/yy9FpxAaskcAsVF2kJxMNS3+lSajbKc2APSYExG3jJxPN2OuiZ3EOUljLw==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-timeout": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-timeout": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-tool-cordis": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-cordis/-/dsh-tool-cordis-0.1.5-rc.2.tgz", - "integrity": "sha512-bm1p2cRmXvO5b4oj2YHvF6OFh8EcHJQREcD52SEkSWtdkeakHbwMEOeCLfSWSNMUiNeOa7tMutUQrepdCS37EA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-cordis/-/dsh-tool-cordis-0.1.7-rc.2.tgz", + "integrity": "sha512-hCZzHeHj2fy+fUnW9aVj4DkMao1KFuzfO249n+7Mkdo5WEEy9s9XlNAgZA6BKST6VuE6opIRbj1HqxEkMUqZuw==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-cordis-host-runner": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-scope": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/cordis-plugin-loader": "~1.0.5", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-app-boot": "0.1.7-rc.2", + "@deepseek-ai/dsh-cordis-host-runner": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-tool-fs": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-fs/-/dsh-tool-fs-0.1.5-rc.2.tgz", - "integrity": "sha512-/3AUx+V1UxVfl24fm10hwRbJnHwpBkRDHniOeocGknMvASheRiKnHpnnj9EszFRLYSpe2PRFSMuyuhXgYyd3MQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-fs/-/dsh-tool-fs-0.1.7-rc.2.tgz", + "integrity": "sha512-/6wYrqHH1530tncA7DxC3IxLN2iI8kyhCPR/NfaugL09yGPpBwxm455bMvITSjIAvINWpJfMQvaijPui6goY2Q==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/dsh-util-code-language": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4", "diff": "^9.0.0" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-attachment": "^0.1.5-rc.2", - "@deepseek-ai/dsh-fs": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-sandbox": "^0.1.5-rc.2", - "@deepseek-ai/dsh-sandbox-policy": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2", - "@deepseek-ai/dsh-user-approval": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-attachment": "0.1.7-rc.2", + "@deepseek-ai/dsh-fs": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox-policy": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2", + "@deepseek-ai/dsh-user-approval": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-tool-fs-search": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-fs-search/-/dsh-tool-fs-search-0.1.5-rc.2.tgz", - "integrity": "sha512-B4UrzbrigYiD8IKweuVzOHHLrhKfBPWTxscPDy0WmaYJ+aYQ/qaix9RgxnmJRoF8aVo4lw/Fzlz6hq30ahwUIw==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-fs-search/-/dsh-tool-fs-search-0.1.7-rc.2.tgz", + "integrity": "sha512-wVxBYba8b9CgnNWUZx6Es10FrM5sP1JbAN/wq3Rv1Qgt/Z5cb3CJwubqvMg5sxpohkqM0y/bXENAgxzh/hbKIw==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/schemastery": "~3.18.4", "@vscode/ripgrep": "^1.18.0" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-output-retention": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-spill": "^0.1.5-rc.2", - "@deepseek-ai/dsh-subprocess": "^0.1.5-rc.2", - "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2", - "@deepseek-ai/dsh-timeout": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-output-retention": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-spill": "0.1.7-rc.2", + "@deepseek-ai/dsh-subprocess": "0.1.7-rc.2", + "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2", + "@deepseek-ai/dsh-timeout": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-tool-goal": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-goal/-/dsh-tool-goal-0.1.5-rc.2.tgz", - "integrity": "sha512-nZ0NkUxvtAsrPAd9NMXt+4kS7WPn8xIvXCwVunKfBwbrnGnFCNmIsTQoHF44J6q9VbMeSCN2eyj07w6ej3Hf+g==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-goal/-/dsh-tool-goal-0.1.7-rc.2.tgz", + "integrity": "sha512-Otb3HOlyZA+44nDXrMi9PW4vlurudOaRYdA7hu4MZBtqvmFEty5loJAzrtDbAhwImhA/UM9M+7Qa2ijwm68qCw==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-goal": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.2", - "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-goal": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2", + "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-tool-jobs": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-jobs/-/dsh-tool-jobs-0.1.5-rc.2.tgz", - "integrity": "sha512-v4y56H3FsVBF2jUJLGLHdPeKaKJxLT4Zx/oii45UmJv5t8Bp3uCTVUoq/mfSFVuFY66q6rHJwgIOKWc4ZO3ySw==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-jobs/-/dsh-tool-jobs-0.1.7-rc.2.tgz", + "integrity": "sha512-FAqhI8Hf1InawbrJF/XUjIlQHV11vRMWbX7ofrekJcX0OBk/Og/h8SUzy1knGBVULEm8m2PDLxggXoMu+HVlvg==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-jobs": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-output-retention": "^0.1.5-rc.2", - "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-jobs": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-output-retention": "0.1.7-rc.2", + "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-tool-present": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-present/-/dsh-tool-present-0.1.5-rc.2.tgz", - "integrity": "sha512-WWxjEgh/nPsATfofNc0Qi+Eshy9LPNAYM+UWWisuKcT6smtv7+pR8Bk79RJu5BiFog8Nq17mwEh5XnFlDIg8FQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-present/-/dsh-tool-present-0.1.7-rc.2.tgz", + "integrity": "sha512-9TcVuL6qaQmKA89ACmPyToorvrLYmiJRVEbMr31WmcnvTyOBYLvQjcM39HWVPS50FKuYmHqlsyh3EkVUOkhTQQ==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-fs": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-fs": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-tool-pwsh": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-pwsh/-/dsh-tool-pwsh-0.1.5-rc.2.tgz", - "integrity": "sha512-rnHM3Jqlr7rthwfPYysXPq6zH+K8JTDqbE+xzjkbo1WIBKBZeSGr8kPjqdCZa7eUtWhmV/RFBP1qmBgDjEZaWg==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-pwsh/-/dsh-tool-pwsh-0.1.7-rc.2.tgz", + "integrity": "sha512-GMFZT35QKoFOXzFV576FbohrdfcXtrMJlOPqdQvNvUdMLYPiiJEIR4WSuqQuGBoez0bLxKVwtodGzwcvPBP+dQ==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-jobs": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-sandbox": "^0.1.5-rc.2", - "@deepseek-ai/dsh-sandbox-policy": "^0.1.5-rc.2", - "@deepseek-ai/dsh-shell": "^0.1.5-rc.2", - "@deepseek-ai/dsh-shell-env": "^0.1.5-rc.2", - "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2", - "@deepseek-ai/dsh-user-approval": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-jobs": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox-policy": "0.1.7-rc.2", + "@deepseek-ai/dsh-shell": "0.1.7-rc.2", + "@deepseek-ai/dsh-shell-env": "0.1.7-rc.2", + "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2", + "@deepseek-ai/dsh-user-approval": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-tool-pwsh-persistent": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-pwsh-persistent/-/dsh-tool-pwsh-persistent-0.1.5-rc.2.tgz", - "integrity": "sha512-NToI2tXkbAZS6Cxjnn7VjgCF7o68vMquvmpVh6RjTXAsawNY0TMmAVo67bREDw07+1j/bTq8EPywrJSmBbS2Fw==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-pwsh-persistent/-/dsh-tool-pwsh-persistent-0.1.7-rc.2.tgz", + "integrity": "sha512-Qmfs0hRjuy6UJXS5f+qyNhtVphZzINQlIbZ8vUCBnBJdByIRbHq8P2Qf97gvndv4XExKQ5vH+i3SwyR7UdK/GQ==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-terminal": "^0.1.5-rc.2", - "@deepseek-ai/dsh-timeout": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-output-retention": "0.1.7-rc.2", + "@deepseek-ai/dsh-terminal": "0.1.7-rc.2", + "@deepseek-ai/dsh-timeout": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-tool-ralph": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-ralph/-/dsh-tool-ralph-0.1.5-rc.2.tgz", - "integrity": "sha512-qP7KoVUBPLvvPSiJBXJtQt6c5ChnJRs5ZJnW/VU2DbBjYn4lkN6BiSfpRsSfjRGKO9fmldn2BYR0OnSLXi57xw==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-ralph/-/dsh-tool-ralph-0.1.7-rc.2.tgz", + "integrity": "sha512-D4AVzhOUVvN3GhM/grIC61acOgMzdka1dsRbPNPsSTAq2b9iocEGWlWexa4QK90fv1O0+r18RrsuLg9CHiWOLg==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-subagent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2", - "@deepseek-ai/dsh-workflow": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-subagent": "0.1.7-rc.2", + "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2", + "@deepseek-ai/dsh-workflow": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-tool-skill": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-skill/-/dsh-tool-skill-0.1.5-rc.2.tgz", - "integrity": "sha512-J0AshOq06tVWFbESolUP+9TEYXymASMULsWsqTBAgaIjzbZjhJ3x2CPMP54gM8uROh/y0qGBhVUErJeamP9AhQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-skill/-/dsh-tool-skill-0.1.7-rc.2.tgz", + "integrity": "sha512-mAhFhl7dmP5VZGsnvr36R/tAbhv1nyWRhdWmCpkkAc/zUNjn4ItqVe8eCeho9rkCfC4d0JmqBLQxY0bR6gVgIQ==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-skill": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-skill": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-tool-str-replace-editor": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-str-replace-editor/-/dsh-tool-str-replace-editor-0.1.5-rc.2.tgz", - "integrity": "sha512-SqxB7jgmAURwttFMQ9CmM4l1n5pdMA1ofPOd0Fp2OqYRdo8C0NCO0YN06PtX3CvmjI6vjDUT3grXqETzhmN3gg==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-str-replace-editor/-/dsh-tool-str-replace-editor-0.1.7-rc.2.tgz", + "integrity": "sha512-3ul3GhzjcPYu455d7UncHYi3k3j0oNaJrOi/Xa5Nu/cu6XFD1RNS+r3oeXoKsnQhhLvamvRNUbZo4+Rf2g3WIw==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-fs": "^0.1.5-rc.2", - "@deepseek-ai/dsh-sandbox": "^0.1.5-rc.2", - "@deepseek-ai/dsh-sandbox-policy": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-fs": "0.1.7-rc.2", + "@deepseek-ai/dsh-output-retention": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox-policy": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-tool-subagent": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-subagent/-/dsh-tool-subagent-0.1.5-rc.2.tgz", - "integrity": "sha512-6H7iL1UMcPrQTZrmp/olatipQzg6z5b3xqqPpW26qhgX9tDttJJGAspObePM8Zj02EO9ibz7QLg/VIehPuu+sg==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-subagent/-/dsh-tool-subagent-0.1.7-rc.2.tgz", + "integrity": "sha512-tsClP3op2uxw3itf/L2EQ37QLS6LEdcKuBKUmq0XNnOvAjut4xUByDzI52W94leJ2hVbWYipmDzlGis27mo95g==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/schemastery": "~3.18.4", "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2", - "@deepseek-ai/dsh-jobs": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-scope": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.2", - "@deepseek-ai/dsh-settings": "^0.1.5-rc.2", - "@deepseek-ai/dsh-subagent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", + "@deepseek-ai/dsh-jobs": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-scope": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2", + "@deepseek-ai/dsh-subagent": "0.1.7-rc.2", + "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-tool-subagent-control": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-subagent-control/-/dsh-tool-subagent-control-0.1.5-rc.2.tgz", - "integrity": "sha512-kuSx9UGDBUSrffTPnNetKj7mUmH1+24BQT+589vaN5epO8GKZ1STzIR3IINn+kMP0t9MAGIhEsa39b30OQu9nA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-subagent-control/-/dsh-tool-subagent-control-0.1.7-rc.2.tgz", + "integrity": "sha512-GQASFI77x8ly7HSJ64Uxd281LqnPlnuQnF860Xx0z36OPHLzDzdFksFiFeT8nI1llun6FoqkZli3EUsPAXme1g==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2" + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-subagent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-subagent": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-tool-todo": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-todo/-/dsh-tool-todo-0.1.5-rc.2.tgz", - "integrity": "sha512-TmyoAthal1pOCQ/XwlohcxDXdI5pq5GlZiQpLaI7e+rAruqneBPz/0Zjv6/rlOMrseoENMx+H0sazwoL9LufTQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-todo/-/dsh-tool-todo-0.1.7-rc.2.tgz", + "integrity": "sha512-W5H6XKw7C9MzEtq+tliiAe2cI8hkbg1QA/yJLpRnm2z0xPZwaaX3I3o76gJa6tQPY7TvkFu8WQYOwtToAI8fwA==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/schemastery": "~3.18.4", "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-tool-web": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-web/-/dsh-tool-web-0.1.5-rc.2.tgz", - "integrity": "sha512-FPHiDBHjyO/2ayVcUL8tmcBqc+Fi8Y0zcQuzsFw6/K8pOJvP/pBSN8mXi4tBVmmqXg25ZXVo1vDDo4T1mBIlFw==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-web/-/dsh-tool-web-0.1.7-rc.2.tgz", + "integrity": "sha512-vFjWk841utlC8M9LMj+Qy1ZQF0skcbnt07vP5guH68UbL3zjDix0+LShpbd/mluQyJ3LhzRpKmqveysnna2hAg==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4", "@joplin/turndown-plugin-gfm": "^1.0.67", "turndown": "^7.2.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2", - "@deepseek-ai/dsh-web": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2", + "@deepseek-ai/dsh-web": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-tool-workflow": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-workflow/-/dsh-tool-workflow-0.1.5-rc.2.tgz", - "integrity": "sha512-co/4mEKOC5MYXM/x2sdTiIwPfUtK3Bhst7HMwmgcz3PNZG4DEkaqLlzsZyisLn4iQvKChtvdyS5fWwNeC8ws1w==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-workflow/-/dsh-tool-workflow-0.1.7-rc.2.tgz", + "integrity": "sha512-VFo7mhhUu+tHS4sLCMejWexhQPYguoiOainwYBCuxd0fCmkgIFnSEH+AmMfsWYAbtUxhMNaoktB4RNnl8QmXmQ==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2", - "@deepseek-ai/dsh-workflow": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", + "@deepseek-ai/dsh-jobs": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2", + "@deepseek-ai/dsh-workflow": "0.1.7-rc.2" + } + }, + "node_modules/@deepseek-ai/dsh-tool-workspace-dependencies": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tool-workspace-dependencies/-/dsh-tool-workspace-dependencies-0.1.7-rc.2.tgz", + "integrity": "sha512-soBNUme9Pfp/rLTM8t4tUqYe6jJHD5rUQWvAr/z3AckuhbkBu+d9BpBij8oinJoM7fRz0uUywzxGtfaFBD42mg==", + "license": "MIT", + "dependencies": { + "@deepseek-ai/schemastery": "~3.18.4" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-tools": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tools/-/dsh-tools-0.1.5-rc.2.tgz", - "integrity": "sha512-k2yZuJJtszaU9lzr2aBtdeFMINrkdlk4ellbtrMokA2oySVqJmAM8dv+u9RtzduD3aRRqyr2i2hWrTACz0qOrA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-tools/-/dsh-tools-0.1.7-rc.2.tgz", + "integrity": "sha512-c3dTdKnslKxVTgjjPLwMKLqGUMwnZH5P8RUsucMQlWn2GViyFW/+5AIUuZHBjjE6Y7NAYl+lVVE/R4LgTp5KWA==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-code-runtime": "^0.1.5-rc.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-scope": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2", - "@deepseek-ai/dsh-user-approval": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-ptc-runtime": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox-policy": "0.1.7-rc.2", + "@deepseek-ai/dsh-scope": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2", + "@deepseek-ai/dsh-user-approval": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-typert-loader": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-typert-loader/-/dsh-typert-loader-0.1.5-rc.2.tgz", - "integrity": "sha512-5kNw5jLJ1PBGqL9Ma/ym+Uz8pbFhMe2Ci0QypPtE71ViUC8K0usgypqmn3+2vXtBk5E5mI/n3UGu9gyTPdHIYA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-typert-loader/-/dsh-typert-loader-0.1.7-rc.2.tgz", + "integrity": "sha512-oA8oXl4tMfhJcaPfi0ZhxZjixCKirLvYpRG09yM1t3oIgm8sG9JlCLwJlNo/jEOlxnO9EDoxLZ2IW5saU7ANrA==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/cordis-plugin-loader": "^1.0.3", - "@deepseek-ai/dsh-typert-registry": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/cordis-plugin-loader": "~1.0.5", + "@deepseek-ai/dsh-typert-registry": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-typert-protocol": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-typert-protocol/-/dsh-typert-protocol-0.1.5-rc.2.tgz", - "integrity": "sha512-zP8J20rBXa1AFjKL2i83JBeQcePZx8yal3pNojj4t7CCokMcoFMUbr50woa6fY1tRJ7qHxgypO3rH8Q6YWgmiA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-typert-protocol/-/dsh-typert-protocol-0.1.7-rc.2.tgz", + "integrity": "sha512-oJm03zqMQlvt16Ejw7VWy3/gqlJGrBCZj3Z4KL8ydLJeeTToKIR49WVCxMbJTlH0F9QFljruLtHguA5B99AeUQ==", "license": "MIT", + "dependencies": { + "@deepseek-ai/dsh-brand": "0.1.7-rc.2" + }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-typert-registry": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-typert-registry/-/dsh-typert-registry-0.1.5-rc.2.tgz", - "integrity": "sha512-GBHGD8T4goY8kKA0U1jD2YRPAgkESdVuSNXn7KpYeb3SLtVntt2ND+FMSwNqcMN/zuBm9Yvo5x/nuK+yxFqvBw==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-typert-registry/-/dsh-typert-registry-0.1.7-rc.2.tgz", + "integrity": "sha512-fU6+xBn1BmFeWR0TlJUrOH3Vek21Wz1XHZvC+y1Ftc/cc4VNRBEQp3tvUSTKC0n3TBELqO9yY0uQP+l0JhlAHQ==", "license": "MIT", "dependencies": { "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-user-approval": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-user-approval/-/dsh-user-approval-0.1.5-rc.2.tgz", - "integrity": "sha512-8UpMEnEyMo6mYEVELBo0DC2iG7aJJfFMTNkU+DKD3c5Ut7ySRDzt1iRr1qni/CzqlTIpQBAkGaG77qk4q/v1bg==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-user-approval/-/dsh-user-approval-0.1.7-rc.2.tgz", + "integrity": "sha512-RQ6GB+C4G6VY/eJrFfS89+89DfHFAJ5G1abhmutfKBhZcYSnGNZyPIzpr5mKbl2xNMIhvCJOb9WiFz2fUPW2HA==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-scope": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-scope": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-user-questions": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-user-questions/-/dsh-user-questions-0.1.5-rc.2.tgz", - "integrity": "sha512-0cRRE9nc9pMxxyC8G8C3859EtPyZR/27FRgRMRe/wDWL30S6JoWWgaw7IFN9FogvaoEp62XV7wQ6ub/eoTqggg==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-user-questions/-/dsh-user-questions-0.1.7-rc.2.tgz", + "integrity": "sha512-Z7rfQTXNRgPEt0gEcetoM7iO9CVxsUCeDwHVj59ArFmUGS4491Y2AxXg8NP6Hu5x79XAZ0N49sHh7FiJBPYUWQ==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-scope": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-scope": "0.1.7-rc.2" + } + }, + "node_modules/@deepseek-ai/dsh-util-code-language": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-util-code-language/-/dsh-util-code-language-0.1.7-rc.2.tgz", + "integrity": "sha512-/NcCcgFXbTfV4sse5HoYO6SyKfcn9GFHeCP/bPkFsACZSv1dhosFivnz8jkkS1esbQe97jiki+UQcZBd+O6Usw==", + "license": "MIT", + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-util-crypto": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-util-crypto/-/dsh-util-crypto-0.1.5-rc.2.tgz", - "integrity": "sha512-JR0aJEUL35RE8FVT89wMZMbPwMrbkjNcy+gE9pq70d/m2Zxw3a0iNer+BAxPAKYPbmy0xDDXReTwXiecKVy4sQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-util-crypto/-/dsh-util-crypto-0.1.7-rc.2.tgz", + "integrity": "sha512-BGc55/bSj/1LcDTQ5fpok4U24X9SFyN+TB23/hBlbe2TBUKVuwO8+X5FFKKje2MLO8PWYEDkXv/LrV6jRVKZEg==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-util-time": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-util-time/-/dsh-util-time-0.1.5-rc.2.tgz", - "integrity": "sha512-nWJrNCaEBANFUX+Rp2cE1+hA2CGCmktXOo2Nsh524aV2VaLumFFS501IsmI9ghUmUE77qZxvayGGO7w3LLIECQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-util-time/-/dsh-util-time-0.1.7-rc.2.tgz", + "integrity": "sha512-+bj6L7zdTybkmhEnIlv8ZR1pOm1S+I569CMCtIfbdIg88334hWxRyygCksvNC/VG3Lk3jeO0HzThkv3R7OIsxw==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-util-values": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-util-values/-/dsh-util-values-0.1.5-rc.2.tgz", - "integrity": "sha512-Cr0TkM6dFAD+Iy4sNXH/afJVMHwJXoOztivj+RflkYoACsOq+Ix0vdHn36hwW7mayU8OK3ZKIZUQ6BPo1fHvUg==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-util-values/-/dsh-util-values-0.1.7-rc.2.tgz", + "integrity": "sha512-UX8nh5SbtZcPVVEvjd+9PCPcbybA6OpVzJGgFxYn59ao/7QQGyYbByS8KXr+THU5JtqmDDVb9xGUSJaF2IYmeQ==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-util-workspace-path": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-util-workspace-path/-/dsh-util-workspace-path-0.1.5-rc.2.tgz", - "integrity": "sha512-RCBz+6BpdPDNsRk2ukIdIIuLdf6u+cS8sLiViFg/8/x/kxc+LEXRKJMy2xv+YA9hYOGFK109rjUFgx9JVtZf2w==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-util-workspace-path/-/dsh-util-workspace-path-0.1.7-rc.2.tgz", + "integrity": "sha512-opp6TTeRvZHPi2bsXNK66TwUBh4uNECZJp/qK35ffLQRNa3L+RoPsGgOJZuRjkXdNygytM26P/CWjaBX65oKXg==", "license": "MIT", "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "@deepseek-ai/cordis": "~4.0.4" } }, "node_modules/@deepseek-ai/dsh-web": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-web/-/dsh-web-0.1.5-rc.2.tgz", - "integrity": "sha512-3qt/Fh+uCghOy2wZPjwQ6xIMU3t1NW4D5yRvTXOyvadwaDwosqXOzCteYUhnuWzWN66adrFLeRrymhSDS4PMeg==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-web/-/dsh-web-0.1.7-rc.2.tgz", + "integrity": "sha512-iMKo3ZeF3OEl0shHmPo/k7UmRQdynPdhLyoHGuSduMj5qPSTnRzZEYCJ4OErvCaxRSY9gSlcVEiOATKhCgUwsQ==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-web-app": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-web-app/-/dsh-web-app-0.1.5-rc.2.tgz", - "integrity": "sha512-Ng7YVDt9txh2BlLmu6B+V677c1bihbh/rq3EOtZK4b0JWtgdNgYb1KPIED8+aK2i+FghrCrIy6X60AyJ45eOvw==", - "license": "MIT", - "dependencies": { - "@deepseek-ai/dsh-agent-presets": "^0.1.5-rc.2", - "@deepseek-ai/dsh-api-remotes": "^0.1.5-rc.2", - "@deepseek-ai/dsh-api-session-controller": "^0.1.5-rc.2", - "@deepseek-ai/dsh-api-settings-controller": "^0.1.5-rc.2", - "@deepseek-ai/dsh-api-workspace-controller": "^0.1.5-rc.2", - "@deepseek-ai/dsh-api-workspace-files": "^0.1.5-rc.2", - "@deepseek-ai/dsh-app-boot": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-connection": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-file-upload": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-hmr": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-locale": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-modules": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-resources": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-agent-preset": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-approval": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-attachment": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-brand-official": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-chat": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-commands": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-conversation": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-cordis": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-deliverables": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-directory-picker-browse": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-directory-picker-native": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-goal": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-input-trigger": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-jobs": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-layout": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-message-feedback": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-model-selection": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-open-in-app": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-permission-presets": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-plan": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-reference": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-renderer": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-schedule": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-settings": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-settings-general": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-settings-models": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-settings-plugin-inventory": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-settings-plugins": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-sidebar": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-sidebar-documentpreview": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-sidebar-files": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-sidebar-right": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-skill": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-subagent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-theme": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-tool": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-trajectory": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-user-questions": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-workflow-run": "^0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-workspace": "^0.1.5-rc.2", - "@deepseek-ai/dsh-cmdline": "^0.1.5-rc.2", - "@deepseek-ai/dsh-code-runtime-worker-thread": "^0.1.5-rc.2", - "@deepseek-ai/dsh-cordis-client-runner": "^0.1.5-rc.2", - "@deepseek-ai/dsh-cordis-host-runner": "^0.1.5-rc.2", - "@deepseek-ai/dsh-file-reference": "^0.1.5-rc.2", - "@deepseek-ai/dsh-file-reference-local": "^0.1.5-rc.2", - "@deepseek-ai/dsh-host-directory-picker-auto": "^0.1.5-rc.2", - "@deepseek-ai/dsh-host-directory-picker-browse": "^0.1.5-rc.2", - "@deepseek-ai/dsh-host-directory-picker-native": "^0.1.5-rc.2", - "@deepseek-ai/dsh-host-frontend-static": "^0.1.5-rc.2", - "@deepseek-ai/dsh-host-open-in-app": "^0.1.5-rc.2", - "@deepseek-ai/dsh-host-plugin-inventory": "^0.1.5-rc.2", - "@deepseek-ai/dsh-host-webserver": "^0.1.5-rc.2", - "@deepseek-ai/dsh-launch-environment": "^0.1.5-rc.2", - "@deepseek-ai/dsh-message-feedback": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-log-export": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-reference": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-stats": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-turn-outline": "^0.1.5-rc.2", - "@deepseek-ai/dsh-subprocess": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tool-subagent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-web-frontend": "^0.1.5-rc.2", - "@deepseek-ai/dsh-workspace": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-web-app/-/dsh-web-app-0.1.7-rc.2.tgz", + "integrity": "sha512-3cMgHys6X9N063HcjhFN2a3azGoWWDtH42/io33gcBZMZxbYP5Kevc4l/erwKa5hAzXtJ2FArjJAytJmy8WSKw==", + "license": "MIT", + "dependencies": { + "@deepseek-ai/dsh-agent-instructions": "0.1.7-rc.2", + "@deepseek-ai/dsh-agent-preset": "0.1.7-rc.2", + "@deepseek-ai/dsh-agent-preset-registry": "0.1.7-rc.2", + "@deepseek-ai/dsh-agent-tool-presentation": "0.1.7-rc.2", + "@deepseek-ai/dsh-api-account-controller": "0.1.7-rc.2", + "@deepseek-ai/dsh-api-job-controller": "0.1.7-rc.2", + "@deepseek-ai/dsh-api-remotes": "0.1.7-rc.2", + "@deepseek-ai/dsh-api-session-controller": "0.1.7-rc.2", + "@deepseek-ai/dsh-api-settings-controller": "0.1.7-rc.2", + "@deepseek-ai/dsh-api-terminal-controller": "0.1.7-rc.2", + "@deepseek-ai/dsh-api-workspace-controller": "0.1.7-rc.2", + "@deepseek-ai/dsh-api-workspace-files": "0.1.7-rc.2", + "@deepseek-ai/dsh-app-boot": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-connection": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-file-upload": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-hmr": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-locale": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-modules": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-resources": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-shortcuts": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-agent-preset": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-approval": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-attachment": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-brand-official": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-chat": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-commands": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-conversation": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-cordis": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-deliverables": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-directory-picker-browse": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-directory-picker-native": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-goal": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-input-trigger": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-jobs": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-layout": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-message-feedback": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-model-selection": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-open-in-app": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-permission-presets": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-plan": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-plugin-manager": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-reference": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-renderer": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-schedule": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-settings": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-settings-account": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-settings-agent-loop": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-settings-general": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-settings-models": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-settings-plugin-inventory": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-settings-plugins": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-settings-shell": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-settings-subagent": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-settings-web-search": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-shortcuts": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-sidebar": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-sidebar-browser": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-sidebar-documentpreview": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-sidebar-files": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-sidebar-right": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-sidebar-terminal": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-skill": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-subagent": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-theme": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-tool": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-trajectory": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-user-questions": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-workflow-run": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-workspace": "0.1.7-rc.2", + "@deepseek-ai/dsh-cmdline": "0.1.7-rc.2", + "@deepseek-ai/dsh-command-compact": "0.1.7-rc.2", + "@deepseek-ai/dsh-command-goal": "0.1.7-rc.2", + "@deepseek-ai/dsh-compaction-basic": "0.1.7-rc.2", + "@deepseek-ai/dsh-compaction-tool-result-pruner": "0.1.7-rc.2", + "@deepseek-ai/dsh-cordis-client-runner": "0.1.7-rc.2", + "@deepseek-ai/dsh-cordis-host-runner": "0.1.7-rc.2", + "@deepseek-ai/dsh-file-reference": "0.1.7-rc.2", + "@deepseek-ai/dsh-file-reference-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-host-directory-picker-auto": "0.1.7-rc.2", + "@deepseek-ai/dsh-host-directory-picker-browse": "0.1.7-rc.2", + "@deepseek-ai/dsh-host-directory-picker-native": "0.1.7-rc.2", + "@deepseek-ai/dsh-host-frontend-static": "0.1.7-rc.2", + "@deepseek-ai/dsh-host-open-in-app": "0.1.7-rc.2", + "@deepseek-ai/dsh-host-plugin-inventory": "0.1.7-rc.2", + "@deepseek-ai/dsh-host-webserver": "0.1.7-rc.2", + "@deepseek-ai/dsh-launch-environment": "0.1.7-rc.2", + "@deepseek-ai/dsh-message-feedback": "0.1.7-rc.2", + "@deepseek-ai/dsh-office-to-pdf": "0.1.7-rc.2", + "@deepseek-ai/dsh-persona": "0.1.7-rc.2", + "@deepseek-ai/dsh-plan-mode": "0.1.7-rc.2", + "@deepseek-ai/dsh-plugin-manager": "0.1.7-rc.2", + "@deepseek-ai/dsh-schedule": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-log-export": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-reference": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-stats": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-turn-outline": "0.1.7-rc.2", + "@deepseek-ai/dsh-skill-filesystem": "0.1.7-rc.2", + "@deepseek-ai/dsh-subprocess": "0.1.7-rc.2", + "@deepseek-ai/dsh-terminal": "0.1.7-rc.2", + "@deepseek-ai/dsh-terminal-bash": "0.1.7-rc.2", + "@deepseek-ai/dsh-time-context": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-ask-user": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-bash": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-bash-persistent": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-cordis": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-fs": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-fs-search": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-goal": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-jobs": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-present": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-pwsh": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-pwsh-persistent": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-ralph": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-skill": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-subagent": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-subagent-control": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-todo": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-web": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-workflow": "0.1.7-rc.2", + "@deepseek-ai/dsh-web-frontend": "0.1.7-rc.2", + "@deepseek-ai/dsh-workflow-ptc": "0.1.7-rc.2", + "@deepseek-ai/dsh-workspace": "0.1.7-rc.2", + "@deepseek-ai/dsh-workspace-changes": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4", "commander": "^15.0.0", "open": "^11.0.0" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/cordis-plugin-loader": "^1.0.3", - "@deepseek-ai/dsh-shell-env": "^0.1.5-rc.2", - "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/cordis-plugin-loader": "~1.0.5", + "@deepseek-ai/dsh-shell-env": "0.1.7-rc.2", + "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-web-fetch-http": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-web-fetch-http/-/dsh-web-fetch-http-0.1.5-rc.2.tgz", - "integrity": "sha512-K3us2mU0L1sgnW4FFtDI6UYcL+JZvIbdRLEAO+8oq9lHAuwKuCcb4RPPuyXMI35ue97PkfBgt6A6Sl0utiIF3A==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-web-fetch-http/-/dsh-web-fetch-http-0.1.7-rc.2.tgz", + "integrity": "sha512-fz1aBg58oqigPDkmePUjlONK4u345fd7BF2q/sD2LGnTafrBBQqeiJ5BZQrjPLYoLywsATveRt9h/tLqU4XD3Q==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/schemastery": "~3.18.4", "ipaddr.js": "^2.5.0", "undici": "^8.10.0" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-http-proxy": "^0.1.5-rc.2", - "@deepseek-ai/dsh-timeout": "^0.1.5-rc.2", - "@deepseek-ai/dsh-web": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-http-proxy": "0.1.7-rc.2", + "@deepseek-ai/dsh-timeout": "0.1.7-rc.2", + "@deepseek-ai/dsh-web": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-web-frontend": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-web-frontend/-/dsh-web-frontend-0.1.5-rc.2.tgz", - "integrity": "sha512-o0+dEbtEzchPnNFkKQ4o3/OekEi+PG8CTEwp1eWWg15TRiZbG2OeUKMsQjPpAVCMDnpEwMQ9skdKcwKj4TXAzQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-web-frontend/-/dsh-web-frontend-0.1.7-rc.2.tgz", + "integrity": "sha512-E9OgyYxFAeVaymPWzlqluWcX2KLmE107FXDB9nUrn/ADitlaEqGlReotK6g9LXqTY5m9TMp+WcTB71qbkg2U5g==", "license": "MIT" }, "node_modules/@deepseek-ai/dsh-web-search-deepseek": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-web-search-deepseek/-/dsh-web-search-deepseek-0.1.5-rc.2.tgz", - "integrity": "sha512-0r9KqkjnOd7VLwWEAYHOEGLctRwhGLOJ9xnnGuL3nd3uFcrA5Wb1MYbJhGKxx+9XRpTJZyi7Aiex9QRAr8c0Ag==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-web-search-deepseek/-/dsh-web-search-deepseek-0.1.7-rc.2.tgz", + "integrity": "sha512-xkDMbKm8Bu/PzoUO7pc3q2ME5p8HQo0NVbT67dGY0jtdwX2klaMMCDkkkMDkPvKJi+HjpVIDLH7eMdtMqQbShw==", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2" + "@deepseek-ai/schemastery": "~3.18.4" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-credentials": "^0.1.5-rc.2", - "@deepseek-ai/dsh-launch-environment": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-settings": "^0.1.5-rc.2", - "@deepseek-ai/dsh-web": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-credentials": "0.1.7-rc.2", + "@deepseek-ai/dsh-launch-environment": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-web": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-webhook": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-webhook/-/dsh-webhook-0.1.5-rc.2.tgz", - "integrity": "sha512-Tv4aR5JYxq9ODe9lYoFaQWjFUf644tPaSVSgfBMPrynN9X94rcY7HAkYxt3qLggvK/cGrtNOFwyqyOIDTjqyJQ==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-webhook/-/dsh-webhook-0.1.7-rc.2.tgz", + "integrity": "sha512-2ZIAdQBN6XxC2aN247m/3Q9qacEJiSE5KINhdYfWDVALt8c7cTMjWwqhIBjQhr8G0LdFUHp9PIUXNnRxNzKezA==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2" + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-agent-default-model": "^0.1.5-rc.2", - "@deepseek-ai/dsh-agent-presets": "^0.1.5-rc.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-permission-presets": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-title": "^0.1.5-rc.2", - "@deepseek-ai/dsh-workspace": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-agent-default-model": "0.1.7-rc.2", + "@deepseek-ai/dsh-agent-preset-registry": "0.1.7-rc.2", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-permission-presets": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-title": "0.1.7-rc.2", + "@deepseek-ai/dsh-workspace": "0.1.7-rc.2" } }, "node_modules/@deepseek-ai/dsh-webhook-github": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-webhook-github/-/dsh-webhook-github-0.1.5-rc.2.tgz", - "integrity": "sha512-esocwn22CYbOAo7WzwWl/E3jsHKOAXFS5e1dnW9b5VNPujnbHdvhXyyNQzUW0nNnxt1QTsIARyhqpDKWuanCcA==", + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-webhook-github/-/dsh-webhook-github-0.1.7-rc.2.tgz", + "integrity": "sha512-PwGhpHa4FiYErVE0Hd905Q50qXty+0WMK+1XXLevEjOHdFyj81m8F+VB5RSw3nNjDhkGzYVmBMlplLwl2drLFw==", "license": "MIT", "dependencies": { - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2", + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4", "@octokit/webhooks": "^14.2.0" }, "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-credentials": "^0.1.5-rc.2", - "@deepseek-ai/dsh-host-webserver": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-webhook": "^0.1.5-rc.2" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-credentials": "0.1.7-rc.2", + "@deepseek-ai/dsh-host-webserver": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-webhook": "0.1.7-rc.2" + } + }, + "node_modules/@deepseek-ai/dsh-win32-process": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-win32-process/-/dsh-win32-process-0.1.7-rc.2.tgz", + "integrity": "sha512-sa3z0camBZEQsf2g5XK8SLsNqTY5OYli0nUCG8j6yzkWOb52cBpDA0hSNo5hP6IhVba5N8hT/DfjS3IbktGz1Q==", + "license": "MIT", + "dependencies": { + "@deepseek-ai/dsh-lazy-require": "0.1.7-rc.2", + "koffi": "^3.1.0" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4" + } + }, + "node_modules/@deepseek-ai/dsh-workflow": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-workflow/-/dsh-workflow-0.1.7-rc.2.tgz", + "integrity": "sha512-PJ8IH48HKPporTG5tGHPWs8pRHADMI/tp147OY09oD5FNQw3MjrVTF38TzhZp3FCjhHCxnbdhcayCxh1QzThFg==", + "license": "MIT", + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2" + } + }, + "node_modules/@deepseek-ai/dsh-workflow-ptc": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-workflow-ptc/-/dsh-workflow-ptc-0.1.7-rc.2.tgz", + "integrity": "sha512-INiZ8OUrrQGYgF/YfbDi6ajwkOaFHwp0YhlSDVZQWiJY+HnG8QY9XEydCyf+wdMkayCwqLHBFSLNzHh4OsM5LA==", + "license": "MIT", + "dependencies": { + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "~3.18.4" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-ptc-runtime": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox-policy": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-subagent": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2", + "@deepseek-ai/dsh-workflow": "0.1.7-rc.2" + } + }, + "node_modules/@deepseek-ai/dsh-workspace": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-workspace/-/dsh-workspace-0.1.7-rc.2.tgz", + "integrity": "sha512-RgSIGkcJnAB6stdJ73yvRT1sXbYtcrYIz9PadVrxTHvcScffaLpXGp8NUNjQgCG0n28CfnCNPdj2qHCbG4yo1g==", + "license": "MIT", + "dependencies": { + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "zod": "^4.4.3" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-persistence": "0.1.7-rc.2", + "@deepseek-ai/dsh-storage": "0.1.7-rc.2", + "@deepseek-ai/dsh-storage-domain": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2" + } + }, + "node_modules/@deepseek-ai/dsh-workspace-changes": { + "version": "0.1.7-rc.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-workspace-changes/-/dsh-workspace-changes-0.1.7-rc.2.tgz", + "integrity": "sha512-5CnBghKfz/Q3bzE8hcwc02GsYpg7BnobUJO7eIrlmCG9764ja+ij5xeuotoNegP9n19+lg7+3A3HKerz2B6m/Q==", + "license": "MIT", + "dependencies": { + "@deepseek-ai/schemastery": "~3.18.4", + "diff": "^9.0.0" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-subprocess": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2" + } + }, + "node_modules/@deepseek-ai/libreoffice-kit": { + "version": "0.1.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/libreoffice-kit/-/libreoffice-kit-0.1.2.tgz", + "integrity": "sha512-PM3GtAr8/nG7mY22yoYQgRTfkhzQ72v1sDME/46I/Kl7S4+yOFYC1h0hRT8JL9p9vjdEwXW9icdhUQK0QPz+YQ==", + "license": "MPL-2.0", + "dependencies": { + "fflate": "0.8.2", + "fontkit": "2.0.4", + "saxes": "6.0.0" + }, + "bin": { + "libreoffice-kit": "lib/cli.js" + }, + "engines": { + "node": ">=22.19.0" + }, + "optionalDependencies": { + "@deepseek-ai/libreoffice-kit-darwin-arm64": "0.1.1", + "@deepseek-ai/libreoffice-kit-darwin-x64": "0.1.1", + "@deepseek-ai/libreoffice-kit-wasm": "0.1.1", + "@deepseek-ai/libreoffice-kit-win32-arm64": "0.1.2", + "@deepseek-ai/libreoffice-kit-win32-x64": "0.1.2" + } + }, + "node_modules/@deepseek-ai/libreoffice-kit-darwin-arm64": { + "version": "0.1.1", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/libreoffice-kit-darwin-arm64/-/libreoffice-kit-darwin-arm64-0.1.1.tgz", + "integrity": "sha512-D6NBvtoNpm9pOgBXGQTdxpds1tYMeiFKhGJgnXF/SE0124ZM8j0AOXI7cZ8CErHctqIoVYP+gKWCrnQl4we41A==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=22.19.0" } }, - "node_modules/@deepseek-ai/dsh-win32-process": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-win32-process/-/dsh-win32-process-0.1.5-rc.2.tgz", - "integrity": "sha512-KWF9pldnznDE1XiD7vjxg+P2cDQHOCJtz8ZQ/P0bLorDog/peQwqxYNgc/nrHxEZ1vWl/vbdd8Nvoen6FJ/Orw==", - "license": "MIT", - "dependencies": { - "koffi": "^3.1.0" - }, - "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2" + "node_modules/@deepseek-ai/libreoffice-kit-darwin-x64": { + "version": "0.1.1", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/libreoffice-kit-darwin-x64/-/libreoffice-kit-darwin-x64-0.1.1.tgz", + "integrity": "sha512-VcAqzmzDbRySLBnpRNYSEd+fDmAtdgL1hQMjRf4sFnQuz7m1vipQ00DtlqFG/T+9uCc20bMIyiDWh8zfYObW3w==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=22.19.0" } }, - "node_modules/@deepseek-ai/dsh-workflow": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-workflow/-/dsh-workflow-0.1.5-rc.2.tgz", - "integrity": "sha512-eGOBiC4RA89zZTTG6hBpTchau55lZ67P/dyqg4kJq8K1FwummTg3xed4Ecy9KQFaSX8rWQP9RMJnaWg1fBgXTA==", - "license": "MIT", - "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2" + "node_modules/@deepseek-ai/libreoffice-kit-wasm": { + "version": "0.1.1", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/libreoffice-kit-wasm/-/libreoffice-kit-wasm-0.1.1.tgz", + "integrity": "sha512-YuKZJdDhR/0GeTZUHJsJvachJR8ZiS4lcrL+lxUF2GLRwXcMikN0zAQOA+6kD/nRI+vlHsCkX0KvHaKvfae79Q==", + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=22.19.0" } }, - "node_modules/@deepseek-ai/dsh-workflow-worker-thread": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-workflow-worker-thread/-/dsh-workflow-worker-thread-0.1.5-rc.2.tgz", - "integrity": "sha512-y8twj+FNYoxaaLWYkr/tQauCHymlY3AUgS5lHEi4tZW1PgYD2mEz7VPHu1nUWX7W6m78gCQvg/6KcDCLrTgvcA==", - "license": "MIT", - "dependencies": { - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "@deepseek-ai/dsh-util-values": "^0.1.5-rc.2", - "@deepseek-ai/schemastery": "^3.18.2" - }, - "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-subagent": "^0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.2", - "@deepseek-ai/dsh-workflow": "^0.1.5-rc.2" + "node_modules/@deepseek-ai/libreoffice-kit-win32-arm64": { + "version": "0.1.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/libreoffice-kit-win32-arm64/-/libreoffice-kit-win32-arm64-0.1.2.tgz", + "integrity": "sha512-+JMKIDfLfpQEIeWWJBkKeAGJ8Niiv6SLQ1SFMh8K28eUOSaLLGPt4j7ywEWtyKCtXenD+VRlKo5gZlqDmCtNCg==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=22.19.0" } }, - "node_modules/@deepseek-ai/dsh-workspace": { - "version": "0.1.5-rc.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/dsh-workspace/-/dsh-workspace-0.1.5-rc.2.tgz", - "integrity": "sha512-J2RIjHk2RNTtQNZ1Dpy1ItdhOmXDsWXLvMNv/MMdvv3NzCjKMYQ8le18lpzboqAZY3I2cOfX0cxu6wHIC96SIg==", - "license": "MIT", - "dependencies": { - "@deepseek-ai/dsh-brand": "^0.1.5-rc.2", - "zod": "^4.4.3" - }, - "peerDependencies": { - "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session": "^0.1.5-rc.2", - "@deepseek-ai/dsh-session-persistence": "^0.1.5-rc.2", - "@deepseek-ai/dsh-storage": "^0.1.5-rc.2", - "@deepseek-ai/dsh-storage-domain": "^0.1.5-rc.2", - "@deepseek-ai/dsh-typert-protocol": "^0.1.5-rc.2" + "node_modules/@deepseek-ai/libreoffice-kit-win32-x64": { + "version": "0.1.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/libreoffice-kit-win32-x64/-/libreoffice-kit-win32-x64-0.1.2.tgz", + "integrity": "sha512-EUuTMnFF404uVVZz0j2oAoHY0Xhobdg0jChUUm74sudwaqxTM9rvgUYEWbeJd95oVjIParMdsb4hLdAhZ10BIw==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=22.19.0" } }, + "node_modules/@deepseek-ai/libreoffice-kit/node_modules/fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmmirror.com/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", + "license": "MIT" + }, "node_modules/@deepseek-ai/node-addon-system": { "version": "0.1.2", "resolved": "https://registry.npmmirror.com/@deepseek-ai/node-addon-system/-/node-addon-system-0.1.2.tgz", @@ -5211,12 +6094,12 @@ } }, "node_modules/@deepseek-ai/schemastery": { - "version": "3.18.2", - "resolved": "https://registry.npmmirror.com/@deepseek-ai/schemastery/-/schemastery-3.18.2.tgz", - "integrity": "sha512-njDtZsznjYxok7KLLlHOPyuv2efdWVbSflAHgztSfbMsg+CVraEoRe2DjOCgClYv3ZCSm7WXoaUkbB/+RY7tWQ==", + "version": "3.18.4", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/schemastery/-/schemastery-3.18.4.tgz", + "integrity": "sha512-SSXO6tYuyrIqKVbmOnIq0s+riUywYzouFMcnBluHF9n4KMo2G8HvEzhCYj6pj2617/glOjbJuVInJ9hfONsjkg==", "license": "MIT", "dependencies": { - "@deepseek-ai/cosmokit": "^1.8.3", + "@deepseek-ai/cosmokit": "~1.8.5", "@standard-schema/spec": "^1.1.0" } }, @@ -5664,74 +6547,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@electron/windows-sign": { - "version": "1.2.2", - "resolved": "https://registry.npmmirror.com/@electron/windows-sign/-/windows-sign-1.2.2.tgz", - "integrity": "sha512-dfZeox66AvdPtb2lD8OsIIQh12Tp0GNCRUDfBHIKGpbmopZto2/A8nSpYYLoedPIHpqkeblZ/k8OV0Gy7PYuyQ==", - "dev": true, - "license": "BSD-2-Clause", - "optional": true, - "peer": true, - "dependencies": { - "cross-dirname": "^0.1.0", - "debug": "^4.3.4", - "fs-extra": "^11.1.1", - "minimist": "^1.2.8", - "postject": "^1.0.0-alpha.6" - }, - "bin": { - "electron-windows-sign": "bin/electron-windows-sign.js" - }, - "engines": { - "node": ">=14.14" - } - }, - "node_modules/@electron/windows-sign/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@electron/windows-sign/node_modules/fs-extra": { - "version": "11.4.0", - "resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-11.4.0.tgz", - "integrity": "sha512-EQsFzMUJkCKGr1ePqlYADkIUmHW1s3ZXr5Yqy6wbGrfUCphpl2maM/kyOIRA2HpP3AaFQTZXD4ldjek+nccddA==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, - "node_modules/@electron/windows-sign/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true - }, "node_modules/@emnapi/runtime": { "version": "1.11.3", "resolved": "https://registry.npmmirror.com/@emnapi/runtime/-/runtime-1.11.3.tgz", @@ -6184,6 +6999,15 @@ "node": ">=18" } }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmmirror.com/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, "node_modules/@exodus/bytes": { "version": "1.15.1", "resolved": "https://registry.npmmirror.com/@exodus/bytes/-/bytes-1.15.1.tgz", @@ -6225,18 +7049,6 @@ } } }, - "node_modules/@hono/node-server": { - "version": "2.1.1", - "resolved": "https://registry.npmmirror.com/@hono/node-server/-/node-server-2.1.1.tgz", - "integrity": "sha512-ELuehkj5VCBdgEw9zs+ivkKwyzzUCSQuE96YmiPvn1ECBoZCczbFXJLeEGMTYjphP6gydh4pHMqEYPVMYUVgQg==", - "license": "MIT", - "engines": { - "node": ">=20" - }, - "peerDependencies": { - "hono": "^4" - } - }, "node_modules/@img/colour": { "version": "1.1.0", "resolved": "https://registry.npmmirror.com/@img/colour/-/colour-1.1.0.tgz", @@ -6854,6 +7666,18 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@js-temporal/polyfill": { + "version": "0.5.1", + "resolved": "https://registry.npmmirror.com/@js-temporal/polyfill/-/polyfill-0.5.1.tgz", + "integrity": "sha512-hloP58zRVCRSpgDxmqCWJNlizAlUgJFqG2ypq79DCvyv9tHjRYMDOcPFjzfl/A1/YxDvRCZz8wvZvmapQnKwFQ==", + "license": "ISC", + "dependencies": { + "jsbi": "^4.3.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@koromix/koffi-darwin-arm64": { "version": "3.1.5", "resolved": "https://registry.npmmirror.com/@koromix/koffi-darwin-arm64/-/koffi-darwin-arm64-3.1.5.tgz", @@ -7180,44 +8004,34 @@ "integrity": "sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==", "license": "BSD-2-Clause" }, - "node_modules/@modelcontextprotocol/sdk": { - "version": "1.30.0", - "resolved": "https://registry.npmmirror.com/@modelcontextprotocol/sdk/-/sdk-1.30.0.tgz", - "integrity": "sha512-xKd8OIzlqNzcqcNumGAa6g+PW2kjD5vrpcKOnfldAUPP3j7lnqMPwlTXQm8gF+UwH72z0lqaRbjr9hqGz0eITA==", + "node_modules/@modelcontextprotocol/client": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/@modelcontextprotocol/client/-/client-2.0.0.tgz", + "integrity": "sha512-8f1OghQ2rjzIOfqgUCP+8GiUWqRs89njoWLNqAe8kWmDePv3s1fZXseej+QXemssEuuOvLLmLO/kqM3IQHtISw==", "license": "MIT", "dependencies": { - "@hono/node-server": "^1.19.9 || ^2.0.5", - "ajv": "^8.17.1", - "ajv-formats": "^3.0.1", - "content-type": "^1.0.5", - "cors": "^2.8.5", + "@modelcontextprotocol/core": "2.0.0", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", - "express": "^5.2.1", - "express-rate-limit": "^8.2.1", - "hono": "^4.11.4", "jose": "^6.1.3", - "json-schema-typed": "^8.0.2", "pkce-challenge": "^5.0.0", - "raw-body": "^3.0.0", - "zod": "^3.25 || ^4.0", - "zod-to-json-schema": "^3.25.1" + "zod": "^4.2.0" }, "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@cfworker/json-schema": "^4.1.1", - "zod": "^3.25 || ^4.0" + "node": ">=20" + } + }, + "node_modules/@modelcontextprotocol/core": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/@modelcontextprotocol/core/-/core-2.0.0.tgz", + "integrity": "sha512-pJCEwGG7Lfr/+PQp9ZTwKXNeO5wzbfKL7H3MYpCorM4oFBoQrdjnBgEoqG+RjhsvS1FKrDbKux+M1HhlnGWqcA==", + "license": "MIT", + "dependencies": { + "zod": "^4.2.0" }, - "peerDependenciesMeta": { - "@cfworker/json-schema": { - "optional": true - }, - "zod": { - "optional": false - } + "engines": { + "node": ">=20" } }, "node_modules/@napi-rs/lzma-linux-x64-gnu": { @@ -7245,7 +8059,6 @@ "resolved": "https://registry.npmmirror.com/@noble/hashes/-/hashes-2.4.0.tgz", "integrity": "sha512-X5XaVWZIBCT7HHZGm5I7ZQXDwLG+bGXuSrMQAW+7Zvl87h1kmc1ZB1VSRJcpUfoUrGQp4Fkoxm5kZ+Ms+aW+eA==", "dev": true, - "devOptional": true, "license": "MIT", "engines": { "node": ">= 20.19.0" @@ -8057,6 +8870,12 @@ "win32" ] }, + "node_modules/@sec-ant/readable-stream": { + "version": "0.4.1", + "resolved": "https://registry.npmmirror.com/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", + "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", + "license": "MIT" + }, "node_modules/@sindresorhus/is": { "version": "4.6.0", "resolved": "https://registry.npmmirror.com/@sindresorhus/is/-/is-4.6.0.tgz", @@ -8070,13 +8889,25 @@ "url": "https://github.com/sindresorhus/is?sponsor=1" } }, + "node_modules/@sindresorhus/merge-streams": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", + "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@smithy/core": { - "version": "3.33.3", - "resolved": "https://registry.npmmirror.com/@smithy/core/-/core-3.33.3.tgz", - "integrity": "sha512-CsOeKq/9kA3y6VJHt+/+VTCtBaxJ4OTFpgrjIUhPpDIKxBci1k2bJaQASF2h/ELWrulGp+t97DZ0mevfAD8idg==", + "version": "3.35.0", + "resolved": "https://registry.npmmirror.com/@smithy/core/-/core-3.35.0.tgz", + "integrity": "sha512-zRMhfkByhT2snNdr1si24vJitU6Cr9ix2MikUfWmkAgp4jrNP0GcKSP5YvwQ+TlI8AZXER5QOGJn3JsVtSD9/A==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.17.2", + "@smithy/types": "^4.19.0", "tslib": "^2.6.2" }, "engines": { @@ -8138,13 +8969,13 @@ } }, "node_modules/@smithy/signature-v4": { - "version": "5.7.3", - "resolved": "https://registry.npmmirror.com/@smithy/signature-v4/-/signature-v4-5.7.3.tgz", - "integrity": "sha512-7ImGm+FkHRLcBaRttIAMZ6bzJZWb2cJGoYjq46F2UjycujWzrL9GEN9h4w7eQyXJYnltrUhxbbieBAIRrdqpow==", + "version": "5.7.4", + "resolved": "https://registry.npmmirror.com/@smithy/signature-v4/-/signature-v4-5.7.4.tgz", + "integrity": "sha512-tHy0K0VtqNd5Y7Y41h0a0Lhh0L1GzC08dTWg0F7vRJWFtTENg7IZikf3wQkanYIRdb7ngoIPMTmqgUi401fEeQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.33.3", - "@smithy/types": "^4.17.2", + "@smithy/core": "^3.35.0", + "@smithy/types": "^4.19.0", "tslib": "^2.6.2" }, "engines": { @@ -8152,9 +8983,9 @@ } }, "node_modules/@smithy/types": { - "version": "4.18.0", - "resolved": "https://registry.npmmirror.com/@smithy/types/-/types-4.18.0.tgz", - "integrity": "sha512-CgB6HHWer/vrKps24ulRIbpcpb7K4xAU7SkZ7YHzBPlwHsvsrCJFEXK421s+cJzX+ZrqtA/TuU5w1HzI7k9N8A==", + "version": "4.19.0", + "resolved": "https://registry.npmmirror.com/@smithy/types/-/types-4.19.0.tgz", + "integrity": "sha512-r7jh49VJxGerfAcTQA6gXcKc+98zOp/tqRwzYjgOE+iSQsP6cEU1hq2QzbuipmP68QtYdY9wKEhiCQZIzHgZ4Q==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -8201,6 +9032,15 @@ "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", "license": "MIT" }, + "node_modules/@swc/helpers": { + "version": "0.5.23", + "resolved": "https://registry.npmmirror.com/@swc/helpers/-/helpers-0.5.23.tgz", + "integrity": "sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, "node_modules/@szmarczak/http-timer": { "version": "4.0.6", "resolved": "https://registry.npmmirror.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", @@ -8279,6 +9119,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/js-yaml": { + "version": "4.0.9", + "resolved": "https://registry.npmmirror.com/@types/js-yaml/-/js-yaml-4.0.9.tgz", + "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/keyv": { "version": "3.1.4", "resolved": "https://registry.npmmirror.com/@types/keyv/-/keyv-3.1.4.tgz", @@ -8640,6 +9487,12 @@ "node": ">=10.0.0" } }, + "node_modules/@xterm/addon-serialize": { + "version": "0.14.0", + "resolved": "https://registry.npmmirror.com/@xterm/addon-serialize/-/addon-serialize-0.14.0.tgz", + "integrity": "sha512-uteyTU1EkrQa2Ux6P/uFl2fzmXI46jy5uoQMKEOM0fKTyiW7cSn0WrFenHm5vO5uEXX/GpwW/FgILvv3r0WbkA==", + "license": "MIT" + }, "node_modules/@xterm/headless": { "version": "6.0.0", "resolved": "https://registry.npmmirror.com/@xterm/headless/-/headless-6.0.0.tgz", @@ -8666,19 +9519,6 @@ "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/accepts": { - "version": "2.0.0", - "resolved": "https://registry.npmmirror.com/accepts/-/accepts-2.0.0.tgz", - "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", - "license": "MIT", - "dependencies": { - "mime-types": "^3.0.0", - "negotiator": "^1.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/agent-base": { "version": "7.1.4", "resolved": "https://registry.npmmirror.com/agent-base/-/agent-base-7.1.4.tgz", @@ -8704,23 +9544,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ajv-formats": { - "version": "3.0.1", - "resolved": "https://registry.npmmirror.com/ajv-formats/-/ajv-formats-3.0.1.tgz", - "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -9068,95 +9891,35 @@ "dev": true, "license": "Apache-2.0", "bin": { - "baseline-browser-mapping": "dist/cli.cjs" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/bidi-js": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/bidi-js/-/bidi-js-1.1.0.tgz", - "integrity": "sha512-fX1Onk0tdVPC7obPWB5EbJ1z7NVhLq4m2xZLq2YXBkxzMXIGRpNMU88n0EPgWseKl12J7zXs7qrDxPK4sRs2fg==", - "license": "MIT", - "dependencies": { - "require-from-string": "^2.0.2" - } - }, - "node_modules/bignumber.js": { - "version": "9.3.1", - "resolved": "https://registry.npmmirror.com/bignumber.js/-/bignumber.js-9.3.1.tgz", - "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmmirror.com/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true, - "license": "MIT" - }, - "node_modules/body-parser": { - "version": "2.3.0", - "resolved": "https://registry.npmmirror.com/body-parser/-/body-parser-2.3.0.tgz", - "integrity": "sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==", - "license": "MIT", - "dependencies": { - "bytes": "^3.1.2", - "content-type": "^2.0.0", - "debug": "^4.4.3", - "http-errors": "^2.0.1", - "iconv-lite": "^0.7.2", - "on-finished": "^2.4.1", - "qs": "^6.15.2", - "raw-body": "^3.0.2", - "type-is": "^2.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/body-parser/node_modules/content-type": { - "version": "2.1.0", - "resolved": "https://registry.npmmirror.com/content-type/-/content-type-2.1.0.tgz", - "integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==", - "license": "MIT", - "engines": { - "node": ">=18" + "baseline-browser-mapping": "dist/cli.cjs" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "engines": { + "node": ">=6.0.0" } }, - "node_modules/body-parser/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "node_modules/bidi-js": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/bidi-js/-/bidi-js-1.1.0.tgz", + "integrity": "sha512-fX1Onk0tdVPC7obPWB5EbJ1z7NVhLq4m2xZLq2YXBkxzMXIGRpNMU88n0EPgWseKl12J7zXs7qrDxPK4sRs2fg==", "license": "MIT", "dependencies": { - "ms": "^2.1.3" - }, + "require-from-string": "^2.0.2" + } + }, + "node_modules/bignumber.js": { + "version": "9.3.1", + "resolved": "https://registry.npmmirror.com/bignumber.js/-/bignumber.js-9.3.1.tgz", + "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", + "license": "MIT", "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": "*" } }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmmirror.com/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true, "license": "MIT" }, "node_modules/boolean": { @@ -9200,6 +9963,15 @@ "node": ">=8" } }, + "node_modules/brotli": { + "version": "1.3.3", + "resolved": "https://registry.npmmirror.com/brotli/-/brotli-1.3.3.tgz", + "integrity": "sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==", + "license": "MIT", + "dependencies": { + "base64-js": "^1.1.2" + } + }, "node_modules/browserslist": { "version": "4.28.9", "resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.28.9.tgz", @@ -9335,9 +10107,9 @@ "license": "MIT" }, "node_modules/bundle-name": { - "version": "4.1.0", - "resolved": "https://registry.npmmirror.com/bundle-name/-/bundle-name-4.1.0.tgz", - "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "version": "4.1.1", + "resolved": "https://registry.npmmirror.com/bundle-name/-/bundle-name-4.1.1.tgz", + "integrity": "sha512-DdH81/zPLVS11EUgWq3tEu/xn+EzljlMYooDNdzWEnFha3R3NBMpMV1UqYIpjYHV/SgpFKMIX1Oh7o06SjM/oA==", "license": "MIT", "dependencies": { "run-applescript": "^7.0.0" @@ -9430,6 +10202,7 @@ "version": "1.0.2", "resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -9443,6 +10216,7 @@ "version": "1.0.4", "resolved": "https://registry.npmmirror.com/call-bound/-/call-bound-1.0.4.tgz", "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -9575,6 +10349,15 @@ "node": ">=12" } }, + "node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmmirror.com/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, "node_modules/clone-response": { "version": "1.0.3", "resolved": "https://registry.npmmirror.com/clone-response/-/clone-response-1.0.3.tgz", @@ -9651,14 +10434,15 @@ } }, "node_modules/compression": { - "version": "1.8.1", - "resolved": "https://registry.npmmirror.com/compression/-/compression-1.8.1.tgz", - "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", + "version": "1.8.2", + "resolved": "https://registry.npmmirror.com/compression/-/compression-1.8.2.tgz", + "integrity": "sha512-o8vI5RE5A6EVVOd9o41jKp41aJom+QTEO/Bx8MYNjexMo/Bv2WOjUfZr+aL0WnYSgymUy6zeguqLTsIhV0gMvQ==", "license": "MIT", "dependencies": { "bytes": "3.1.2", "compressible": "~2.0.18", "debug": "2.6.9", + "destroy": "1.2.0", "negotiator": "~0.6.4", "on-headers": "~1.1.0", "safe-buffer": "5.2.1", @@ -9666,6 +10450,10 @@ }, "engines": { "node": ">= 0.8.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/compression/node_modules/negotiator": { @@ -9684,10 +10472,10 @@ "dev": true, "license": "MIT" }, - "node_modules/content-disposition": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/content-disposition/-/content-disposition-1.1.0.tgz", - "integrity": "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==", + "node_modules/content-type": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/content-type/-/content-type-2.1.0.tgz", + "integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==", "license": "MIT", "engines": { "node": ">=18" @@ -9697,15 +10485,6 @@ "url": "https://opencollective.com/express" } }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmmirror.com/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -9713,56 +10492,12 @@ "dev": true, "license": "MIT" }, - "node_modules/cookie": { - "version": "0.7.2", - "resolved": "https://registry.npmmirror.com/cookie/-/cookie-0.7.2.tgz", - "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.2.2", - "resolved": "https://registry.npmmirror.com/cookie-signature/-/cookie-signature-1.2.2.tgz", - "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", - "license": "MIT", - "engines": { - "node": ">=6.6.0" - } - }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "license": "MIT" }, - "node_modules/cors": { - "version": "2.8.6", - "resolved": "https://registry.npmmirror.com/cors/-/cors-2.8.6.tgz", - "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", - "license": "MIT", - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/cross-dirname": { - "version": "0.1.0", - "resolved": "https://registry.npmmirror.com/cross-dirname/-/cross-dirname-0.1.0.tgz", - "integrity": "sha512-+R08/oI0nl3vfPcqftZRpytksBXDzOUveBq/NBVx0sUp1axwzPQrKinNx5yd5sxPu8j1wIy8AfnVQ+5eFdha6Q==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true - }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -9962,13 +10697,14 @@ "node": ">=0.4.0" } }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmmirror.com/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "license": "MIT", "engines": { - "node": ">= 0.8" + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" } }, "node_modules/detect-libc": { @@ -9988,6 +10724,12 @@ "license": "MIT", "optional": true }, + "node_modules/dfa": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/dfa/-/dfa-1.2.0.tgz", + "integrity": "sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q==", + "license": "MIT" + }, "node_modules/diff": { "version": "9.0.0", "resolved": "https://registry.npmmirror.com/diff/-/diff-9.0.0.tgz", @@ -10112,77 +10854,18 @@ "link": true }, "node_modules/dsh-ppt": { - "version": "0.1.1-rc.2", - "resolved": "file:packages/ppt-bundles/dsh-ppt-0.1.1-rc.2-desktop-20260906.tgz", - "integrity": "sha512-oQKrluB+/0M0j3iDeSdNMR8zbYE45HvaibzlALRAjlxFqpGCYtjavrul6iuQHc3CXe768kzLKvhXKcL9Vch3LA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@aiden0z/pptx-renderer": "1.2.4", - "@deepseek-ai/schemastery": "3.18.2", - "fflate": "^0.8.3", - "js-yaml": "^4.2.0", - "jsdom": "29.1.1", - "pptxgenjs": "^4.0.1", - "sharp": "^0.35.3", - "typescript": "^6.0.3", - "zod": "^4.4.3" - }, - "bin": { - "dsh-pptd": "lib/bin.js" - }, - "engines": { - "node": "^22.19.0 || >=24.0.0" - }, - "peerDependencies": { - "@deepseek-ai/cordis": "4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.1", - "@deepseek-ai/dsh-brand": "^0.1.5-rc.1", - "@deepseek-ai/dsh-client-connection": "^0.1.5-rc.1", - "@deepseek-ai/dsh-client-locale": "^0.1.5-rc.1", - "@deepseek-ai/dsh-client-ui-conversation": "^0.1.5-rc.1", - "@deepseek-ai/dsh-client-ui-primitives": "^0.1.5-rc.1", - "@deepseek-ai/dsh-client-ui-slots": "^0.1.5-rc.1", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.1", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.1", - "@deepseek-ai/dsh-session": "^0.1.5-rc.1", - "@deepseek-ai/dsh-skill": "^0.1.5-rc.1", - "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.1", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.1", - "react": "^18.2.0" - } + "resolved": "packages/ppt-runtime/core", + "link": true }, "node_modules/dsh-ppt-composer": { - "version": "0.1.1-rc.2", - "resolved": "file:packages/ppt-bundles/dsh-ppt-composer-0.1.1-rc.2-desktop-20260906.tgz", - "integrity": "sha512-3yyc063vC46yEBnukIxL5e0DyViEX/Cru8Bt7jniaHjLhDkd9fqeK5mpa+KosHqHSajB4wgFkrX9d2wqPCAYoA==", - "license": "MIT", - "dependencies": { - "@deepseek-ai/schemastery": "3.18.2", - "dsh-ppt": "0.1.1-rc.2" - }, - "peerDependencies": { - "@deepseek-ai/cordis": "4.0.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.1" - } - }, - "node_modules/dsh-ppt/node_modules/typescript": { - "version": "6.0.3", - "resolved": "https://registry.npmmirror.com/typescript/-/typescript-6.0.3.tgz", - "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } + "resolved": "packages/ppt-runtime/adapter", + "link": true }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", @@ -10228,12 +10911,6 @@ "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", "license": "0BSD" }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmmirror.com/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "license": "MIT" - }, "node_modules/ejs": { "version": "3.1.10", "resolved": "https://registry.npmmirror.com/ejs/-/ejs-3.1.10.tgz", @@ -10251,9 +10928,9 @@ } }, "node_modules/electron": { - "version": "43.4.0", - "resolved": "https://registry.npmmirror.com/electron/-/electron-43.4.0.tgz", - "integrity": "sha512-3qxGF0CeQbiox5oWV1JlbWGQ1VerbmDhTFqW4sJ8h7uqTHniFYPObXJcDna0DMh32et0fFyKzz0YY8lJv3t5jg==", + "version": "43.0.0", + "resolved": "https://registry.npmmirror.com/electron/-/electron-43.0.0.tgz", + "integrity": "sha512-PV60GsWU6qufhuOhw3n+Yix3WPDcqDtBqE8orbEQGQGHEkgp9o/JCPgb7L4vIL0r1HnfPdqSRtboOTqbDkcFDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -10295,19 +10972,6 @@ "node": ">=14.0.0" } }, - "node_modules/electron-builder-squirrel-windows": { - "version": "26.15.3", - "resolved": "https://registry.npmmirror.com/electron-builder-squirrel-windows/-/electron-builder-squirrel-windows-26.15.3.tgz", - "integrity": "sha512-Jc19XPV9y9+2bAdZPkXuVNGNIEFBq9poHC61l8Kv6FdK7DRG3+Ic0rerC0DXOaeHNz8yW0fg/JnF8GQROOF5MA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "app-builder-lib": "26.15.3", - "builder-util": "26.15.3", - "electron-winstaller": "5.4.0" - } - }, "node_modules/electron-publish": { "version": "26.15.3", "resolved": "https://registry.npmmirror.com/electron-publish/-/electron-publish-26.15.3.tgz", @@ -10391,108 +11055,12 @@ } } }, - "node_modules/electron-winstaller": { - "version": "5.4.0", - "resolved": "https://registry.npmmirror.com/electron-winstaller/-/electron-winstaller-5.4.0.tgz", - "integrity": "sha512-bO3y10YikuUwUuDUQRM4KfwNkKhnpVO7IPdbsrejwN9/AABJzzTQ4GeHwyzNSrVO+tEH3/Np255a3sVZpZDjvg==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@electron/asar": "^3.2.1", - "debug": "^4.1.1", - "fs-extra": "^7.0.1", - "lodash": "^4.17.21", - "temp": "^0.9.0" - }, - "engines": { - "node": ">=8.0.0" - }, - "optionalDependencies": { - "@electron/windows-sign": "^1.1.2" - } - }, - "node_modules/electron-winstaller/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/electron-winstaller/node_modules/fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/electron-winstaller/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "license": "MIT", - "peer": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/electron-winstaller/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/electron-winstaller/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmmirror.com/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "license": "MIT" }, - "node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmmirror.com/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/end-of-stream": { "version": "1.4.5", "resolved": "https://registry.npmmirror.com/end-of-stream/-/end-of-stream-1.4.5.tgz", @@ -10539,6 +11107,7 @@ "version": "1.0.1", "resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -10548,6 +11117,7 @@ "version": "1.3.0", "resolved": "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -10564,6 +11134,7 @@ "version": "1.1.2", "resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.2.tgz", "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", + "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -10648,12 +11219,6 @@ "node": ">=6" } }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "license": "MIT" - }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -10678,15 +11243,6 @@ "@types/estree": "^1.0.0" } }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmmirror.com/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/eventsource": { "version": "3.0.7", "resolved": "https://registry.npmmirror.com/eventsource/-/eventsource-3.0.7.tgz", @@ -10696,142 +11252,88 @@ "eventsource-parser": "^3.0.1" }, "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/eventsource-parser": { - "version": "3.1.1", - "resolved": "https://registry.npmmirror.com/eventsource-parser/-/eventsource-parser-3.1.1.tgz", - "integrity": "sha512-EKN1vKAMcZ8MlYMpaNuxN6R9yakzH6uajHcHVTqWJzvu5pWw9DyhbP35HH8MVBQ+dZjAfDxk+A8NiR9KWaXiyQ==", - "license": "MIT", - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/expect-type": { - "version": "1.4.0", - "resolved": "https://registry.npmmirror.com/expect-type/-/expect-type-1.4.0.tgz", - "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.0.0" + "node": ">=18.0.0" } }, - "node_modules/exponential-backoff": { - "version": "3.1.3", - "resolved": "https://registry.npmmirror.com/exponential-backoff/-/exponential-backoff-3.1.3.tgz", - "integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/express": { - "version": "5.2.1", - "resolved": "https://registry.npmmirror.com/express/-/express-5.2.1.tgz", - "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", - "license": "MIT", - "dependencies": { - "accepts": "^2.0.0", - "body-parser": "^2.2.1", - "content-disposition": "^1.0.0", - "content-type": "^1.0.5", - "cookie": "^0.7.1", - "cookie-signature": "^1.2.1", - "debug": "^4.4.0", - "depd": "^2.0.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "finalhandler": "^2.1.0", - "fresh": "^2.0.0", - "http-errors": "^2.0.0", - "merge-descriptors": "^2.0.0", - "mime-types": "^3.0.0", - "on-finished": "^2.4.1", - "once": "^1.4.0", - "parseurl": "^1.3.3", - "proxy-addr": "^2.0.7", - "qs": "^6.14.0", - "range-parser": "^1.2.1", - "router": "^2.2.0", - "send": "^1.1.0", - "serve-static": "^2.2.0", - "statuses": "^2.0.1", - "type-is": "^2.0.1", - "vary": "^1.1.2" - }, + "node_modules/eventsource-parser": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/eventsource-parser/-/eventsource-parser-3.1.1.tgz", + "integrity": "sha512-EKN1vKAMcZ8MlYMpaNuxN6R9yakzH6uajHcHVTqWJzvu5pWw9DyhbP35HH8MVBQ+dZjAfDxk+A8NiR9KWaXiyQ==", + "license": "MIT", "engines": { - "node": ">= 18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "node": ">=18.0.0" } }, - "node_modules/express-rate-limit": { - "version": "8.7.0", - "resolved": "https://registry.npmmirror.com/express-rate-limit/-/express-rate-limit-8.7.0.tgz", - "integrity": "sha512-hOwV7WOxXfjRpAM1DSJWZDXx3GhplwD8IfwuwvogD8i1Qnkgosw/H45s4ZnFAUHDAhPjlY9hLBvJhKmGMyY26g==", + "node_modules/execa": { + "version": "10.0.1", + "resolved": "https://registry.npmmirror.com/execa/-/execa-10.0.1.tgz", + "integrity": "sha512-ge98qjkRK4IB7tL7Ju/6qmm5LHoH1eEMt5FNZrz3f4UIYhF28lggX20z3FaX1sgc67msLEn0N0BscOs29iuwyw==", "license": "MIT", "dependencies": { - "debug": "^4.4.3", - "ip-address": "^10.2.0" + "@sindresorhus/merge-streams": "^4.0.0", + "figures": "^6.1.0", + "get-stream": "^9.0.1", + "human-signals": "^8.0.1", + "is-plain-obj": "^4.1.0", + "is-stream": "^4.0.1", + "npm-run-path": "^6.0.0", + "pretty-ms": "^9.3.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^4.0.0", + "which-command": "^0.1.0", + "yoctocolors": "^2.1.2" }, "engines": { - "node": ">= 16" + "node": ">=22" }, "funding": { - "url": "https://github.com/sponsors/express-rate-limit" - }, - "peerDependencies": { - "express": ">= 4.11" + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/express-rate-limit/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "node_modules/execa/node_modules/get-stream": { + "version": "9.0.1", + "resolved": "https://registry.npmmirror.com/get-stream/-/get-stream-9.0.1.tgz", + "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", "license": "MIT", "dependencies": { - "ms": "^2.1.3" + "@sec-ant/readable-stream": "^0.4.1", + "is-stream": "^4.0.1" }, "engines": { - "node": ">=6.0" + "node": ">=18" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/express-rate-limit/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/express/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, + "node_modules/execa/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", "engines": { - "node": ">=6.0" + "node": ">=14" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/express/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" + "node_modules/expect-type": { + "version": "1.4.0", + "resolved": "https://registry.npmmirror.com/expect-type/-/expect-type-1.4.0.tgz", + "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.3", + "resolved": "https://registry.npmmirror.com/exponential-backoff/-/exponential-backoff-3.1.3.tgz", + "integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==", + "dev": true, + "license": "Apache-2.0" }, "node_modules/extend": { "version": "3.0.2", @@ -10914,6 +11416,21 @@ "integrity": "sha512-tbZNuJrLwGUp3zshBtdy4W+ORxZuIh8a5ilyIEQDC5rY1f3U20JMry0Ll3WBzU58EZKsEuJFXhb5gwv8CsPvgA==", "license": "MIT" }, + "node_modules/figures": { + "version": "6.1.0", + "resolved": "https://registry.npmmirror.com/figures/-/figures-6.1.0.tgz", + "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", + "license": "MIT", + "dependencies": { + "is-unicode-supported": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/filelist": { "version": "1.0.6", "resolved": "https://registry.npmmirror.com/filelist/-/filelist-1.0.6.tgz", @@ -10967,50 +11484,6 @@ "node": ">=8" } }, - "node_modules/finalhandler": { - "version": "2.1.1", - "resolved": "https://registry.npmmirror.com/finalhandler/-/finalhandler-2.1.1.tgz", - "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", - "license": "MIT", - "dependencies": { - "debug": "^4.4.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "on-finished": "^2.4.1", - "parseurl": "^1.3.3", - "statuses": "^2.0.1" - }, - "engines": { - "node": ">= 18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, "node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmmirror.com/find-up/-/find-up-4.1.0.tgz", @@ -11034,6 +11507,23 @@ "micromatch": "^4.0.2" } }, + "node_modules/fontkit": { + "version": "2.0.4", + "resolved": "https://registry.npmmirror.com/fontkit/-/fontkit-2.0.4.tgz", + "integrity": "sha512-syetQadaUEDNdxdugga9CpEYVaQIxOwk7GlwZWWZ19//qW4zE5bknOKeMBDYAASwnpaSHKJITRLMF9m1fp3s6g==", + "license": "MIT", + "dependencies": { + "@swc/helpers": "^0.5.12", + "brotli": "^1.3.2", + "clone": "^2.1.2", + "dfa": "^1.2.0", + "fast-deep-equal": "^3.1.3", + "restructure": "^3.0.0", + "tiny-inflate": "^1.0.3", + "unicode-properties": "^1.4.0", + "unicode-trie": "^2.0.0" + } + }, "node_modules/form-data": { "version": "4.0.6", "resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.6.tgz", @@ -11086,24 +11576,6 @@ "node": ">=12.20.0" } }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmmirror.com/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmmirror.com/fresh/-/fresh-2.0.0.tgz", - "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/fs-extra": { "version": "10.1.0", "resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-10.1.0.tgz", @@ -11144,6 +11616,7 @@ "version": "1.1.2", "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -11200,6 +11673,7 @@ "version": "1.3.0", "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -11224,6 +11698,7 @@ "version": "1.0.1", "resolved": "https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", @@ -11369,6 +11844,7 @@ "version": "1.2.0", "resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -11436,6 +11912,7 @@ "version": "1.1.0", "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -11464,6 +11941,7 @@ "version": "2.0.4", "resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.4.tgz", "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "dev": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -11472,15 +11950,6 @@ "node": ">= 0.4" } }, - "node_modules/hono": { - "version": "4.13.7", - "resolved": "https://registry.npmmirror.com/hono/-/hono-4.13.7.tgz", - "integrity": "sha512-c8/gF9ac8Y78/agExVocyLevgR+JlpNB444Py0FSX8pJoPdYUfUzRcXtYEYGwt6l19qIlVZPN5Mfsw9jFShmQQ==", - "license": "MIT", - "engines": { - "node": ">=16.9.0" - } - }, "node_modules/hosted-git-info": { "version": "4.1.0", "resolved": "https://registry.npmmirror.com/hosted-git-info/-/hosted-git-info-4.1.0.tgz", @@ -11533,26 +12002,6 @@ "dev": true, "license": "BSD-2-Clause" }, - "node_modules/http-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmmirror.com/http-errors/-/http-errors-2.0.1.tgz", - "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", - "license": "MIT", - "dependencies": { - "depd": "~2.0.0", - "inherits": "~2.0.4", - "setprototypeof": "~1.2.0", - "statuses": "~2.0.2", - "toidentifier": "~1.0.1" - }, - "engines": { - "node": ">= 0.8" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, "node_modules/http-proxy-agent": { "version": "7.0.2", "resolved": "https://registry.npmmirror.com/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", @@ -11645,20 +12094,13 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, - "node_modules/iconv-lite": { - "version": "0.7.3", - "resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.7.3.tgz", - "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, + "node_modules/human-signals": { + "version": "8.0.1", + "resolved": "https://registry.npmmirror.com/human-signals/-/human-signals-8.0.1.tgz", + "integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==", + "license": "Apache-2.0", "engines": { - "node": ">=0.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "node": ">=18.18.0" } }, "node_modules/image-size": { @@ -11700,15 +12142,6 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, - "node_modules/ip-address": { - "version": "10.7.0", - "resolved": "https://registry.npmmirror.com/ip-address/-/ip-address-10.7.0.tgz", - "integrity": "sha512-BGFsyJd5mpXp3rK6jIdADLNgpJUK1jnjzvYF8lK+VyDab9JAmqN0YOKDdP17HlgKb2+ehPgDc8EtnRLbGCAMhA==", - "license": "MIT", - "engines": { - "node": ">= 12" - } - }, "node_modules/ipaddr.js": { "version": "2.5.0", "resolved": "https://registry.npmmirror.com/ipaddr.js/-/ipaddr.js-2.5.0.tgz", @@ -11782,17 +12215,47 @@ "node": ">=0.12.0" } }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-potential-custom-element-name": { "version": "1.0.1", "resolved": "https://registry.npmmirror.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", "license": "MIT" }, - "node_modules/is-promise": { - "version": "4.0.0", - "resolved": "https://registry.npmmirror.com/is-promise/-/is-promise-4.0.0.tgz", - "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", - "license": "MIT" + "node_modules/is-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmmirror.com/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/is-wsl": { "version": "3.1.1", @@ -11900,6 +12363,12 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsbi": { + "version": "4.3.2", + "resolved": "https://registry.npmmirror.com/jsbi/-/jsbi-4.3.2.tgz", + "integrity": "sha512-9fqMSQbhJykSeii05nxKl4m6Eqn2P6rOlYiS+C5Dr/HPIU/7yZxu5qzbs40tgaFORiw2Amd0mirjxatXYMkIew==", + "license": "Apache-2.0" + }, "node_modules/jsdom": { "version": "29.1.1", "resolved": "https://registry.npmmirror.com/jsdom/-/jsdom-29.1.1.tgz", @@ -12006,12 +12475,6 @@ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "license": "MIT" }, - "node_modules/json-schema-typed": { - "version": "8.0.2", - "resolved": "https://registry.npmmirror.com/json-schema-typed/-/json-schema-typed-8.0.2.tgz", - "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", - "license": "BSD-2-Clause" - }, "node_modules/json-stable-stringify": { "version": "1.3.0", "resolved": "https://registry.npmmirror.com/json-stable-stringify/-/json-stable-stringify-1.3.0.tgz", @@ -12268,6 +12731,7 @@ "version": "1.1.0", "resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -12279,31 +12743,6 @@ "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", "license": "CC0-1.0" }, - "node_modules/media-typer": { - "version": "1.1.1", - "resolved": "https://registry.npmmirror.com/media-typer/-/media-typer-1.1.1.tgz", - "integrity": "sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/merge-descriptors": { - "version": "2.0.0", - "resolved": "https://registry.npmmirror.com/merge-descriptors/-/merge-descriptors-2.0.0.tgz", - "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmmirror.com/micromatch/-/micromatch-4.0.8.tgz", @@ -12428,20 +12867,6 @@ "node": ">= 18" } }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmmirror.com/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz", @@ -12468,26 +12893,13 @@ } }, "node_modules/negotiator": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/negotiator/-/negotiator-1.1.0.tgz", - "integrity": "sha512-NMPBRMJgiQHjbd8phG3Vebdx4kZ1H121rbl5IkMqeOsahptB9BKo/d7oJ3zTXqTgagn2bWlNSXkh0QUGM31RYg==", - "license": "MIT", - "dependencies": { - "content-type": "^2.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/negotiator/node_modules/content-type": { - "version": "2.1.0", - "resolved": "https://registry.npmmirror.com/content-type/-/content-type-2.1.0.tgz", - "integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==", + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/negotiator/-/negotiator-1.1.0.tgz", + "integrity": "sha512-NMPBRMJgiQHjbd8phG3Vebdx4kZ1H121rbl5IkMqeOsahptB9BKo/d7oJ3zTXqTgagn2bWlNSXkh0QUGM31RYg==", "license": "MIT", + "dependencies": { + "content-type": "^2.1.0" + }, "engines": { "node": ">=18" }, @@ -12532,39 +12944,39 @@ "license": "MIT" }, "node_modules/node-addon-native-custom-loader": { - "version": "0.1.5", - "resolved": "https://registry.npmmirror.com/node-addon-native-custom-loader/-/node-addon-native-custom-loader-0.1.5.tgz", - "integrity": "sha512-rL0XXRytayIChYf1xaG9/1NzGBRTyFkQTIpn+MDz/hpr0PZw1a9PZIoH9HlYfagNawhXU+jfN650EvoSIvR7Vw==", + "version": "0.1.6", + "resolved": "https://registry.npmmirror.com/node-addon-native-custom-loader/-/node-addon-native-custom-loader-0.1.6.tgz", + "integrity": "sha512-QaW7d8lTcGCXrpNVyFDtID3vrpa7vFdpcY9pql2/9FGFSe7tcSnhQOKZX+1aOWq+pB1d2ZwNnKAdQI5nD9wAXA==", "license": "MIT", "engines": { "node": ">=20" } }, "node_modules/node-addon-require-builtin": { - "version": "0.1.5", - "resolved": "https://registry.npmmirror.com/node-addon-require-builtin/-/node-addon-require-builtin-0.1.5.tgz", - "integrity": "sha512-isaquiStlp7qdFpaffy+2ssJPUR/kLPRE5gqfeWbb0Ahph9H7O3BOFwThqkVaTrxfpnjrQauxlOEgvzD+snhUg==", + "version": "0.1.6", + "resolved": "https://registry.npmmirror.com/node-addon-require-builtin/-/node-addon-require-builtin-0.1.6.tgz", + "integrity": "sha512-P9ZGMDkloktirLJSggfpxsJ9jog5FItE1Omxpj50UBn3LhD6TS6/yx0jEBXsCGK3P9EtW1EpQVA1QL5gb11GaQ==", "license": "MIT", "dependencies": { - "node-addon-native-custom-loader": "0.1.5" + "node-addon-native-custom-loader": "0.1.6" }, "engines": { "node": ">=20" }, "optionalDependencies": { - "node-addon-require-builtin-darwin-arm64": "0.1.5", - "node-addon-require-builtin-darwin-x64": "0.1.5", - "node-addon-require-builtin-linux-arm64-gnu": "0.1.5", - "node-addon-require-builtin-linux-x64-gnu": "0.1.5", - "node-addon-require-builtin-win32-arm64-msvc": "0.1.5", - "node-addon-require-builtin-win32-ia32-msvc": "0.1.5", - "node-addon-require-builtin-win32-x64-msvc": "0.1.5" + "node-addon-require-builtin-darwin-arm64": "0.1.6", + "node-addon-require-builtin-darwin-x64": "0.1.6", + "node-addon-require-builtin-linux-arm64-gnu": "0.1.6", + "node-addon-require-builtin-linux-x64-gnu": "0.1.6", + "node-addon-require-builtin-win32-arm64-msvc": "0.1.6", + "node-addon-require-builtin-win32-ia32-msvc": "0.1.6", + "node-addon-require-builtin-win32-x64-msvc": "0.1.6" } }, "node_modules/node-addon-require-builtin-darwin-arm64": { - "version": "0.1.5", - "resolved": "https://registry.npmmirror.com/node-addon-require-builtin-darwin-arm64/-/node-addon-require-builtin-darwin-arm64-0.1.5.tgz", - "integrity": "sha512-MZ5RyGhuU7DTbwuNpOQW81/ep8n5Yd5YlZa6dWiEfJEh+01Dl4cCKGmMCWNgb0VtqAImRtAOtmZIPtwngiemKQ==", + "version": "0.1.6", + "resolved": "https://registry.npmmirror.com/node-addon-require-builtin-darwin-arm64/-/node-addon-require-builtin-darwin-arm64-0.1.6.tgz", + "integrity": "sha512-KpaAh0mDcIScoJs7gD/mjXREcENJ023/DgWW3GrlLXFVzCE6bK6wFrTFpNfnkxZZP8yWsEWOg1o5T+uQ7olgTQ==", "cpu": [ "arm64" ], @@ -12574,16 +12986,16 @@ "darwin" ], "dependencies": { - "node-addon-native-custom-loader": "0.1.5" + "node-addon-native-custom-loader": "0.1.6" }, "engines": { "node": ">=20" } }, "node_modules/node-addon-require-builtin-darwin-x64": { - "version": "0.1.5", - "resolved": "https://registry.npmmirror.com/node-addon-require-builtin-darwin-x64/-/node-addon-require-builtin-darwin-x64-0.1.5.tgz", - "integrity": "sha512-wdCSPn49AdNZ2EXHQqswiXk1cROFe9zSRaAX8PwQLxmjdLt+xZF7vZP6VlqgXm+VAOHv98q8kp9m7mO9jY3OgQ==", + "version": "0.1.6", + "resolved": "https://registry.npmmirror.com/node-addon-require-builtin-darwin-x64/-/node-addon-require-builtin-darwin-x64-0.1.6.tgz", + "integrity": "sha512-lh9o5rCvmkH8MZgBBmhyKzJRc1M1hJzgXLTFzB6iomRXNH9P1DKjN2nAJLmvGrdTij47Wcch1JVnlV5AG0cRCQ==", "cpu": [ "x64" ], @@ -12593,16 +13005,16 @@ "darwin" ], "dependencies": { - "node-addon-native-custom-loader": "0.1.5" + "node-addon-native-custom-loader": "0.1.6" }, "engines": { "node": ">=20" } }, "node_modules/node-addon-require-builtin-linux-arm64-gnu": { - "version": "0.1.5", - "resolved": "https://registry.npmmirror.com/node-addon-require-builtin-linux-arm64-gnu/-/node-addon-require-builtin-linux-arm64-gnu-0.1.5.tgz", - "integrity": "sha512-hCqzKpQiknDDv6rUdZqrxCBXROg/uUruO0geUuZsdM9M/Lds45gSb4bDE958HlPaCvrDyR0wTHl3II8A7yQeew==", + "version": "0.1.6", + "resolved": "https://registry.npmmirror.com/node-addon-require-builtin-linux-arm64-gnu/-/node-addon-require-builtin-linux-arm64-gnu-0.1.6.tgz", + "integrity": "sha512-DrQA3aS1LBn4NgrewbZkzSAWdSSRPD/fYO5AkQfvriQ/TQD3E2adB012sZ5eac6p9TAcTjUIYhk395AYVxo4Zw==", "cpu": [ "arm64" ], @@ -12615,16 +13027,16 @@ "linux" ], "dependencies": { - "node-addon-native-custom-loader": "0.1.5" + "node-addon-native-custom-loader": "0.1.6" }, "engines": { "node": ">=20" } }, "node_modules/node-addon-require-builtin-linux-x64-gnu": { - "version": "0.1.5", - "resolved": "https://registry.npmmirror.com/node-addon-require-builtin-linux-x64-gnu/-/node-addon-require-builtin-linux-x64-gnu-0.1.5.tgz", - "integrity": "sha512-lgP+ruwWXbcXDslhp5uIc+dFgzITEGPZ4E50WdHGt/OzcoVhN6y5z72pRRvxy8DE661//QxqmCLe72rS3SVg+w==", + "version": "0.1.6", + "resolved": "https://registry.npmmirror.com/node-addon-require-builtin-linux-x64-gnu/-/node-addon-require-builtin-linux-x64-gnu-0.1.6.tgz", + "integrity": "sha512-8wCxrFlB2Ld5DhxIm2P+nNFnQ0wjzDE5sXF68EUhLH0X+z313B07TUQFMBKCOkyhZIIBh590dBmhHCuA43No2A==", "cpu": [ "x64" ], @@ -12637,16 +13049,16 @@ "linux" ], "dependencies": { - "node-addon-native-custom-loader": "0.1.5" + "node-addon-native-custom-loader": "0.1.6" }, "engines": { "node": ">=20" } }, "node_modules/node-addon-require-builtin-win32-arm64-msvc": { - "version": "0.1.5", - "resolved": "https://registry.npmmirror.com/node-addon-require-builtin-win32-arm64-msvc/-/node-addon-require-builtin-win32-arm64-msvc-0.1.5.tgz", - "integrity": "sha512-KEO2eWS4lvZg6JmPPz04OdI4Ojrc7YzOs++4r6VnvwsqYN2r6mjGSGpouQkk8J2eLXBzC7X/D9wYTbUuQS8u1Q==", + "version": "0.1.6", + "resolved": "https://registry.npmmirror.com/node-addon-require-builtin-win32-arm64-msvc/-/node-addon-require-builtin-win32-arm64-msvc-0.1.6.tgz", + "integrity": "sha512-NET6DiLnKrK2DHuO4NNN+zJz0CFas+RwpJlGY0d3A3A3tc5dJQqZXgw8DzLOn4cSTAQCaDq6+LbPyYX7jE2F3Q==", "cpu": [ "arm64" ], @@ -12656,16 +13068,16 @@ "win32" ], "dependencies": { - "node-addon-native-custom-loader": "0.1.5" + "node-addon-native-custom-loader": "0.1.6" }, "engines": { "node": ">=20" } }, "node_modules/node-addon-require-builtin-win32-ia32-msvc": { - "version": "0.1.5", - "resolved": "https://registry.npmmirror.com/node-addon-require-builtin-win32-ia32-msvc/-/node-addon-require-builtin-win32-ia32-msvc-0.1.5.tgz", - "integrity": "sha512-iSC988EqZm5XbKWp/giW6K6EBRTrHt/YQbAkKsZLglt7PplmvvrZ7C3tUsyh1wVxUTYAaxFdE2xbqSdpw0rb6g==", + "version": "0.1.6", + "resolved": "https://registry.npmmirror.com/node-addon-require-builtin-win32-ia32-msvc/-/node-addon-require-builtin-win32-ia32-msvc-0.1.6.tgz", + "integrity": "sha512-oj4G51r81kJ3E2t5KknKhBNb8TmTWzc/t9x7jkBF9JeRd+1a0kr99mVJVYwJNxq9d3jpt7dgBdI8mxaomuXOEQ==", "cpu": [ "ia32" ], @@ -12675,16 +13087,16 @@ "win32" ], "dependencies": { - "node-addon-native-custom-loader": "0.1.5" + "node-addon-native-custom-loader": "0.1.6" }, "engines": { "node": ">=20 <23" } }, "node_modules/node-addon-require-builtin-win32-x64-msvc": { - "version": "0.1.5", - "resolved": "https://registry.npmmirror.com/node-addon-require-builtin-win32-x64-msvc/-/node-addon-require-builtin-win32-x64-msvc-0.1.5.tgz", - "integrity": "sha512-pjuco/ESU3ChIp7WwacWfY2ENu2K5rGAgqjcXedoiFcTrjTf5Ln/miKSuNfE6IiuJ7tfMTJH6VH5hq+C1Y8JMQ==", + "version": "0.1.6", + "resolved": "https://registry.npmmirror.com/node-addon-require-builtin-win32-x64-msvc/-/node-addon-require-builtin-win32-x64-msvc-0.1.6.tgz", + "integrity": "sha512-ZQ+6thVzQBOFamW7s3t2YqHsw99EEPBNH1uAjvCx4QfnjFJTsu6I/H3prpN8i6cSt6gjnQtArfWc2LXN2ufcJQ==", "cpu": [ "x64" ], @@ -12694,7 +13106,7 @@ "win32" ], "dependencies": { - "node-addon-native-custom-loader": "0.1.5" + "node-addon-native-custom-loader": "0.1.6" }, "engines": { "node": ">=20" @@ -12881,25 +13293,32 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "node_modules/npm-run-path": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/npm-run-path/-/npm-run-path-6.0.0.tgz", + "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", "license": "MIT", + "dependencies": { + "path-key": "^4.0.0", + "unicorn-magic": "^0.3.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/object-keys": { @@ -12926,18 +13345,6 @@ "node": ">=12.20.0" } }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmmirror.com/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/on-headers": { "version": "1.1.0", "resolved": "https://registry.npmmirror.com/on-headers/-/on-headers-1.1.0.tgz", @@ -12951,15 +13358,16 @@ "version": "1.4.0", "resolved": "https://registry.npmmirror.com/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, "license": "ISC", "dependencies": { "wrappy": "1" } }, "node_modules/open": { - "version": "11.0.2", - "resolved": "https://registry.npmmirror.com/open/-/open-11.0.2.tgz", - "integrity": "sha512-RWqF+pBSkqecEvCKOn8QYhaNdRMJDZRIrlS/7rTDdLHaPcfXGCZ/h8zb413NfvdeAV0MR7T1yJcA34/q+CSm1Q==", + "version": "11.0.4", + "resolved": "https://registry.npmmirror.com/open/-/open-11.0.4.tgz", + "integrity": "sha512-++Zlftm0kVLPmzC06t6epuWmcRMDbI4z5P3NNX979WA/k23+NtSOynEGzsVfZwguKw2mi5umVgnBlJQMwRz4Pg==", "license": "MIT", "dependencies": { "default-browser": "^5.5.1", @@ -13075,6 +13483,18 @@ "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", "license": "(MIT AND Zlib)" }, + "node_modules/parse-ms": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/parse-ms/-/parse-ms-4.0.0.tgz", + "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/parse5": { "version": "8.0.1", "resolved": "https://registry.npmmirror.com/parse5/-/parse5-8.0.1.tgz", @@ -13087,15 +13507,6 @@ "url": "https://github.com/inikulin/parse5?sponsor=1" } }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmmirror.com/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/partial-json": { "version": "0.1.7", "resolved": "https://registry.npmmirror.com/partial-json/-/partial-json-0.1.7.tgz", @@ -13222,16 +13633,6 @@ "node": ">=8" } }, - "node_modules/path-to-regexp": { - "version": "8.4.2", - "resolved": "https://registry.npmmirror.com/path-to-regexp/-/path-to-regexp-8.4.2.tgz", - "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, "node_modules/pathe": { "version": "2.0.3", "resolved": "https://registry.npmmirror.com/pathe/-/pathe-2.0.3.tgz", @@ -13381,36 +13782,6 @@ "node": "^10 || ^12 || >=14" } }, - "node_modules/postject": { - "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmmirror.com/postject/-/postject-1.0.0-alpha.6.tgz", - "integrity": "sha512-b9Eb8h2eVqNE8edvKdwqkrY6O7kAwmI8kcnBv1NScolYJbo59XUF0noFq+lxbC1yN20bmC0WBEbDC5H/7ASb0A==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "commander": "^9.4.0" - }, - "bin": { - "postject": "dist/cli.js" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/postject/node_modules/commander": { - "version": "9.5.0", - "resolved": "https://registry.npmmirror.com/commander/-/commander-9.5.0.tgz", - "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": "^12.20.0 || >=14" - } - }, "node_modules/powershell-utils": { "version": "0.2.1", "resolved": "https://registry.npmmirror.com/powershell-utils/-/powershell-utils-0.2.1.tgz", @@ -13450,6 +13821,21 @@ "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "license": "MIT" }, + "node_modules/pretty-ms": { + "version": "9.3.1", + "resolved": "https://registry.npmmirror.com/pretty-ms/-/pretty-ms-9.3.1.tgz", + "integrity": "sha512-HzMy3Geq23nVALD/M2LliU+F+M+gVNsvkQWWqeBZ8HDiCgzo6YPJ/Omrmtq24EFrIsk0a3EkQGEd7bDOo+IhGA==", + "license": "MIT", + "dependencies": { + "parse-ms": "^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/proc-log": { "version": "6.1.0", "resolved": "https://registry.npmmirror.com/proc-log/-/proc-log-6.1.0.tgz", @@ -13545,28 +13931,6 @@ "node": ">=12.0.0" } }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmmirror.com/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "license": "MIT", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/proxy-addr/node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmmirror.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, "node_modules/pump": { "version": "3.0.4", "resolved": "https://registry.npmmirror.com/pump/-/pump-3.0.4.tgz", @@ -13690,22 +14054,6 @@ "node": ">=6" } }, - "node_modules/qs": { - "version": "6.16.0", - "resolved": "https://registry.npmmirror.com/qs/-/qs-6.16.0.tgz", - "integrity": "sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA==", - "license": "BSD-3-Clause", - "dependencies": { - "es-define-property": "^1.0.1", - "side-channel": "^1.1.1" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/queue": { "version": "6.0.2", "resolved": "https://registry.npmmirror.com/queue/-/queue-6.0.2.tgz", @@ -13728,34 +14076,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/range-parser": { - "version": "1.3.0", - "resolved": "https://registry.npmmirror.com/range-parser/-/range-parser-1.3.0.tgz", - "integrity": "sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/raw-body": { - "version": "3.0.2", - "resolved": "https://registry.npmmirror.com/raw-body/-/raw-body-3.0.2.tgz", - "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", - "license": "MIT", - "dependencies": { - "bytes": "~3.1.2", - "http-errors": "~2.0.1", - "iconv-lite": "~0.7.0", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/react": { "version": "18.3.1", "resolved": "https://registry.npmmirror.com/react/-/react-18.3.1.tgz", @@ -13930,6 +14250,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/restructure": { + "version": "3.0.2", + "resolved": "https://registry.npmmirror.com/restructure/-/restructure-3.0.2.tgz", + "integrity": "sha512-gSfoiOEA0VPE6Tukkrr7I0RBdE0s7H1eFCDBk05l1KIQT1UIKNc5JZy6jdyW6eYH3aR3g5b3PuL77rq0hvwtAw==", + "license": "MIT" + }, "node_modules/retry": { "version": "0.13.1", "resolved": "https://registry.npmmirror.com/retry/-/retry-0.13.1.tgz", @@ -13939,21 +14265,6 @@ "node": ">= 4" } }, - "node_modules/rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmmirror.com/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, "node_modules/roarr": { "version": "2.15.4", "resolved": "https://registry.npmmirror.com/roarr/-/roarr-2.15.4.tgz", @@ -14019,45 +14330,6 @@ "fsevents": "~2.3.2" } }, - "node_modules/router": { - "version": "2.2.0", - "resolved": "https://registry.npmmirror.com/router/-/router-2.2.0.tgz", - "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", - "license": "MIT", - "dependencies": { - "debug": "^4.4.0", - "depd": "^2.0.0", - "is-promise": "^4.0.0", - "parseurl": "^1.3.3", - "path-to-regexp": "^8.0.0" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/router/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/router/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, "node_modules/run-applescript": { "version": "7.1.0", "resolved": "https://registry.npmmirror.com/run-applescript/-/run-applescript-7.1.0.tgz", @@ -14090,12 +14362,6 @@ ], "license": "MIT" }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "license": "MIT" - }, "node_modules/sanitize-filename": { "version": "1.6.4", "resolved": "https://registry.npmmirror.com/sanitize-filename/-/sanitize-filename-1.6.4.tgz", @@ -14156,55 +14422,6 @@ "license": "MIT", "optional": true }, - "node_modules/send": { - "version": "1.2.1", - "resolved": "https://registry.npmmirror.com/send/-/send-1.2.1.tgz", - "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", - "license": "MIT", - "dependencies": { - "debug": "^4.4.3", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "fresh": "^2.0.0", - "http-errors": "^2.0.1", - "mime-types": "^3.0.2", - "ms": "^2.1.3", - "on-finished": "^2.4.1", - "range-parser": "^1.2.1", - "statuses": "^2.0.2" - }, - "engines": { - "node": ">= 18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/send/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, "node_modules/serialize-error": { "version": "7.0.1", "resolved": "https://registry.npmmirror.com/serialize-error/-/serialize-error-7.0.1.tgz", @@ -14222,25 +14439,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/serve-static": { - "version": "2.2.1", - "resolved": "https://registry.npmmirror.com/serve-static/-/serve-static-2.2.1.tgz", - "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", - "license": "MIT", - "dependencies": { - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "parseurl": "^1.3.3", - "send": "^1.2.0" - }, - "engines": { - "node": ">= 18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmmirror.com/set-blocking/-/set-blocking-2.0.0.tgz", @@ -14271,12 +14469,6 @@ "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", "license": "MIT" }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "license": "ISC" - }, "node_modules/sharp": { "version": "0.35.4", "resolved": "https://registry.npmmirror.com/sharp/-/sharp-0.35.4.tgz", @@ -14316,109 +14508,129 @@ "@img/sharp-linuxmusl-arm64": "0.35.4", "@img/sharp-linuxmusl-x64": "0.35.4", "@img/sharp-webcontainers-wasm32": "0.35.4", - "@img/sharp-win32-arm64": "0.35.4", - "@img/sharp-win32-ia32": "0.35.4", - "@img/sharp-win32-x64": "0.35.4" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/side-channel": { - "version": "1.1.1", - "resolved": "https://registry.npmmirror.com/side-channel/-/side-channel-1.1.1.tgz", - "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.4", - "side-channel-list": "^1.0.1", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-list": { - "version": "1.0.1", - "resolved": "https://registry.npmmirror.com/side-channel-list/-/side-channel-list-1.0.1.tgz", - "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.4" - }, - "engines": { - "node": ">= 0.4" + "@img/sharp-win32-arm64": "0.35.4", + "@img/sharp-win32-ia32": "0.35.4", + "@img/sharp-win32-x64": "0.35.4" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmmirror.com/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "license": "MIT", "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" + "shebang-regex": "^3.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmmirror.com/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, + "node_modules/sherpa-onnx-darwin-arm64": { + "version": "1.13.8", + "resolved": "https://registry.npmmirror.com/sherpa-onnx-darwin-arm64/-/sherpa-onnx-darwin-arm64-1.13.8.tgz", + "integrity": "sha512-FPNgJMgnWVl/KhRTIhG3KL3A4Om63Rn4YKXc9/uHY7SzLcvqLJLc/h7UBWJwduXvv7K18t5NpxHR6XgXn4sjWw==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/sherpa-onnx-darwin-x64": { + "version": "1.13.8", + "resolved": "https://registry.npmmirror.com/sherpa-onnx-darwin-x64/-/sherpa-onnx-darwin-x64-1.13.8.tgz", + "integrity": "sha512-7BLRpjM6w4f9W46/nmkmq8lEKUayhebvcpslCVQ+6QN2uReYlZEMDZlSpXMjme+hUFrPfRz8P3UNq8ep/4d19g==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/sherpa-onnx-linux-arm64": { + "version": "1.13.8", + "resolved": "https://registry.npmmirror.com/sherpa-onnx-linux-arm64/-/sherpa-onnx-linux-arm64-1.13.8.tgz", + "integrity": "sha512-Tlg7a70b/Wge3OF8IgTHF9jhSVCsLyKQKhwc4BsJ5A+dL/SrFtGBjzuHp4XeLhiiOT7afCxX5PdSn/D4c8Lnuw==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/sherpa-onnx-linux-x64": { + "version": "1.13.8", + "resolved": "https://registry.npmmirror.com/sherpa-onnx-linux-x64/-/sherpa-onnx-linux-x64-1.13.8.tgz", + "integrity": "sha512-6plnhjagsSeTntCgnlag86hWbs/uZE9Crms1LgOb68/1nKsIQjMd+WG519m+aPwT6TrsBOiEMzrx41t8sL5L5g==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/sherpa-onnx-node": { + "version": "1.13.8", + "resolved": "https://registry.npmmirror.com/sherpa-onnx-node/-/sherpa-onnx-node-1.13.8.tgz", + "integrity": "sha512-MsDMBdhLFTZ1GwvcGSSQhnS7g/EA8OMH6IYysCVUOM7j8Icty9KRc0E6YT1A5fWBsZwRfKOeh88QC95aRvS8ag==", + "license": "Apache-2.0", + "optionalDependencies": { + "sherpa-onnx-darwin-arm64": "^1.13.8", + "sherpa-onnx-darwin-x64": "^1.13.8", + "sherpa-onnx-linux-arm64": "^1.13.8", + "sherpa-onnx-linux-x64": "^1.13.8", + "sherpa-onnx-win-ia32": "^1.13.8", + "sherpa-onnx-win-x64": "^1.13.8" + } + }, + "node_modules/sherpa-onnx-win-ia32": { + "version": "1.13.8", + "resolved": "https://registry.npmmirror.com/sherpa-onnx-win-ia32/-/sherpa-onnx-win-ia32-1.13.8.tgz", + "integrity": "sha512-H0Ojln9hfvM+pxWqW0cnjB/XK8/JPq4/k0IWu2JpY5Z458M3zv+XC3Hu+wmot3AoH/K1Bgt23n/tTKtPV9x8qg==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/sherpa-onnx-win-x64": { + "version": "1.13.8", + "resolved": "https://registry.npmmirror.com/sherpa-onnx-win-x64/-/sherpa-onnx-win-x64-1.13.8.tgz", + "integrity": "sha512-oZF1c9VPOKtMwn83Bboc5XSWL+76BRoyB3eUuVnCknBKxwSULZU2Foia9VHWzU+n4I12rPsP6z6H9Rp1hD9o8g==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/siginfo": { "version": "2.0.0", "resolved": "https://registry.npmmirror.com/siginfo/-/siginfo-2.0.0.tgz", @@ -14521,15 +14733,6 @@ "node": ">= 6" } }, - "node_modules/statuses": { - "version": "2.0.2", - "resolved": "https://registry.npmmirror.com/statuses/-/statuses-2.0.2.tgz", - "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/std-env": { "version": "4.2.0", "resolved": "https://registry.npmmirror.com/std-env/-/std-env-4.2.0.tgz", @@ -14578,6 +14781,18 @@ "node": ">=8" } }, + "node_modules/strip-final-newline": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/strip-final-newline/-/strip-final-newline-4.0.0.tgz", + "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/sumchecker": { "version": "3.0.1", "resolved": "https://registry.npmmirror.com/sumchecker/-/sumchecker-3.0.1.tgz", @@ -14662,21 +14877,6 @@ "node": ">=18" } }, - "node_modules/temp": { - "version": "0.9.4", - "resolved": "https://registry.npmmirror.com/temp/-/temp-0.9.4.tgz", - "integrity": "sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "mkdirp": "^0.5.1", - "rimraf": "~2.6.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/temp-file": { "version": "3.4.0", "resolved": "https://registry.npmmirror.com/temp-file/-/temp-file-3.4.0.tgz", @@ -14708,6 +14908,12 @@ "semver": "bin/semver" } }, + "node_modules/tiny-inflate": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/tiny-inflate/-/tiny-inflate-1.0.3.tgz", + "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==", + "license": "MIT" + }, "node_modules/tiny-typed-emitter": { "version": "2.1.0", "resolved": "https://registry.npmmirror.com/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz", @@ -14809,15 +15015,6 @@ "node": ">=8.0" } }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmmirror.com/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "license": "MIT", - "engines": { - "node": ">=0.6" - } - }, "node_modules/tough-cookie": { "version": "6.0.2", "resolved": "https://registry.npmmirror.com/tough-cookie/-/tough-cookie-6.0.2.tgz", @@ -14891,37 +15088,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/type-is": { - "version": "2.1.0", - "resolved": "https://registry.npmmirror.com/type-is/-/type-is-2.1.0.tgz", - "integrity": "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==", - "license": "MIT", - "dependencies": { - "content-type": "^2.0.0", - "media-typer": "^1.1.0", - "mime-types": "^3.0.0" - }, - "engines": { - "node": ">= 18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/type-is/node_modules/content-type": { - "version": "2.1.0", - "resolved": "https://registry.npmmirror.com/content-type/-/content-type-2.1.0.tgz", - "integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, "node_modules/typebox": { "version": "1.3.7", "resolved": "https://registry.npmmirror.com/typebox/-/typebox-1.3.7.tgz", @@ -14943,9 +15109,9 @@ } }, "node_modules/undici": { - "version": "8.10.2", - "resolved": "https://registry.npmmirror.com/undici/-/undici-8.10.2.tgz", - "integrity": "sha512-/y4/bH9YNU5hi9NIrpOuvGXFcxrj3CMrV+/AYpowAYTpHn8gX/XPFjNy766FPoYY0miQhdW977JFWKGNhBdwyQ==", + "version": "8.11.2", + "resolved": "https://registry.npmmirror.com/undici/-/undici-8.11.2.tgz", + "integrity": "sha512-u4UB2/IrKdU6lFxumHmmo1a3fCQO5tzQllRorfoRS63txhrB7xTpSn1PftwC4qEHkOaqP95fCWW4lJzwErwzhQ==", "license": "MIT", "engines": { "node": ">=22.19.0" @@ -14957,6 +15123,44 @@ "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", "license": "MIT" }, + "node_modules/unicode-properties": { + "version": "1.4.1", + "resolved": "https://registry.npmmirror.com/unicode-properties/-/unicode-properties-1.4.1.tgz", + "integrity": "sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg==", + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.0", + "unicode-trie": "^2.0.0" + } + }, + "node_modules/unicode-trie": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/unicode-trie/-/unicode-trie-2.0.0.tgz", + "integrity": "sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==", + "license": "MIT", + "dependencies": { + "pako": "^0.2.5", + "tiny-inflate": "^1.0.0" + } + }, + "node_modules/unicode-trie/node_modules/pako": { + "version": "0.2.9", + "resolved": "https://registry.npmmirror.com/pako/-/pako-0.2.9.tgz", + "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==", + "license": "MIT" + }, + "node_modules/unicorn-magic": { + "version": "0.3.0", + "resolved": "https://registry.npmmirror.com/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/universalify": { "version": "2.0.1", "resolved": "https://registry.npmmirror.com/universalify/-/universalify-2.0.1.tgz", @@ -14966,15 +15170,6 @@ "node": ">= 10.0.0" } }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmmirror.com/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/unzipper": { "version": "0.12.5", "resolved": "https://registry.npmmirror.com/unzipper/-/unzipper-0.12.5.tgz", @@ -15788,6 +15983,21 @@ "node": ">= 8" } }, + "node_modules/which-command": { + "version": "0.1.0", + "resolved": "https://registry.npmmirror.com/which-command/-/which-command-0.1.0.tgz", + "integrity": "sha512-XZyoF5/5hZtXitIwzrU4NKK+Wtbb9aB9CezUEw2Q0wlYK8NUYQxC1rRXgNueYLtBAJwXIb+/tFVk4dozciNJMA==", + "license": "MIT", + "bin": { + "which-command": "cli.js" + }, + "engines": { + "node": ">=22" + }, + "funding": { + "url": "https://github.com/sindresorhus/which-command?sponsor=1" + } + }, "node_modules/which-module": { "version": "2.0.1", "resolved": "https://registry.npmmirror.com/which-module/-/which-module-2.0.1.tgz", @@ -15833,6 +16043,7 @@ "version": "1.0.2", "resolved": "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, "license": "ISC" }, "node_modules/ws": { @@ -15983,6 +16194,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/yoctocolors": { + "version": "2.2.0", + "resolved": "https://registry.npmmirror.com/yoctocolors/-/yoctocolors-2.2.0.tgz", + "integrity": "sha512-xYqdZFUK/VYazNl/oCDYN+3WloWQwMfZxBoiNt6qNyk+xfOdi598muWE42rNZFp1kNOiqW936q5RhUdnpqElSg==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/zod": { "version": "4.6.1", "resolved": "https://registry.npmmirror.com/zod/-/zod-4.6.1.tgz", @@ -15992,15 +16215,6 @@ "url": "https://github.com/sponsors/colinhacks" } }, - "node_modules/zod-to-json-schema": { - "version": "3.25.2", - "resolved": "https://registry.npmmirror.com/zod-to-json-schema/-/zod-to-json-schema-3.25.2.tgz", - "integrity": "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==", - "license": "ISC", - "peerDependencies": { - "zod": "^3.25.28 || ^4" - } - }, "node_modules/zrender": { "version": "6.1.0", "resolved": "https://registry.npmmirror.com/zrender/-/zrender-6.1.0.tgz", @@ -16021,9 +16235,12 @@ "license": "MIT", "peerDependencies": { "@deepseek-ai/cordis": "^4.0.1", - "@deepseek-ai/dsh-client-ui-conversation": "^0.1.5-rc.1", - "@deepseek-ai/dsh-client-ui-renderer": "^0.1.5-rc.1", - "@deepseek-ai/dsh-client-ui-sidebar": "^0.1.5-rc.1" + "@deepseek-ai/dsh-api-session-controller": "^0.1.7-rc.1", + "@deepseek-ai/dsh-client-ui-conversation": "^0.1.5-rc.1 || ^0.1.6-alpha.1 || ^0.1.7-rc.1", + "@deepseek-ai/dsh-client-ui-renderer": "^0.1.5-rc.1 || ^0.1.6-alpha.1 || ^0.1.7-rc.1", + "@deepseek-ai/dsh-client-ui-sidebar": "^0.1.5-rc.1 || ^0.1.6-alpha.1 || ^0.1.7-rc.1", + "@deepseek-ai/dsh-client-ui-sidebar-documentpreview": "^0.1.7-rc.1", + "@deepseek-ai/dsh-client-ui-workspace": "^0.1.7-rc.1" } }, "packages/dsh-desktop-hmr-fallback": { @@ -16044,13 +16261,11 @@ "version": "0.1.0", "license": "MIT", "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2", "pnpm": "10.34.5" }, "peerDependencies": { "@deepseek-ai/cordis": "^4.0.1", - "@deepseek-ai/dsh-settings": "^0.1.5-rc.1", - "@deepseek-ai/dsh-host-webserver": "^0.1.5-rc.1" + "@deepseek-ai/dsh-host-webserver": "^0.1.5-rc.1 || ^0.1.6-alpha.1 || ^0.1.7-rc.1" } }, "packages/dsh-desktop-preset-transfer": { @@ -16061,7 +16276,7 @@ }, "peerDependencies": { "@deepseek-ai/cordis": "^4.0.1", - "@deepseek-ai/dsh-agent-presets": "^0.1.5-rc.1", + "@deepseek-ai/dsh-agent-preset-registry": "^0.1.7-rc.1", "fflate": "^0.8.2" } }, @@ -16074,16 +16289,101 @@ }, "peerDependencies": { "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-api-session-controller": "^0.1.2-rc.1", - "@deepseek-ai/dsh-client-connection": "^0.1.2-rc.1", - "@deepseek-ai/dsh-credentials": "^0.1.2-rc.1", - "@deepseek-ai/dsh-sandbox": "^0.1.2-rc.1", - "@deepseek-ai/dsh-sandbox-policy": "^0.1.2-rc.1", - "@deepseek-ai/dsh-settings": "^0.1.2-rc.1", - "@deepseek-ai/dsh-skill": "^0.1.2-rc.1", - "@deepseek-ai/dsh-subprocess": "^0.1.2-rc.1", - "@deepseek-ai/dsh-system-prompt": "^0.1.2-rc.1", - "@deepseek-ai/dsh-tools": "^0.1.2-rc.1" + "@deepseek-ai/dsh-api-session-controller": "^0.1.2-rc.1 || ^0.1.7-rc.1", + "@deepseek-ai/dsh-client-connection": "^0.1.2-rc.1 || ^0.1.7-rc.1", + "@deepseek-ai/dsh-credentials": "^0.1.2-rc.1 || ^0.1.7-rc.1", + "@deepseek-ai/dsh-sandbox": "^0.1.2-rc.1 || ^0.1.7-rc.1", + "@deepseek-ai/dsh-sandbox-policy": "^0.1.2-rc.1 || ^0.1.7-rc.1", + "@deepseek-ai/dsh-settings": "^0.1.2-rc.1 || ^0.1.7-rc.1", + "@deepseek-ai/dsh-skill": "^0.1.2-rc.1 || ^0.1.7-rc.1", + "@deepseek-ai/dsh-subprocess": "^0.1.2-rc.1 || ^0.1.7-rc.1", + "@deepseek-ai/dsh-system-prompt": "^0.1.2-rc.1 || ^0.1.7-rc.1", + "@deepseek-ai/dsh-tools": "^0.1.2-rc.1 || ^0.1.7-rc.1" + } + }, + "packages/ppt-runtime/adapter": { + "name": "dsh-ppt-composer", + "version": "0.1.1-rc.2", + "license": "MIT", + "dependencies": { + "@deepseek-ai/schemastery": "3.18.2", + "dsh-ppt": "0.1.1-rc.2" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-invariants": "^0.1.5-rc.1 || ^0.1.6-alpha.2 || ^0.1.7-rc.1" + } + }, + "packages/ppt-runtime/adapter/node_modules/@deepseek-ai/schemastery": { + "version": "3.18.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/schemastery/-/schemastery-3.18.2.tgz", + "integrity": "sha512-njDtZsznjYxok7KLLlHOPyuv2efdWVbSflAHgztSfbMsg+CVraEoRe2DjOCgClYv3ZCSm7WXoaUkbB/+RY7tWQ==", + "license": "MIT", + "dependencies": { + "@deepseek-ai/cosmokit": "^1.8.3", + "@standard-schema/spec": "^1.1.0" + } + }, + "packages/ppt-runtime/core": { + "name": "dsh-ppt", + "version": "0.1.1-rc.2", + "license": "MIT", + "dependencies": { + "@aiden0z/pptx-renderer": "1.2.4", + "@deepseek-ai/schemastery": "3.18.2", + "fflate": "^0.8.3", + "js-yaml": "^4.2.0", + "jsdom": "29.1.1", + "pptxgenjs": "^4.0.1", + "sharp": "^0.35.3", + "typescript": "^6.0.3", + "zod": "^4.4.3" + }, + "bin": { + "dsh-pptd": "lib/bin.js" + }, + "engines": { + "node": "^22.19.0 || >=24.0.0" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "^0.1.5-rc.1 || ^0.1.6-alpha.2 || ^0.1.7-rc.1", + "@deepseek-ai/dsh-brand": "^0.1.5-rc.1 || ^0.1.6-alpha.2 || ^0.1.7-rc.1", + "@deepseek-ai/dsh-client-connection": "^0.1.5-rc.1 || ^0.1.6-alpha.2 || ^0.1.7-rc.1", + "@deepseek-ai/dsh-client-locale": "^0.1.5-rc.1 || ^0.1.6-alpha.2 || ^0.1.7-rc.1", + "@deepseek-ai/dsh-client-ui-conversation": "^0.1.5-rc.1 || ^0.1.6-alpha.2 || ^0.1.7-rc.1", + "@deepseek-ai/dsh-client-ui-primitives": "^0.1.5-rc.1 || ^0.1.6-alpha.2 || ^0.1.7-rc.1", + "@deepseek-ai/dsh-client-ui-slots": "^0.1.5-rc.1 || ^0.1.6-alpha.2 || ^0.1.7-rc.1", + "@deepseek-ai/dsh-invariants": "^0.1.5-rc.1 || ^0.1.6-alpha.2 || ^0.1.7-rc.1", + "@deepseek-ai/dsh-llm": "^0.1.5-rc.1 || ^0.1.6-alpha.2 || ^0.1.7-rc.1", + "@deepseek-ai/dsh-session": "^0.1.5-rc.1 || ^0.1.6-alpha.2 || ^0.1.7-rc.1", + "@deepseek-ai/dsh-skill": "^0.1.5-rc.1 || ^0.1.6-alpha.2 || ^0.1.7-rc.1", + "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.1 || ^0.1.6-alpha.2 || ^0.1.7-rc.1", + "@deepseek-ai/dsh-tools": "^0.1.5-rc.1 || ^0.1.6-alpha.2 || ^0.1.7-rc.1", + "react": "^18.2.0" + } + }, + "packages/ppt-runtime/core/node_modules/@deepseek-ai/schemastery": { + "version": "3.18.2", + "resolved": "https://registry.npmmirror.com/@deepseek-ai/schemastery/-/schemastery-3.18.2.tgz", + "integrity": "sha512-njDtZsznjYxok7KLLlHOPyuv2efdWVbSflAHgztSfbMsg+CVraEoRe2DjOCgClYv3ZCSm7WXoaUkbB/+RY7tWQ==", + "license": "MIT", + "dependencies": { + "@deepseek-ai/cosmokit": "^1.8.3", + "@standard-schema/spec": "^1.1.0" + } + }, + "packages/ppt-runtime/core/node_modules/typescript": { + "version": "6.0.3", + "resolved": "https://registry.npmmirror.com/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" } } } diff --git a/package.json b/package.json index b1739fb63..469ca5882 100644 --- a/package.json +++ b/package.json @@ -24,8 +24,8 @@ ], "scripts": { "postinstall": "patch-package && node scripts/install-brand-assets.mjs && install-electron --no", - "dev": "electron-vite dev", - "build": "electron-vite build", + "dev": "npm run ppt:build && electron-vite dev", + "build": "npm run ppt:build && electron-vite build", "icons:generate": "node scripts/generate-app-icons.mjs", "loader:generate": "node scripts/generate-loader-gifs.mjs", "preview": "electron-vite preview", @@ -36,260 +36,265 @@ "package:dev:dir": "npm run build && electron-builder --dir --config electron-builder.dev.cjs", "package:dev:mac:arm64": "node scripts/verify-target.mjs darwin arm64 && npm run build && electron-builder --mac --arm64 --publish never --config electron-builder.dev.cjs", "package:dev:mac:x64": "node scripts/verify-target.mjs darwin x64 && npm run build && electron-builder --mac --x64 --publish never --config electron-builder.dev.cjs", - "package:dev:win": "node scripts/verify-target.mjs win32 x64 && npm run build && electron-builder --win --x64 --publish never --config electron-builder.dev.cjs", + "package:dev:win": "node scripts/verify-target.mjs win32 x64 && npm run build && node scripts/electron-builder-windows.mjs --win --x64 --publish never --config electron-builder.dev.cjs", "package:mac": "npm run build && electron-builder --mac --publish never", "package:mac:arm64": "node scripts/verify-target.mjs darwin arm64 && npm run build && electron-builder --mac --arm64 --publish never", "package:mac:x64": "node scripts/verify-target.mjs darwin x64 && npm run build && electron-builder --mac --x64 --publish never", - "package:win": "node scripts/verify-target.mjs win32 x64 && npm run build && electron-builder --win --x64 --publish never", - "ppt:build": "node scripts/generate-zara-ppt-templates.mjs && node scripts/localize-ppt-templates.mjs && node scripts/enrich-ppt-templates.mjs && node scripts/build-ppt-runtime.mjs" + "package:win": "node scripts/verify-target.mjs win32 x64 && npm run build && node scripts/electron-builder-windows.mjs --win --x64 --publish never", + "ppt:build": "node scripts/prepare-ppt-runtime.mjs", + "pretest": "npm run ppt:build", + "pretest:watch": "npm run ppt:build" }, "dependencies": { - "@deepseek-ai/cordis": "4.0.2", - "@deepseek-ai/cordis-plugin-group": "1.0.2", - "@deepseek-ai/cordis-plugin-hmr": "1.0.17", - "@deepseek-ai/cordis-plugin-include": "1.0.7", - "@deepseek-ai/cordis-plugin-loader": "1.0.3", - "@deepseek-ai/cordis-plugin-timer": "1.1.4", - "@deepseek-ai/cosmokit": "1.8.3", - "@deepseek-ai/dsh": "0.1.5-rc.2", - "@deepseek-ai/dsh-acp": "0.1.5-rc.2", - "@deepseek-ai/dsh-acp-app": "0.1.5-rc.2", - "@deepseek-ai/dsh-agent": "0.1.5-rc.2", - "@deepseek-ai/dsh-agent-default-model": "0.1.5-rc.2", - "@deepseek-ai/dsh-agent-instructions": "0.1.5-rc.2", - "@deepseek-ai/dsh-agent-loop": "0.1.5-rc.2", - "@deepseek-ai/dsh-agent-presets": "0.1.5-rc.2", - "@deepseek-ai/dsh-agent-tool-presentation": "0.1.5-rc.2", - "@deepseek-ai/dsh-anonymous-user-id": "0.1.5-rc.2", - "@deepseek-ai/dsh-api-gateway": "0.1.5-rc.2", - "@deepseek-ai/dsh-api-remotes": "0.1.5-rc.2", - "@deepseek-ai/dsh-api-session-controller": "0.1.5-rc.2", - "@deepseek-ai/dsh-api-settings-controller": "0.1.5-rc.2", - "@deepseek-ai/dsh-api-workspace-controller": "0.1.5-rc.2", - "@deepseek-ai/dsh-app-boot": "0.1.5-rc.2", - "@deepseek-ai/dsh-atomic-write": "0.1.5-rc.2", - "@deepseek-ai/dsh-attachment": "0.1.5-rc.2", - "@deepseek-ai/dsh-attachment-local": "0.1.5-rc.2", - "@deepseek-ai/dsh-authorization": "0.1.5-rc.2", - "@deepseek-ai/dsh-base": "0.1.5-rc.2", - "@deepseek-ai/dsh-bash-local": "0.1.5-rc.2", - "@deepseek-ai/dsh-bash-sandbox": "0.1.5-rc.2", - "@deepseek-ai/dsh-brand": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-connection": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-hmr": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-locale": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-modules": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-store": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-agent-preset": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-approval": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-attachment": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-brand-official": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-chat": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-commands": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-conversation": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-cordis": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-deliverables": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-directory-picker-browse": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-directory-picker-native": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-goal": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-input-trigger": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-jobs": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-layout": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-message-feedback": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-model-selection": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-permission-presets": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-plan": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-primitives": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-reference": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-renderer": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-schedule": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-session": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-settings": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-settings-general": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-settings-models": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-settings-plugin-inventory": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-settings-plugins": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-sidebar": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-skill": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-slots": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-subagent": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-theme": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-tool": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-trajectory": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-user-questions": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-workflow-run": "0.1.5-rc.2", - "@deepseek-ai/dsh-client-ui-workspace": "0.1.5-rc.2", - "@deepseek-ai/dsh-cmdline": "0.1.5-rc.2", - "@deepseek-ai/dsh-code-runtime": "0.1.5-rc.2", - "@deepseek-ai/dsh-code-runtime-worker-thread": "0.1.5-rc.2", - "@deepseek-ai/dsh-command-compact": "0.1.5-rc.2", - "@deepseek-ai/dsh-command-feedback": "0.1.5-rc.2", - "@deepseek-ai/dsh-command-goal": "0.1.5-rc.2", - "@deepseek-ai/dsh-commands": "0.1.5-rc.2", - "@deepseek-ai/dsh-compaction": "0.1.5-rc.2", - "@deepseek-ai/dsh-compaction-basic": "0.1.5-rc.2", - "@deepseek-ai/dsh-compaction-tool-result-pruner": "0.1.5-rc.2", - "@deepseek-ai/dsh-cordis-client-runner": "0.1.5-rc.2", - "@deepseek-ai/dsh-cordis-host-runner": "0.1.5-rc.2", - "@deepseek-ai/dsh-credentials": "0.1.5-rc.2", - "@deepseek-ai/dsh-credentials-local": "0.1.5-rc.2", - "@deepseek-ai/dsh-deepseek-llm-api-extensions": "0.1.5-rc.2", - "@deepseek-ai/dsh-deque": "0.1.5-rc.2", - "@deepseek-ai/dsh-file-reference": "0.1.5-rc.2", - "@deepseek-ai/dsh-file-reference-local": "0.1.5-rc.2", - "@deepseek-ai/dsh-fs": "0.1.5-rc.2", - "@deepseek-ai/dsh-fs-local": "0.1.5-rc.2", - "@deepseek-ai/dsh-fs-observation-policy": "0.1.5-rc.2", - "@deepseek-ai/dsh-fs-sandbox": "0.1.5-rc.2", - "@deepseek-ai/dsh-goal": "0.1.5-rc.2", - "@deepseek-ai/dsh-goal-round-driver": "0.1.5-rc.2", - "@deepseek-ai/dsh-headless": "0.1.5-rc.2", - "@deepseek-ai/dsh-home-paths": "0.1.5-rc.2", - "@deepseek-ai/dsh-hook-protocol": "0.1.5-rc.2", - "@deepseek-ai/dsh-hooks-claude-code": "0.1.5-rc.2", - "@deepseek-ai/dsh-hooks-codex": "0.1.5-rc.2", - "@deepseek-ai/dsh-host-directory-picker": "0.1.5-rc.2", - "@deepseek-ai/dsh-host-directory-picker-auto": "0.1.5-rc.2", - "@deepseek-ai/dsh-host-directory-picker-browse": "0.1.5-rc.2", - "@deepseek-ai/dsh-host-directory-picker-native": "0.1.5-rc.2", - "@deepseek-ai/dsh-host-frontend-static": "0.1.5-rc.2", - "@deepseek-ai/dsh-host-plugin-inventory": "0.1.5-rc.2", - "@deepseek-ai/dsh-host-webserver": "0.1.5-rc.2", - "@deepseek-ai/dsh-invariants": "0.1.5-rc.2", - "@deepseek-ai/dsh-jobs": "0.1.5-rc.2", - "@deepseek-ai/dsh-jobs-local": "0.1.5-rc.2", - "@deepseek-ai/dsh-launch-environment": "0.1.5-rc.2", - "@deepseek-ai/dsh-llm": "0.1.5-rc.2", - "@deepseek-ai/dsh-llm-deepseek": "0.1.5-rc.2", - "@deepseek-ai/dsh-llm-pi-ai": "0.1.5-rc.2", - "@deepseek-ai/dsh-llm-retry": "0.1.5-rc.2", - "@deepseek-ai/dsh-mcp-client": "0.1.5-rc.2", - "@deepseek-ai/dsh-message-feedback": "0.1.5-rc.2", - "@deepseek-ai/dsh-native-command": "0.1.5-rc.2", - "@deepseek-ai/dsh-output-retention": "0.1.5-rc.2", - "@deepseek-ai/dsh-permission-presets": "0.1.5-rc.2", - "@deepseek-ai/dsh-persona": "0.1.5-rc.2", - "@deepseek-ai/dsh-plan-mode": "0.1.5-rc.2", - "@deepseek-ai/dsh-plugin-package-inventory-deepseek": "0.1.5-rc.2", - "@deepseek-ai/dsh-pwsh-local": "0.1.5-rc.2", - "@deepseek-ai/dsh-pwsh-sandbox": "0.1.5-rc.2", - "@deepseek-ai/dsh-repeat-tool-reminder": "0.1.5-rc.2", - "@deepseek-ai/dsh-sandbox": "0.1.5-rc.2", - "@deepseek-ai/dsh-sandbox-local": "0.1.5-rc.2", - "@deepseek-ai/dsh-sandbox-policy": "0.1.5-rc.2", - "@deepseek-ai/dsh-sandbox-windows-acl": "0.1.5-rc.2", - "@deepseek-ai/dsh-schedule": "0.1.5-rc.2", - "@deepseek-ai/dsh-scope": "0.1.5-rc.2", - "@deepseek-ai/dsh-sdk-app": "0.1.5-rc.2", - "@deepseek-ai/dsh-sdk-jsonrpc-server": "0.1.5-rc.2", - "@deepseek-ai/dsh-sdk-minimal": "0.1.5-rc.2", - "@deepseek-ai/dsh-sdk-protocol": "0.1.5-rc.2", - "@deepseek-ai/dsh-session": "0.1.5-rc.2", - "@deepseek-ai/dsh-session-checkpoint-policy": "0.1.5-rc.2", - "@deepseek-ai/dsh-session-log-deepseek": "0.1.5-rc.2", - "@deepseek-ai/dsh-session-log-export": "0.1.5-rc.2", - "@deepseek-ai/dsh-session-persistence": "0.1.5-rc.2", - "@deepseek-ai/dsh-session-persistence-jsonl": "0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection": "0.1.5-rc.2", - "@deepseek-ai/dsh-session-projection-cache": "0.1.5-rc.2", - "@deepseek-ai/dsh-session-query": "0.1.5-rc.2", - "@deepseek-ai/dsh-session-query-sqlite": "0.1.5-rc.2", - "@deepseek-ai/dsh-session-reference": "0.1.5-rc.2", - "@deepseek-ai/dsh-session-stats": "0.1.5-rc.2", - "@deepseek-ai/dsh-session-telemetry": "0.1.5-rc.2", - "@deepseek-ai/dsh-session-telemetry-otel": "0.1.5-rc.2", - "@deepseek-ai/dsh-session-title": "0.1.5-rc.2", - "@deepseek-ai/dsh-session-title-first-prompt-llm": "0.1.5-rc.2", - "@deepseek-ai/dsh-session-title-llm": "0.1.5-rc.2", - "@deepseek-ai/dsh-session-turn-outline": "0.1.5-rc.2", - "@deepseek-ai/dsh-settings": "0.1.5-rc.2", - "@deepseek-ai/dsh-settings-file": "0.1.5-rc.2", - "@deepseek-ai/dsh-shell": "0.1.5-rc.2", - "@deepseek-ai/dsh-shell-env": "0.1.5-rc.2", - "@deepseek-ai/dsh-skill": "0.1.5-rc.2", - "@deepseek-ai/dsh-skill-badge": "0.1.5-rc.2", - "@deepseek-ai/dsh-skill-filesystem": "0.1.5-rc.2", - "@deepseek-ai/dsh-spill": "0.1.5-rc.2", - "@deepseek-ai/dsh-spill-local": "0.1.5-rc.2", - "@deepseek-ai/dsh-spill-policy": "0.1.5-rc.2", - "@deepseek-ai/dsh-storage": "0.1.5-rc.2", - "@deepseek-ai/dsh-storage-domain": "0.1.5-rc.2", - "@deepseek-ai/dsh-storage-json": "0.1.5-rc.2", - "@deepseek-ai/dsh-subagent": "0.1.5-rc.2", - "@deepseek-ai/dsh-subagent-fork-in-process": "0.1.5-rc.2", - "@deepseek-ai/dsh-subagent-in-process-driver": "0.1.5-rc.2", - "@deepseek-ai/dsh-subagent-spawn-in-process": "0.1.5-rc.2", - "@deepseek-ai/dsh-subprocess": "0.1.5-rc.2", - "@deepseek-ai/dsh-subprocess-local": "0.1.5-rc.2", - "@deepseek-ai/dsh-system-prompt": "0.1.5-rc.2", - "@deepseek-ai/dsh-terminal": "0.1.5-rc.2", - "@deepseek-ai/dsh-terminal-bash": "0.1.5-rc.2", - "@deepseek-ai/dsh-time-context": "0.1.5-rc.2", - "@deepseek-ai/dsh-timeout": "0.1.5-rc.2", - "@deepseek-ai/dsh-tmux-context": "0.1.5-rc.2", - "@deepseek-ai/dsh-token-meter": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-ask-user": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-bash": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-bash-persistent": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-call-timeout-policy": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-cordis": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-fs": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-fs-search": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-goal": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-jobs": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-pwsh": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-pwsh-persistent": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-ralph": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-skill": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-str-replace-editor": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-subagent": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-subagent-control": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-todo": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-web": "0.1.5-rc.2", - "@deepseek-ai/dsh-tool-workflow": "0.1.5-rc.2", - "@deepseek-ai/dsh-tools": "0.1.5-rc.2", - "@deepseek-ai/dsh-typert-loader": "0.1.5-rc.2", - "@deepseek-ai/dsh-typert-protocol": "0.1.5-rc.2", - "@deepseek-ai/dsh-typert-registry": "0.1.5-rc.2", - "@deepseek-ai/dsh-user-approval": "0.1.5-rc.2", - "@deepseek-ai/dsh-user-questions": "0.1.5-rc.2", - "@deepseek-ai/dsh-util-crypto": "0.1.5-rc.2", - "@deepseek-ai/dsh-util-time": "0.1.5-rc.2", - "@deepseek-ai/dsh-util-values": "0.1.5-rc.2", - "@deepseek-ai/dsh-util-workspace-path": "0.1.5-rc.2", - "@deepseek-ai/dsh-web": "0.1.5-rc.2", - "@deepseek-ai/dsh-web-app": "0.1.5-rc.2", - "@deepseek-ai/dsh-web-fetch-http": "0.1.5-rc.2", - "@deepseek-ai/dsh-web-frontend": "0.1.5-rc.2", - "@deepseek-ai/dsh-web-search-deepseek": "0.1.5-rc.2", - "@deepseek-ai/dsh-webhook": "0.1.5-rc.2", - "@deepseek-ai/dsh-webhook-github": "0.1.5-rc.2", - "@deepseek-ai/dsh-win32-process": "0.1.5-rc.2", - "@deepseek-ai/dsh-workflow": "0.1.5-rc.2", - "@deepseek-ai/dsh-workflow-worker-thread": "0.1.5-rc.2", - "@deepseek-ai/dsh-workspace": "0.1.5-rc.2", - "@deepseek-ai/schemastery": "3.18.2", + "@deepseek-ai/cordis": "4.0.4", + "@deepseek-ai/cordis-plugin-group": "1.0.4", + "@deepseek-ai/cordis-plugin-hmr": "1.0.19", + "@deepseek-ai/cordis-plugin-include": "1.0.9", + "@deepseek-ai/cordis-plugin-loader": "1.0.5", + "@deepseek-ai/cordis-plugin-timer": "1.1.6", + "@deepseek-ai/cosmokit": "1.8.5", + "@deepseek-ai/dsh": "0.1.7-rc.2", + "@deepseek-ai/dsh-acp": "0.1.7-rc.2", + "@deepseek-ai/dsh-acp-app": "0.1.7-rc.2", + "@deepseek-ai/dsh-agent": "0.1.7-rc.2", + "@deepseek-ai/dsh-agent-default-model": "0.1.7-rc.2", + "@deepseek-ai/dsh-agent-instructions": "0.1.7-rc.2", + "@deepseek-ai/dsh-agent-loop": "0.1.7-rc.2", + "@deepseek-ai/dsh-agent-preset": "0.1.7-rc.2", + "@deepseek-ai/dsh-agent-tool-presentation": "0.1.7-rc.2", + "@deepseek-ai/dsh-anonymous-user-id": "0.1.7-rc.2", + "@deepseek-ai/dsh-api-gateway": "0.1.7-rc.2", + "@deepseek-ai/dsh-api-remotes": "0.1.7-rc.2", + "@deepseek-ai/dsh-api-session-controller": "0.1.7-rc.2", + "@deepseek-ai/dsh-api-settings-controller": "0.1.7-rc.2", + "@deepseek-ai/dsh-api-workspace-controller": "0.1.7-rc.2", + "@deepseek-ai/dsh-app-boot": "0.1.7-rc.2", + "@deepseek-ai/dsh-atomic-write": "0.1.7-rc.2", + "@deepseek-ai/dsh-attachment": "0.1.7-rc.2", + "@deepseek-ai/dsh-attachment-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-authorization": "0.1.7-rc.2", + "@deepseek-ai/dsh-base": "0.1.7-rc.2", + "@deepseek-ai/dsh-bash-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-bash-sandbox": "0.1.7-rc.2", + "@deepseek-ai/dsh-brand": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-connection": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-hmr": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-locale": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-modules": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-store": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-agent-preset": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-approval": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-attachment": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-brand-official": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-chat": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-commands": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-conversation": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-cordis": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-deliverables": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-directory-picker-browse": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-directory-picker-native": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-goal": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-input-trigger": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-jobs": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-layout": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-message-feedback": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-model-selection": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-permission-presets": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-plan": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-primitives": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-reference": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-renderer": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-schedule": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-settings": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-settings-general": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-settings-models": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-settings-plugin-inventory": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-settings-plugins": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-sidebar": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-skill": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-slots": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-subagent": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-theme": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-tool": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-trajectory": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-user-questions": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-workflow-run": "0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-workspace": "0.1.7-rc.2", + "@deepseek-ai/dsh-cmdline": "0.1.7-rc.2", + "@deepseek-ai/dsh-command-compact": "0.1.7-rc.2", + "@deepseek-ai/dsh-command-feedback": "0.1.7-rc.2", + "@deepseek-ai/dsh-command-goal": "0.1.7-rc.2", + "@deepseek-ai/dsh-commands": "0.1.7-rc.2", + "@deepseek-ai/dsh-compaction": "0.1.7-rc.2", + "@deepseek-ai/dsh-compaction-basic": "0.1.7-rc.2", + "@deepseek-ai/dsh-compaction-tool-result-pruner": "0.1.7-rc.2", + "@deepseek-ai/dsh-cordis-client-runner": "0.1.7-rc.2", + "@deepseek-ai/dsh-cordis-host-runner": "0.1.7-rc.2", + "@deepseek-ai/dsh-credentials": "0.1.7-rc.2", + "@deepseek-ai/dsh-credentials-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-deepseek-account": "0.1.7-rc.2", + "@deepseek-ai/dsh-deepseek-llm-api-extensions": "0.1.7-rc.2", + "@deepseek-ai/dsh-deque": "0.1.7-rc.2", + "@deepseek-ai/dsh-file-reference": "0.1.7-rc.2", + "@deepseek-ai/dsh-file-reference-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-fs": "0.1.7-rc.2", + "@deepseek-ai/dsh-fs-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-fs-observation-policy": "0.1.7-rc.2", + "@deepseek-ai/dsh-fs-sandbox": "0.1.7-rc.2", + "@deepseek-ai/dsh-goal": "0.1.7-rc.2", + "@deepseek-ai/dsh-goal-round-driver": "0.1.7-rc.2", + "@deepseek-ai/dsh-headless": "0.1.7-rc.2", + "@deepseek-ai/dsh-hmr": "0.1.7-rc.2", + "@deepseek-ai/dsh-home-paths": "0.1.7-rc.2", + "@deepseek-ai/dsh-hook-protocol": "0.1.7-rc.2", + "@deepseek-ai/dsh-hooks-claude-code": "0.1.7-rc.2", + "@deepseek-ai/dsh-hooks-codex": "0.1.7-rc.2", + "@deepseek-ai/dsh-host-directory-picker": "0.1.7-rc.2", + "@deepseek-ai/dsh-host-directory-picker-auto": "0.1.7-rc.2", + "@deepseek-ai/dsh-host-directory-picker-browse": "0.1.7-rc.2", + "@deepseek-ai/dsh-host-directory-picker-native": "0.1.7-rc.2", + "@deepseek-ai/dsh-host-frontend-static": "0.1.7-rc.2", + "@deepseek-ai/dsh-host-plugin-inventory": "0.1.7-rc.2", + "@deepseek-ai/dsh-host-webserver": "0.1.7-rc.2", + "@deepseek-ai/dsh-invariants": "0.1.7-rc.2", + "@deepseek-ai/dsh-jobs": "0.1.7-rc.2", + "@deepseek-ai/dsh-jobs-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-launch-environment": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm-deepseek": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm-pi-ai": "0.1.7-rc.2", + "@deepseek-ai/dsh-llm-retry": "0.1.7-rc.2", + "@deepseek-ai/dsh-mcp-client": "0.1.7-rc.2", + "@deepseek-ai/dsh-mcp-resources": "0.1.7-rc.2", + "@deepseek-ai/dsh-message-feedback": "0.1.7-rc.2", + "@deepseek-ai/dsh-native-command": "0.1.7-rc.2", + "@deepseek-ai/dsh-output-retention": "0.1.7-rc.2", + "@deepseek-ai/dsh-permission-presets": "0.1.7-rc.2", + "@deepseek-ai/dsh-persona": "0.1.7-rc.2", + "@deepseek-ai/dsh-plan-mode": "0.1.7-rc.2", + "@deepseek-ai/dsh-plugin-manager": "0.1.7-rc.2", + "@deepseek-ai/dsh-plugin-package-inventory-deepseek": "0.1.7-rc.2", + "@deepseek-ai/dsh-ptc-runtime": "0.1.7-rc.2", + "@deepseek-ai/dsh-pwsh-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-pwsh-sandbox": "0.1.7-rc.2", + "@deepseek-ai/dsh-repeat-tool-reminder": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox-policy": "0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox-windows-acl": "0.1.7-rc.2", + "@deepseek-ai/dsh-schedule": "0.1.7-rc.2", + "@deepseek-ai/dsh-scope": "0.1.7-rc.2", + "@deepseek-ai/dsh-sdk-app": "0.1.7-rc.2", + "@deepseek-ai/dsh-sdk-jsonrpc-server": "0.1.7-rc.2", + "@deepseek-ai/dsh-sdk-minimal": "0.1.7-rc.2", + "@deepseek-ai/dsh-sdk-protocol": "0.1.7-rc.2", + "@deepseek-ai/dsh-session": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-checkpoint-policy": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-log-deepseek": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-log-export": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-persistence": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-persistence-jsonl": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-projection-cache": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-query": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-query-sqlite": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-reference": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-stats": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-telemetry": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-telemetry-otel": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-title": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-title-first-prompt-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-title-llm": "0.1.7-rc.2", + "@deepseek-ai/dsh-session-turn-outline": "0.1.7-rc.2", + "@deepseek-ai/dsh-settings": "0.1.7-rc.2", + "@deepseek-ai/dsh-shell": "0.1.7-rc.2", + "@deepseek-ai/dsh-shell-env": "0.1.7-rc.2", + "@deepseek-ai/dsh-skill": "0.1.7-rc.2", + "@deepseek-ai/dsh-skill-badge": "0.1.7-rc.2", + "@deepseek-ai/dsh-skill-filesystem": "0.1.7-rc.2", + "@deepseek-ai/dsh-spill": "0.1.7-rc.2", + "@deepseek-ai/dsh-spill-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-spill-policy": "0.1.7-rc.2", + "@deepseek-ai/dsh-storage": "0.1.7-rc.2", + "@deepseek-ai/dsh-storage-domain": "0.1.7-rc.2", + "@deepseek-ai/dsh-storage-json": "0.1.7-rc.2", + "@deepseek-ai/dsh-subagent": "0.1.7-rc.2", + "@deepseek-ai/dsh-subagent-fork-in-process": "0.1.7-rc.2", + "@deepseek-ai/dsh-subagent-in-process-driver": "0.1.7-rc.2", + "@deepseek-ai/dsh-subagent-spawn-in-process": "0.1.7-rc.2", + "@deepseek-ai/dsh-subprocess": "0.1.7-rc.2", + "@deepseek-ai/dsh-subprocess-local": "0.1.7-rc.2", + "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2", + "@deepseek-ai/dsh-terminal": "0.1.7-rc.2", + "@deepseek-ai/dsh-terminal-bash": "0.1.7-rc.2", + "@deepseek-ai/dsh-time-context": "0.1.7-rc.2", + "@deepseek-ai/dsh-timeout": "0.1.7-rc.2", + "@deepseek-ai/dsh-tmux-context": "0.1.7-rc.2", + "@deepseek-ai/dsh-token-meter": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-ask-user": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-bash": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-bash-persistent": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-call-timeout-policy": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-cordis": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-fs": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-fs-search": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-goal": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-jobs": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-pwsh": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-pwsh-persistent": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-ralph": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-skill": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-str-replace-editor": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-subagent": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-subagent-control": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-todo": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-web": "0.1.7-rc.2", + "@deepseek-ai/dsh-tool-workflow": "0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-loader": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2", + "@deepseek-ai/dsh-typert-registry": "0.1.7-rc.2", + "@deepseek-ai/dsh-user-approval": "0.1.7-rc.2", + "@deepseek-ai/dsh-user-questions": "0.1.7-rc.2", + "@deepseek-ai/dsh-util-crypto": "0.1.7-rc.2", + "@deepseek-ai/dsh-util-time": "0.1.7-rc.2", + "@deepseek-ai/dsh-util-values": "0.1.7-rc.2", + "@deepseek-ai/dsh-util-workspace-path": "0.1.7-rc.2", + "@deepseek-ai/dsh-web": "0.1.7-rc.2", + "@deepseek-ai/dsh-web-app": "0.1.7-rc.2", + "@deepseek-ai/dsh-web-fetch-http": "0.1.7-rc.2", + "@deepseek-ai/dsh-web-frontend": "0.1.7-rc.2", + "@deepseek-ai/dsh-web-search-deepseek": "0.1.7-rc.2", + "@deepseek-ai/dsh-webhook": "0.1.7-rc.2", + "@deepseek-ai/dsh-webhook-github": "0.1.7-rc.2", + "@deepseek-ai/dsh-win32-process": "0.1.7-rc.2", + "@deepseek-ai/dsh-workflow": "0.1.7-rc.2", + "@deepseek-ai/dsh-workflow-ptc": "0.1.7-rc.2", + "@deepseek-ai/dsh-workspace": "0.1.7-rc.2", + "@deepseek-ai/schemastery": "3.18.4", "dsh-desktop-client-ui": "file:packages/dsh-desktop-client-ui", "dsh-desktop-hmr-fallback": "file:packages/dsh-desktop-hmr-fallback", "dsh-desktop-log-bridge": "file:packages/dsh-desktop-log-bridge", "dsh-desktop-market-installer": "file:packages/dsh-desktop-market-installer", "dsh-desktop-preset-transfer": "file:packages/dsh-desktop-preset-transfer", + "dsh-image-generation": "file:packages/dsh-image-generation", + "dsh-ppt": "file:packages/ppt-runtime/core", + "dsh-ppt-composer": "file:packages/ppt-runtime/adapter", "electron-updater": "^6.8.9", "node": "24.9.0", "pnpm": "10.34.5", "qrcode": "^1.5.4", "react": "18.3.1", "react-dom": "18.3.1", - "ws": "^8.21.3", - "dsh-ppt": "file:packages/ppt-bundles/dsh-ppt-0.1.1-rc.2-desktop-20260906.tgz", - "dsh-ppt-composer": "file:packages/ppt-bundles/dsh-ppt-composer-0.1.1-rc.2-desktop-20260906.tgz", - "dsh-image-generation": "file:packages/dsh-image-generation" + "ws": "^8.21.3" }, "devDependencies": { + "@types/js-yaml": "4.0.9", "@types/node": "24.10.1", "@types/qrcode": "^1.5.6", "@types/ws": "^8.18.1", - "electron": "43.4.0", + "electron": "43.0.0", "electron-builder": "26.15.3", "electron-vite": "5.0.0", "patch-package": "^8.0.1", @@ -303,7 +308,11 @@ "build": { "appId": "io.dsh.desktop", "productName": "DSH Desktop", - "asar": false, + "asar": true, + "asarUnpack": [ + "node_modules/**/*", + ".build/ppt-runtime/packages/**/*" + ], "npmRebuild": false, "compression": "maximum", "electronLanguages": [ @@ -320,6 +329,22 @@ "files": [ "out/**/*", "node_modules/**/*", + "!node_modules/dsh-ppt-composer{,/**}", + "!node_modules/dsh-ppt{,/**}", + { + "from": ".build/ppt-runtime/packages/dsh-ppt-composer", + "to": "node_modules/dsh-ppt-composer", + "filter": [ + "**/*" + ] + }, + { + "from": ".build/ppt-runtime/packages/dsh-ppt", + "to": "node_modules/dsh-ppt", + "filter": [ + "**/*" + ] + }, "package.json", "!**/*.map", "!**/*.d.ts", @@ -406,7 +431,6 @@ "from": "build/safe-mode.html", "to": "safe-mode.html" }, - { "from": "build/community-wechat-qr.png", "to": "community-wechat-qr.png" @@ -439,7 +463,13 @@ }, "win": { "icon": "build/icon.ico", - "verifyUpdateCodeSignature": false, + "verifyUpdateCodeSignature": true, + "signtoolOptions": { + "publisherName": "Beijing Shuju Xiangsu Intelligence Technology Co., Ltd.", + "signingHashAlgorithms": [ + "sha256" + ] + }, "requestedExecutionLevel": "asInvoker", "target": [ { @@ -457,6 +487,7 @@ "allowToChangeInstallationDirectory": true, "createDesktopShortcut": true, "createStartMenuShortcut": true - } + }, + "afterPack": "scripts/verify-packaged-ppt-runtime.cjs" } } diff --git a/packages/dsh-desktop-client-ui/client.js b/packages/dsh-desktop-client-ui/client.js index 003539cd0..25be78701 100644 --- a/packages/dsh-desktop-client-ui/client.js +++ b/packages/dsh-desktop-client-ui/client.js @@ -6,7 +6,7 @@ window.__ModuleLoader__.load({ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }) const React = require('react') - const { BrandWordmark, FishLogo } = require('@deepseek-ai/dsh-client-ui-primitives') + const { BrandWordmark, FishLogo, MenuItemButton } = require('@deepseek-ai/dsh-client-ui-primitives') // Tight bounds of the mark inside its 1000x1000 source artwork. const BRAND_MARK_VIEWBOX = { x: 42, y: 218, width: 898, height: 564 } @@ -37,8 +37,101 @@ window.__ModuleLoader__.load({ return React.createElement(FishLogo, props) } - const inject = ['slots'] + function OpenUnpreviewableFile({ absolutePath, openWorkspacePath }) { + const [error, setError] = React.useState('') + const label = document.documentElement.lang?.toLowerCase().startsWith('zh') + ? '用本地应用打开' + : 'Open with local app' + return React.createElement( + React.Fragment, + null, + React.createElement('button', { + type: 'button', + 'data-textpreview-open-local': true, + onClick: () => { + setError('') + void openWorkspacePath(absolutePath).catch((reason) => { + setError(reason instanceof Error ? reason.message : String(reason)) + }) + } + }, label), + error && React.createElement('span', { role: 'alert' }, error) + ) + } + + function DeleteSessionMenuItem({ sessionId, displayTitle, useMenuOpenState, deleteSession }) { + const [, setMenuOpen] = useMenuOpenState() + const chinese = document.documentElement.lang?.toLowerCase().startsWith('zh') + const label = chinese ? '永久删除会话' : 'Delete session permanently' + const warning = chinese + ? `确定删除“${displayTitle || sessionId}”?工作区文件会保留。此操作无法撤销。` + : `Delete “${displayTitle || sessionId}”? Workspace files are kept. This can’t be undone.` + return React.createElement(MenuItemButton, { + danger: true, + onSelect: () => { + setMenuOpen(false) + if (!window.confirm(warning)) return + void Promise.resolve().then(() => deleteSession(sessionId)).catch((reason) => { + window.alert(reason instanceof Error ? reason.message : String(reason)) + }) + } + }, label) + } + + function OpenSessionFolderMenuItem({ sessionId, useMenuOpenState, openInFinder }) { + const [, setMenuOpen] = useMenuOpenState() + if (typeof window.dshDesktop?.openInFinder !== 'function') return null + const chinese = document.documentElement.lang?.toLowerCase().startsWith('zh') + const label = chinese ? '在文件管理器中打开' : 'Open in file manager' + return React.createElement(MenuItemButton, { + onSelect: () => { + setMenuOpen(false) + void Promise.resolve().then(() => openInFinder(sessionId)).catch((reason) => { + window.alert(reason instanceof Error ? reason.message : String(reason)) + }) + } + }, label) + } + + function UnreadSessionMenuItem({ sessionId, unread, onUnreadChange, useMenuOpenState }) { + const [, setMenuOpen] = useMenuOpenState() + const chinese = document.documentElement.lang?.toLowerCase().startsWith('zh') + return React.createElement(MenuItemButton, { + onSelect: () => { + setMenuOpen(false) + onUnreadChange(sessionId, !unread) + } + }, unread ? (chinese ? '标为已读' : 'Mark as read') : (chinese ? '标为未读' : 'Mark as unread')) + } + + const inject = ['slots', 'remote.session', 'sessions', 'uiWorkspace'] function apply(ctx) { + ctx.effect(() => { + const id = 'dsh-desktop-preset-toolbar-style' + if (document.getElementById(id)) return + const style = document.createElement('style') + style.id = id + style.textContent = ` + [data-dsh-preset-heading] { display:flex; align-items:center; flex-wrap:wrap; gap:12px 16px; } + [data-dsh-preset-heading] h2 { margin:0; } + [data-dsh-preset-actions] { display:flex; flex-wrap:wrap; align-items:center; gap:8px; margin-left:auto; } + [data-dsh-preset-actions] button { white-space:nowrap; } + [data-dsh-preset-search] { margin-bottom:16px; } + [data-dsh-preset-search] input[type=search] { + box-sizing:border-box; width:100%; min-width:0; height:36px; + border:1px solid var(--dsw-alias-border-l2); border-radius:10px; + background:var(--dsw-alias-bg-module-platform); color:var(--dsw-alias-label-primary); + padding:0 12px; font:inherit; font-size:13px; + } + [data-dsh-preset-search] input[type=search]::placeholder { color:var(--dsw-alias-label-caption); } + [data-dsh-preset-search] input[type=search]:focus-visible { + outline:2px solid var(--dsw-alias-state-business-primary); outline-offset:2px; + background:var(--dsw-alias-bg-base); + } + ` + document.head.appendChild(style) + return () => style.remove() + }) ctx.slots.inject('sidebar.brand.mark', () => ctx.slots.inject('sidebar.brand.name', () => ctx.slots.inject('conversation.hero.brand.mark', function* () { @@ -51,6 +144,50 @@ window.__ModuleLoader__.load({ }) ) ) + ctx.slots.inject('sidebar.right.tab.document.unpreviewable', () => + ctx.slots.register({ + name: 'sidebar.right.tab.document.unpreviewable', + id: 'desktop-open-local', + inject: () => ({ + openWorkspacePath: (path) => ctx.remote.session.openWorkspacePath({ path }) + }) + }, OpenUnpreviewableFile) + ) + ctx.slots.inject('sidebar.workspaces.session.menu.item', () => + ctx.slots.register({ + name: 'sidebar.workspaces.session.menu.item', + id: 'desktop-delete-session', + order: 900, + inject: () => ({ + deleteSession: (sessionId) => { + const workspace = ctx.get('uiWorkspace') + if (!workspace) throw new Error('Workspace navigation is unavailable') + return workspace.deleteSession(sessionId) + } + }) + }, DeleteSessionMenuItem) + ) + ctx.slots.inject('sidebar.workspaces.session.menu.item', () => + ctx.slots.register({ + name: 'sidebar.workspaces.session.menu.item', + id: 'desktop-open-session-folder', + order: 800, + inject: () => ({ + openInFinder: (sessionId) => { + const cwd = ctx.get('sessions').list.getSnapshot().byId[sessionId]?.cwd + if (!cwd) throw new Error('Session workspace directory is unavailable') + return window.dshDesktop.openInFinder(cwd) + } + }) + }, OpenSessionFolderMenuItem) + ) + ctx.slots.inject('sidebar.workspaces.session.menu.item', () => + ctx.slots.register({ + name: 'sidebar.workspaces.session.menu.item', + id: 'desktop-unread-session', + order: 350 + }, UnreadSessionMenuItem) + ) } exports.apply = apply diff --git a/packages/dsh-desktop-client-ui/package.json b/packages/dsh-desktop-client-ui/package.json index d53f4d0ac..9ab4df121 100644 --- a/packages/dsh-desktop-client-ui/package.json +++ b/packages/dsh-desktop-client-ui/package.json @@ -15,7 +15,10 @@ "inject": [ "@deepseek-ai/dsh-client-ui-conversation", "@deepseek-ai/dsh-client-ui-renderer", - "@deepseek-ai/dsh-client-ui-sidebar" + "@deepseek-ai/dsh-client-ui-sidebar", + "@deepseek-ai/dsh-client-ui-sidebar-documentpreview", + "@deepseek-ai/dsh-api-session-controller", + "@deepseek-ai/dsh-client-ui-workspace" ], "platform": "web" } @@ -23,8 +26,11 @@ "license": "MIT", "peerDependencies": { "@deepseek-ai/cordis": "^4.0.1", - "@deepseek-ai/dsh-client-ui-conversation": "^0.1.5-rc.1", - "@deepseek-ai/dsh-client-ui-renderer": "^0.1.5-rc.1", - "@deepseek-ai/dsh-client-ui-sidebar": "^0.1.5-rc.1" + "@deepseek-ai/dsh-client-ui-conversation": "^0.1.5-rc.1 || ^0.1.6-alpha.1 || ^0.1.7-rc.1 || ^0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-renderer": "^0.1.5-rc.1 || ^0.1.6-alpha.1 || ^0.1.7-rc.1 || ^0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-sidebar": "^0.1.5-rc.1 || ^0.1.6-alpha.1 || ^0.1.7-rc.1 || ^0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-sidebar-documentpreview": "^0.1.7-rc.1 || ^0.1.7-rc.2", + "@deepseek-ai/dsh-api-session-controller": "^0.1.7-rc.1 || ^0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-workspace": "^0.1.7-rc.1 || ^0.1.7-rc.2" } } diff --git a/packages/dsh-desktop-market-installer/generations/installer.d.ts b/packages/dsh-desktop-market-installer/generations/installer.d.ts index ab8acdaed..d08a2963f 100644 --- a/packages/dsh-desktop-market-installer/generations/installer.d.ts +++ b/packages/dsh-desktop-market-installer/generations/installer.d.ts @@ -55,5 +55,6 @@ export function pinnedGitBuildApproval( export function verifyGenerationPeers( dshHome: string, - generation: Generation + generation: Generation, + options?: { dshEntryPath?: string } ): Promise<{ ok: boolean; problems: string[] }> diff --git a/packages/dsh-desktop-market-installer/generations/installer.mjs b/packages/dsh-desktop-market-installer/generations/installer.mjs index 5131891cd..cd8cfdec8 100644 --- a/packages/dsh-desktop-market-installer/generations/installer.mjs +++ b/packages/dsh-desktop-market-installer/generations/installer.mjs @@ -235,7 +235,9 @@ export async function installGeneration(options) { const { dshHome, pluginSpec, onTrace } = options const trace = (line) => onTrace?.(`generation-install: ${line}`) const layout = await ensureRegistryDirectories(dshHome) - const pluginName = options.expectedPluginName ?? (pluginSpec.replace(/@[^@/]+$/u, '') || pluginSpec) + // Known registry/path names make staging provenance readable; generic git and + // tarball specs are resolved to their actual direct dependency after pnpm runs. + let pluginName = options.expectedPluginName ?? (pluginSpec.replace(/@[^@/]+$/u, '') || pluginSpec) const stagingDir = join(layout.staging, randomUUID()) await mkdir(stagingDir, { recursive: true }) @@ -313,6 +315,16 @@ export async function installGeneration(options) { } trace(`installed in ${Date.now() - started}ms`) + const stagingManifest = JSON.parse(await readFile(join(stagingDir, 'package.json'), 'utf8')) + const directDependencies = Object.keys(stagingManifest.dependencies ?? {}) + if (directDependencies.length === 1 && directDependencies[0] !== undefined) { + pluginName = directDependencies[0] + } + if (options.expectedPluginName !== undefined && pluginName !== options.expectedPluginName) { + await cleanupStaging() + return { ok: false, detail: `pnpm installed ${pluginName}, expected ${options.expectedPluginName}` } + } + const installedManifestPath = join(stagingDir, 'node_modules', pluginName, 'package.json') if (!existsSync(installedManifestPath)) { await cleanupStaging() @@ -511,8 +523,18 @@ function importExportTarget(value) { } async function resolveNonRootPackage(requireFromPackage, dependency) { - for (const modules of requireFromPackage.resolve.paths(dependency) ?? []) { - const file = join(modules, dependency, 'package.json') + // Harness intercepts package resolution, but resolve.paths() still exposes + // legacy filesystem links. Ask the active resolver for the manifest first. + let selectedManifest + try { + selectedManifest = requireFromPackage.resolve(`${dependency}/package.json`) + } catch { + // Packages with exports may hide their manifest; keep the bounded lookup. + } + const files = selectedManifest ? [selectedManifest] + : (requireFromPackage.resolve.paths(dependency) ?? []).map(modules => join(modules, dependency, 'package.json')) + for (const file of files) { + const packageDirectory = file.slice(0, -'package.json'.length) let manifest try { manifest = JSON.parse(await readFile(file, 'utf8')) @@ -526,16 +548,30 @@ async function resolveNonRootPackage(requireFromPackage, dependency) { Object.hasOwn(exported, '.') ? exported['.'] : exported const importTarget = importExportTarget(rootExport) if (typeof importTarget === 'string' && importTarget.startsWith('./')) { - const entry = join(modules, dependency, importTarget) + const entry = join(packageDirectory, importTarget) if (existsSync(entry)) return entry } + // CLI-only packages (including @deepseek-ai/dsh) have no importable root. + // Validate an actual executable target; a manifest alone is not enough. + // Do not let a bin hide a broken library main/exports entry. + if (!manifest.main && manifest.exports === undefined && manifest.bin) { + const targets = typeof manifest.bin === 'string' ? [manifest.bin] + : typeof manifest.bin === 'object' ? Object.values(manifest.bin) : [] + const root = packageDirectory + for (const target of targets) { + if (typeof target !== 'string' || isAbsolute(target)) continue + const entry = join(root, target) + if (!isInsideDirectory(root, entry)) continue + if ((await lstat(entry).catch(() => undefined))?.isFile()) return entry + } + } const declarationOnly = typeof (manifest.types ?? manifest.typings) === 'string' && !manifest.main && !hasRuntimeExport(manifest.exports) const subpathOnly = manifest.exports !== null && typeof manifest.exports === 'object' && !Array.isArray(manifest.exports) && !Object.hasOwn(manifest.exports, '.') && Object.keys(manifest.exports).some((key) => key.startsWith('./')) if (declarationOnly) { - const declaration = join(modules, dependency, manifest.types ?? manifest.typings) + const declaration = join(packageDirectory, manifest.types ?? manifest.typings) return existsSync(declaration) ? declaration : undefined } // Some SDKs publish a root export without shipping its target, while their @@ -547,7 +583,7 @@ async function resolveNonRootPackage(requireFromPackage, dependency) { if (!subpath.startsWith('./') || subpath.includes('*')) continue const selected = importExportTarget(target) if (typeof selected !== 'string' || !selected.startsWith('./') || selected.includes('*')) continue - const entry = join(modules, dependency, selected) + const entry = join(packageDirectory, selected) if (existsSync(entry)) return entry } } @@ -559,8 +595,25 @@ async function resolveNonRootPackage(requireFromPackage, dependency) { } /** Verify every installed package's required runtime dependency stays in an allowed closure. */ -export async function verifyGenerationPeers(dshHome, generation) { +export async function verifyGenerationPeers(dshHome, generation, options = {}) { const { createRequire } = await import('node:module') + // 0.1.7 can resolve host packages through runtime hooks without refreshing + // legacy Profile links. Validate the exact entry supplied by this running host. + const hostRequire = options.dshEntryPath ? createRequire(options.dshEntryPath) : undefined + const hostEntries = new Map() + const hostEntry = async (dependency) => { + if (!hostRequire || !isHostSingleton(dependency)) return undefined + if (!hostEntries.has(dependency)) { + let resolved + try { + resolved = hostRequire.resolve(dependency) + } catch { + resolved = await resolveNonRootPackage(hostRequire, dependency) + } + hostEntries.set(dependency, resolved === undefined ? undefined : await realpath(resolved).catch(() => resolved)) + } + return hostEntries.get(dependency) + } const generationRoot = await realpath(generation.directory) const closure = await realpath(installationClosureDir(dshHome)).catch( () => installationClosureDir(dshHome) @@ -649,7 +702,8 @@ export async function verifyGenerationPeers(dshHome, generation) { } const realResolved = await realpath(resolved).catch(() => resolved) const providedRoot = await fallbackRoot(dependency) - const insideClosure = isInsideDirectory(closure, realResolved) || + const currentHostEntry = await hostEntry(dependency) + const insideClosure = currentHostEntry !== undefined ? realResolved === currentHostEntry : isInsideDirectory(closure, realResolved) || (providedRoot !== undefined && isInsideDirectory(providedRoot, realResolved)) if (isHostSingleton(dependency)) { if (!insideClosure) { diff --git a/packages/dsh-desktop-market-installer/generations/package-backend.d.ts b/packages/dsh-desktop-market-installer/generations/package-backend.d.ts new file mode 100644 index 000000000..15652a43e --- /dev/null +++ b/packages/dsh-desktop-market-installer/generations/package-backend.d.ts @@ -0,0 +1,45 @@ +export interface PackageResult { + exitCode: number + output: string + truncated: boolean + logPath: string +} + +export interface ProfileBundleInstallRequest { + spec: string + kind: 'registry' | 'path' | 'git' | 'tarball' + path?: string + expectedName?: string + registry?: string + expectedVersion?: string + autoInstallPeers?: boolean + minimumReleaseAge?: number + signal?: AbortSignal + onOutput?(text: string, stream: 'stdout' | 'stderr'): void +} + +export interface ProfileBundlePackageBackend { + install(request: ProfileBundleInstallRequest): Promise<{ + packageResult: PackageResult + bundle?: string + replaced?: boolean + pendingBuilds?: string[] + rollback?(): Promise + commit?(): void + }> + remove(request: { + name: string + signal?: AbortSignal + onOutput?(text: string, stream: 'stdout' | 'stderr'): void + }): Promise<{ packageResult: PackageResult }> +} + +export function createGenerationPackageBackend(options: { + dshHome: string + dshEntryPath?: string + nodeExecutablePath: string + pnpmEntryPath: string + environment?: NodeJS.ProcessEnv + spawnProcess?: unknown + runInstall?: unknown +}): ProfileBundlePackageBackend diff --git a/packages/dsh-desktop-market-installer/generations/package-backend.mjs b/packages/dsh-desktop-market-installer/generations/package-backend.mjs new file mode 100644 index 000000000..a1ebd0a2c --- /dev/null +++ b/packages/dsh-desktop-market-installer/generations/package-backend.mjs @@ -0,0 +1,286 @@ +import { randomUUID } from 'node:crypto' +import { mkdir, open, readFile } from 'node:fs/promises' +import { isAbsolute, join } from 'node:path' +import { installGeneration, verifyGenerationPeers } from './installer.mjs' +import { + listGenerations, + readDesired, + withRegistryLock, + writeDesired +} from './registry.mjs' +import { projectGenerations, publishGenerationManifest, publishInstalledGeneration } from './projection.mjs' + +const PROFILE = 'web' +const MAX_OUTPUT_BYTES = 16 * 1024 + +function errorText(error) { + return error instanceof Error ? error.message : String(error) +} + +function packageNameFromRegistrySpec(spec) { + const match = /^(?@[^/]+\/[^@]+|[^@/][^@]*)?(?:@[^@]+)?$/u.exec(spec) + return match?.groups?.name || undefined +} + +async function localPackageName(path) { + const manifest = JSON.parse(await readFile(join(path, 'package.json'), 'utf8')) + if (typeof manifest.name !== 'string' || manifest.name.length === 0) { + throw new Error('The local package manifest names no package.') + } + return manifest.name +} + +function replaceDesiredGeneration(desired, generations, pluginName, generationId) { + const byId = new Map(generations.map(generation => [generation.id, generation])) + return [ + ...desired.filter(id => byId.get(id)?.pluginName !== pluginName), + generationId + ] +} + +async function createOperationLog(dshHome) { + const directory = join(dshHome, 'profiles', PROFILE, '.plugin-manager', 'logs', randomUUID()) + await mkdir(directory, { recursive: true, mode: 0o700 }) + const path = join(directory, 'generation.log') + const file = await open(path, 'wx', 0o600) + let output = Buffer.alloc(0) + let truncated = false + return { + path, + async append(text) { + const bytes = Buffer.from(text) + await file.write(bytes) + output = Buffer.concat([output, bytes]) + if (output.length > MAX_OUTPUT_BYTES) { + truncated = true + output = output.subarray(output.length - MAX_OUTPUT_BYTES) + } + }, + async close() { + await file.close() + return { output: output.toString('utf8'), truncated } + } + } +} + +/** + * Host package-mutation backend consumed by the patched Harness Plugin Manager. + * Staging and promotion happen before publication; the returned rollback remains + * live only until Plugin Manager has validated the bundle and begins enablement. + */ +export function createGenerationPackageBackend(options) { + const { + dshHome, + dshEntryPath, + nodeExecutablePath, + pnpmEntryPath, + environment = process.env, + spawnProcess, + runInstall + } = options + + return Object.freeze({ + async install(request) { + const log = await createOperationLog(dshHome) + let activeChild + const abortChild = () => activeChild?.kill('SIGKILL') + request.signal?.addEventListener('abort', abortChild, { once: true }) + let closed = false + let outputWrites = Promise.resolve() + const finishLog = async () => { + if (closed) return { output: '', truncated: false } + await outputWrites + closed = true + return log.close() + } + const emit = (text, stream = 'stdout') => { + outputWrites = outputWrites.then(async () => { + await log.append(text) + request.onOutput?.(text, stream) + }) + return outputWrites + } + + try { + request.signal?.throwIfAborted() + let expectedPluginName = request.expectedName + let sourceDirectory + let sourceSpec + if (request.kind === 'registry') { + expectedPluginName ??= packageNameFromRegistrySpec(request.spec) + } else if (request.kind === 'path') { + const path = request.path + if (typeof path !== 'string' || !isAbsolute(path)) { + throw new Error('Desktop generation installation requires an absolute local package path.') + } + expectedPluginName ??= await localPackageName(path) + sourceDirectory = path + sourceSpec = request.spec + } + + const result = await withRegistryLock(dshHome, async () => { + request.signal?.throwIfAborted() + const beforeDesired = await readDesired(dshHome) + const beforeGenerations = await listGenerations(dshHome) + const install = await installGeneration({ + dshHome, + profile: PROFILE, + pluginSpec: request.spec, + expectedPluginName, + sourceDirectory, + sourceSpec, + registry: request.registry, + expectedVersion: request.expectedVersion, + autoInstallPeers: request.autoInstallPeers, + minimumReleaseAge: request.minimumReleaseAge, + nodeExecutablePath, + pnpmEntryPath, + environment, + spawnProcess, + registerChild: child => { + activeChild = child + if (request.signal?.aborted) abortChild() + }, + runInstall, + onTrace: line => { void emit(`${line}\n`) }, + onOutput: text => { void emit(text) } + }) + if (!install.ok || install.generation === undefined) { + return { ok: false, detail: install.detail ?? 'generation install failed' } + } + request.signal?.throwIfAborted() + const generation = install.generation + const peers = await verifyGenerationPeers(dshHome, generation, { dshEntryPath }) + if (!peers.ok) { + return { ok: false, detail: `generation peer validation failed: ${peers.problems.join('; ')}` } + } + const replaced = beforeGenerations.some(item => + beforeDesired.includes(item.id) && item.pluginName === generation.pluginName + ) + const nextDesired = replaceDesiredGeneration( + beforeDesired, + await listGenerations(dshHome), + generation.pluginName, + generation.id + ) + await writeDesired(dshHome, nextDesired) + try { + await publishInstalledGeneration(dshHome, generation.pluginName, PROFILE, { + syncBundles: false + }) + } catch (error) { + await writeDesired(dshHome, beforeDesired) + throw error + } + + let committed = false + const rollback = async () => { + if (committed) return + await withRegistryLock(dshHome, async () => { + if (committed) return + const currentDesired = await readDesired(dshHome) + // A newer operation may already have replaced this package. Its + // pointer must win, while unrelated package changes are kept. + if (!currentDesired.includes(generation.id)) return + const previousIds = beforeDesired.filter(id => + beforeGenerations.some(item => item.id === id && item.pluginName === generation.pluginName) + ) + const restored = [ + ...currentDesired.filter(id => id !== generation.id), + ...previousIds + ] + await writeDesired(dshHome, restored) + try { + await projectGenerations(dshHome, PROFILE) + } catch (error) { + await writeDesired(dshHome, currentDesired) + throw error + } + committed = true + }) + } + return { + ok: true, + bundle: generation.pluginName, + replaced, + rollback, + commit: () => { committed = true } + } + }) + + if (!result.ok) { + await emit(`generation-install: ${result.detail}\n`, 'stderr') + const captured = await finishLog() + return { + packageResult: { + exitCode: 1, + ...captured, + logPath: log.path + } + } + } + const captured = await finishLog() + return { + packageResult: { + exitCode: 0, + ...captured, + logPath: log.path + }, + bundle: result.bundle, + replaced: result.replaced, + rollback: result.rollback, + commit: result.commit + } + } catch (error) { + await emit(`generation-install: ${errorText(error)}\n`, 'stderr').catch(() => undefined) + const captured = await finishLog() + return { + packageResult: { + exitCode: 1, + ...captured, + logPath: log.path + } + } + } finally { + request.signal?.removeEventListener('abort', abortChild) + } + }, + + async remove(request) { + const log = await createOperationLog(dshHome) + const emit = async (text, stream = 'stdout') => { + await log.append(text) + request.onOutput?.(text, stream) + } + try { + request.signal?.throwIfAborted() + await withRegistryLock(dshHome, async () => { + request.signal?.throwIfAborted() + const beforeDesired = await readDesired(dshHome) + const generations = await listGenerations(dshHome) + const removedIds = new Set( + generations.filter(item => item.pluginName === request.name).map(item => item.id) + ) + const nextDesired = beforeDesired.filter(id => !removedIds.has(id)) + if (nextDesired.length === beforeDesired.length) { + throw new Error(`No enabled generation for ${request.name}.`) + } + await writeDesired(dshHome, nextDesired) + try { + await publishGenerationManifest(dshHome, PROFILE, { syncBundles: true }) + } catch (error) { + await writeDesired(dshHome, beforeDesired) + throw error + } + await emit(`generation-remove: staged ${request.name} for removal on restart\n`) + }) + const captured = await log.close() + return { packageResult: { exitCode: 0, ...captured, logPath: log.path } } + } catch (error) { + await emit(`generation-remove: ${errorText(error)}\n`, 'stderr').catch(() => undefined) + const captured = await log.close() + return { packageResult: { exitCode: 1, ...captured, logPath: log.path } } + } + } + }) +} diff --git a/packages/dsh-desktop-market-installer/index.js b/packages/dsh-desktop-market-installer/index.js index 2eaa11704..702799fcc 100644 --- a/packages/dsh-desktop-market-installer/index.js +++ b/packages/dsh-desktop-market-installer/index.js @@ -7,11 +7,9 @@ import { delimiter, dirname, isAbsolute, join, resolve } from 'node:path' import { fileURLToPath } from 'node:url' import { PassThrough } from 'node:stream' -import z from '@deepseek-ai/schemastery' -import { installGeneration } from './generations/installer.mjs' +import { createGenerationPackageBackend } from './generations/package-backend.mjs' import { - publishInstalledGeneration, publishGenerationManifest } from './generations/projection.mjs' import { @@ -25,7 +23,7 @@ import { resolveMarketRegistry } from './market-registry.mjs' import { SIDELINE_MARKER } from './pnpm-runner.mjs' import { removeTree } from './remove-tree.mjs' -export const RECOMMENDED_MARKET_VERSION = '^1.45.1' +export const RECOMMENDED_MARKET_VERSION = '^1.65.1' export const MARKET_PACKAGE = 'dshmarket' export const MARKET_PROFILE = 'web' export const STATUS_PATH = '/dsh-desktop/market-installer/status' @@ -36,7 +34,7 @@ const OPERATION_TIMEOUT_MS = 15 * 60 * 1000 const MAX_LOG_BYTES = 32 * 1024 export const name = 'dsh-desktop-market-installer' -export const inject = ['settings'] +export const inject = [] function dshHome() { return process.env.DSH_HOME || join(homedir(), '.dsh') @@ -436,6 +434,15 @@ export function createDesktopPnpmService(options) { let closed = false const pnpmEntryPath = resolvePnpmEntry() + const marketGenerationBackend = createGenerationPackageBackend({ + dshHome: home, + dshEntryPath, + nodeExecutablePath: executablePath, + pnpmEntryPath, + environment, + spawnProcess, + runInstall: options.runGenerationInstall + }) /** * A synthetic handle in the shape `runPlugin` returns, driven by an async @@ -588,64 +595,53 @@ export function createDesktopPnpmService(options) { const spec = args.slice(1).find((argument) => !argument.startsWith('-')) if (spec === undefined) throw new Error('The install boundary needs a package spec.') - const handle = asHandle(async ({ write, isCancelled, setCancel }) => - withRegistryLock(home, async () => { - if (isCancelled()) return { exitCode: 1, message: 'The package operation was aborted.' } - const packageName = spec.slice(0, spec.lastIndexOf('@')) - if (packageName === MARKET_PACKAGE) { - return updateSharedMarket(args, spec, invokingDir, write, isCancelled, setCancel) - } - write(`Installing ${spec} as an isolated generation…`) - // The market picked this exact version by reading ITS registry; the - // install has to fetch from the same one (#337). `args` is consulted - // too, so a market that names a registry outright is believed over - // anything inferred here. - const registry = await resolveMarketRegistry({ - profileDir: profileDirectory(home), - args, - environment - }) - const install = await installGeneration({ - dshHome: home, - pluginSpec: spec, - expectedVersion: spec.slice(spec.lastIndexOf('@') + 1), - // Preserve the market's peer-fetch recovery policy across the - // Profile -> isolated generation boundary (including camelCase). - autoInstallPeers: args.reduce((value, arg) => { - const match = /^--config\.(?:autoInstallPeers|auto-install-peers)=(true|false)$/.exec(arg) - return match ? match[1] === 'true' : value - }, undefined), - minimumReleaseAge: args.some(arg => /^--config\.(?:minimumReleaseAge|minimum-release-age)=0$/.test(arg)) ? 0 : 1440, - nodeExecutablePath: executablePath, - pnpmEntryPath, - spawnProcess, - environment, - registry, - onTrace: write, - onOutput: (chunk) => write(chunk.replace(/\r?\n$/u, '')), - runInstall: options.runGenerationInstall - }) - if (!install.ok) return { exitCode: 1, message: install.detail ?? 'generation install failed' } - - // Replace any earlier generation of the same plugin, keep the rest. - const [desired, generations] = await Promise.all([readDesired(home), listGenerations(home)]) - const byId = new Map(generations.map((generation) => [generation.id, generation])) - const kept = desired.filter((id) => { - const generation = byId.get(id) - return generation === undefined || generation.pluginName !== install.generation.pluginName - }) - if (isCancelled()) return { exitCode: 1, message: 'The package operation was aborted.' } - await writeDesired(home, [...kept, install.generation.id]) - try { - await publishInstalledGeneration(home, install.generation.pluginName) - } catch (error) { - await writeDesired(home, desired) - throw error - } - write(`installed in profile: ${install.generation.pluginName}@${install.generation.version}; activation may require restart`) - return { exitCode: 0 } + const handle = asHandle(async ({ write, isCancelled, setCancel }) => { + if (isCancelled()) return { exitCode: 1, message: 'The package operation was aborted.' } + const packageName = spec.slice(0, spec.lastIndexOf('@')) + if (packageName === MARKET_PACKAGE) { + return withRegistryLock(home, () => + updateSharedMarket(args, spec, invokingDir, write, isCancelled, setCancel) + ) + } + write(`Installing ${spec} as an isolated generation…`) + // The market picked this exact version by reading ITS registry; the + // install has to fetch from the same one (#337). `args` is consulted + // too, so a market that names a registry outright is believed over + // anything inferred here. + const registry = await resolveMarketRegistry({ + profileDir: profileDirectory(home), + args, + environment }) - ) + const control = new AbortController() + setCancel(() => control.abort()) + const mutation = await marketGenerationBackend.install({ + kind: 'registry', + spec, + expectedVersion: spec.slice(spec.lastIndexOf('@') + 1), + // Preserve the market's peer-fetch recovery policy across the + // Profile -> isolated generation boundary (including camelCase). + autoInstallPeers: args.reduce((value, arg) => { + const match = /^--config\.(?:autoInstallPeers|auto-install-peers)=(true|false)$/.exec(arg) + return match ? match[1] === 'true' : value + }, undefined), + minimumReleaseAge: args.some(arg => /^--config\.(?:minimumReleaseAge|minimum-release-age)=0$/.test(arg)) ? 0 : 1440, + registry, + signal: control.signal, + onOutput: chunk => write(chunk.replace(/\r?\n$/u, '')) + }) + if (isCancelled()) { + await mutation.rollback?.() + return { exitCode: 1, message: 'The package operation was aborted.' } + } + if (mutation.packageResult.exitCode !== 0 || !mutation.bundle) { + return { exitCode: 1, message: mutation.packageResult.output || 'generation install failed' } + } + mutation.commit?.() + setCancel(() => {}) + write(`published in profile: ${mutation.bundle}@${spec.slice(spec.lastIndexOf('@') + 1)}; activation may require restart`) + return { exitCode: 0 } + }) active = handle signal?.addEventListener('abort', handle.cancel, { once: true }) void handle.done.finally(() => { @@ -807,10 +803,6 @@ function killProcessTree(child) { } export async function apply(ctx) { - // The configurable Plugins tab only dispatches cards for served settings - // namespaces. Keep this Desktop-owned control discoverable while the image - // generation package itself is switched off. - ctx.settings.register('desktop-host-plugins', z.object({}), { applies: 'restart' }) const home = dshHome() const directory = profileDirectory(home) const manifestPath = join(directory, 'package.json') @@ -826,8 +818,15 @@ export async function apply(ctx) { const binDirectory = await ensurePnpmShim(home) const desktopProfiles = createDesktopProfilesService(home) const desktopPnpm = createDesktopPnpmService({ binDirectory }) + const profileBundlePackageBackend = createGenerationPackageBackend({ + dshHome: home, + dshEntryPath: resolveDshEntry(), + nodeExecutablePath: process.execPath, + pnpmEntryPath: resolvePnpmEntry() + }) ctx.provide('desktopProfiles', desktopProfiles) ctx.provide('desktopPnpm', desktopPnpm) + ctx.provide('profileBundlePackageBackend', profileBundlePackageBackend) ctx.effect(() => () => desktopPnpm.dispose(), 'dsh-desktop-market-installer: desktop pnpm') const runProfileCommand = async (args, action) => { diff --git a/packages/dsh-desktop-market-installer/package.json b/packages/dsh-desktop-market-installer/package.json index 999698b8f..af46eef07 100644 --- a/packages/dsh-desktop-market-installer/package.json +++ b/packages/dsh-desktop-market-installer/package.json @@ -20,6 +20,10 @@ "types": "./generations/projection.d.ts", "default": "./generations/projection.mjs" }, + "./generations/package-backend": { + "types": "./generations/package-backend.d.ts", + "default": "./generations/package-backend.mjs" + }, "./market-registry": { "types": "./market-registry.d.ts", "default": "./market-registry.mjs" @@ -39,11 +43,9 @@ "license": "MIT", "peerDependencies": { "@deepseek-ai/cordis": "^4.0.1", - "@deepseek-ai/dsh-settings": "^0.1.5-rc.1", - "@deepseek-ai/dsh-host-webserver": "^0.1.5-rc.1" + "@deepseek-ai/dsh-host-webserver": "^0.1.5-rc.1 || ^0.1.6-alpha.1 || ^0.1.7-rc.1 || ^0.1.7-rc.2" }, "dependencies": { - "@deepseek-ai/schemastery": "^3.18.2", "pnpm": "10.34.5" } } diff --git a/packages/dsh-desktop-preset-transfer/package.json b/packages/dsh-desktop-preset-transfer/package.json index 58bdf0f0e..6b062f821 100644 --- a/packages/dsh-desktop-preset-transfer/package.json +++ b/packages/dsh-desktop-preset-transfer/package.json @@ -18,7 +18,7 @@ }, "peerDependencies": { "@deepseek-ai/cordis": "^4.0.1", - "@deepseek-ai/dsh-agent-presets": "^0.1.5-rc.1", + "@deepseek-ai/dsh-agent-preset-registry": "^0.1.7-rc.1 || ^0.1.7-rc.2", "fflate": "^0.8.2" }, "types": "./index.d.ts" diff --git a/packages/dsh-image-generation/client.js b/packages/dsh-image-generation/client.js index 065e3e858..bf2cec6a8 100644 --- a/packages/dsh-image-generation/client.js +++ b/packages/dsh-image-generation/client.js @@ -2,7 +2,7 @@ window.__ModuleLoader__.load({ id: 'dsh-image-generation', factory: require => { const React = require('react') - const { IconChevronDownOutline14, Menu } = require('@deepseek-ai/dsh-client-ui-primitives') + const { IconChevronDownOutlineRegular, Menu } = require('@deepseek-ai/dsh-client-ui-primitives') const h = React.createElement const NS = 'settings.imageGeneration' const zh = { @@ -102,7 +102,7 @@ window.__ModuleLoader__.load({ onSelect: selected => { if (!disabled) { close(true); onChange(selected) } }, anchor: h('button', { ref: trigger, name, type: 'button', disabled, className: 'dshImageSelectTrigger', 'aria-labelledby': `${id}-label ${id}-value`, 'aria-haspopup': 'menu', 'aria-expanded': open && !disabled, onClick: () => setOpen(previous => !previous) }, - h('span', { id: `${id}-value`, className: 'dshImageSelectValue' }, options.find(option => option.id === value)?.label || value), h(IconChevronDownOutline14)) })) + h('span', { id: `${id}-value`, className: 'dshImageSelectValue' }, options.find(option => option.id === value)?.label || value), h(IconChevronDownOutlineRegular)) })) } function ImageCard({ t, callApi }) { const [expanded, setExpanded] = React.useState(false) @@ -226,10 +226,10 @@ window.__ModuleLoader__.load({ } const field = (key, label, type = 'text', placeholder) => h('label', { className: 'dshImageField', key }, t(label), h('input', { name: key, type, value: draft[key], placeholder, autoComplete: 'off', spellCheck: false, onChange: event => edit(key, event.target.value) })) - return h('li', { className: `dshImageCard${expanded ? ' dshImageCardOpen' : ''}`, 'data-testid': 'image-generation-card' }, + return h('section', { className: `dshImageCard${expanded ? ' dshImageCardOpen' : ''}`, 'data-testid': 'image-generation-card' }, h('button', { className: 'dshImageHeader', type: 'button', 'aria-expanded': expanded, 'aria-controls': `${id}-body`, onClick: () => setExpanded(value => !value) }, h('span', { className: 'dshImageHeading' }, h('span', { className: 'dshImageTitle' }, t('title')), h('span', { className: 'dshImageDescription' }, t('description'))), - h(IconChevronDownOutline14, { className: 'dshImageChevron' })), + h(IconChevronDownOutlineRegular, { className: 'dshImageChevron' })), expanded && h('form', { id: `${id}-body`, className: 'dshImageBody', onSubmit: save, 'aria-busy': busy || fetching || loading }, hostEnabled !== null && h('div', { className: 'dshImageHostControl' }, h('label', null, h('input', { type: 'checkbox', role: 'switch', checked: hostEnabled, disabled: hostBusy, onChange: toggleHost }), t('builtInEnabled')), @@ -346,8 +346,10 @@ window.__ModuleLoader__.load({ document.head.appendChild(style) return () => style.remove() }, 'image-generation styles') - ctx.slots.inject('settings.plugin.item', () => ctx.slots.register({ - name: 'settings.plugin.item', key: 'image-generation', order: -100, locale: NS, + const t = ctx.locale.bind(NS) + ctx.slots.inject('settings.plugins.tab', () => ctx.slots.register({ + name: 'settings.plugins.tab', id: 'image-generation', order: -100, locale: NS, + label: () => t('title'), inject: () => ({ callApi }), }, ImageCard)) }, diff --git a/packages/dsh-image-generation/package.json b/packages/dsh-image-generation/package.json index b19eb3603..6f727ec0c 100644 --- a/packages/dsh-image-generation/package.json +++ b/packages/dsh-image-generation/package.json @@ -56,15 +56,15 @@ }, "peerDependencies": { "@deepseek-ai/cordis": "^4.0.2", - "@deepseek-ai/dsh-client-connection": "^0.1.2-rc.1", - "@deepseek-ai/dsh-credentials": "^0.1.2-rc.1", - "@deepseek-ai/dsh-sandbox-policy": "^0.1.2-rc.1", - "@deepseek-ai/dsh-sandbox": "^0.1.2-rc.1", - "@deepseek-ai/dsh-subprocess": "^0.1.2-rc.1", - "@deepseek-ai/dsh-settings": "^0.1.2-rc.1", - "@deepseek-ai/dsh-skill": "^0.1.2-rc.1", - "@deepseek-ai/dsh-system-prompt": "^0.1.2-rc.1", - "@deepseek-ai/dsh-tools": "^0.1.2-rc.1", - "@deepseek-ai/dsh-api-session-controller": "^0.1.2-rc.1" + "@deepseek-ai/dsh-client-connection": "^0.1.2-rc.1 || ^0.1.7-rc.1 || ^0.1.7-rc.2", + "@deepseek-ai/dsh-credentials": "^0.1.2-rc.1 || ^0.1.7-rc.1 || ^0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox-policy": "^0.1.2-rc.1 || ^0.1.7-rc.1 || ^0.1.7-rc.2", + "@deepseek-ai/dsh-sandbox": "^0.1.2-rc.1 || ^0.1.7-rc.1 || ^0.1.7-rc.2", + "@deepseek-ai/dsh-subprocess": "^0.1.2-rc.1 || ^0.1.7-rc.1 || ^0.1.7-rc.2", + "@deepseek-ai/dsh-settings": "^0.1.2-rc.1 || ^0.1.7-rc.1 || ^0.1.7-rc.2", + "@deepseek-ai/dsh-skill": "^0.1.2-rc.1 || ^0.1.7-rc.1 || ^0.1.7-rc.2", + "@deepseek-ai/dsh-system-prompt": "^0.1.2-rc.1 || ^0.1.7-rc.1 || ^0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "^0.1.2-rc.1 || ^0.1.7-rc.1 || ^0.1.7-rc.2", + "@deepseek-ai/dsh-api-session-controller": "^0.1.2-rc.1 || ^0.1.7-rc.1 || ^0.1.7-rc.2" } } diff --git a/packages/ppt-runtime/README.md b/packages/ppt-runtime/README.md index e61c0a2f9..c4a2970d5 100644 --- a/packages/ppt-runtime/README.md +++ b/packages/ppt-runtime/README.md @@ -1,6 +1,6 @@ # Maintained DSH PPT runtime -Product packages: **`dsh-ppt`** (authoring/export) and **`dsh-ppt-composer`** (PPT button/template chooser). Their pinned distributions live in `../ppt-bundles/`. +Product packages: **`dsh-ppt`** (authoring/export) and **`dsh-ppt-composer`** (PPT button/template chooser). The repository keeps their maintained runtime seeds and generator inputs, while every dev, test, build and package run assembles complete distributions under the ignored `.build/ppt-runtime/packages/` staging root. This directory maintains the distributed JavaScript extracted at Desktop base `9d4502f`; the complete original TypeScript source was not present. Original copyright notices and factual Kimi Slides research attribution remain in `THIRD_PARTY_NOTICES.md`. Renaming does not change provenance or establish legal clearance. @@ -20,12 +20,14 @@ Every metadata/design record contains English and Chinese title/body fonts and p ## Build and install -`npm run ppt:build` regenerates the ten Zara packs, restores the six maintained baseline packs from `scripts/ppt/base-templates/`, applies reviewed English translations, and expands all sixteen packs to twelve layouts each. It validates and renders the 192 English previews and builds both archives. `artifacts.json` records their hashes. The baseline inputs are separate from generated `source/` and `source-zh/`, so consecutive builds do not translate enriched output again. Every pack retains explicit English/Chinese font pairs. The two original experiments live in `scripts/ppt/rich-layouts.mjs`; the other composition plans and editable geometry live in `scripts/ppt/composition-library.mjs`. +`npm run ppt:build` starts from an empty `.build/ppt-runtime/` directory, regenerates the ten Zara packs, restores the six maintained baseline packs from `scripts/ppt/base-templates/`, applies reviewed English translations, and expands all sixteen packs to twelve layouts each. It validates and renders the 192 English previews, hydrates the runtime clients/catalog, assembles both package directories, then atomically projects those directories into `node_modules` for local execution. It never writes generated templates, previews, archives or hash manifests back into tracked source paths. Every pack retains explicit English/Chinese font pairs. The two original experiments live in `scripts/ppt/rich-layouts.mjs`; the other composition plans and editable geometry live in `scripts/ppt/composition-library.mjs`. -After rebuilding, refresh both dependency integrity entries in `package-lock.json`, then use `npm ci` and the normal postinstall flow. Tests verify the exact archives, language coverage, fonts, activation and state migration. The 23 withdrawn designs and 345 excluded images remain absent; `excluded-assets.json` is a hash-only regression list. +`npm ci` bootstraps from the tracked local package seeds, so a clean checkout does not need a pre-existing archive. The `dev`, `build` and `test` lifecycles all invoke the same preparation step; every package script delegates to `build`. Electron Builder excludes the bootstrap links and copies the current staged packages explicitly. Tests verify the generated distributions, language coverage, fonts, activation and state migration. The 23 withdrawn designs and 345 excluded images remain absent; `excluded-assets.json` is a hash-only regression list. ## Compatibility +For Harness `0.1.7-rc.1`, the chooser uses `conversation.hero.dock` (list, session-maybe, InputZone owner) before a session exists and the existing session-only `conversation.composer.dock` afterwards. The hero outlet belongs to ConversationContent and sits after its input bar; it must not be rendered inside the independently registered InputBar. Only one chooser outlet is active at a time, sharing the mode-button store. The panel measures the composer card width because the upstream session dock can shrink to its content width. The conversation patch can drop the extra hero outlet when Harness provides an equivalent public pre-session outlet. + The built-in profile loads one `dsh-ppt-composer` plugin. The Skill, new automatic context records, client registration and primary RPC use DSH names. Historical attribution is kept in notices and an entry-point comment. Desktop's startup bundle reconciliation removes `dsh-ppt` and `dsh-ppt-composer` from the normal Profile's extra bundle list: the Desktop patch already loads the composer, which mounts the core. This prevents duplicate preview routes and the `dsh-ppt-bundled` skill provider when a Profile also declares these packages. Dependencies, installed packages, user patch files and existing `kimi-ppt` projects are retained. Custom patch rows are not rewritten; this reconciliation handles standard bundle declarations only. Standalone Harness profiles do not opt into Desktop's bundle ownership. @@ -42,9 +44,7 @@ The host stores source PPTX, editable PPTD pages, assets, previews and conversio `ppt_template_create_project` copies the selected personal template into a new confined workspace directory. The model then adapts that copy with the existing PPTD tools and exports through `pptd_render`. The saved source remains separate from generated task files. All conversion and copy operations use the existing bounded parser/compiler and host audit. Company template fidelity requires review of actual imported pages, particularly master elements and advanced Office objects. Product rules and evidence: [Personal PPT templates](../../docs/ppt-personal-templates.md). -For runtime-only changes, `node scripts/build-ppt-runtime.mjs --reuse-previews` validates all built-in source decks and packages their existing reviewed previews. A full `npm run ppt:build` regenerates the built-in assets. - -Validation evidence and temporary exports live under ignored `doc/ppt-remediation/`. Windows packaging and native Windows PowerPoint require their own runner/device validation. +Generated templates, previews, package directories and build diagnostics live under ignored `.build/ppt-runtime/`. Validation evidence and temporary exports live under ignored `doc/ppt-remediation/`. Windows packaging and native Windows PowerPoint require their own runner/device validation. ### Layout refinement diff --git a/packages/ppt-runtime/adapter/lib/client.js b/packages/ppt-runtime/adapter/lib/client.js index ca542f081..ff5dcaa70 100644 --- a/packages/ppt-runtime/adapter/lib/client.js +++ b/packages/ppt-runtime/adapter/lib/client.js @@ -24,7 +24,7 @@ window.__ModuleLoader__.load({ const CURATED_TEMPLATE_PREVIEWS = /* GENERATED_PPT_PREVIEWS */ {}; //#endregion //#region \0dsh-css:ppt-composer.css.mjs - const css = "._2S_x-q_modeRoot{box-sizing:border-box;width:100%;padding:0 var(--dsh-composer-side-clearance);position:relative}._2S_x-q_modeRow{flex-wrap:wrap;justify-content:flex-start;align-items:center;gap:8px;min-height:32px;display:flex}._2S_x-q_modeChip{border:1px solid var(--dsw-alias-border-l2-darkmode-thin);color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;background:0 0;border-radius:999px;align-items:center;gap:6px;padding:7px 13px;font-size:12px;line-height:16px;display:inline-flex}._2S_x-q_modeChip:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}._2S_x-q_modeChip[data-selected=true]{border-color:color-mix(in srgb, var(--dsw-alias-state-business-primary) 55%, transparent);background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 12%, transparent);color:var(--dsw-alias-state-business-primary)}._2S_x-q_templatePanel{box-sizing:border-box;z-index:2;width:100%;max-width:calc(var(--dsh-composer-card-max-width) + 32px);height:var(--office-ppt-template-panel-height,calc(100dvh - 178px));max-height:var(--office-ppt-template-panel-height,calc(100dvh - 178px));background:0 0;flex-direction:column;margin-top:8px;display:flex;position:absolute;top:100%;left:50%;overflow:hidden;transform:translate(-50%)}._2S_x-q_modeRoot[data-placement=fixed]{height:0;overflow:visible}._2S_x-q_modeRoot[data-placement=fixed] ._2S_x-q_templatePanel{max-height:none;top:0}._2S_x-q_modeRoot[data-placement=fixed] ._2S_x-q_templateViewport{overscroll-behavior:contain;flex:auto;padding-bottom:12px;overflow-y:auto}._2S_x-q_templateToolbar{padding-inline:4px;z-index:2;background:0 0;flex:none;justify-content:space-between;align-items:center;gap:12px;min-height:38px;display:flex;position:relative}._2S_x-q_templateViewport{box-sizing:border-box;overscroll-behavior:contain;scrollbar-width:none;min-height:0;padding:4px 4px 12px;overflow-x:hidden;overflow-y:auto}._2S_x-q_templateViewport::-webkit-scrollbar{display:none}._2S_x-q_categoryTabs{scrollbar-width:none;gap:4px;min-width:0;display:flex;overflow-x:auto}._2S_x-q_categoryTabs::-webkit-scrollbar{display:none}._2S_x-q_categoryTabs button{color:var(--dsw-alias-label-caption);font:inherit;cursor:pointer;background:0 0;border:0;border-radius:999px;flex:none;padding:5px 10px;font-size:11px;line-height:16px}._2S_x-q_categoryTabs button:hover{color:var(--dsw-alias-label-primary)}._2S_x-q_categoryTabs button[data-selected=true]{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}._2S_x-q_templateGrid{background:0 0;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px 14px;display:grid}._2S_x-q_templateCard{min-width:0;min-height:0;position:relative}._2S_x-q_templateSelect{width:100%;min-width:0;color:var(--dsw-alias-label-tertiary);font:inherit;cursor:pointer;background:0 0;border:0;outline:0;flex-direction:column;padding:0;display:flex}._2S_x-q_previewViewport,._2S_x-q_selectionPreview{container-type:inline-size}._2S_x-q_previewViewport{box-sizing:border-box;aspect-ratio:16/9;border:2px solid #0000;border-radius:9px;width:100%;transition:border-color .12s,transform .12s;display:block;position:relative;overflow:hidden}._2S_x-q_previewViewport>._2S_x-q_preview{aspect-ratio:auto;width:100%;height:100%;animation:.18s _2S_x-q_previewReveal}@keyframes _2S_x-q_previewReveal{0%{opacity:.72}to{opacity:1}}._2S_x-q_templateCard:hover ._2S_x-q_previewViewport{transform:translateY(-1px)}._2S_x-q_templateSelect:active ._2S_x-q_previewViewport{transform:scale(.985)}._2S_x-q_templateCard[data-selected=true] ._2S_x-q_previewViewport{border-color:var(--dsw-alias-state-business-primary)}._2S_x-q_templateSelect:focus-visible ._2S_x-q_previewViewport{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}._2S_x-q_templateName{text-align:center;text-overflow:ellipsis;white-space:nowrap;padding-top:5px;font-size:12px;line-height:16px;overflow:hidden}._2S_x-q_templateCard[data-selected=true] ._2S_x-q_templateName{color:var(--dsw-alias-label-primary)}._2S_x-q_panelState{min-height:160px;color:var(--dsw-alias-label-tertiary);place-items:center;gap:10px;font-size:12px;display:grid}._2S_x-q_templateError{border:1px solid color-mix(in srgb, var(--dsw-alias-state-error-primary) 40%, transparent);background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 10%, transparent);color:var(--dsw-alias-state-error-primary);border-radius:8px;margin-bottom:8px;padding:7px 10px;font-size:11px;line-height:16px}._2S_x-q_retryButton{border:1px solid var(--dsw-alias-border-l2-darkmode-thin);color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;background:0 0;border-radius:999px;padding:6px 12px}._2S_x-q_retryButton:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}._2S_x-q_selection{align-items:flex-start;display:flex}._2S_x-q_selectionPreview{aspect-ratio:16/9;transform-origin:50%;flex:none;width:clamp(76px,10vw,92px);transition:transform .2s cubic-bezier(.34,1.56,.64,1);display:block;position:relative;transform:rotate(-3deg)scale(1)}._2S_x-q_selectionFrame{border:2px solid var(--dsw-alias-state-business-primary);background:var(--dsw-alias-bg-base);border-radius:9px;width:100%;height:100%;display:block;overflow:hidden;box-shadow:0 4px 14px #0000002e}._2S_x-q_selectionRemove{z-index:2;color:#fff;opacity:0;pointer-events:none;cursor:pointer;background:#111111e0;border:1px solid #ffffff4d;border-radius:50%;place-items:center;width:20px;height:20px;padding:0;font:500 15px/1 ui-sans-serif,system-ui,sans-serif;transition:opacity .12s,transform .12s;display:grid;position:absolute;top:-8px;right:-8px;transform:rotate(3deg)scale(.88);box-shadow:0 3px 10px #00000047}._2S_x-q_selectionPreview:hover ._2S_x-q_selectionRemove,._2S_x-q_selectionPreview:focus-within ._2S_x-q_selectionRemove{opacity:1;pointer-events:auto;transform:rotate(3deg)scale(1)}._2S_x-q_selectionRemove:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}._2S_x-q_preview{box-sizing:border-box;aspect-ratio:16/9;background:var(--office-bg);color:var(--office-text);flex-direction:column;justify-content:center;padding:12% 10%;display:flex;position:relative;overflow:hidden}._2S_x-q_preview[data-source-preview=true]{background:#fff;padding:0}._2S_x-q_preview[data-source-preview=true]:before,._2S_x-q_preview[data-source-preview=true]:after{display:none}._2S_x-q_previewImage{object-fit:cover;-webkit-user-drag:none;width:100%;height:100%;display:block;position:absolute;inset:0}._2S_x-q_preview:before,._2S_x-q_preview:after{content:\"\";pointer-events:none;position:absolute}._2S_x-q_preview:before{border-left:1px solid color-mix(in srgb, var(--office-accent) 35%, transparent);background:color-mix(in srgb, var(--office-surface) 92%, transparent);width:34%;height:100%;top:0;right:0}._2S_x-q_preview:after{background:var(--office-accent);width:18%;height:clamp(1px,1.3cqi,3px);bottom:13%;right:8%}._2S_x-q_previewAccent{background:var(--office-accent);width:18%;height:clamp(1px,1.3cqi,3px);position:absolute;top:16%;left:10%}._2S_x-q_preview strong,._2S_x-q_preview small{z-index:1;text-overflow:ellipsis;white-space:nowrap;width:66%;display:block;position:relative;overflow:hidden}._2S_x-q_preview strong{margin-top:8%;font-size:clamp(4px,6cqi,14px);font-weight:650;line-height:1.12}._2S_x-q_preview small{color:var(--office-muted);margin-top:4px;font-size:clamp(3px,3.4cqi,8px)}._2S_x-q_preview[data-variant=blue-professional]:before{clip-path:polygon(25% 0,100% 0,100% 100%,0 100%);background:var(--office-surface);border:0;width:40%}._2S_x-q_preview[data-variant=blue-professional]:after{width:15%;height:2px;bottom:14%;right:8%}._2S_x-q_preview[data-variant=editorial-forest]{background:var(--office-surface);color:var(--office-accent);justify-content:flex-end;padding:10%;font-family:Georgia,Times New Roman,serif}._2S_x-q_preview[data-variant=editorial-forest]:before{aspect-ratio:1;border:1px solid var(--office-accent);background:0 0;border-radius:50%;width:16%;height:auto;top:11%;right:9%}._2S_x-q_preview[data-variant=editorial-forest]:after{background:var(--office-accent);width:80%;height:1px;bottom:10%;right:10%}._2S_x-q_preview[data-variant=editorial-forest] ._2S_x-q_previewAccent{background:var(--office-accent);width:26%;height:1px;top:13%}._2S_x-q_preview[data-variant=editorial-forest] strong,._2S_x-q_preview[data-variant=editorial-forest] small{width:78%}._2S_x-q_preview[data-variant=editorial-forest] strong{margin-bottom:11%;font-size:clamp(5px,7.4cqi,17px);font-weight:500}._2S_x-q_preview[data-variant=editorial-forest] small{color:var(--office-bg);font-family:ui-monospace,SFMono-Regular,Menlo,monospace;position:absolute;top:16%;left:10%}._2S_x-q_preview[data-variant=signal]{background:var(--office-bg);color:var(--office-text);font-family:Georgia,Times New Roman,serif}._2S_x-q_preview[data-variant=signal]:before{background-image:linear-gradient(color-mix(in srgb, var(--office-secondary) 55%, transparent) 1px, transparent 1px), linear-gradient(90deg, color-mix(in srgb, var(--office-secondary) 55%, transparent) 1px, transparent 1px);opacity:.45;background-size:18% 31%;border:0;width:100%;height:100%;inset:0}._2S_x-q_preview[data-variant=signal]:after{background:var(--office-secondary);width:80%;height:1px;bottom:15%;left:10%;right:auto}._2S_x-q_preview[data-variant=signal] ._2S_x-q_previewAccent{background:var(--office-accent);width:14%;height:1px;top:18%}._2S_x-q_preview[data-variant=signal] strong{font-size:clamp(5px,6.8cqi,16px);font-weight:600}._2S_x-q_preview[data-variant=signal] small{color:var(--office-muted);letter-spacing:.08em;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}._2S_x-q_preview[data-variant=orange-data]{color:#111;background:#fff;justify-content:flex-start;padding:15% 8%;font-family:Arial,sans-serif}._2S_x-q_preview[data-variant=orange-data]:before{background:linear-gradient(90deg, var(--office-accent) 0 25%, var(--office-secondary) 25% 50%, #f19309 50% 75%, #f9c22b 75%) 0 21% / 100% 28% no-repeat, linear-gradient(#f2f2f2 0 0) 0 70% / 72% 24% no-repeat;border:0;border-top:clamp(1px,.9cqi,2px) solid #111;width:84%;height:45%;inset:8% 8% auto}._2S_x-q_preview[data-variant=orange-data]:after{background:#111;width:84%;height:11%;bottom:11%;right:8%}._2S_x-q_preview[data-variant=orange-data] ._2S_x-q_previewAccent{background:var(--office-accent);width:22%;height:clamp(1px,.9cqi,2px);top:8%;left:8%}._2S_x-q_preview[data-variant=orange-data] strong,._2S_x-q_preview[data-variant=orange-data] small{z-index:2;width:52%}._2S_x-q_preview[data-variant=orange-data] strong{margin-top:10%;font-size:clamp(4px,5.8cqi,13px)}._2S_x-q_preview[data-variant=orange-data] small{color:#5b626d;letter-spacing:.06em;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}._2S_x-q_preview[data-variant=custom]:before{background:linear-gradient(145deg, var(--office-surface), var(--office-secondary));width:40%}._2S_x-q_preview[data-page=\"1\"],._2S_x-q_preview[data-page=\"2\"]{background:color-mix(in srgb, var(--office-bg) 92%, var(--office-surface));color:var(--office-text);font-family:var(--font-sans,ui-sans-serif, system-ui, sans-serif);justify-content:flex-start;padding:8% 8% 7%}._2S_x-q_preview[data-page=\"1\"]:before,._2S_x-q_preview[data-page=\"2\"]:before{background:linear-gradient(90deg, color-mix(in srgb, var(--office-accent) 13%, transparent) 1px, transparent 1px), linear-gradient(color-mix(in srgb, var(--office-accent) 13%, transparent) 1px, transparent 1px);clip-path:none;opacity:.48;background-size:20% 25%;border:0;width:100%;height:100%;inset:0}._2S_x-q_preview[data-page=\"1\"]:after,._2S_x-q_preview[data-page=\"2\"]:after{background:var(--office-accent);width:18%;height:2px;top:8%;bottom:auto;right:8%}._2S_x-q_preview[data-page=\"1\"] ._2S_x-q_previewAccent,._2S_x-q_preview[data-page=\"2\"] ._2S_x-q_previewAccent{background:color-mix(in srgb, var(--office-muted) 38%, transparent);width:84%;height:1px;top:auto;bottom:7%;left:8%}._2S_x-q_preview[data-page=\"1\"] strong,._2S_x-q_preview[data-page=\"2\"] strong{width:78%;margin-top:3%;font-size:clamp(4px,5.3cqi,12px);line-height:1.12}._2S_x-q_previewEyebrow{letter-spacing:.06em;width:74%!important;color:var(--office-muted)!important;margin:0!important;font:500 clamp(3px,2.7cqi,6px)/1.1 ui-monospace,SFMono-Regular,Menlo,monospace!important}._2S_x-q_previewKpis{z-index:1;grid-template-columns:repeat(3,minmax(0,1fr));gap:4px;width:100%;margin-top:auto;display:grid;position:relative}._2S_x-q_previewKpis>span{border:1px solid color-mix(in srgb, var(--office-accent) 18%, transparent);background:color-mix(in srgb, var(--office-surface) 88%, transparent);border-radius:3px;justify-content:space-between;align-items:baseline;min-width:0;padding:7% 8%;display:flex}._2S_x-q_previewKpis b{font-size:clamp(4px,4.8cqi,11px);font-weight:700}._2S_x-q_previewKpis i{color:var(--office-muted);font:clamp(2px,2.2cqi,5px)/1 ui-monospace,monospace}._2S_x-q_previewFooter,._2S_x-q_previewInsight{z-index:1;width:100%;color:var(--office-muted);text-overflow:ellipsis;white-space:nowrap;margin-top:4px;font-size:clamp(2px,2.3cqi,5px);line-height:1.15;display:block;position:relative;overflow:hidden}._2S_x-q_previewChart{z-index:1;border-bottom:1px solid color-mix(in srgb, var(--office-muted) 34%, transparent);align-items:flex-end;gap:7%;height:43%;margin-top:auto;padding:4% 5% 0;display:flex;position:relative}._2S_x-q_previewChart i{background:var(--office-accent);border-radius:2px 2px 0 0;width:11%}._2S_x-q_previewChart i:first-child{opacity:.52;height:28%}._2S_x-q_previewChart i:nth-child(2){opacity:.64;height:46%}._2S_x-q_previewChart i:nth-child(3){opacity:.76;height:41%}._2S_x-q_previewChart i:nth-child(4){opacity:.88;height:72%}._2S_x-q_previewChart i:nth-child(5){height:91%}@media (prefers-reduced-motion:reduce){._2S_x-q_previewViewport,._2S_x-q_selectionPreview{transition:none}._2S_x-q_previewViewport>._2S_x-q_preview{animation:none}}"; + const css = "._2S_x-q_modeRoot{box-sizing:border-box;width:100%;padding:0 var(--dsh-composer-side-clearance);position:relative}._2S_x-q_modeRow{flex-wrap:wrap;justify-content:flex-start;align-items:center;gap:8px;min-height:32px;display:flex}._2S_x-q_modeChip{border:1px solid var(--dsw-alias-border-l2-darkmode-thin);color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;background:0 0;border-radius:999px;align-items:center;gap:6px;padding:7px 13px;font-size:12px;line-height:16px;display:inline-flex}._2S_x-q_modeChip:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}._2S_x-q_modeChip[data-selected=true]{border-color:color-mix(in srgb, var(--dsw-alias-state-business-primary) 55%, transparent);background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 12%, transparent);color:var(--dsw-alias-state-business-primary)}._2S_x-q_templatePanel{box-sizing:border-box;z-index:2;width:100%;max-width:calc(var(--dsh-composer-card-max-width) + 32px);height:var(--office-ppt-template-panel-height,calc(100dvh - 178px));max-height:var(--office-ppt-template-panel-height,calc(100dvh - 178px));background:0 0;flex-direction:column;margin-top:8px;display:flex;position:absolute;top:100%;left:50%;overflow:hidden;transform:translate(-50%)}._2S_x-q_modeRoot[data-placement=fixed]{height:0;overflow:visible}._2S_x-q_modeRoot[data-placement=fixed] ._2S_x-q_templatePanel{width:var(--office-ppt-template-panel-width,var(--dsh-composer-card-max-width));max-height:none;top:0}._2S_x-q_modeRoot[data-placement=fixed] ._2S_x-q_templateViewport{overscroll-behavior:contain;flex:auto;padding-bottom:12px;overflow-y:auto}._2S_x-q_templateToolbar{padding-inline:4px;z-index:2;background:0 0;flex:none;justify-content:space-between;align-items:center;gap:12px;min-height:38px;display:flex;position:relative}._2S_x-q_templateViewport{box-sizing:border-box;overscroll-behavior:contain;scrollbar-width:none;min-height:0;padding:4px 4px 12px;overflow-x:hidden;overflow-y:auto}._2S_x-q_templateViewport::-webkit-scrollbar{display:none}._2S_x-q_categoryTabs{scrollbar-width:none;gap:4px;min-width:0;display:flex;overflow-x:auto}._2S_x-q_categoryTabs::-webkit-scrollbar{display:none}._2S_x-q_categoryTabs button{color:var(--dsw-alias-label-caption);font:inherit;cursor:pointer;background:0 0;border:0;border-radius:999px;flex:none;padding:5px 10px;font-size:11px;line-height:16px}._2S_x-q_categoryTabs button:hover{color:var(--dsw-alias-label-primary)}._2S_x-q_categoryTabs button[data-selected=true]{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}._2S_x-q_templateGrid{background:0 0;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px 14px;display:grid}._2S_x-q_templateCard{min-width:0;min-height:0;position:relative}._2S_x-q_templateSelect{width:100%;min-width:0;color:var(--dsw-alias-label-tertiary);font:inherit;cursor:pointer;background:0 0;border:0;outline:0;flex-direction:column;padding:0;display:flex}._2S_x-q_previewViewport,._2S_x-q_selectionPreview{container-type:inline-size}._2S_x-q_previewViewport{box-sizing:border-box;aspect-ratio:16/9;border:2px solid #0000;border-radius:9px;width:100%;transition:border-color .12s,transform .12s;display:block;position:relative;overflow:hidden}._2S_x-q_previewViewport>._2S_x-q_preview{aspect-ratio:auto;width:100%;height:100%;animation:.18s _2S_x-q_previewReveal}@keyframes _2S_x-q_previewReveal{0%{opacity:.72}to{opacity:1}}._2S_x-q_templateCard:hover ._2S_x-q_previewViewport{transform:translateY(-1px)}._2S_x-q_templateSelect:active ._2S_x-q_previewViewport{transform:scale(.985)}._2S_x-q_templateCard[data-selected=true] ._2S_x-q_previewViewport{border-color:var(--dsw-alias-state-business-primary)}._2S_x-q_templateSelect:focus-visible ._2S_x-q_previewViewport{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}._2S_x-q_templateName{text-align:center;text-overflow:ellipsis;white-space:nowrap;padding-top:5px;font-size:12px;line-height:16px;overflow:hidden}._2S_x-q_templateCard[data-selected=true] ._2S_x-q_templateName{color:var(--dsw-alias-label-primary)}._2S_x-q_panelState{min-height:160px;color:var(--dsw-alias-label-tertiary);place-items:center;gap:10px;font-size:12px;display:grid}._2S_x-q_templateError{border:1px solid color-mix(in srgb, var(--dsw-alias-state-error-primary) 40%, transparent);background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 10%, transparent);color:var(--dsw-alias-state-error-primary);border-radius:8px;margin-bottom:8px;padding:7px 10px;font-size:11px;line-height:16px}._2S_x-q_retryButton{border:1px solid var(--dsw-alias-border-l2-darkmode-thin);color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;background:0 0;border-radius:999px;padding:6px 12px}._2S_x-q_retryButton:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}._2S_x-q_selection{align-items:flex-start;display:flex}._2S_x-q_selectionPreview{aspect-ratio:16/9;transform-origin:50%;flex:none;width:clamp(76px,10vw,92px);transition:transform .2s cubic-bezier(.34,1.56,.64,1);display:block;position:relative;transform:rotate(-3deg)scale(1)}._2S_x-q_selectionFrame{border:2px solid var(--dsw-alias-state-business-primary);background:var(--dsw-alias-bg-base);border-radius:9px;width:100%;height:100%;display:block;overflow:hidden;box-shadow:0 4px 14px #0000002e}._2S_x-q_selectionRemove{z-index:2;color:#fff;opacity:0;pointer-events:none;cursor:pointer;background:#111111e0;border:1px solid #ffffff4d;border-radius:50%;place-items:center;width:20px;height:20px;padding:0;font:500 15px/1 ui-sans-serif,system-ui,sans-serif;transition:opacity .12s,transform .12s;display:grid;position:absolute;top:-8px;right:-8px;transform:rotate(3deg)scale(.88);box-shadow:0 3px 10px #00000047}._2S_x-q_selectionPreview:hover ._2S_x-q_selectionRemove,._2S_x-q_selectionPreview:focus-within ._2S_x-q_selectionRemove{opacity:1;pointer-events:auto;transform:rotate(3deg)scale(1)}._2S_x-q_selectionRemove:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}._2S_x-q_preview{box-sizing:border-box;aspect-ratio:16/9;background:var(--office-bg);color:var(--office-text);flex-direction:column;justify-content:center;padding:12% 10%;display:flex;position:relative;overflow:hidden}._2S_x-q_preview[data-source-preview=true]{background:#fff;padding:0}._2S_x-q_preview[data-source-preview=true]:before,._2S_x-q_preview[data-source-preview=true]:after{display:none}._2S_x-q_previewImage{object-fit:cover;-webkit-user-drag:none;width:100%;height:100%;display:block;position:absolute;inset:0}._2S_x-q_preview:before,._2S_x-q_preview:after{content:\"\";pointer-events:none;position:absolute}._2S_x-q_preview:before{border-left:1px solid color-mix(in srgb, var(--office-accent) 35%, transparent);background:color-mix(in srgb, var(--office-surface) 92%, transparent);width:34%;height:100%;top:0;right:0}._2S_x-q_preview:after{background:var(--office-accent);width:18%;height:clamp(1px,1.3cqi,3px);bottom:13%;right:8%}._2S_x-q_previewAccent{background:var(--office-accent);width:18%;height:clamp(1px,1.3cqi,3px);position:absolute;top:16%;left:10%}._2S_x-q_preview strong,._2S_x-q_preview small{z-index:1;text-overflow:ellipsis;white-space:nowrap;width:66%;display:block;position:relative;overflow:hidden}._2S_x-q_preview strong{margin-top:8%;font-size:clamp(4px,6cqi,14px);font-weight:650;line-height:1.12}._2S_x-q_preview small{color:var(--office-muted);margin-top:4px;font-size:clamp(3px,3.4cqi,8px)}._2S_x-q_preview[data-variant=blue-professional]:before{clip-path:polygon(25% 0,100% 0,100% 100%,0 100%);background:var(--office-surface);border:0;width:40%}._2S_x-q_preview[data-variant=blue-professional]:after{width:15%;height:2px;bottom:14%;right:8%}._2S_x-q_preview[data-variant=editorial-forest]{background:var(--office-surface);color:var(--office-accent);justify-content:flex-end;padding:10%;font-family:Georgia,Times New Roman,serif}._2S_x-q_preview[data-variant=editorial-forest]:before{aspect-ratio:1;border:1px solid var(--office-accent);background:0 0;border-radius:50%;width:16%;height:auto;top:11%;right:9%}._2S_x-q_preview[data-variant=editorial-forest]:after{background:var(--office-accent);width:80%;height:1px;bottom:10%;right:10%}._2S_x-q_preview[data-variant=editorial-forest] ._2S_x-q_previewAccent{background:var(--office-accent);width:26%;height:1px;top:13%}._2S_x-q_preview[data-variant=editorial-forest] strong,._2S_x-q_preview[data-variant=editorial-forest] small{width:78%}._2S_x-q_preview[data-variant=editorial-forest] strong{margin-bottom:11%;font-size:clamp(5px,7.4cqi,17px);font-weight:500}._2S_x-q_preview[data-variant=editorial-forest] small{color:var(--office-bg);font-family:ui-monospace,SFMono-Regular,Menlo,monospace;position:absolute;top:16%;left:10%}._2S_x-q_preview[data-variant=signal]{background:var(--office-bg);color:var(--office-text);font-family:Georgia,Times New Roman,serif}._2S_x-q_preview[data-variant=signal]:before{background-image:linear-gradient(color-mix(in srgb, var(--office-secondary) 55%, transparent) 1px, transparent 1px), linear-gradient(90deg, color-mix(in srgb, var(--office-secondary) 55%, transparent) 1px, transparent 1px);opacity:.45;background-size:18% 31%;border:0;width:100%;height:100%;inset:0}._2S_x-q_preview[data-variant=signal]:after{background:var(--office-secondary);width:80%;height:1px;bottom:15%;left:10%;right:auto}._2S_x-q_preview[data-variant=signal] ._2S_x-q_previewAccent{background:var(--office-accent);width:14%;height:1px;top:18%}._2S_x-q_preview[data-variant=signal] strong{font-size:clamp(5px,6.8cqi,16px);font-weight:600}._2S_x-q_preview[data-variant=signal] small{color:var(--office-muted);letter-spacing:.08em;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}._2S_x-q_preview[data-variant=orange-data]{color:#111;background:#fff;justify-content:flex-start;padding:15% 8%;font-family:Arial,sans-serif}._2S_x-q_preview[data-variant=orange-data]:before{background:linear-gradient(90deg, var(--office-accent) 0 25%, var(--office-secondary) 25% 50%, #f19309 50% 75%, #f9c22b 75%) 0 21% / 100% 28% no-repeat, linear-gradient(#f2f2f2 0 0) 0 70% / 72% 24% no-repeat;border:0;border-top:clamp(1px,.9cqi,2px) solid #111;width:84%;height:45%;inset:8% 8% auto}._2S_x-q_preview[data-variant=orange-data]:after{background:#111;width:84%;height:11%;bottom:11%;right:8%}._2S_x-q_preview[data-variant=orange-data] ._2S_x-q_previewAccent{background:var(--office-accent);width:22%;height:clamp(1px,.9cqi,2px);top:8%;left:8%}._2S_x-q_preview[data-variant=orange-data] strong,._2S_x-q_preview[data-variant=orange-data] small{z-index:2;width:52%}._2S_x-q_preview[data-variant=orange-data] strong{margin-top:10%;font-size:clamp(4px,5.8cqi,13px)}._2S_x-q_preview[data-variant=orange-data] small{color:#5b626d;letter-spacing:.06em;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}._2S_x-q_preview[data-variant=custom]:before{background:linear-gradient(145deg, var(--office-surface), var(--office-secondary));width:40%}._2S_x-q_preview[data-page=\"1\"],._2S_x-q_preview[data-page=\"2\"]{background:color-mix(in srgb, var(--office-bg) 92%, var(--office-surface));color:var(--office-text);font-family:var(--font-sans,ui-sans-serif, system-ui, sans-serif);justify-content:flex-start;padding:8% 8% 7%}._2S_x-q_preview[data-page=\"1\"]:before,._2S_x-q_preview[data-page=\"2\"]:before{background:linear-gradient(90deg, color-mix(in srgb, var(--office-accent) 13%, transparent) 1px, transparent 1px), linear-gradient(color-mix(in srgb, var(--office-accent) 13%, transparent) 1px, transparent 1px);clip-path:none;opacity:.48;background-size:20% 25%;border:0;width:100%;height:100%;inset:0}._2S_x-q_preview[data-page=\"1\"]:after,._2S_x-q_preview[data-page=\"2\"]:after{background:var(--office-accent);width:18%;height:2px;top:8%;bottom:auto;right:8%}._2S_x-q_preview[data-page=\"1\"] ._2S_x-q_previewAccent,._2S_x-q_preview[data-page=\"2\"] ._2S_x-q_previewAccent{background:color-mix(in srgb, var(--office-muted) 38%, transparent);width:84%;height:1px;top:auto;bottom:7%;left:8%}._2S_x-q_preview[data-page=\"1\"] strong,._2S_x-q_preview[data-page=\"2\"] strong{width:78%;margin-top:3%;font-size:clamp(4px,5.3cqi,12px);line-height:1.12}._2S_x-q_previewEyebrow{letter-spacing:.06em;width:74%!important;color:var(--office-muted)!important;margin:0!important;font:500 clamp(3px,2.7cqi,6px)/1.1 ui-monospace,SFMono-Regular,Menlo,monospace!important}._2S_x-q_previewKpis{z-index:1;grid-template-columns:repeat(3,minmax(0,1fr));gap:4px;width:100%;margin-top:auto;display:grid;position:relative}._2S_x-q_previewKpis>span{border:1px solid color-mix(in srgb, var(--office-accent) 18%, transparent);background:color-mix(in srgb, var(--office-surface) 88%, transparent);border-radius:3px;justify-content:space-between;align-items:baseline;min-width:0;padding:7% 8%;display:flex}._2S_x-q_previewKpis b{font-size:clamp(4px,4.8cqi,11px);font-weight:700}._2S_x-q_previewKpis i{color:var(--office-muted);font:clamp(2px,2.2cqi,5px)/1 ui-monospace,monospace}._2S_x-q_previewFooter,._2S_x-q_previewInsight{z-index:1;width:100%;color:var(--office-muted);text-overflow:ellipsis;white-space:nowrap;margin-top:4px;font-size:clamp(2px,2.3cqi,5px);line-height:1.15;display:block;position:relative;overflow:hidden}._2S_x-q_previewChart{z-index:1;border-bottom:1px solid color-mix(in srgb, var(--office-muted) 34%, transparent);align-items:flex-end;gap:7%;height:43%;margin-top:auto;padding:4% 5% 0;display:flex;position:relative}._2S_x-q_previewChart i{background:var(--office-accent);border-radius:2px 2px 0 0;width:11%}._2S_x-q_previewChart i:first-child{opacity:.52;height:28%}._2S_x-q_previewChart i:nth-child(2){opacity:.64;height:46%}._2S_x-q_previewChart i:nth-child(3){opacity:.76;height:41%}._2S_x-q_previewChart i:nth-child(4){opacity:.88;height:72%}._2S_x-q_previewChart i:nth-child(5){height:91%}@media (prefers-reduced-motion:reduce){._2S_x-q_previewViewport,._2S_x-q_selectionPreview{transition:none}._2S_x-q_previewViewport>._2S_x-q_preview{animation:none}}"; const tagId = "dsh-ppt-composer/OfficePptHero.module.css"; if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) { const tag = document.createElement("style"); @@ -736,6 +736,8 @@ button[data-desktop-ppt]:focus-visible{outline:2px solid var(--dsw-alias-label-p if (scrollBody === null || composerCard === null) return; const syncGeometry = () => { const scrollRect = scrollBody.getBoundingClientRect(); + const cardRect = composerCard.getBoundingClientRect(); + root.style.setProperty("--office-ppt-template-panel-width", `${Math.min(cardRect.width, scrollRect.width)}px`); const panelRect = panel.getBoundingClientRect(); const availableHeight = Math.max(TEMPLATE_PANEL_MIN_HEIGHT_PX, Math.floor(scrollRect.bottom - panelRect.top - TEMPLATE_DOCK_BOTTOM_PX)); root.style.setProperty("--office-ppt-template-panel-height", `${availableHeight}px`); @@ -750,6 +752,7 @@ button[data-desktop-ppt]:focus-visible{outline:2px solid var(--dsw-alias-label-p resizeObserver?.disconnect(); window.removeEventListener("resize", syncGeometry); root.style.removeProperty("--office-ppt-template-panel-height"); + root.style.removeProperty("--office-ppt-template-panel-width"); }; }, [placement, state.activeMode]); if (placement === "trigger") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", { @@ -1119,6 +1122,13 @@ button[data-desktop-ppt]:focus-visible{outline:2px solid var(--dsw-alias-label-p locale: NS, inject: injectHero }, OfficePptStandardInputAccessory)); + ctx.slots.inject("conversation.hero.dock", () => ctx.slots.register({ + name: "conversation.hero.dock", + id: "dsh-ppt", + order: 20, + locale: NS, + inject: injectHero + }, OfficePptStandardComposerDock)); ctx.slots.inject("conversation.composer.dock", () => ctx.slots.register({ name: "conversation.composer.dock", id: "dsh-ppt", diff --git a/packages/ppt-runtime/adapter/package.json b/packages/ppt-runtime/adapter/package.json index feeffc3a5..60f481749 100644 --- a/packages/ppt-runtime/adapter/package.json +++ b/packages/ppt-runtime/adapter/package.json @@ -58,8 +58,8 @@ "@deepseek-ai/schemastery": "3.18.2" }, "peerDependencies": { - "@deepseek-ai/cordis": "4.0.2", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.1" + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-invariants": "^0.1.5-rc.1 || ^0.1.6-alpha.2 || ^0.1.7-rc.1 || ^0.1.7-rc.2" }, "keywords": [ "dsh-plugin", diff --git a/packages/ppt-runtime/core/lib/index.js b/packages/ppt-runtime/core/lib/index.js index 67e9a19ff..679833b1c 100644 --- a/packages/ppt-runtime/core/lib/index.js +++ b/packages/ppt-runtime/core/lib/index.js @@ -2594,11 +2594,19 @@ function pptComposerContext(state) { "workflow: direct local PPTD authoring with bounded pptd_* tools and final pptd_render conversion" ].join("\n"); } +function sourcePluginName(source) { + if (typeof source !== "object" || source === null) return undefined; + if (typeof source.plugin === "string" && source.plugin.length > 0) return source.plugin; + if (typeof source.kind === "string" && source.kind.startsWith("plugin:")) return source.kind.slice("plugin:".length); + return typeof source.kind === "string" ? source.kind : undefined; +} function hasActiveSkill(agent) { return agent.session.deriveMessages().some((message) => { if (message.role !== "user") return false; - if (message.source.kind === "skill-invocation") return message.source.name === DSH_PPT_SKILL_NAME; - return message.source.kind === "plugin" && message.source.plugin === SKILL_PLUGIN && message.source.form === "snapshot" && message.source.sections.some((section) => section.name === "dsh-ppt"); + if (message.source?.kind === "skill-invocation") return message.source.name === DSH_PPT_SKILL_NAME; + const source = message.source; + if (!source || source.form !== "snapshot") return false; + return sourcePluginName(source) === SKILL_PLUGIN && Array.isArray(source.sections) && source.sections.some((section) => section.name === "dsh-ppt"); }); } async function automaticSkill(ctx, agent, signal) { @@ -2616,7 +2624,7 @@ async function automaticSkill(ctx, agent, signal) { text: skillText }], source: { - kind: "plugin", + kind: `plugin:${SKILL_PLUGIN}`, plugin: SKILL_PLUGIN, form: "snapshot", sections: [{ @@ -2635,13 +2643,14 @@ function clearAutomaticPptContext(agent, staleOnly = false) { for (const seq of [...agent.session.surface.nodes]) { const event = agent.session.eventAt(seq); if (event?.type !== "user/message") continue; - const source = event.data.source; - if (source.kind !== "plugin" || source.form !== "snapshot") continue; - if (![SKILL_PLUGIN, "dsh-ppt-composer", "kimi-ppt-skill", "kimi-ppt-composer"].includes(source.plugin)) continue; - if (staleOnly && source.plugin !== "kimi-ppt-skill" && source.plugin !== "kimi-ppt-composer" && (source.plugin !== SKILL_PLUGIN || event.data.content.some(part => part.type === "text" && part.text.includes("DSH-PPT-AUTHORING-20260910-V4")))) continue; + const source = event.data?.source; + if (!source || source.form !== "snapshot") continue; + const plugin = sourcePluginName(source); + if (![SKILL_PLUGIN, "dsh-ppt-composer", "kimi-ppt-skill", "kimi-ppt-composer"].includes(plugin)) continue; + if (staleOnly && plugin !== "kimi-ppt-skill" && plugin !== "kimi-ppt-composer" && (plugin !== SKILL_PLUGIN || event.data.content?.some(part => part.type === "text" && part.text.includes("DSH-PPT-AUTHORING-20260910-V4")))) continue; agent.session.append("user/message", createUserMessage({ content: [{ type: "text", text: "[Retired automatic PPT instructions cleared.]" }], - source: { kind: "plugin", plugin: "dsh-ppt-context-cleared" } + source: { kind: "plugin:dsh-ppt-context-cleared", plugin: "dsh-ppt-context-cleared" } }), { surfaceOp: { op: "replace", startSeq: seq, endSeq: seq }, sourceEventSeqs: [seq] @@ -2688,7 +2697,7 @@ function registerPptTools(ctx, service) { text: context }], source: { - kind: "plugin", + kind: "plugin:dsh-ppt-composer", plugin: "dsh-ppt-composer", form: "snapshot", sections: [{ diff --git a/packages/ppt-runtime/core/package.json b/packages/ppt-runtime/core/package.json index b2e5e2194..2152f0832 100644 --- a/packages/ppt-runtime/core/package.json +++ b/packages/ppt-runtime/core/package.json @@ -74,20 +74,20 @@ "zod": "^4.4.3" }, "peerDependencies": { - "@deepseek-ai/cordis": "4.0.2", - "@deepseek-ai/dsh-agent": "^0.1.5-rc.1", - "@deepseek-ai/dsh-brand": "^0.1.5-rc.1", - "@deepseek-ai/dsh-client-connection": "^0.1.5-rc.1", - "@deepseek-ai/dsh-client-locale": "^0.1.5-rc.1", - "@deepseek-ai/dsh-client-ui-conversation": "^0.1.5-rc.1", - "@deepseek-ai/dsh-client-ui-primitives": "^0.1.5-rc.1", - "@deepseek-ai/dsh-client-ui-slots": "^0.1.5-rc.1", - "@deepseek-ai/dsh-invariants": "^0.1.5-rc.1", - "@deepseek-ai/dsh-llm": "^0.1.5-rc.1", - "@deepseek-ai/dsh-session": "^0.1.5-rc.1", - "@deepseek-ai/dsh-skill": "^0.1.5-rc.1", - "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.1", - "@deepseek-ai/dsh-tools": "^0.1.5-rc.1", + "@deepseek-ai/cordis": "~4.0.4", + "@deepseek-ai/dsh-agent": "^0.1.5-rc.1 || ^0.1.6-alpha.2 || ^0.1.7-rc.1 || ^0.1.7-rc.2", + "@deepseek-ai/dsh-brand": "^0.1.5-rc.1 || ^0.1.6-alpha.2 || ^0.1.7-rc.1 || ^0.1.7-rc.2", + "@deepseek-ai/dsh-client-connection": "^0.1.5-rc.1 || ^0.1.6-alpha.2 || ^0.1.7-rc.1 || ^0.1.7-rc.2", + "@deepseek-ai/dsh-client-locale": "^0.1.5-rc.1 || ^0.1.6-alpha.2 || ^0.1.7-rc.1 || ^0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-conversation": "^0.1.5-rc.1 || ^0.1.6-alpha.2 || ^0.1.7-rc.1 || ^0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-primitives": "^0.1.5-rc.1 || ^0.1.6-alpha.2 || ^0.1.7-rc.1 || ^0.1.7-rc.2", + "@deepseek-ai/dsh-client-ui-slots": "^0.1.5-rc.1 || ^0.1.6-alpha.2 || ^0.1.7-rc.1 || ^0.1.7-rc.2", + "@deepseek-ai/dsh-invariants": "^0.1.5-rc.1 || ^0.1.6-alpha.2 || ^0.1.7-rc.1 || ^0.1.7-rc.2", + "@deepseek-ai/dsh-llm": "^0.1.5-rc.1 || ^0.1.6-alpha.2 || ^0.1.7-rc.1 || ^0.1.7-rc.2", + "@deepseek-ai/dsh-session": "^0.1.5-rc.1 || ^0.1.6-alpha.2 || ^0.1.7-rc.1 || ^0.1.7-rc.2", + "@deepseek-ai/dsh-skill": "^0.1.5-rc.1 || ^0.1.6-alpha.2 || ^0.1.7-rc.1 || ^0.1.7-rc.2", + "@deepseek-ai/dsh-system-prompt": "^0.1.5-rc.1 || ^0.1.6-alpha.2 || ^0.1.7-rc.1 || ^0.1.7-rc.2", + "@deepseek-ai/dsh-tools": "^0.1.5-rc.1 || ^0.1.6-alpha.2 || ^0.1.7-rc.1 || ^0.1.7-rc.2", "react": "^18.2.0" }, "files": [ diff --git a/patches/@deepseek-ai+dsh+0.1.7-rc.2.patch b/patches/@deepseek-ai+dsh+0.1.7-rc.2.patch new file mode 100644 index 000000000..3db63c80c --- /dev/null +++ b/patches/@deepseek-ai+dsh+0.1.7-rc.2.patch @@ -0,0 +1,36 @@ +diff --git a/node_modules/@deepseek-ai/dsh/lib/bin.js b/node_modules/@deepseek-ai/dsh/lib/bin.js +index cfab70d..a665887 100755 +--- a/node_modules/@deepseek-ai/dsh/lib/bin.js ++++ b/node_modules/@deepseek-ai/dsh/lib/bin.js +@@ -223,7 +223,8 @@ async function runCli() { + version, + profile: invocation.profile + }); +- process.exit(1); ++ process.exitCode = 1; ++ throw error; + } + break; + } +diff --git a/node_modules/@deepseek-ai/dsh/package.json b/node_modules/@deepseek-ai/dsh/package.json +index c2e1b4a..90986d4 100644 +--- a/node_modules/@deepseek-ai/dsh/package.json ++++ b/node_modules/@deepseek-ai/dsh/package.json +@@ -100,7 +100,16 @@ + "@deepseek-ai/dsh-atomic-write": "0.1.7-rc.2", + "@deepseek-ai/dsh-experimental-voice-input-bundle": "0.1.7-rc.2", + "@deepseek-ai/dsh-agent-preset": "0.1.7-rc.2", +- "@deepseek-ai/dsh-experimental-auto-review": "0.1.7-rc.2" ++ "@deepseek-ai/dsh-experimental-auto-review": "0.1.7-rc.2", ++ "@deepseek-ai/dsh-deepseek-account": "0.1.7-rc.2", ++ "dsh-ppt-composer": "0.1.1-rc.2", ++ "dsh-desktop-client-ui": "0.1.0", ++ "dsh-desktop-hmr-fallback": "0.1.0", ++ "dsh-desktop-log-bridge": "0.1.0", ++ "dsh-desktop-market-installer": "0.1.0", ++ "dsh-desktop-preset-transfer": "0.1.0", ++ "dsh-image-generation": "0.1.0", ++ "react-dom": "18.3.1" + }, + "devDependencies": { + "@agentclientprotocol/sdk": "1.4.0", diff --git a/patches/@deepseek-ai+dsh-api-remotes+0.1.7-rc.2.patch b/patches/@deepseek-ai+dsh-api-remotes+0.1.7-rc.2.patch new file mode 100644 index 000000000..b944934b4 --- /dev/null +++ b/patches/@deepseek-ai+dsh-api-remotes+0.1.7-rc.2.patch @@ -0,0 +1,57 @@ +diff --git a/node_modules/@deepseek-ai/dsh-api-remotes/lib/client.js b/node_modules/@deepseek-ai/dsh-api-remotes/lib/client.js +index abec6c7..d732576 100644 +--- a/node_modules/@deepseek-ai/dsh-api-remotes/lib/client.js ++++ b/node_modules/@deepseek-ai/dsh-api-remotes/lib/client.js +@@ -9879,6 +9879,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs. + "sessionId": intersection(string(), unknown()).readonly(), + "agentPreset": string().readonly().optional() + }); ++ let _deepseek_ai_dsh_api_session_controller_session_delete_parameter_0$schema$value; ++ const _deepseek_ai_dsh_api_session_controller_session_delete_parameter_0$schema = () => _deepseek_ai_dsh_api_session_controller_session_delete_parameter_0$schema$value ??= object({ ++ sessionId: intersection(string(), unknown()).readonly() ++ }); ++ let _deepseek_ai_dsh_api_session_controller_session_delete_result$schema$value; ++ const _deepseek_ai_dsh_api_session_controller_session_delete_result$schema = () => _deepseek_ai_dsh_api_session_controller_session_delete_result$schema$value ??= object({ ++ deleted: literal(true).readonly() ++ }); + let _deepseek_ai_dsh_api_session_controller_session_follow_parameter_0$schema$value; + const _deepseek_ai_dsh_api_session_controller_session_follow_parameter_0$schema = () => _deepseek_ai_dsh_api_session_controller_session_follow_parameter_0$schema$value ??= object({ + "address": union([object({ +@@ -11431,7 +11439,36 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs. + } + }, + { +- id: "@deepseek-ai/dsh-api-job-controller#job/list", ++ id: "@deepseek-ai/dsh-api-session-controller#session/delete", ++ service: "sessionController", ++ namespace: "session", ++ method: "delete", ++ invocation: { kind: "direct" }, ++ parameters: [ ++ { ++ name: "request", ++ wire: "request", ++ source: "json", ++ codec: { ++ mode: "strict", ++ typeSymbol: "@deepseek-ai/dsh-api-session-controller/types#SessionDeleteRequest", ++ create: _deepseek_ai_dsh_api_session_controller_session_delete_parameter_0$schema ++ } ++ } ++ ], ++ result: { ++ mode: "strict", ++ typeSymbol: "@deepseek-ai/dsh-api-session-controller/types#SessionDeleteValue", ++ create: _deepseek_ai_dsh_api_session_controller_session_delete_result$schema ++ }, ++ sourceLocation: { ++ "file": "packages/api/session-controller/src/index.ts", ++ "line": 312, ++ "column": 3 ++ } ++ }, ++ { ++ id: "@deepseek-ai/dsh-api-job-controller#job/list", + service: "jobController", + namespace: "job", + method: "list", diff --git a/patches/@deepseek-ai+dsh-api-session-controller+0.1.7-rc.2.patch b/patches/@deepseek-ai+dsh-api-session-controller+0.1.7-rc.2.patch new file mode 100644 index 000000000..d89b2ba6d --- /dev/null +++ b/patches/@deepseek-ai+dsh-api-session-controller+0.1.7-rc.2.patch @@ -0,0 +1,1229 @@ +diff --git a/node_modules/@deepseek-ai/dsh-api-session-controller/lib/client.js b/node_modules/@deepseek-ai/dsh-api-session-controller/lib/client.js +index 3622a98..51c8247 100644 +--- a/node_modules/@deepseek-ai/dsh-api-session-controller/lib/client.js ++++ b/node_modules/@deepseek-ai/dsh-api-session-controller/lib/client.js +@@ -1786,6 +1786,63 @@ window.__ModuleLoader__.load({ + } + }; + } ++ /** ++ * Resolve one session-authorized uploaded file to its Host filesystem path. ++ * Used to open the stock document-preview pane; never treat the display name as a workspace path. ++ * @param attachmentIdOrName - opaque id from a staged receipt / session file block, or `{ name }` for a unique display-name lookup. ++ * @returns the absolute host path and display name. ++ */ ++ async readFileHostPath(attachmentIdOrName) { ++ const query = new URLSearchParams({ sessionId: this.sessionId }); ++ if (typeof attachmentIdOrName === "object" && attachmentIdOrName !== null && typeof attachmentIdOrName.name === "string") query.set("name", attachmentIdOrName.name); ++ else query.set("attachmentId", String(attachmentIdOrName)); ++ const response = await fetch(`/api/session/fileHostPath?${query.toString()}`, { credentials: "include" }); ++ if (response.status !== 200) return { ++ ok: false, ++ error: { ++ code: "gateway/internal", ++ message: `file host path failed with HTTP ${String(response.status)}`, ++ details: {} ++ } ++ }; ++ const body = await response.json(); ++ if (typeof body !== "object" || body === null || typeof body.ok !== "boolean") return { ++ ok: false, ++ error: { ++ code: "gateway/internal", ++ message: "file host path returned an invalid result", ++ details: {} ++ } ++ }; ++ if (!body.ok) { ++ const error = body.error; ++ return { ++ ok: false, ++ error: { ++ code: typeof error?.code === "string" ? error.code : "gateway/internal", ++ message: typeof error?.message === "string" ? error.message : "file host path failed", ++ details: typeof error?.details === "object" && error.details !== null ? error.details : {} ++ } ++ }; ++ } ++ const value = body.value; ++ if (typeof value?.path !== "string" || typeof value?.name !== "string" || typeof value?.bytes !== "number") return { ++ ok: false, ++ error: { ++ code: "gateway/internal", ++ message: "file host path returned an invalid value", ++ details: {} ++ } ++ }; ++ return { ++ ok: true, ++ value: { ++ path: value.path, ++ name: value.name, ++ bytes: value.bytes ++ } ++ }; ++ } + /** Apply one operation to a still-pending queue occurrence. */ + async updateQueue(itemId, action) { + return this.remote.session.updateQueue({ +@@ -2711,6 +2768,15 @@ window.__ModuleLoader__.load({ + } + return result; + } ++ /** Contract session.delete; remove the row immediately after Host commit. */ ++ async delete(sessionId) { ++ const result = await this.remote.session.delete({ sessionId }); ++ if (result.ok) this.recordMutation({ ++ kind: "remove", ++ sessionId ++ }); ++ return result; ++ } + /** + * Contract session.fork; on success merge the child into summaries + * immediately (same synchronous-addressability guarantee as create). +@@ -3045,6 +3111,17 @@ window.__ModuleLoader__.load({ + this.sourceSessionId = sourceSessionId; + } + }; ++ /** Structured permanent Session-deletion failure. */ ++ var SessionDeleteError = class extends Error { ++ rpcError; ++ sessionId; ++ name = "SessionDeleteError"; ++ constructor(rpcError, sessionId) { ++ super(`session delete failed: ${rpcError.code}: ${rpcError.message}`); ++ this.rpcError = rpcError; ++ this.sessionId = sessionId; ++ } ++ }; + /** + * Display title projection: durable title, project directory basename, then + * the raw id. +@@ -3328,6 +3405,15 @@ window.__ModuleLoader__.load({ + return result.value.sessionId; + } + /** ++ * Permanently delete one ordinary Session. Selection belongs to ++ * uiWorkspace, which releases its main view before calling this method. ++ */ ++ async delete(sessionId) { ++ const result = await this.manager.delete(sessionId); ++ if (!result.ok) throw new SessionDeleteError(result.error, sessionId); ++ this.projectList(); ++ } ++ /** + * Fork a session from an exact inclusive prefix of the source (same + * synchronous-addressability guarantee as {@link ClientSessions.create}: + * on resolution the child is catalogued and may be explicitly retained). +diff --git a/node_modules/@deepseek-ai/dsh-api-session-controller/lib/index.js b/node_modules/@deepseek-ai/dsh-api-session-controller/lib/index.js +index 3b8507e..8d84248 100644 +--- a/node_modules/@deepseek-ai/dsh-api-session-controller/lib/index.js ++++ b/node_modules/@deepseek-ai/dsh-api-session-controller/lib/index.js +@@ -5,7 +5,7 @@ import { AssistantStreamAccumulator, ReasoningEffortId, assistantStreamChunks, c + import { canOpenNativePath, nativeFileApplications, nativeFileManager, openNativeAssociatedPath, openNativeFileApplication, revealNativePath } from "@deepseek-ai/dsh-native-command"; + import { SessionQueryError } from "@deepseek-ai/dsh-session-query"; + import { Remote, RemoteError, TypertRemoteService, remoteErrorOf } from "@deepseek-ai/dsh-typert-protocol"; +-import { mkdir } from "node:fs/promises"; ++import { link, mkdir } from "node:fs/promises"; + import { installModelSelection } from "@deepseek-ai/dsh-agent"; + import { credentialRef } from "@deepseek-ai/dsh-credentials"; + import { randomUUID } from "node:crypto"; +@@ -179,11 +179,15 @@ var ApiSessionAgentController = class { + ctx; + resumes = /* @__PURE__ */ new Map(); + creations = /* @__PURE__ */ new Map(); ++ handles = /* @__PURE__ */ new Map(); + selections = /* @__PURE__ */ new WeakMap(); + imageAdmissionChains = /* @__PURE__ */ new WeakMap(); + /** @param ctx - Host context carrying Agent, model, persistence, and Typert services. */ + constructor(ctx) { + this.ctx = ctx; ++ ctx.on("session/disposed", (session) => { ++ this.handles.delete(session.id); ++ }); + ctx.typert.lookups.configure("agent", async (sessionId) => { + const found = await this.resolveAgent(sessionId); + if ("error" in found) throw found.error; +@@ -216,6 +220,21 @@ var ApiSessionAgentController = class { + async resolveObservedAgent(observation) { + return this.resolve(observation.header.id, observation); + } ++ /** Retain the teardown capability for an Agent created outside the normal create path. */ ++ retainHandle(handle) { ++ this.handles.set(handle.agent.id, handle); ++ return handle.agent; ++ } ++ /** Dispose an ordinary Agent owned by this controller, waiting for in-flight activation first. */ ++ async disposeOwned(sessionId) { ++ const pending = [this.resumes.get(sessionId), this.creations.get(sessionId)].filter((operation) => operation !== void 0); ++ await Promise.allSettled(pending); ++ const handle = this.handles.get(sessionId); ++ if (handle === void 0) return false; ++ await handle.dispose(); ++ this.handles.delete(sessionId); ++ return true; ++ } + async resolve(sessionId, observation) { + const live = this.liveAgent(sessionId); + if (live !== void 0) return live; +@@ -360,9 +379,22 @@ var ApiSessionAgentController = class { + if (presets === void 0) return { setup: (_agentCtx, agent) => { + this.installSelection(agent); + } }; +- const resolvedId = (await presets.resolve(presetId)).id; ++ let resolved; ++ let fallbackFrom; ++ try { ++ resolved = await presets.resolve(presetId); ++ } catch (error) { ++ // A deleted preset must not strand durable history. Resume with the ++ // standard composition and append a selection event after activation, ++ // so later launches no longer depend on the removed identifier. ++ if (presetId === void 0 || !(error instanceof RemoteError) || error.code !== "agent-preset/not-found") throw error; ++ resolved = await presets.resolve("standard"); ++ fallbackFrom = presetId; ++ } ++ const resolvedId = resolved.id; + return { + agentPreset: resolvedId, ++ ...fallbackFrom === void 0 ? {} : { fallbackFrom }, + setup: async (agentCtx, agent) => { + this.installSelection(agent); + await presets.mount(agentCtx, resolvedId); +@@ -403,11 +435,20 @@ var ApiSessionAgentController = class { + const published = this.ctx.sessions.get(sessionId); + const live = this.ctx.agents.get(sessionId); + if (published !== void 0 && hasApiSessionSubagentOwner(this.ctx, published, live)) throw new ApiSessionSubagentOwnership(sessionId); +- return (await this.ctx.agents.resume({ ++ return this.resumeWithComposition(sessionId, composition); ++ } ++ /** Resume one stored Session and durably record a one-time legacy-preset migration. */ ++ async resumeWithComposition(sessionId, composition) { ++ const agent = this.retainHandle(await this.ctx.agents.resume({ + resumeSessionId: sessionId, + agentOptions: this.agentOptions(), + setup: composition.setup +- })).agent; ++ })); ++ if (composition.fallbackFrom !== void 0) { ++ agent.session.append("agent-preset/selected", { agentPreset: composition.agentPreset }); ++ console.warn(`api-session: migrated session "${sessionId}" from unavailable preset "${composition.fallbackFrom}" to "${composition.agentPreset}"`); ++ } ++ return agent; + } + async createOrAdopt(sessionId, cwd, checkPersistedIdentity, presetId) { + const attached = this.ctx.sessions.get(sessionId); +@@ -427,11 +468,7 @@ var ApiSessionAgentController = class { + const storedPreset = this.presetForObservation(observation); + this.assertPresetUnchanged(sessionId, presetId, storedPreset); + const composition = await this.composeAgent(storedPreset); +- return (await this.ctx.agents.resume({ +- resumeSessionId: sessionId, +- agentOptions: this.agentOptions(), +- setup: composition.setup +- })).agent; ++ return this.resumeWithComposition(sessionId, composition); + } catch (e_3) { + env_3.error = e_3; + env_3.hasError = true; +@@ -447,7 +484,7 @@ var ApiSessionAgentController = class { + throw new Error(`failed to ensure project directory "${cwd}": ${String(error)}`, { cause: error }); + } + const composition = await this.composeAgent(presetId); +- return (await this.ctx.agents.create({ ++ return this.retainHandle(await this.ctx.agents.create({ + sessionId, + agentOptions: this.agentOptions(), + meta: { +@@ -455,7 +492,7 @@ var ApiSessionAgentController = class { + ...composition.agentPreset === void 0 ? {} : { agentPreset: composition.agentPreset } + }, + setup: composition.setup +- })).agent; ++ })); + } + agentOptions() { + const { provider, model } = this.ctx.agentDefaultModel.currentSelection(); +@@ -766,6 +803,34 @@ var SessionCommandController = class { + throw new RemoteError("gateway/internal", `failed to rename session "${request.sessionId}": ${String(error)}`, {}); + } + } ++ /** Permanently delete one ordinary Session while retaining its Workspace files. */ ++ async delete(request) { ++ let state; ++ try { ++ state = await this.readSessionState(request.sessionId); ++ } catch (error) { ++ if (error instanceof ApiSessionNotFound) throw new RemoteError("session/not-found", error.message, { sessionId: request.sessionId }); ++ throw new RemoteError("gateway/internal", `failed to inspect session "${request.sessionId}" before deletion: ${String(error)}`, {}); ++ } ++ const live = this.ctx.agents.get(request.sessionId); ++ if (hasApiSessionSubagentOwner(this.ctx, { header: state.header }, live)) throw apiSessionSubagentOwnershipError(request.sessionId); ++ const persistence = this.ctx.get("sessionPersistence"); ++ if (persistence === void 0) throw new RemoteError("gateway/internal", "session deletion is unavailable: this deployment mounts no session-persistence service", {}); ++ const hadLiveSession = this.ctx.sessions.get(request.sessionId) !== void 0; ++ try { ++ await this.agents.disposeOwned(request.sessionId); ++ if (this.ctx.agents.get(request.sessionId) !== void 0 || this.ctx.sessions.get(request.sessionId) !== void 0) throw new RemoteError("session/agent-busy", `session "${request.sessionId}" is still active`, { reason: "the live Agent is owned by another capability" }); ++ // Remove idempotent Workspace metadata before the irreversible persistence commit. ++ // Otherwise a cleanup failure leaves a retry unable to reach the ghost metadata. ++ await this.ctx.workspaceRegistry.forgetSession(request.sessionId); ++ if (!await persistence.delete(request.sessionId)) throw new RemoteError("session/not-found", `session "${request.sessionId}" not found`, { sessionId: request.sessionId }); ++ if (!hadLiveSession) this.ctx.emit("api-session/removed", request.sessionId); ++ return { deleted: true }; ++ } catch (error) { ++ if (remoteErrorOf(error) !== void 0) throw error; ++ throw new RemoteError("gateway/internal", `failed to delete session "${request.sessionId}": ${String(error)}`, {}); ++ } ++ } + /** + * Create a new ordinary Session from an exact event prefix. An explicit + * `atSeq` is the inclusive cut; an omitted value selects the latest +@@ -807,7 +872,7 @@ var SessionCommandController = class { + const composition = await this.agents.composeAgent(this.agents.presetForObservation(source)); + try { + const { provider, model } = this.ctx.agentDefaultModel.currentSelection(); +- await this.ctx.agents.create({ ++ const handle = await this.ctx.agents.create({ + sessionId: childId, + seed, + inheritedEventCount: SessionLogOffset(boundary + 1), +@@ -823,6 +888,7 @@ var SessionCommandController = class { + }, + setup: composition.setup + }); ++ this.agents.retainHandle(handle); + } catch (error) { + throw new RemoteError("gateway/internal", `failed to fork session "${request.sessionId}": ${String(error)}`, {}); + } +@@ -1124,6 +1190,126 @@ function referencedImage(events, attachmentId) { + if (found !== void 0) return found; + } + } ++function fileBlockIn(content, match) { ++ if (!Array.isArray(content)) return void 0; ++ for (const value of content) { ++ if (typeof value !== "object" || value === null || Array.isArray(value)) continue; ++ const block = value; ++ if (block.type === "file" && typeof block.attachment === "object" && block.attachment !== null) { ++ const ref = block.attachment; ++ if (match(ref)) return ref; ++ } ++ if (block.type === "tool-result") { ++ const nested = fileBlockIn(block.content, match); ++ if (nested !== void 0) return nested; ++ } ++ } ++} ++function fileInEvent(event, match) { ++ const data = event.data; ++ const direct = fileBlockIn(data.content, match); ++ if (direct !== void 0) return direct; ++ const message = fileBlockIn(data.message?.content, match); ++ if (message !== void 0) return message; ++ for (const inserted of data.inserted ?? []) { ++ const found = fileBlockIn(inserted.content, match); ++ if (found !== void 0) return found; ++ } ++ if (event.type === "assistant/message" || event.type === "assistant/attempt") for (const chunk of assistantStreamChunks(event.data.stream, "block-end")) { ++ const found = fileBlockIn([chunk.block], match); ++ if (found !== void 0) return found; ++ } ++} ++function referencedFile(events, attachmentId) { ++ for (const event of events) { ++ const found = fileInEvent(event, (ref) => String(ref.attachmentId) === attachmentId); ++ if (found !== void 0) return found; ++ } ++} ++/** Leaf name of a path-like display string (POSIX or Windows separators). */ ++function basenameLeaf(value) { ++ const parts = String(value).split(/[/\\]/); ++ return parts[parts.length - 1] || String(value); ++} ++function fileNameEquals(left, right) { ++ if (left === right) return true; ++ // NTFS / Explorer treat names as case-insensitive; assistant mentions often ++ // disagree with the stored attachment casing on Windows. ++ if (process.platform === "win32") return left.toLowerCase() === right.toLowerCase(); ++ return false; ++} ++function fileNameMatches(refName, needle) { ++ const name = String(refName ?? ""); ++ const needleBase = basenameLeaf(needle); ++ const nameBase = basenameLeaf(name); ++ return fileNameEquals(name, needle) || fileNameEquals(nameBase, needle) || fileNameEquals(nameBase, needleBase); ++} ++/** ++* Collect every distinct file attachment whose display name or basename matches. ++* Used when assistant prose mentions a file by name rather than attachment id. ++*/ ++function collectReferencedFilesByName(events, name) { ++ const matches = []; ++ const seen = /* @__PURE__ */ new Set(); ++ const visit = (ref) => { ++ if (!fileNameMatches(ref.name, name)) return; ++ const id = String(ref.attachmentId); ++ if (seen.has(id)) return; ++ seen.add(id); ++ matches.push(ref); ++ }; ++ for (const event of events) fileInEventCollect(event, visit); ++ return matches; ++} ++/** ++* Collect every distinct image attachment whose display name or basename matches. ++* Assistant prose often cites uploaded screenshots by filename. ++*/ ++function collectReferencedImagesByName(events, name) { ++ const matches = []; ++ const seen = /* @__PURE__ */ new Set(); ++ const visit = (ref) => { ++ if (!fileNameMatches(ref.name, name)) return; ++ const id = String(ref.attachmentId); ++ if (seen.has(id)) return; ++ seen.add(id); ++ matches.push(ref); ++ }; ++ for (const event of events) imageInEventCollect(event, visit); ++ return matches; ++} ++function fileBlockInCollect(content, visit) { ++ if (!Array.isArray(content)) return; ++ for (const value of content) { ++ if (typeof value !== "object" || value === null || Array.isArray(value)) continue; ++ const block = value; ++ if (block.type === "file" && typeof block.attachment === "object" && block.attachment !== null) visit(block.attachment); ++ if (block.type === "tool-result") fileBlockInCollect(block.content, visit); ++ } ++} ++function imageBlockInCollect(content, visit) { ++ if (!Array.isArray(content)) return; ++ for (const value of content) { ++ if (typeof value !== "object" || value === null || Array.isArray(value)) continue; ++ const block = value; ++ if (block.type === "image" && typeof block.attachment === "object" && block.attachment !== null) visit(block.attachment); ++ if (block.type === "tool-result") imageBlockInCollect(block.content, visit); ++ } ++} ++function fileInEventCollect(event, visit) { ++ const data = event.data; ++ fileBlockInCollect(data.content, visit); ++ fileBlockInCollect(data.message?.content, visit); ++ for (const inserted of data.inserted ?? []) fileBlockInCollect(inserted.content, visit); ++ if (event.type === "assistant/message" || event.type === "assistant/attempt") for (const chunk of assistantStreamChunks(event.data.stream, "block-end")) fileBlockInCollect([chunk.block], visit); ++} ++function imageInEventCollect(event, visit) { ++ const data = event.data; ++ imageBlockInCollect(data.content, visit); ++ imageBlockInCollect(data.message?.content, visit); ++ for (const inserted of data.inserted ?? []) imageBlockInCollect(inserted.content, visit); ++ if (event.type === "assistant/message" || event.type === "assistant/attempt") for (const chunk of assistantStreamChunks(event.data.stream, "block-end")) imageBlockInCollect([chunk.block], visit); ++} + //#endregion + //#region lib/types/control.js + /** Live Session projection state with reconnect baselines. */ +@@ -2401,6 +2587,171 @@ const SessionMediaReferences = { + }), "session-controller: /api/file"); + } + }; ++const FILE_HOST_PATH = "/api/session/fileHostPath"; ++function fileHostPathResult(ok, payload) { ++ return new Response(JSON.stringify(ok ? { ok: true, value: payload } : { ok: false, error: payload }), { ++ status: 200, ++ headers: { ++ "content-type": "application/json; charset=utf-8", ++ "cache-control": "no-store" ++ } ++ }); ++} ++async function resolveAuthorizedFileRef(ctx, sessionId, attachmentId) { ++ const live = ctx.agents.get(sessionId); ++ if (live !== void 0) { ++ const staged = ctx.fileUploads.findStagedFile(live, attachmentId); ++ if (staged !== void 0) return staged; ++ } ++ let events; ++ const attached = ctx.sessions.get(sessionId); ++ if (attached !== void 0) events = attached.snapshotEvents(); ++ else { ++ try { ++ events = (await inspectApiSession(ctx, sessionId)).events; ++ } catch (error) { ++ if (error instanceof ApiSessionNotFound) throw new RemoteError("session/not-found", error.message, { sessionId }); ++ if (error instanceof SessionQueryError && error.code === "SESSION_QUERY_SESSION_NOT_FOUND") throw new RemoteError("session/not-found", `session "${sessionId}" not found`, { sessionId }); ++ throw new RemoteError("gateway/internal", `attachment authorization unavailable for session "${sessionId}": ${String(error)}`, {}); ++ } ++ } ++ const ref = referencedFile(events, attachmentId); ++ if (ref === void 0) throw new RemoteError("session/attachment-invalid", "File is not referenced by this session.", { reason: "ATTACHMENT_NOT_REFERENCED" }); ++ return ref; ++} ++async function resolveAuthorizedFileRefByName(ctx, sessionId, name) { ++ const matches = []; ++ const seen = /* @__PURE__ */ new Set(); ++ const add = (kind, ref) => { ++ const id = String(ref.attachmentId); ++ if (seen.has(id)) return; ++ seen.add(id); ++ matches.push({ kind, ref }); ++ }; ++ let events; ++ const attached = ctx.sessions.get(sessionId); ++ if (attached !== void 0) events = attached.snapshotEvents(); ++ else { ++ try { ++ events = (await inspectApiSession(ctx, sessionId)).events; ++ } catch (error) { ++ if (error instanceof ApiSessionNotFound) throw new RemoteError("session/not-found", error.message, { sessionId }); ++ if (error instanceof SessionQueryError && error.code === "SESSION_QUERY_SESSION_NOT_FOUND") throw new RemoteError("session/not-found", `session "${sessionId}" not found`, { sessionId }); ++ throw new RemoteError("gateway/internal", `attachment authorization unavailable for session "${sessionId}": ${String(error)}`, {}); ++ } ++ } ++ for (const ref of collectReferencedFilesByName(events, name)) add("file", ref); ++ for (const ref of collectReferencedImagesByName(events, name)) add("image", ref); ++ if (matches.length === 0) throw new RemoteError("session/attachment-invalid", "File is not referenced by this session.", { reason: "ATTACHMENT_NOT_REFERENCED" }); ++ if (matches.length > 1) throw new RemoteError("session/attachment-invalid", "Multiple uploaded files share this name.", { reason: "ATTACHMENT_NAME_AMBIGUOUS" }); ++ return matches[0]; ++} ++function attachmentHostPath(ctx, match, fallbackName) { ++ if (match.kind === "image") { ++ const host = ctx.attachments.imageHostPath(match.ref); ++ if (host === void 0) return; ++ return ensureImagePreviewPath(host, match.ref, fallbackName); ++ } ++ return ctx.attachments.fileHostPath(match.ref); ++} ++/** ++* Document preview picks an image body from the path suffix. Attachment objects ++* are extensionless digests, so mint a same-inode alias that ends in `.png` etc. ++*/ ++async function ensureImagePreviewPath(hostPath, ref, fallbackName) { ++ const ext = imagePreviewExtension(ref, fallbackName); ++ if (ext === "" || hostPath.toLowerCase().endsWith(ext)) return hostPath; ++ const aliased = `${hostPath}${ext}`; ++ try { ++ await link(hostPath, aliased); ++ } catch (error) { ++ if (error && typeof error === "object" && "code" in error && error.code === "EEXIST") return aliased; ++ console.warn("session-controller: image preview alias failed:", error); ++ return hostPath; ++ } ++ return aliased; ++} ++function imagePreviewExtension(ref, fallbackName) { ++ for (const candidate of [ref.name, fallbackName]) { ++ const leaf = basenameLeaf(String(candidate ?? "")); ++ const dot = leaf.lastIndexOf("."); ++ if (dot > 0 && dot < leaf.length - 1) { ++ const ext = leaf.slice(dot).toLowerCase(); ++ if (/^\.[a-z0-9]{1,8}$/.test(ext)) return ext; ++ } ++ } ++ switch (String(ref.mediaType ?? "")) { ++ case "image/jpeg": return ".jpg"; ++ case "image/png": return ".png"; ++ case "image/gif": return ".gif"; ++ case "image/webp": return ".webp"; ++ case "image/bmp": return ".bmp"; ++ case "image/svg+xml": return ".svg"; ++ case "image/x-icon": return ".ico"; ++ default: return ".png"; ++ } ++} ++async function handleFileHostPath(ctx, request) { ++ if (request.method !== "GET") return new Response(null, { ++ status: 405, ++ headers: { allow: "GET" } ++ }); ++ const url = new URL(request.url); ++ const sessionId = url.searchParams.get("sessionId"); ++ const attachmentId = url.searchParams.get("attachmentId"); ++ const name = url.searchParams.get("name"); ++ if (sessionId === null || sessionId === "") return new Response("sessionId is required", { status: 400 }); ++ const hasAttachmentId = attachmentId !== null && attachmentId !== ""; ++ const hasName = name !== null && name !== ""; ++ if (!hasAttachmentId && !hasName) return new Response("attachmentId or name is required", { status: 400 }); ++ try { ++ let path; ++ let ref; ++ if (hasAttachmentId) { ++ ref = await resolveAuthorizedFileRef(ctx, brandString(sessionId), attachmentId); ++ path = ctx.attachments.fileHostPath(ref); ++ } else { ++ const match = await resolveAuthorizedFileRefByName(ctx, brandString(sessionId), name); ++ ref = match.ref; ++ path = await attachmentHostPath(ctx, match, name); ++ } ++ if (path === void 0) throw new RemoteError("session/attachment-invalid", "File host path is unavailable.", { reason: "FILE_HOST_PATH_UNAVAILABLE" }); ++ return fileHostPathResult(true, { ++ path, ++ name: typeof ref.name === "string" && ref.name !== "" ? ref.name : name ?? String(ref.attachmentId), ++ bytes: typeof ref.bytes === "number" ? ref.bytes : 0 ++ }); ++ } catch (error) { ++ const failure = remoteErrorOf(error); ++ return fileHostPathResult(false, failure !== void 0 ? { ++ code: failure.code, ++ message: failure.message, ++ details: failure.details ++ } : { ++ code: "gateway/internal", ++ message: error instanceof Error ? error.message : String(error), ++ details: {} ++ }); ++ } ++} ++const SessionFileHostPath = { ++ inject: [ ++ "connection", ++ "attachments", ++ "fileUploads", ++ "agents", ++ "sessions", ++ "sessionQuery" ++ ], ++ apply(ctx) { ++ ctx.effect(() => ctx.connection.fetch.register({ ++ path: FILE_HOST_PATH, ++ methods: ["GET"], ++ requestBody: "buffered", ++ fetch: (request) => handleFileHostPath(ctx, request) ++ }), "session-controller: /api/session/fileHostPath"); ++ } ++}; + //#endregion + //#region lib/types/archived-session-gate.js + /** +@@ -2566,6 +2917,7 @@ let SessionController = (() => { + let _openWorkspacePath_decorators; + let _workspacePathApplications_decorators; + let _rename_decorators; ++ let _delete_decorators; + let _fork_decorators; + let _prompt_decorators; + let _attachment_decorators; +@@ -2588,6 +2940,7 @@ let SessionController = (() => { + _openWorkspacePath_decorators = [Remote("openWorkspacePath")]; + _workspacePathApplications_decorators = [Remote("workspacePathApplications")]; + _rename_decorators = [Remote("rename")]; ++ _delete_decorators = [Remote("delete")]; + _fork_decorators = [Remote("fork")]; + _prompt_decorators = [Remote("prompt")]; + _attachment_decorators = [Remote("attachment")]; +@@ -2707,6 +3060,17 @@ let SessionController = (() => { + }, + metadata: _metadata + }, null, _instanceExtraInitializers); ++ __esDecorate(this, null, _delete_decorators, { ++ kind: "method", ++ name: "delete", ++ static: false, ++ private: false, ++ access: { ++ has: (obj) => "delete" in obj, ++ get: (obj) => obj.delete ++ }, ++ metadata: _metadata ++ }, null, _instanceExtraInitializers); + __esDecorate(this, null, _fork_decorators, { + kind: "method", + name: "fork", +@@ -2868,10 +3232,12 @@ let SessionController = (() => { + this.canOpenPath = internals.canOpenPath ?? (() => config.nativeOpen ?? (internals.openPath !== void 0 || canOpenNativePath())); + ctx.plugin(SessionFileReferences); + ctx.plugin(SessionMediaReferences); ++ ctx.plugin(SessionFileHostPath); + ctx.plugin(SessionSkillCatalog); + ctx.plugin(ArchivedSessionGate); + ctx.on("session/created", (session) => { +- ctx.emit("api-session/added", this.listState.summaryFor(session)); ++ const { projections: _projections, ...remoteSummary } = this.listState.summaryFor(session); ++ ctx.emit("api-session/added", remoteSummary); + }); + ctx.on("session/disposed", (session) => { + ctx.emit("api-session/removed", session.id); +@@ -3077,6 +3443,10 @@ let SessionController = (() => { + rename(request) { + return this.commands.rename(request); + } ++ /** Permanently delete one ordinary Session while retaining Workspace files. */ ++ delete(request) { ++ return this.commands.delete(request); ++ } + /** + * Fork one cold-readable exact event prefix into a new Session. An omitted + * boundary selects the latest completed-turn prefix; an open cut receives +diff --git a/node_modules/@deepseek-ai/dsh-api-session-controller/lib/typert.host.js b/node_modules/@deepseek-ai/dsh-api-session-controller/lib/typert.host.js +index 3ee71e3..919a477 100644 +--- a/node_modules/@deepseek-ai/dsh-api-session-controller/lib/typert.host.js ++++ b/node_modules/@deepseek-ai/dsh-api-session-controller/lib/typert.host.js +@@ -170,6 +170,14 @@ const _deepseek_ai_dsh_api_session_controller_session_create_result$schema = () + 'sessionId': z.intersection(z.string(), z.unknown()).readonly(), + 'agentPreset': z.string().readonly().optional(), + })) ++let _deepseek_ai_dsh_api_session_controller_session_delete_parameter_0$schema$value ++const _deepseek_ai_dsh_api_session_controller_session_delete_parameter_0$schema = () => (_deepseek_ai_dsh_api_session_controller_session_delete_parameter_0$schema$value ??= z.object({ ++ 'sessionId': z.intersection(z.string(), z.unknown()).readonly(), ++})) ++let _deepseek_ai_dsh_api_session_controller_session_delete_result$schema$value ++const _deepseek_ai_dsh_api_session_controller_session_delete_result$schema = () => (_deepseek_ai_dsh_api_session_controller_session_delete_result$schema$value ??= z.object({ ++ 'deleted': z.literal(true).readonly(), ++})) + let _deepseek_ai_dsh_api_session_controller_session_follow_parameter_0$schema$value + const _deepseek_ai_dsh_api_session_controller_session_follow_parameter_0$schema = () => (_deepseek_ai_dsh_api_session_controller_session_follow_parameter_0$schema$value ??= z.object({ + 'address': z.union([z.object({ +@@ -895,6 +903,31 @@ export const TYPERT = { + }, + sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":520,"column":3}, + }, ++ { ++ id: '@deepseek-ai/dsh-api-session-controller#session/delete', ++ service: 'sessionController', ++ namespace: 'session', ++ method: 'delete', ++ invocation: { kind: 'direct' }, ++ parameters: [ ++ { ++ name: 'request', ++ wire: 'request', ++ source: 'json', ++ codec: { ++ mode: 'strict', ++ typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionDeleteRequest', ++ create: _deepseek_ai_dsh_api_session_controller_session_delete_parameter_0$schema, ++ }, ++ }, ++ ], ++ result: { ++ mode: 'strict', ++ typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionDeleteValue', ++ create: _deepseek_ai_dsh_api_session_controller_session_delete_result$schema, ++ }, ++ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":312,"column":3}, ++ }, + { + id: '@deepseek-ai/dsh-api-session-controller#session/create', + service: 'sessionController', +@@ -1387,6 +1420,13 @@ export const TYPERT = { + "summary": "Rename one Session after explicitly resuming it.", + "jsDoc": "/**\n * Rename one Session after explicitly resuming it.\n * @param request - Session identity and proposed title.\n * @returns the accepted title and durable event sequence.\n */" + }, ++ { ++ "kind": "method", ++ "name": "delete", ++ "signature": "@Remote('delete') delete(request: SessionDeleteRequest): Promise", ++ "summary": "Permanently delete one ordinary Session while retaining Workspace files.", ++ "jsDoc": "/** Permanently delete one ordinary Session while retaining Workspace files. */" ++ }, + { + "kind": "method", + "name": "fork", +@@ -1980,6 +2020,14 @@ export const TYPERT = { + "name": "SessionCreateValue", + "declaration": "export interface SessionCreateValue {\n readonly sessionId: SessionId;\n readonly agentPreset?: string;\n}" + }, ++ { ++ "name": "SessionDeleteRequest", ++ "declaration": "export interface SessionDeleteRequest {\n readonly sessionId: SessionId;\n}" ++ }, ++ { ++ "name": "SessionDeleteValue", ++ "declaration": "export interface SessionDeleteValue {\n readonly deleted: true;\n}" ++ }, + { + "name": "SessionEvent", + "declaration": "export type SessionEvent = { [K in SessionEventType]: { type: K; seq: SessionSeq; time: number; data: SessionEventMap[K]; ignorable?: true; } & (K extends SurfaceEventType ? SurfaceIntent : { surfaceOp?: never; sourceEventSeqs?: never; }) }[T];" +diff --git a/node_modules/@deepseek-ai/dsh-api-session-controller/lib/typert.remote-client.d.ts b/node_modules/@deepseek-ai/dsh-api-session-controller/lib/typert.remote-client.d.ts +index 853e788..e97465a 100644 +--- a/node_modules/@deepseek-ai/dsh-api-session-controller/lib/typert.remote-client.d.ts ++++ b/node_modules/@deepseek-ai/dsh-api-session-controller/lib/typert.remote-client.d.ts +@@ -4,7 +4,7 @@ import type { + RemoteStreamHandle, + TypertRemoteContribution, + } from '@deepseek-ai/dsh-typert-protocol' +-import type { ModelCatalog, SessionAttachmentRequest, SessionAttachmentValue, SessionCancelRequest, SessionCancelValue, SessionControlFrame, SessionCreateRequest, SessionCreateValue, SessionFollowFrame, SessionFollowRequest, SessionForkRequest, SessionForkValue, SessionListRequest, SessionListValue, SessionOpenWorkspacePathRequest, SessionOpenWorkspacePathValue, SessionPage, SessionPageRequest, SessionProjectionsRequest, SessionProjectionsValue, SessionPromptRequest, SessionPromptValue, SessionRenameRequest, SessionRenameValue, SessionSearchRequest, SessionSearchValue, SessionSelectModelRequest, SessionSelectModelValue, SessionUpdateQueueRequest, SessionUpdateQueueValue, SessionWorkspacePathApplication, SkillListRequest, SkillListValue } from '@deepseek-ai/dsh-api-session-controller/types' ++import type { ModelCatalog, SessionAttachmentRequest, SessionAttachmentValue, SessionCancelRequest, SessionCancelValue, SessionControlFrame, SessionCreateRequest, SessionCreateValue, SessionFollowFrame, SessionDeleteRequest, SessionDeleteValue, SessionFollowRequest, SessionForkRequest, SessionForkValue, SessionListRequest, SessionListValue, SessionOpenWorkspacePathRequest, SessionOpenWorkspacePathValue, SessionPage, SessionPageRequest, SessionProjectionsRequest, SessionProjectionsValue, SessionPromptRequest, SessionPromptValue, SessionRenameRequest, SessionRenameValue, SessionSearchRequest, SessionSearchValue, SessionSelectModelRequest, SessionSelectModelValue, SessionUpdateQueueRequest, SessionUpdateQueueValue, SessionWorkspacePathApplication, SkillListRequest, SkillListValue } from '@deepseek-ai/dsh-api-session-controller/types' + import type { FileReferenceCandidate } from '@deepseek-ai/dsh-file-reference/types' + import type { SessionId } from '@deepseek-ai/dsh-session/types' + +@@ -18,6 +18,7 @@ declare module '@deepseek-ai/dsh-typert-protocol' { + canOpenWorkspacePath: () => Promise> + control: (signal?: AbortSignal) => RemoteStreamHandle + create: (request: SessionCreateRequest) => Promise> ++ delete: (request: SessionDeleteRequest) => Promise> + follow: (request: SessionFollowRequest, signal?: AbortSignal) => RemoteStreamHandle + fork: (request: SessionForkRequest) => Promise> + initializeDefaultModel: () => Promise> +@@ -43,6 +44,7 @@ declare module '@deepseek-ai/dsh-typert-protocol' { + 'session/canOpenWorkspacePath': () => Promise> + 'session/control': (signal?: AbortSignal) => RemoteStreamHandle + 'session/create': (request: SessionCreateRequest) => Promise> ++ 'session/delete': (request: SessionDeleteRequest) => Promise> + 'session/follow': (request: SessionFollowRequest, signal?: AbortSignal) => RemoteStreamHandle + 'session/fork': (request: SessionForkRequest) => Promise> + 'session/initializeDefaultModel': () => Promise> +diff --git a/node_modules/@deepseek-ai/dsh-api-session-controller/lib/typert.remote-client.js b/node_modules/@deepseek-ai/dsh-api-session-controller/lib/typert.remote-client.js +index 2a0d24d..ae3f6fa 100644 +--- a/node_modules/@deepseek-ai/dsh-api-session-controller/lib/typert.remote-client.js ++++ b/node_modules/@deepseek-ai/dsh-api-session-controller/lib/typert.remote-client.js +@@ -170,6 +170,14 @@ const _deepseek_ai_dsh_api_session_controller_session_create_result$schema = () + 'sessionId': z.intersection(z.string(), z.unknown()).readonly(), + 'agentPreset': z.string().readonly().optional(), + })) ++let _deepseek_ai_dsh_api_session_controller_session_delete_parameter_0$schema$value ++const _deepseek_ai_dsh_api_session_controller_session_delete_parameter_0$schema = () => (_deepseek_ai_dsh_api_session_controller_session_delete_parameter_0$schema$value ??= z.object({ ++ 'sessionId': z.intersection(z.string(), z.unknown()).readonly(), ++})) ++let _deepseek_ai_dsh_api_session_controller_session_delete_result$schema$value ++const _deepseek_ai_dsh_api_session_controller_session_delete_result$schema = () => (_deepseek_ai_dsh_api_session_controller_session_delete_result$schema$value ??= z.object({ ++ 'deleted': z.literal(true).readonly(), ++})) + let _deepseek_ai_dsh_api_session_controller_session_follow_parameter_0$schema$value + const _deepseek_ai_dsh_api_session_controller_session_follow_parameter_0$schema = () => (_deepseek_ai_dsh_api_session_controller_session_follow_parameter_0$schema$value ??= z.object({ + 'address': z.union([z.object({ +@@ -892,6 +900,31 @@ export const TYPERT_REMOTE = { + }, + sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":520,"column":3}, + }, ++ { ++ id: '@deepseek-ai/dsh-api-session-controller#session/delete', ++ service: 'sessionController', ++ namespace: 'session', ++ method: 'delete', ++ invocation: { kind: 'direct' }, ++ parameters: [ ++ { ++ name: 'request', ++ wire: 'request', ++ source: 'json', ++ codec: { ++ mode: 'strict', ++ typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionDeleteRequest', ++ create: _deepseek_ai_dsh_api_session_controller_session_delete_parameter_0$schema, ++ }, ++ }, ++ ], ++ result: { ++ mode: 'strict', ++ typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionDeleteValue', ++ create: _deepseek_ai_dsh_api_session_controller_session_delete_result$schema, ++ }, ++ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":312,"column":3}, ++ }, + { + id: '@deepseek-ai/dsh-api-session-controller#session/create', + service: 'sessionController', +diff --git a/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/agent.d.ts b/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/agent.d.ts +index b2b9d2e..39e1163 100644 +--- a/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/agent.d.ts ++++ b/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/agent.d.ts +@@ -1,6 +1,6 @@ + /** Agent activation, composition, and model-selection policy owned by API Session. */ + import type { Context } from '@deepseek-ai/cordis'; +-import type { Agent, AgentSetup, ModelSelection as AgentModelSelection, ModelSelectionRef } from '@deepseek-ai/dsh-agent'; ++import type { Agent, AgentHandle, AgentSetup, ModelSelection as AgentModelSelection, ModelSelectionRef } from '@deepseek-ai/dsh-agent'; + import type { Session, SessionId } from '@deepseek-ai/dsh-session'; + import type { SessionInspection } from '@deepseek-ai/dsh-session-persistence'; + import { type SessionObservation } from '@deepseek-ai/dsh-session-query'; +@@ -67,6 +67,7 @@ export declare class ApiSessionAgentController { + private readonly ctx; + private readonly resumes; + private readonly creations; ++ private readonly handles; + private readonly selections; + private readonly imageAdmissionChains; + /** @param ctx - Host context carrying Agent, model, persistence, and Typert services. */ +@@ -83,6 +84,10 @@ export declare class ApiSessionAgentController { + * @returns the live Agent or a stable Session-domain failure. + */ + resolveObservedAgent(observation: SessionObservation): Promise; ++ /** Retain the teardown capability for an Agent created outside the normal create path. */ ++ retainHandle(handle: AgentHandle): Agent; ++ /** Dispose an ordinary Agent owned by this controller, waiting for in-flight activation first. */ ++ disposeOwned(sessionId: SessionId): Promise; + private resolve; + /** + * Resolve one requested identity, creating or resuming it once. +diff --git a/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/agent.js b/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/agent.js +index 9e3657a..0490f35 100644 +--- a/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/agent.js ++++ b/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/agent.js +@@ -165,11 +165,13 @@ export class ApiSessionAgentController { + ctx; + resumes = new Map(); + creations = new Map(); ++ handles = new Map(); + selections = new WeakMap(); + imageAdmissionChains = new WeakMap(); + /** @param ctx - Host context carrying Agent, model, persistence, and Typert services. */ + constructor(ctx) { + this.ctx = ctx; ++ ctx.on('session/disposed', (session) => { this.handles.delete(session.id); }); + ctx.typert.lookups.configure('agent', async (sessionId) => { + const found = await this.resolveAgent(sessionId); + if ('error' in found) +@@ -205,6 +207,23 @@ export class ApiSessionAgentController { + async resolveObservedAgent(observation) { + return this.resolve(observation.header.id, observation); + } ++ /** Retain the teardown capability for an Agent created outside the normal create path. */ ++ retainHandle(handle) { ++ this.handles.set(handle.agent.id, handle); ++ return handle.agent; ++ } ++ /** Dispose an ordinary Agent owned by this controller, waiting for in-flight activation first. */ ++ async disposeOwned(sessionId) { ++ const pending = [this.resumes.get(sessionId), this.creations.get(sessionId)] ++ .filter((operation) => operation !== undefined); ++ await Promise.allSettled(pending); ++ const handle = this.handles.get(sessionId); ++ if (handle === undefined) ++ return false; ++ await handle.dispose(); ++ this.handles.delete(sessionId); ++ return true; ++ } + async resolve(sessionId, observation) { + const live = this.liveAgent(sessionId); + if (live !== undefined) +@@ -445,11 +464,11 @@ export class ApiSessionAgentController { + if (published !== undefined && hasApiSessionSubagentOwner(this.ctx, published, live)) { + throw new ApiSessionSubagentOwnership(sessionId); + } +- return (await this.ctx.agents.resume({ ++ return this.retainHandle(await this.ctx.agents.resume({ + resumeSessionId: sessionId, + agentOptions: this.agentOptions(), + setup: composition.setup, +- })).agent; ++ })); + } + async createOrAdopt(sessionId, cwd, checkPersistedIdentity, presetId) { + const attached = this.ctx.sessions.get(sessionId); +@@ -473,11 +492,11 @@ export class ApiSessionAgentController { + const storedPreset = this.presetForObservation(observation); + this.assertPresetUnchanged(sessionId, presetId, storedPreset); + const composition = await this.composeAgent(storedPreset); +- return (await this.ctx.agents.resume({ ++ return this.retainHandle(await this.ctx.agents.resume({ + resumeSessionId: sessionId, + agentOptions: this.agentOptions(), + setup: composition.setup, +- })).agent; ++ })); + } + catch (e_3) { + env_3.error = e_3; +@@ -500,7 +519,7 @@ export class ApiSessionAgentController { + throw new Error(`failed to ensure project directory "${cwd}": ${String(error)}`, { cause: error }); + } + const composition = await this.composeAgent(presetId); +- return (await this.ctx.agents.create({ ++ return this.retainHandle(await this.ctx.agents.create({ + sessionId, + agentOptions: this.agentOptions(), + meta: { +@@ -508,7 +527,7 @@ export class ApiSessionAgentController { + ...(composition.agentPreset === undefined ? {} : { agentPreset: composition.agentPreset }), + }, + setup: composition.setup, +- })).agent; ++ })); + } + agentOptions() { + const { provider, model } = this.ctx.agentDefaultModel.currentSelection(); +diff --git a/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/client/contract/sessions.d.ts b/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/client/contract/sessions.d.ts +index 6eddfb2..438c8c0 100644 +--- a/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/client/contract/sessions.d.ts ++++ b/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/client/contract/sessions.d.ts +@@ -82,6 +82,8 @@ export interface ISessions { + cwd?: string; + sessionId?: SessionId; + }): Promise; ++ /** Permanently delete one ordinary Session while retaining Workspace files. */ ++ delete(sessionId: SessionId): Promise; + /** + * Resolve an already discovered direct-parent address without opening it. + * @param id - possible addressed child id. +diff --git a/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/client/sessions/manager.d.ts b/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/client/sessions/manager.d.ts +index 6075c6a..8c76fda 100644 +--- a/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/client/sessions/manager.d.ts ++++ b/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/client/sessions/manager.d.ts +@@ -164,6 +164,10 @@ export declare class SessionManager { + }): Promise>; ++ /** Contract session.delete; remove the row immediately after Host commit. */ ++ delete(sessionId: SessionId): Promise>; + /** + * Contract session.fork; on success merge the child into summaries + * immediately (same synchronous-addressability guarantee as create). +diff --git a/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/client/sessions/manager.js b/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/client/sessions/manager.js +index aeba315..6016fbc 100644 +--- a/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/client/sessions/manager.js ++++ b/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/client/sessions/manager.js +@@ -447,6 +447,13 @@ export class SessionManager { + } + return result; + } ++ /** Contract session.delete; remove the row immediately after Host commit. */ ++ async delete(sessionId) { ++ const result = await this.remote.session.delete({ sessionId }); ++ if (result.ok) ++ this.recordMutation({ kind: 'remove', sessionId }); ++ return result; ++ } + /** + * Contract session.fork; on success merge the child into summaries + * immediately (same synchronous-addressability guarantee as create). +diff --git a/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/client/sessions/service.d.ts b/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/client/sessions/service.d.ts +index 4db7072..9c81aed 100644 +--- a/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/client/sessions/service.d.ts ++++ b/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/client/sessions/service.d.ts +@@ -72,6 +72,13 @@ export declare class SessionForkError extends Error { + */ + constructor(rpcError: RemoteFailure, sourceSessionId: SessionId); + } ++/** Structured permanent Session-deletion failure. */ ++export declare class SessionDeleteError extends Error { ++ readonly rpcError: RemoteFailure; ++ readonly sessionId: SessionId; ++ readonly name = "SessionDeleteError"; ++ constructor(rpcError: RemoteFailure, sessionId: SessionId); ++} + /** Identity-stable logical binding for one materialized Client Session. */ + export interface SessionBinding { + readonly sessionId: SessionId; +@@ -181,6 +188,8 @@ export declare class ClientSessions implements ISessions { + cwd?: string; + sessionId?: SessionId; + }): Promise; ++ /** Permanently delete one ordinary Session; uiWorkspace owns clearing the selection. */ ++ delete(sessionId: SessionId): Promise; + /** + * Fork a session from an exact inclusive prefix of the source (same + * synchronous-addressability guarantee as {@link ClientSessions.create}: +diff --git a/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/client/sessions/service.js b/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/client/sessions/service.js +index 344cb96..1554a31 100644 +--- a/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/client/sessions/service.js ++++ b/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/client/sessions/service.js +@@ -34,6 +34,17 @@ export class SessionForkError extends Error { + this.sourceSessionId = sourceSessionId; + } + } ++/** Structured permanent Session-deletion failure. */ ++export class SessionDeleteError extends Error { ++ rpcError; ++ sessionId; ++ name = 'SessionDeleteError'; ++ constructor(rpcError, sessionId) { ++ super(`session delete failed: ${rpcError.code}: ${rpcError.message}`); ++ this.rpcError = rpcError; ++ this.sessionId = sessionId; ++ } ++} + // Scope primitives live in ../scope.ts (the client mirror of host + // dsh-scope, keyed by Agent identity); re-exported here so existing + // consumers keep their import site. +@@ -323,6 +334,16 @@ export class ClientSessions { + this.projectList(); + return result.value.sessionId; + } ++ /** ++ * Permanently delete one ordinary Session. Selection belongs to ++ * uiWorkspace, which releases its main view after this resolves. ++ */ ++ async delete(sessionId) { ++ const result = await this.manager.delete(sessionId); ++ if (!result.ok) ++ throw new SessionDeleteError(result.error, sessionId); ++ this.projectList(); ++ } + /** + * Fork a session from an exact inclusive prefix of the source (same + * synchronous-addressability guarantee as {@link ClientSessions.create}: +diff --git a/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/commands.d.ts b/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/commands.d.ts +index fcb93a6..5779c7c 100644 +--- a/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/commands.d.ts ++++ b/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/commands.d.ts +@@ -1,7 +1,7 @@ + /** Session commands whose activation policy is explicit at each Remote method. */ + import type { Context } from '@deepseek-ai/cordis'; + import { ApiSessionAgentController } from './agent.ts'; +-import type { SessionAttachmentRequest, SessionAttachmentValue, SessionCancelRequest, SessionCancelValue, SessionCreateRequest, SessionCreateValue, SessionForkRequest, SessionForkValue, SessionPromptRequest, SessionPromptValue, SessionRenameRequest, SessionRenameValue, SessionSelectModelRequest, SessionSelectModelValue, SessionUpdateQueueRequest, SessionUpdateQueueValue } from './types.ts'; ++import type { SessionAttachmentRequest, SessionAttachmentValue, SessionCancelRequest, SessionCancelValue, SessionCreateRequest, SessionCreateValue, SessionDeleteRequest, SessionDeleteValue, SessionForkRequest, SessionForkValue, SessionPromptRequest, SessionPromptValue, SessionRenameRequest, SessionRenameValue, SessionSelectModelRequest, SessionSelectModelValue, SessionUpdateQueueRequest, SessionUpdateQueueValue } from './types.ts'; + /** Implements Session business commands delegated by the Session Controller Remote service. */ + export declare class SessionCommandController { + private readonly ctx; +@@ -31,6 +31,8 @@ export declare class SessionCommandController { + * @returns the accepted title and durable event sequence. + */ + rename(request: SessionRenameRequest): Promise; ++ /** Permanently delete one ordinary Session while retaining its Workspace files. */ ++ delete(request: SessionDeleteRequest): Promise; + /** + * Create a new ordinary Session from an exact event prefix. An explicit + * `atSeq` is the inclusive cut; an omitted value selects the latest +diff --git a/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/commands.js b/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/commands.js +index cd4e27c..0a70822 100644 +--- a/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/commands.js ++++ b/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/commands.js +@@ -196,6 +196,47 @@ export class SessionCommandController { + throw new RemoteError('gateway/internal', `failed to rename session "${request.sessionId}": ${String(error)}`, {}); + } + } ++ /** Permanently delete one ordinary Session while retaining its Workspace files. */ ++ async delete(request) { ++ let state; ++ try { ++ state = await this.readSessionState(request.sessionId); ++ } ++ catch (error) { ++ if (error instanceof ApiSessionNotFound) { ++ throw new RemoteError('session/not-found', error.message, { sessionId: request.sessionId }); ++ } ++ throw new RemoteError('gateway/internal', `failed to inspect session "${request.sessionId}" before deletion: ${String(error)}`, {}); ++ } ++ const live = this.ctx.agents.get(request.sessionId); ++ if (hasApiSessionSubagentOwner(this.ctx, { header: state.header }, live)) { ++ throw apiSessionSubagentOwnershipError(request.sessionId); ++ } ++ const persistence = this.ctx.get('sessionPersistence'); ++ if (persistence === undefined) { ++ throw new RemoteError('gateway/internal', 'session deletion is unavailable: this deployment mounts no session-persistence service', {}); ++ } ++ const hadLiveSession = this.ctx.sessions.get(request.sessionId) !== undefined; ++ try { ++ await this.agents.disposeOwned(request.sessionId); ++ if (this.ctx.agents.get(request.sessionId) !== undefined ++ || this.ctx.sessions.get(request.sessionId) !== undefined) { ++ throw new RemoteError('session/agent-busy', `session "${request.sessionId}" is still active`, { reason: 'the live Agent is owned by another capability' }); ++ } ++ if (!(await persistence.delete(request.sessionId))) { ++ throw new RemoteError('session/not-found', `session "${request.sessionId}" not found`, { sessionId: request.sessionId }); ++ } ++ await this.ctx.workspaceRegistry.forgetSession(request.sessionId); ++ if (!hadLiveSession) ++ this.ctx.emit('api-session/removed', request.sessionId); ++ return { deleted: true }; ++ } ++ catch (error) { ++ if (remoteErrorOf(error) !== undefined) ++ throw error; ++ throw new RemoteError('gateway/internal', `failed to delete session "${request.sessionId}": ${String(error)}`, {}); ++ } ++ } + /** + * Create a new ordinary Session from an exact event prefix. An explicit + * `atSeq` is the inclusive cut; an omitted value selects the latest +@@ -245,7 +286,7 @@ export class SessionCommandController { + const composition = await this.agents.composeAgent(this.agents.presetForObservation(source)); + try { + const { provider, model } = this.ctx.agentDefaultModel.currentSelection(); +- await this.ctx.agents.create({ ++ const handle = await this.ctx.agents.create({ + sessionId: childId, + seed, + inheritedEventCount: SessionLogOffset(boundary + 1), +@@ -260,6 +301,7 @@ export class SessionCommandController { + agentOptions: { provider, model }, + setup: composition.setup, + }); ++ this.agents.retainHandle(handle); + } + catch (error) { + throw new RemoteError('gateway/internal', `failed to fork session "${request.sessionId}": ${String(error)}`, {}); +diff --git a/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/index.d.ts b/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/index.d.ts +index 58e6dd4..eb163e9 100644 +--- a/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/index.d.ts ++++ b/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/index.d.ts +@@ -7,7 +7,7 @@ import type { SessionInspection } from '@deepseek-ai/dsh-session-persistence'; + import { TypertRemoteService } from '@deepseek-ai/dsh-typert-protocol'; + import { type ApiSessionAgentResult } from './agent.ts'; + import { buildModelCatalog } from './catalog.ts'; +-import type { ModelCatalog, SessionWorkspacePathApplication, SessionAttachmentRequest, SessionAttachmentValue, SessionCancelRequest, SessionCancelValue, SessionControlFrame, SessionCreateRequest, SessionCreateValue, SessionFollowFrame, SessionFollowRequest, SessionForkRequest, SessionForkValue, SessionListRequest, SessionListValue, SessionOpenWorkspacePathRequest, SessionOpenWorkspacePathValue, SessionPage, SessionPageRequest, SessionPromptRequest, SessionPromptValue, SessionRenameRequest, SessionRenameValue, SessionSearchRequest, SessionSearchValue, SessionSelectModelRequest, SessionSelectModelValue, SessionProjectionsRequest, SessionProjectionsValue, SessionUpdateQueueRequest, SessionUpdateQueueValue } from './types.ts'; ++import type { ModelCatalog, SessionWorkspacePathApplication, SessionAttachmentRequest, SessionAttachmentValue, SessionCancelRequest, SessionCancelValue, SessionControlFrame, SessionCreateRequest, SessionCreateValue, SessionFollowFrame, SessionDeleteRequest, SessionDeleteValue, SessionFollowRequest, SessionForkRequest, SessionForkValue, SessionListRequest, SessionListValue, SessionOpenWorkspacePathRequest, SessionOpenWorkspacePathValue, SessionPage, SessionPageRequest, SessionPromptRequest, SessionPromptValue, SessionRenameRequest, SessionRenameValue, SessionSearchRequest, SessionSearchValue, SessionSelectModelRequest, SessionSelectModelValue, SessionProjectionsRequest, SessionProjectionsValue, SessionUpdateQueueRequest, SessionUpdateQueueValue } from './types.ts'; + export type * from './types.ts'; + export { ApiSessionNotFound } from './agent.ts'; + export { SessionFileReferences } from './file-references.ts'; +@@ -146,6 +146,8 @@ export declare class SessionController extends TypertRemoteService { + * @returns the accepted title and durable event sequence. + */ + rename(request: SessionRenameRequest): Promise; ++ /** Permanently delete one ordinary Session while retaining Workspace files. */ ++ delete(request: SessionDeleteRequest): Promise; + /** + * Fork one cold-readable exact event prefix into a new Session. An omitted + * boundary selects the latest completed-turn prefix; an open cut receives +diff --git a/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/index.js b/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/index.js +index fa9422e..933ae11 100644 +--- a/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/index.js ++++ b/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/index.js +@@ -120,6 +120,7 @@ let SessionController = (() => { + let _openWorkspacePath_decorators; + let _workspacePathApplications_decorators; + let _rename_decorators; ++ let _delete_decorators; + let _fork_decorators; + let _prompt_decorators; + let _attachment_decorators; +@@ -142,6 +143,7 @@ let SessionController = (() => { + _openWorkspacePath_decorators = [Remote('openWorkspacePath')]; + _workspacePathApplications_decorators = [Remote('workspacePathApplications')]; + _rename_decorators = [Remote('rename')]; ++ _delete_decorators = [Remote('delete')]; + _fork_decorators = [Remote('fork')]; + _prompt_decorators = [Remote('prompt')]; + _attachment_decorators = [Remote('attachment')]; +@@ -161,6 +163,7 @@ let SessionController = (() => { + __esDecorate(this, null, _openWorkspacePath_decorators, { kind: "method", name: "openWorkspacePath", static: false, private: false, access: { has: obj => "openWorkspacePath" in obj, get: obj => obj.openWorkspacePath }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate(this, null, _workspacePathApplications_decorators, { kind: "method", name: "workspacePathApplications", static: false, private: false, access: { has: obj => "workspacePathApplications" in obj, get: obj => obj.workspacePathApplications }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate(this, null, _rename_decorators, { kind: "method", name: "rename", static: false, private: false, access: { has: obj => "rename" in obj, get: obj => obj.rename }, metadata: _metadata }, null, _instanceExtraInitializers); ++ __esDecorate(this, null, _delete_decorators, { kind: "method", name: "delete", static: false, private: false, access: { has: obj => "delete" in obj, get: obj => obj.delete }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate(this, null, _fork_decorators, { kind: "method", name: "fork", static: false, private: false, access: { has: obj => "fork" in obj, get: obj => obj.fork }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate(this, null, _prompt_decorators, { kind: "method", name: "prompt", static: false, private: false, access: { has: obj => "prompt" in obj, get: obj => obj.prompt }, metadata: _metadata }, null, _instanceExtraInitializers); + __esDecorate(this, null, _attachment_decorators, { kind: "method", name: "attachment", static: false, private: false, access: { has: obj => "attachment" in obj, get: obj => obj.attachment }, metadata: _metadata }, null, _instanceExtraInitializers); +@@ -237,7 +240,8 @@ let SessionController = (() => { + // answer the Workspace registry's archive-admission events. + ctx.plugin(ArchivedSessionGate); + ctx.on('session/created', (session) => { +- ctx.emit('api-session/added', this.listState.summaryFor(session)); ++ const { projections: _projections, ...remoteSummary } = this.listState.summaryFor(session); ++ ctx.emit('api-session/added', remoteSummary); + }); + ctx.on('session/disposed', (session) => { + ctx.emit('api-session/removed', session.id); +@@ -457,6 +461,10 @@ let SessionController = (() => { + rename(request) { + return this.commands.rename(request); + } ++ /** Permanently delete one ordinary Session while retaining Workspace files. */ ++ delete(request) { ++ return this.commands.delete(request); ++ } + /** + * Fork one cold-readable exact event prefix into a new Session. An omitted + * boundary selects the latest completed-turn prefix; an open cut receives +diff --git a/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/types.d.ts b/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/types.d.ts +index 1ce67e4..20eb105 100644 +--- a/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/types.d.ts ++++ b/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/types.d.ts +@@ -305,6 +305,14 @@ export interface SessionRenameValue { + readonly title: string; + readonly seq: number; + } ++/** Session permanent-deletion request. */ ++export interface SessionDeleteRequest { ++ readonly sessionId: SessionId; ++} ++/** Session permanent-deletion response. */ ++export interface SessionDeleteValue { ++ readonly deleted: true; ++} + /** Session fork request. */ + export interface SessionForkRequest { + readonly sessionId: SessionId; diff --git a/patches/@deepseek-ai+dsh-app-boot+0.1.7-rc.2.patch b/patches/@deepseek-ai+dsh-app-boot+0.1.7-rc.2.patch new file mode 100644 index 000000000..160306d5b --- /dev/null +++ b/patches/@deepseek-ai+dsh-app-boot+0.1.7-rc.2.patch @@ -0,0 +1,190 @@ +diff --git a/node_modules/@deepseek-ai/dsh-app-boot/lib/index.js b/node_modules/@deepseek-ai/dsh-app-boot/lib/index.js +index 8f6041d..ed13f1f 100644 +--- a/node_modules/@deepseek-ai/dsh-app-boot/lib/index.js ++++ b/node_modules/@deepseek-ai/dsh-app-boot/lib/index.js +@@ -318,8 +318,17 @@ function evaluatePluginCompatibility(manifest, exemptions = {}, runtimeVersion = + * @returns an English diagnostic for logs and stderr. + */ + function pluginCompatibilityWarning(issue) { +- const key = `${issue.name}@${issue.version}`; +- return `Plugin ${key} is incompatible with dsh ${issue.runtimeVersion}: peerDependencies ${JSON.stringify(issue.peers)}. Running it may cause crashes or data loss. Update the plugin or install a plugin version compatible with this dsh runtime. To accept this risk explicitly, grant the exact-version exemption for ${key} on dsh ${issue.runtimeVersion} with \`dsh plugin allow-version\` or the plugin manager, then retry the installation or restart dsh. Exact-version exemption: ${issue.exempted ? "active" : "not active"}.`; ++ return `Plugin ${issue.name}@${issue.version} declares Harness peerDependencies ${JSON.stringify(issue.peers)} that do not include dsh ${issue.runtimeVersion}. Compatibility is unverified; Desktop will attempt loading it and report actual import or activation failures.`; ++} ++// Desktop treats declared version ranges as advisory. Keep evaluation pure for ++// diagnostics; report once per declaration/runtime per process, without writing ++// exemptions or changing the installed plugin manifest. ++const reportedPluginCompatibility = new Set(); ++function reportPluginCompatibility(issue) { ++ const message = pluginCompatibilityWarning(issue); ++ if (reportedPluginCompatibility.has(message)) return; ++ reportedPluginCompatibility.add(message); ++ process.stderr.write(`[desktop] compatibility warning: ${message}\n`); + } + //#endregion + //#region lib/types/profile-compatibility.js +@@ -835,6 +844,17 @@ function readProfileManifest(binName, dir) { + if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error(`${binName}: profile manifest ${path} must hold a JSON object`); + return parsed; + } ++// The market package switch must be read before preparing bundle manifests. ++// An unreadable state cannot authorize skipping any bundle. ++function readDisabledProfileBundles(dir) { ++ try { ++ const state = JSON.parse(readFileSync(join(dir, ".dsh-market", "state.json"), "utf8")); ++ const list = state.disabled !== void 0 ? state.disabled : state.disabledSkins; ++ return new Set(Array.isArray(list) ? list.filter((name) => typeof name === "string") : []); ++ } catch { ++ return new Set(); ++ } ++} + /** + * Write a profile's manifest back (2-space JSON, trailing newline). + * @param dir - the profile directory. +@@ -916,31 +936,49 @@ function resolveBundleDir(binName, packageName, installAnchor, profileDir) { + * @param options - `userLayer: false` skips reading `cordis.patch.yml`. + * @returns the successfully loaded bundle layers and optional user patch layer. + */ ++// Bundle ownership survives patch composition and nested Loader groups. ++function annotatePluginPatches(patches, owner) { ++ const annotate = (row) => { ++ row.__dshPluginOwner = owner; ++ if (row.group && Array.isArray(row.config)) row.config.forEach(annotate); ++ }; ++ for (const patch of patches) { ++ if (Array.isArray(patch.insert)) patch.insert.forEach(annotate); ++ else annotate(patch); ++ } ++ return patches; ++} + function loadProfileDirectory(binName, dir, installAnchor, options = {}) { + const bundles = readProfileManifest(binName, dir).dsh?.profile?.bundles ?? []; ++ const disabled = readDisabledProfileBundles(dir); + const layers = []; + const skippedBundles = []; + const exemptions = bundles.length === 0 ? {} : readProfileVersionExemptions(dir); +- for (const packageName of bundles) try { ++ for (const packageName of bundles) { ++ if (disabled.has(packageName)) continue; ++ const owner = { packageName }; ++ try { + const packageDir = resolveBundleDir(binName, packageName, installAnchor, dir); ++ owner.packageDir = packageDir; + const bundleManifest = readProfileManifest(binName, packageDir); ++ owner.version = bundleManifest.version; + const bundle = bundleManifest.dsh?.bundle; + if (bundle === void 0) throw new Error(`${binName}: profile bundle ${JSON.stringify(packageName)} declares no dsh.bundle in its package.json`); + const issue = evaluatePluginCompatibility(bundleManifest, exemptions); +- if (issue !== void 0 && !issue.exempted) throw new Error(pluginCompatibilityWarning(issue)); ++ if (issue !== void 0 && !issue.exempted) reportPluginCompatibility(issue); + const patchPaths = bundlePatchPaths(packageDir, bundle); +- const patches = patchPaths.flatMap((patchPath) => loadOverlayPatches(binName, patchPath)); ++ const patches = annotatePluginPatches(patchPaths.flatMap((patchPath) => loadOverlayPatches(binName, patchPath)), owner); + layers.push({ + packageName, + packageDir, + patchPaths, + patches + }); +- } catch (error) { +- skippedBundles.push({ +- packageName, +- reason: String(error) +- }); ++ } catch (cause) { ++ const error = new Error(`${binName}: failed to prepare profile bundle ${packageName}`, { cause }); ++ error.dshPluginFailure = { stage: "prepare", packageName, owner, chain: [], message: cause instanceof Error ? cause.message : String(cause) }; ++ throw error; ++ } + } + const patchPath = join(dir, PROFILE_PATCH_FILENAME); + const patches = options.userLayer !== false && existsSync(patchPath) ? loadOverlayPatches(binName, patchPath) : []; +@@ -2076,7 +2114,8 @@ function preflight(ctx, entries, parentURL, report) { + const manifest = manifestOf(ctx, row.name, base); + if (manifest === void 0) return void 0; + const issue = evaluatePluginCompatibility(manifest, exemptions); +- return issue === void 0 || issue.exempted ? void 0 : pluginCompatibilityWarning(issue); ++ if (issue !== void 0 && !issue.exempted) reportPluginCompatibility(issue); ++ return void 0; + } catch (error) { + return `its declared peer dependencies cannot be validated: ${error instanceof Error ? error.message : String(error)}`; + } +@@ -3869,7 +3908,10 @@ var StartupError = class extends Error { + * @param entries - inactive plugin metadata and original failure values. + */ + constructor(message, entries) { +- const failures = entries.flatMap(({ outcome }) => outcome.kind === "failed" ? [outcome.error] : []); ++ const failures = entries.flatMap(({ outcome, failure }) => { ++ const original = outcome.kind === "failed" ? [outcome.error] : []; ++ return failure === void 0 ? original : [...original, failure]; ++ }); + super(message, failures.length > 0 ? { cause: new AggregateError(failures, "Plugin activation failures") } : void 0); + this.entries = entries; + Object.defineProperties(this, { +@@ -3906,7 +3948,7 @@ async function inactiveEntries(ctx) { + entry, + outcome: { + kind: "failed", +- error: "failed to import" ++ error: entry.lastImportError ?? "failed to import" + } + }); + continue; +@@ -4007,13 +4049,14 @@ function startupDiagnostic(binName, failures, required) { + */ + async function auditStartupEntries(ctx, binName, warn = (line) => void process.stderr.write(line)) { + const failures = await inactiveEntries(ctx); +- const required = new Set(failures.filter(({ entry }) => entry === bootstrapIncludes.get(ctx) || requiredStartupEntryIds.has(entry.options.id)).map(({ entry }) => entry)); ++ const required = new Set(failures.map(({ entry }) => entry)); + if (required.size > 0) throw new StartupError(startupDiagnostic(binName, failures, required), failures.map(({ entry, outcome }) => ({ + id: entry.options.id, + module: entry.options.name, + required: required.has(entry), + fiberState: entry.fiber?.state, +- outcome ++ outcome, ++ failure: entry._failure(outcome.kind === "pending" ? "activate" : entry.fiber === void 0 ? "import" : "apply", outcome.kind === "failed" ? outcome.error : new Error(`pending (waiting for ${outcome.missing.length === 1 ? "service" : "services"}: ${outcome.missing.join(", ") || "unknown"})`)) + }))); + if (failures.length > 0) warn(activationDiagnostic(binName, failures)); + } +@@ -4085,7 +4128,11 @@ async function boot(binName, absoluteConfigPath, patches, prepare, bareModuleBas + await auditStartupEntries(ctx, binName); + return ctx; + } catch (cause) { +- await ctx.fiber.dispose(); ++ try { ++ await ctx.fiber.dispose(); ++ } catch (cleanupError) { ++ cause = new AggregateError([cause, cleanupError], "plugin boot and cleanup failed"); ++ } + if (cause instanceof StartupError) { + cause.startup = { + configurationPath: absoluteConfigPath, +@@ -4133,4 +4180,4 @@ function addHarnessSourceSection(ctx, sourceRoot) { + }); + } + //#endregion +-export { DEFAULT_PROFILE_BUNDLES, FAIL_LOUD_RELEASE_TIMEOUT_MS, HARNESS_SOURCE_SECTION, LOADER_EXPRESSION_SCHEMA, OPTIONAL_BUNDLES, PROFILES_DIR, PROFILE_COMPATIBILITY_FILENAME, PROFILE_PATCH_FILENAME, PROFILE_TEMPLATES, PluginPackages, StartupError, addHarnessSourceSection, auditStartupEntries, boot, bundlePatchFiles, bundlePatchPaths, composeEntries, createConfigProjector, createRuntimeResolution, evaluatePluginCompatibility, generateConfigSchema, getDshRuntimeVersion, initProfile, installFailLoud, isNativeConfigSchema, loadEnv, loadLayeredEnv, loadOptionalPatches, loadOverlayPatches, loadProfile, loadProfileDirectory, mountRootInclude, pluginCompatibilityWarning, prepareProfileEntries, prepareProfilePatches, readPluginMeta, readProfileCompatibility, readProfileManifest, readProfilePatches, readProfilePlugins, readProfileVersionExemptions, reconcileProfilePatches, reconcileProfilePlugins, removeLinkProjections, renderConfigDump, reportSkippedBundles, resolveBundleDir, resolveConfigPath, resolveProfileDir, resolveTelemetryPatch, sanitizeProfile, setProfileVersionExemption, writeProfileBundles, writeProfileManifest }; ++export { DEFAULT_PROFILE_BUNDLES, FAIL_LOUD_RELEASE_TIMEOUT_MS, HARNESS_SOURCE_SECTION, LOADER_EXPRESSION_SCHEMA, OPTIONAL_BUNDLES, PROFILES_DIR, PROFILE_COMPATIBILITY_FILENAME, PROFILE_PATCH_FILENAME, PROFILE_TEMPLATES, PluginPackages, StartupError, addHarnessSourceSection, auditStartupEntries, boot, bundlePatchFiles, bundlePatchPaths, composeEntries, createConfigProjector, createRuntimeResolution, evaluatePluginCompatibility, generateConfigSchema, getDshRuntimeVersion, reportPluginCompatibility, initProfile, installFailLoud, isNativeConfigSchema, loadEnv, loadLayeredEnv, loadOptionalPatches, loadOverlayPatches, loadProfile, loadProfileDirectory, mountRootInclude, pluginCompatibilityWarning, prepareProfileEntries, prepareProfilePatches, readPluginMeta, readProfileCompatibility, readProfileManifest, readProfilePatches, readProfilePlugins, readProfileVersionExemptions, reconcileProfilePatches, reconcileProfilePlugins, removeLinkProjections, renderConfigDump, reportSkippedBundles, resolveBundleDir, resolveConfigPath, resolveProfileDir, resolveTelemetryPatch, sanitizeProfile, setProfileVersionExemption, writeProfileBundles, writeProfileManifest }; +diff --git a/node_modules/@deepseek-ai/dsh-app-boot/lib/types/index.d.ts b/node_modules/@deepseek-ai/dsh-app-boot/lib/types/index.d.ts +index 5e9a393..7eb148e 100644 +--- a/node_modules/@deepseek-ai/dsh-app-boot/lib/types/index.d.ts ++++ b/node_modules/@deepseek-ai/dsh-app-boot/lib/types/index.d.ts +@@ -12,7 +12,7 @@ import { dshHomePath } from '@deepseek-ai/dsh-home-paths'; + import { type LaunchEnvironmentSnapshot } from '@deepseek-ai/dsh-launch-environment'; + export { readProfilePatches, resolveTelemetryPatch, type ProfileContext, type ProfilePnpmInvocation } from './profile-context.ts'; + export { sanitizeProfile } from './profile-sanitize.ts'; +-export { getDshRuntimeVersion, evaluatePluginCompatibility, pluginCompatibilityWarning, type PluginCompatibility } from './plugin-compatibility.ts'; ++export { getDshRuntimeVersion, evaluatePluginCompatibility, pluginCompatibilityWarning, reportPluginCompatibility, type PluginCompatibility } from './plugin-compatibility.ts'; + export { PROFILE_COMPATIBILITY_FILENAME, readProfileCompatibility, readProfileVersionExemptions, setProfileVersionExemption, type ProfileCompatibility, } from './profile-compatibility.ts'; + export { prepareProfileEntries, prepareProfilePatches } from './compatibility-preflight.ts'; + export { readPluginMeta } from './package-meta.ts'; +diff --git a/node_modules/@deepseek-ai/dsh-app-boot/lib/types/plugin-compatibility.d.ts b/node_modules/@deepseek-ai/dsh-app-boot/lib/types/plugin-compatibility.d.ts +index 5e91973..23bf288 100644 +--- a/node_modules/@deepseek-ai/dsh-app-boot/lib/types/plugin-compatibility.d.ts ++++ b/node_modules/@deepseek-ai/dsh-app-boot/lib/types/plugin-compatibility.d.ts +@@ -33,3 +33,5 @@ export declare function evaluatePluginCompatibility(manifest: object, exemptions + */ + export declare function pluginCompatibilityWarning(issue: PluginCompatibility): string; + //# sourceMappingURL=plugin-compatibility.d.ts.map ++/** Report an unverified version declaration without blocking installation or loading. */ ++export declare function reportPluginCompatibility(issue: PluginCompatibility): void; diff --git a/patches/@deepseek-ai+dsh-client-file-upload+0.1.7-rc.2.patch b/patches/@deepseek-ai+dsh-client-file-upload+0.1.7-rc.2.patch new file mode 100644 index 000000000..1b9fcab90 --- /dev/null +++ b/patches/@deepseek-ai+dsh-client-file-upload+0.1.7-rc.2.patch @@ -0,0 +1,24 @@ +diff --git a/node_modules/@deepseek-ai/dsh-client-file-upload/lib/index.js b/node_modules/@deepseek-ai/dsh-client-file-upload/lib/index.js +index 4094ab6..6cc5771 100644 +--- a/node_modules/@deepseek-ai/dsh-client-file-upload/lib/index.js ++++ b/node_modules/@deepseek-ai/dsh-client-file-upload/lib/index.js +@@ -231,6 +231,19 @@ let FileUploads = (() => { + return this.stagedFiles.get(agent.session)?.get(receiptId)?.file; + } + /** ++ * Find one staged durable file by attachment id inside the Agent scope. ++ * @param agent - receiving Agent. ++ * @param attachmentId - content-addressed file identity. ++ * @returns durable file reference, or `undefined` when nothing staged matches. ++ */ ++ findStagedFile(agent, attachmentId) { ++ this.assertAgentScope(agent); ++ const staged = this.stagedFiles.get(agent.session); ++ if (staged === void 0) return; ++ const id = String(attachmentId); ++ for (const upload of staged.values()) if (String(upload.file.attachmentId) === id) return upload.file; ++ } ++ /** + * Bind receipts while one prompt enters an Agent inbox. + * Disposal restores every prior binding unless the caller commits successful delivery. + * @param agent - receiving Agent. diff --git a/patches/@deepseek-ai+dsh-client-modules+0.1.7-rc.2.patch b/patches/@deepseek-ai+dsh-client-modules+0.1.7-rc.2.patch new file mode 100644 index 000000000..3c4f4bd69 --- /dev/null +++ b/patches/@deepseek-ai+dsh-client-modules+0.1.7-rc.2.patch @@ -0,0 +1,66 @@ +diff --git a/node_modules/@deepseek-ai/dsh-client-modules/lib/index.js b/node_modules/@deepseek-ai/dsh-client-modules/lib/index.js +index b948b1b..197762d 100644 +--- a/node_modules/@deepseek-ai/dsh-client-modules/lib/index.js ++++ b/node_modules/@deepseek-ai/dsh-client-modules/lib/index.js +@@ -283,7 +283,7 @@ function readSourceMap(clientPath) { + /** Count generated lines while assembling indexed-map section offsets. */ + function newlineCount(value) { + let count = 0; +- for (const char of value) if (char === "\n") count += 1; ++ for (let index = value.indexOf("\n"); index !== -1; index = value.indexOf("\n", index + 1)) count += 1; + return count; + } + /** Resolve section sources against their original per-plugin map URL before combo relocation. */ +@@ -305,7 +305,8 @@ function comboSectionMap(resource, original) { + } + /** Map each generated line to the same line in a bundled JavaScript source. */ + function identitySectionMap(source, sourceUrl) { +- const mappings = Array.from({ length: newlineCount(source) }, (_, index) => index === 0 ? "AAAA" : "AACA").join(";"); ++ const lines = newlineCount(source); ++ const mappings = lines === 0 ? "" : `AAAA${";AACA".repeat(lines - 1)}`; + return { + version: 3, + names: [], +@@ -378,6 +379,16 @@ function buildCombo(records, sourceMapOf, revision) { + sourceMapBody: lazyBody(() => buildComboSourceMap(resources, sourceMapOf)) + }; + } ++const recordComboCache = /* @__PURE__ */ new WeakMap(); ++/** Reuse one-record combo metadata until the record's content revision changes. */ ++function recordCombo(record, sourceMapOf) { ++ const cached = recordComboCache.get(record); ++ if (cached?.rev === record.entry.rev) return cached.artifact; ++ const artifact = buildCombo([record], sourceMapOf, record.entry.rev); ++ recordComboCache.set(record, { rev: record.entry.rev, artifact }); ++ return artifact; ++} ++ + /** Add initial-load scheduling metadata to a combo artifact. */ + function buildBatch(phase, records, sourceMapOf) { + const artifact = buildCombo(records, sourceMapOf); +@@ -667,7 +678,7 @@ var ClientModuleRegistry = class extends Service { + } + const responses = new Map(batchResponses); + for (const record of this.table.values()) { +- const artifact = buildCombo([record], this.readSourceMap, record.entry.rev); ++ const artifact = recordCombo(record, this.readSourceMap); + responses.set(artifact.url, responses.get(artifact.url) ?? this.responses.get(artifact.url) ?? { + body: artifact.scriptBody, + contentType: "text/javascript; charset=utf-8" +@@ -767,7 +778,15 @@ var ClientModuleRegistry = class extends Service { + attributes: {} + }).url : internal.resolveSync(loaderName, baseUrl, {}).url; + } catch { +- return; ++ if (expectedPackageName === void 0) return; ++ try { ++ return { ++ path: createRequire(baseUrl).resolve(`${expectedPackageName}/package.json`), ++ packageName: expectedPackageName ++ }; ++ } catch { ++ return; ++ } + } + return this.nearestPackage(moduleUrl, expectedPackageName); + } diff --git a/patches/@deepseek-ai+dsh-client-shortcuts+0.1.7-rc.2.patch b/patches/@deepseek-ai+dsh-client-shortcuts+0.1.7-rc.2.patch new file mode 100644 index 000000000..fc0754fc7 --- /dev/null +++ b/patches/@deepseek-ai+dsh-client-shortcuts+0.1.7-rc.2.patch @@ -0,0 +1,13 @@ +diff --git a/node_modules/@deepseek-ai/dsh-client-shortcuts/lib/client.js b/node_modules/@deepseek-ai/dsh-client-shortcuts/lib/client.js +index 8670231..0367eb1 100644 +--- a/node_modules/@deepseek-ai/dsh-client-shortcuts/lib/client.js ++++ b/node_modules/@deepseek-ai/dsh-client-shortcuts/lib/client.js +@@ -721,7 +721,7 @@ window.__ModuleLoader__.load({ + const desktop = document.documentElement.dataset.platform; + const device = desktop ?? navigator.platform; + return { +- runtime: desktop === void 0 ? "web" : "desktop", ++ runtime: desktop === void 0 || document.documentElement.dataset.dshDesktopWebShortcuts === "true" ? "web" : "desktop", + platform: /darwin|mac|iphone|ipad/iu.test(device) ? "macos" : /win/iu.test(device) ? "windows" : "linux" + }; + } diff --git a/patches/@deepseek-ai+dsh-client-ui-agent-preset+0.1.7-rc.2.patch b/patches/@deepseek-ai+dsh-client-ui-agent-preset+0.1.7-rc.2.patch new file mode 100644 index 000000000..d0ae9e749 --- /dev/null +++ b/patches/@deepseek-ai+dsh-client-ui-agent-preset+0.1.7-rc.2.patch @@ -0,0 +1,215 @@ +diff --git a/node_modules/@deepseek-ai/dsh-client-ui-agent-preset/lib/client.js b/node_modules/@deepseek-ai/dsh-client-ui-agent-preset/lib/client.js +index 7f96b5f..14780a1 100644 +--- a/node_modules/@deepseek-ai/dsh-client-ui-agent-preset/lib/client.js ++++ b/node_modules/@deepseek-ai/dsh-client-ui-agent-preset/lib/client.js +@@ -271,6 +271,7 @@ window.__ModuleLoader__.load({ + /** Locale bundles for the agent-preset hero chip, header label, and management section. */ + /** English copy. */ + const en = { ++ desktopImport: "Import", desktopAwesome: "Awesome preset", desktopSearch: "Search presets", + ...guideEn, + builtInGroup: "Built-in", + customGroup: "Custom", +@@ -299,6 +300,7 @@ window.__ModuleLoader__.load({ + }; + /** Simplified Chinese copy. */ + const zh = { ++ desktopImport: "导入", desktopAwesome: "Awesome preset", desktopSearch: "搜索预设", + ...guideZh, + builtInGroup: "内置", + customGroup: "自定义", +@@ -854,6 +856,85 @@ window.__ModuleLoader__.load({ + function AgentPresetSection({ useAgentPresetSection, load, view, closeView, makeDefault, startCreatorDraft, close: closeSettings, useDeveloperTools, t }) { + const state = useAgentPresetSection((value) => value); + const developerTools = useDeveloperTools((enabled) => enabled); ++ const chinese = document.documentElement.lang?.toLowerCase().startsWith("zh"); ++ const copy = chinese ? { ++ import: "导入", export: "导出预设", search: "搜索预设", awesome: "Awesome preset", ++ trust: "自定义预设可以使用与 Agent 相同权限的工具和命令。请只导入可信来源。", ++ rename: "预设 ID", conflict: "该 ID 已存在,请换一个名称。", install: "安装并在重启后启用", ++ restart: "预设已导入。重启 DSH Desktop 后生效。", cancel: "取消" ++ } : { ++ import: "Import", export: "Export preset", search: "Search presets", awesome: "Awesome preset", ++ trust: "Custom presets can run tools and commands with the same permissions as the Agent. Import only from trusted sources.", ++ rename: "Preset ID", conflict: "This ID already exists. Choose another name.", install: "Install and enable after restart", ++ restart: "Preset imported. Restart DSH Desktop to use it.", cancel: "Cancel" ++ }; ++ const [search, setSearch] = (0, react.useState)(""); ++ const [importFile, setImportFile] = (0, react.useState)(null); ++ const [importDraft, setImportDraft] = (0, react.useState)(null); ++ const [importId, setImportId] = (0, react.useState)(""); ++ const [importBusy, setImportBusy] = (0, react.useState)(false); ++ const [transferError, setTransferError] = (0, react.useState)(null); ++ const [transferNotice, setTransferNotice] = (0, react.useState)(null); ++ const importInput = (0, react.useRef)(null); ++ const transferUrl = (id = "", install = false) => { ++ const params = new URLSearchParams(); ++ if (id) params.set("agentPreset", id); ++ if (install) params.set("install", "1"); ++ const query = params.toString(); ++ return `/api/agent-preset.import${query ? `?${query}` : ""}`; ++ }; ++ const readTransferError = async (response) => { ++ const body = await response.json().catch(() => ({})); ++ return body.error ?? `HTTP ${response.status}`; ++ }; ++ const previewImport = async (file) => { ++ setImportBusy(true); ++ setTransferError(null); ++ try { ++ const response = await fetch(transferUrl(), { method: "POST", headers: { "content-type": "application/vnd.dsh.preset+zip" }, body: file }); ++ if (!response.ok) throw new Error(await readTransferError(response)); ++ const draft = await response.json(); ++ setImportFile(file); ++ setImportDraft(draft); ++ setImportId(draft.agentPreset); ++ } catch (error) { ++ setTransferError(error instanceof Error ? error.message : String(error)); ++ } finally { ++ setImportBusy(false); ++ } ++ }; ++ const confirmImport = async () => { ++ if (!importFile) return; ++ setImportBusy(true); ++ setTransferError(null); ++ try { ++ const response = await fetch(transferUrl(importId.trim().toLowerCase(), true), { method: "POST", headers: { "content-type": "application/vnd.dsh.preset+zip" }, body: importFile }); ++ if (!response.ok) throw new Error(await readTransferError(response)); ++ setImportFile(null); ++ setImportDraft(null); ++ setTransferNotice(copy.restart); ++ } catch (error) { ++ setTransferError(error instanceof Error ? error.message : String(error)); ++ } finally { ++ setImportBusy(false); ++ } ++ }; ++ const exportPreset = async (id) => { ++ setTransferError(null); ++ try { ++ const response = await fetch(`/api/agent-preset.export?agentPreset=${encodeURIComponent(id)}`); ++ if (!response.ok) throw new Error(await readTransferError(response)); ++ const url = URL.createObjectURL(await response.blob()); ++ try { ++ const anchor = document.createElement("a"); ++ anchor.href = url; ++ anchor.download = `${id}.dshpreset`; ++ anchor.click(); ++ } finally { setTimeout(() => URL.revokeObjectURL(url), 0); } ++ } catch (error) { ++ setTransferError(error instanceof Error ? error.message : String(error)); ++ } ++ }; + const [guide, setGuide] = (0, react.useState)(null); + const viewTrigger = (0, react.useRef)(null); + const closeViewOnUnmount = (0, react.useRef)(closeView); +@@ -888,21 +969,53 @@ window.__ModuleLoader__.load({ + return (0, react_jsx_runtime.jsxs)("section", { + className: AgentPresetSection_module_css_default.section, + children: [ +- (0, react_jsx_runtime.jsx)("h2", { +- className: AgentPresetSection_module_css_default.title, +- children: t("nav") +- }), ++ (0, react_jsx_runtime.jsxs)("div", { ++ "data-dsh-preset-heading": "", ++ children: [(0, react_jsx_runtime.jsx)("h2", { ++ className: AgentPresetSection_module_css_default.title, ++ children: t("nav") ++ }), (0, react_jsx_runtime.jsxs)("div", { ++ "data-dsh-preset-actions": "", ++ children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, { ++ variant: "outline", disabled: importBusy, ++ icon: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconArchiveOutlineRegular, { size: 16 }), ++ onClick: () => importInput.current?.click(), children: t("desktopImport") ++ }), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, { ++ variant: "outline", ++ onClick: () => window.open("https://www.dshdesktop.com/preset/", "_blank", "noopener,noreferrer"), ++ children: t("desktopAwesome") ++ })] ++ })] ++ }), + (0, react_jsx_runtime.jsx)("p", { + className: AgentPresetSection_module_css_default.intro, + children: t("sectionIntro") + }), ++ (0, react_jsx_runtime.jsxs)("div", { ++ "data-dsh-preset-search": "", ++ children: [ ++ (0, react_jsx_runtime.jsx)("input", { ++ type: "search", value: search, placeholder: t("desktopSearch"), ++ "aria-label": t("desktopSearch"), onChange: (event) => setSearch(event.target.value), ++ ++ }), ++ ++ (0, react_jsx_runtime.jsx)("input", { ++ ref: importInput, type: "file", accept: ".dshpreset,application/zip", style: { display: "none" }, ++ onChange: (event) => { const file = event.target.files?.[0]; if (file) void previewImport(file); event.target.value = ""; } ++ }) ++ ] ++ }), ++ transferError && (0, react_jsx_runtime.jsx)("p", { role: "alert", children: transferError }), ++ transferNotice && (0, react_jsx_runtime.jsx)("p", { role: "status", children: transferNotice }), + state.error === null ? null : (0, react_jsx_runtime.jsx)("p", { + className: AgentPresetSection_module_css_default.error, + role: "alert", + children: state.error + }), + [true, false].map((builtIn) => { +- const rows = state.rows.filter((row) => isBuiltInPreset(row) === builtIn); ++ const query = search.trim().toLowerCase(); ++ const rows = state.rows.filter((row) => isBuiltInPreset(row) === builtIn && (query === "" || `${row.id} ${presetDisplayText(row, t).name} ${presetDisplayText(row, t).description ?? ""}`.toLowerCase().includes(query))); + const entry = builtIn ? null : creatorButton; + if (rows.length === 0 && entry === null) return null; + return (0, react_jsx_runtime.jsxs)("section", { +@@ -1011,7 +1124,13 @@ window.__ModuleLoader__.load({ + view(row.id); + }, + children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconBrowseOutlineRegular, {}) +- })] ++ }), !builtIn && (0, react_jsx_runtime.jsx)("button", { ++ type: "button", ++ "aria-label": `${copy.export}: ${display.name}`, ++ title: copy.export, ++ onClick: () => { void exportPreset(row.id); }, ++ children: copy.export ++ })] + })] + }, row.id); + }) +@@ -1028,6 +1147,34 @@ window.__ModuleLoader__.load({ + setGuide(null); + } + }), ++ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, { ++ open: importDraft !== null, ++ onClose: () => { if (!importBusy) { setImportDraft(null); setImportFile(null); setTransferError(null); } }, ++ closeLabel: copy.cancel, ++ title: copy.import, ++ footer: (0, react_jsx_runtime.jsxs)("div", { ++ style: { display: "flex", gap: 8, justifyContent: "flex-end" }, ++ children: [ ++ (0, react_jsx_runtime.jsx)("button", { type: "button", disabled: importBusy, onClick: () => { setImportDraft(null); setImportFile(null); setTransferError(null); }, children: copy.cancel }), ++ (0, react_jsx_runtime.jsx)("button", { ++ type: "button", disabled: importBusy || !/^[a-z0-9][a-z0-9-]*$/.test(importId.trim().toLowerCase()) || importDraft?.conflict && importId.trim().toLowerCase() === importDraft.agentPreset, ++ onClick: () => { void confirmImport(); }, children: copy.install ++ }) ++ ] ++ }), ++ children: importDraft === null ? null : (0, react_jsx_runtime.jsxs)("div", { ++ style: { display: "grid", gap: 12 }, ++ children: [ ++ (0, react_jsx_runtime.jsx)("strong", { children: importDraft.name }), ++ (0, react_jsx_runtime.jsx)("p", { children: `${importDraft.fileCount} files · ${importDraft.sourceDshVersion ?? "unknown version"}` }), ++ (0, react_jsx_runtime.jsx)("p", { children: copy.trust }), ++ importDraft.warnings?.length > 0 && (0, react_jsx_runtime.jsx)("p", { role: "alert", children: importDraft.warnings.join(", ") }), ++ (0, react_jsx_runtime.jsxs)("label", { children: [copy.rename, (0, react_jsx_runtime.jsx)("input", { value: importId, onChange: (event) => setImportId(event.target.value), style: { display: "block", width: "100%" } })] }), ++ importDraft.conflict && importId.trim().toLowerCase() === importDraft.agentPreset && (0, react_jsx_runtime.jsx)("p", { role: "alert", children: copy.conflict }), ++ transferError && (0, react_jsx_runtime.jsx)("p", { role: "alert", children: transferError }) ++ ] ++ }) ++ }), + (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, { + open: viewed !== null, + onClose: closeViewer, diff --git a/patches/@deepseek-ai+dsh-client-ui-attachment+0.1.7-rc.2.patch b/patches/@deepseek-ai+dsh-client-ui-attachment+0.1.7-rc.2.patch new file mode 100644 index 000000000..f558240e0 --- /dev/null +++ b/patches/@deepseek-ai+dsh-client-ui-attachment+0.1.7-rc.2.patch @@ -0,0 +1,65 @@ +diff --git a/node_modules/@deepseek-ai/dsh-client-ui-attachment/lib/client.js b/node_modules/@deepseek-ai/dsh-client-ui-attachment/lib/client.js +index 5f86649..62dfe16 100644 +--- a/node_modules/@deepseek-ai/dsh-client-ui-attachment/lib/client.js ++++ b/node_modules/@deepseek-ai/dsh-client-ui-attachment/lib/client.js +@@ -363,7 +363,7 @@ window.__ModuleLoader__.load({ + const tag = document.createElement("style"); + tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-attachment"; + tag.dataset.pluginCss = tagId$2; +- tag.textContent = css$2; ++ tag.textContent = css$2 + ".gSkjMW_preview{color:inherit;font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;padding:0}"; + document.head.appendChild(tag); + } + var FileCard_module_css_default = { +@@ -376,6 +376,7 @@ window.__ModuleLoader__.load({ + "meta": "gSkjMW_meta", + "metaFailed": "gSkjMW_metaFailed", + "name": "gSkjMW_name", ++ "preview": "gSkjMW_preview", + "progressBar": "gSkjMW_progressBar", + "progressTrack": "gSkjMW_progressTrack", + "remove": "gSkjMW_remove", +@@ -386,7 +387,7 @@ window.__ModuleLoader__.load({ + //#endregion + //#region lib/types/FileCard.js + /** One pending file card: type glyph, name, size or upload status, remove, retry. */ +- function FileCard({ name, bytes, state, progress, labels, onRemove, onRetry }) { ++ function FileCard({ name, bytes, state, progress, labels, onRemove, onRetry, onOpen }) { + const extension = (0, _deepseek_ai_dsh_client_ui_primitives.fileExtension)(name).toUpperCase().slice(0, 8); + const meta = state === "uploading" ? labels.uploading : state === "error" ? labels.failed : [extension, (0, _deepseek_ai_dsh_client_ui_primitives.fileSizeText)(bytes)].filter((part) => part !== "").join(" "); + const retryable = state === "error"; +@@ -411,9 +412,11 @@ window.__ModuleLoader__.load({ + className: `${FileCard_module_css_default.meta} ${FileCard_module_css_default.metaFailed}`, + children: meta + })] +- }) : (0, react_jsx_runtime.jsxs)("span", { +- className: FileCard_module_css_default.body, ++ }) : (0, react_jsx_runtime.jsxs)(onOpen === void 0 ? "span" : "button", { ++ type: onOpen === void 0 ? void 0 : "button", ++ className: onOpen === void 0 ? FileCard_module_css_default.body : `${FileCard_module_css_default.body} ${FileCard_module_css_default.preview}`, + "aria-label": labels.label, ++ onClick: onOpen, + children: [(0, react_jsx_runtime.jsx)("span", { + className: FileCard_module_css_default.name, + children: name +@@ -608,7 +611,7 @@ window.__ModuleLoader__.load({ + //#endregion + //#region lib/types/client/ComposerAttachments.js + /** Draft image previews, pending-file cards, drop target, and original-image preview. */ +- function ComposerAttachments({ attachments, canAcceptDrop, onAddFiles, onRemoveAttachment, uploads, onRetryFile, dropLimits, t }) { ++ function ComposerAttachments({ attachments, canAcceptDrop, onAddFiles, onRemoveAttachment, uploads, onRetryFile, onOpenUploadedFile, dropLimits, t }) { + const [preview, setPreview] = (0, react.useState)(null); + const [dragActive, setDragActive] = (0, react.useState)(false); + const dragDepth = (0, react.useRef)(0); +@@ -650,7 +653,10 @@ window.__ModuleLoader__.load({ + }, + onRetry: () => { + onRetryFile(attachment.id); +- } ++ }, ++ onOpen: upload?.status === "ready" && upload.file !== void 0 && onOpenUploadedFile !== void 0 ? () => { ++ onOpenUploadedFile(upload.file.attachmentId); ++ } : void 0 + }); + } + return (0, react_jsx_runtime.jsxs)("div", { diff --git a/patches/@deepseek-ai+dsh-client-ui-chat+0.1.7-rc.2.patch b/patches/@deepseek-ai+dsh-client-ui-chat+0.1.7-rc.2.patch new file mode 100644 index 000000000..fb156a140 --- /dev/null +++ b/patches/@deepseek-ai+dsh-client-ui-chat+0.1.7-rc.2.patch @@ -0,0 +1,252 @@ +diff --git a/node_modules/@deepseek-ai/dsh-client-ui-chat/lib/client.js b/node_modules/@deepseek-ai/dsh-client-ui-chat/lib/client.js +index a99972a..e26619b 100644 +--- a/node_modules/@deepseek-ai/dsh-client-ui-chat/lib/client.js ++++ b/node_modules/@deepseek-ai/dsh-client-ui-chat/lib/client.js +@@ -115,6 +115,22 @@ window.__ModuleLoader__.load({ + if (!/^https?:/u.test(base) && !base.startsWith("dsh-app://app/") || !isAbsoluteWorkspacePath(path) || /^[/\\]{2}/u.test(path) || /[\u0000-\u001f\u007f]/u.test(path)) return void 0; + return new URL(`api/file?path=${encodeURIComponent(path)}`, base).href; + } ++ function hostPathForOpen(cwd, path) { ++ const normalized = path.replace(/\\/g, "/"); ++ if (isAbsoluteWorkspacePath(normalized)) return path; ++ const root = cwd === void 0 ? "" : cwd.replace(/\\/g, "/").replace(/\/+$/, ""); ++ if (root === "") return path; ++ return `${root}/${normalized.replace(/^\/+/, "")}`; ++ } ++ async function openResolvedHostFile(ctx, sessionId, cwd, hostPath, options) { ++ const address = fileAddressFor(sessionId, cwd, hostPath); ++ if (ctx.sidebarRightTabs.candidates(address).length === 0) { ++ await ctx.remote.session.openWorkspacePath({ path: hostPath }); ++ return; ++ } ++ if (options?.line === void 0) ctx.sidebarRight.openResource(address); ++ else ctx.sidebarRight.openResource(address, { params: { line: options.line } }); ++ } + //#endregion + //#region lib/types/client/contract/snapshot.js + const EMPTY_LIST$1 = []; +@@ -217,7 +233,7 @@ window.__ModuleLoader__.load({ + const tag = document.createElement("style"); + tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-chat"; + tag.dataset.pluginCss = tagId$17; +- tag.textContent = css$17; ++ tag.textContent = css$17 + ".Sixlwa_fileCardButton{color:inherit;font:inherit;cursor:pointer;appearance:none}"; + document.head.appendChild(tag); + } + var MessageItem_module_css_default = { +@@ -234,6 +250,7 @@ window.__ModuleLoader__.load({ + "compactionTitle": "Sixlwa_compactionTitle", + "contextRow": "Sixlwa_contextRow", + "fileCard": "Sixlwa_fileCard", ++ "fileCardButton": "Sixlwa_fileCardButton", + "fileContent": "Sixlwa_fileContent", + "fileIcon": "Sixlwa_fileIcon", + "fileMeta": "Sixlwa_fileMeta", +@@ -1230,6 +1247,7 @@ window.__ModuleLoader__.load({ + if (code === "ACCOUNT_SIGNED_OUT") return t("message.failure.accountSignedOut"); + if (code === "ACCOUNT_SIGN_IN_REQUIRED") return t("message.failure.accountSignInRequired"); + if (code === "QUOTA" || code === "ACCOUNT_QUOTA") return t("message.failure.quota"); ++ if (code === "FORBIDDEN") return t("message.failure.forbidden"); + return code === "AUTH" ? t("message.failure.auth") : message; + } + function ModelRetryItem({ node, active, t }) { +@@ -1336,7 +1354,7 @@ window.__ModuleLoader__.load({ + }); + } + /** Right-aligned bubble shared by user and steering rows. */ +- function UserStyleBubble({ content, renderMessageImages, actions, pending = false, echo = false, referenceLabels = [], skillNames = [], previewAttachments, references, t }) { ++ function UserStyleBubble({ content, renderMessageImages, actions, pending = false, echo = false, referenceLabels = [], skillNames = [], previewAttachments, references, onOpenUploadedFile, t }) { + const { text, attachments: contentAttachments, rest } = contentParts(content); + const attachments = previewAttachments ?? contentAttachments; + const compactImages = attachments.length > 1; +@@ -1356,9 +1374,13 @@ window.__ModuleLoader__.load({ + images: [attachment.image], + align: "end", + compact: compactImages +- }) }, `image:${index}`) : (0, react_jsx_runtime.jsxs)("span", { +- className: MessageItem_module_css_default.fileCard, ++ }) }, `image:${index}`) : (0, react_jsx_runtime.jsxs)(onOpenUploadedFile !== void 0 && attachment.file.attachmentId !== void 0 ? "button" : "span", { ++ type: onOpenUploadedFile !== void 0 && attachment.file.attachmentId !== void 0 ? "button" : void 0, ++ className: onOpenUploadedFile !== void 0 && attachment.file.attachmentId !== void 0 ? `${MessageItem_module_css_default.fileCard} ${MessageItem_module_css_default.fileCardButton}` : MessageItem_module_css_default.fileCard, + title: attachment.file.name, ++ onClick: onOpenUploadedFile === void 0 || attachment.file.attachmentId === void 0 ? void 0 : () => { ++ onOpenUploadedFile(attachment.file.attachmentId); ++ }, + children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.FileTypeIcon, { + path: attachment.file.name, + className: MessageItem_module_css_default.fileIcon +@@ -1418,7 +1440,7 @@ window.__ModuleLoader__.load({ + * @param props - the session snapshot's pending submission and render seats. + * @returns the echoed user bubble. + */ +- function PendingSubmissionBubble({ submission, renderMessageImages, t }) { ++ function PendingSubmissionBubble({ submission, renderMessageImages, onOpenUploadedFile, t }) { + return (0, react_jsx_runtime.jsx)(UserStyleBubble, { + content: (0, react.useMemo)(() => submission.text === "" ? [] : [{ + type: "text", +@@ -1437,6 +1459,7 @@ window.__ModuleLoader__.load({ + file: attachment.value + }), [submission.attachments]), + renderMessageImages, ++ onOpenUploadedFile, + pending: submission.placement === "steering", + echo: true, + t, +@@ -1450,7 +1473,7 @@ window.__ModuleLoader__.load({ + }); + } + /** User and admitted-steering keyed Chat renderer. */ +- const UserMessageNodeView = (0, react.memo)(function UserMessageNodeView({ node, renderMessageImages, openFile, openSkill, t }) { ++ const UserMessageNodeView = (0, react.memo)(function UserMessageNodeView({ node, renderMessageImages, openFile, openSkill, onOpenUploadedFile, t }) { + const data = node.data; + return (0, react_jsx_runtime.jsx)(UserStyleBubble, { + content: data.content, +@@ -1459,6 +1482,7 @@ window.__ModuleLoader__.load({ + openSkill + }, + renderMessageImages, ++ onOpenUploadedFile, + ...data.referenceLabels === void 0 ? {} : { referenceLabels: data.referenceLabels }, + ...data.skillNames === void 0 ? {} : { skillNames: data.skillNames }, + t, +@@ -1665,7 +1689,7 @@ window.__ModuleLoader__.load({ + * Policy reads select this seat's own conclusion, so a mode change re-renders + * only seats whose visibility actually changes. + */ +- const ChatNodeSeat = (0, react.memo)(function ChatNodeSeat({ nodeKey, groupPart, useChatNode, useChatNodeProcess, usePresentation, cwd, openFile, openSkill, inspectCall, forkAt, loadImage, renderMessageImages, fileMentions, useStore, actions, renderSlot, t }) { ++ const ChatNodeSeat = (0, react.memo)(function ChatNodeSeat({ nodeKey, groupPart, useChatNode, useChatNodeProcess, usePresentation, cwd, openFile, openSkill, inspectCall, forkAt, loadImage, renderMessageImages, fileMentions, useStore, actions, renderSlot, onOpenUploadedFile, t }) { + const node = useChatNode(nodeKey); + const routedNode = node; + const turn = turnOf$1(routedNode); +@@ -1729,6 +1753,7 @@ window.__ModuleLoader__.load({ + cwd, + openFile, + openSkill, ++ onOpenUploadedFile, + inspectCall, + forkAt, + loadImage, +@@ -1741,6 +1766,7 @@ window.__ModuleLoader__.load({ + cwd, + openFile, + openSkill, ++ onOpenUploadedFile, + inspectCall, + forkAt, + loadImage, +@@ -5021,6 +5047,7 @@ window.__ModuleLoader__.load({ + }); + const pendingRows = pendingInputs.map((item) => "requestId" in item ? (0, react_jsx_runtime.jsx)(PendingSubmissionBubble, { + submission: item, ++ onOpenUploadedFile: seatProps.onOpenUploadedFile, + renderMessageImages: seatProps.renderMessageImages, + t: seatProps.t + }, item.requestId) : (0, react_jsx_runtime.jsx)(PendingSteeringBubble, { +@@ -5040,7 +5067,7 @@ window.__ModuleLoader__.load({ + * The chat view slot entry: pure component over the composed props; each + * ordered business Node crosses the keyed renderer seat. + */ +- function ChatView({ useSession, useChat, useChatNode, useChatNodeProcess, useChatGroup, useConversation, useSessions, useStore, actions, renderSlot, sessionId, openFile, openSkill, openExternalLink, loadOlder, loadThrough, loadImage, inspectCall, chatScroll, forkAt, fileMentions, usePresentation, useProjection, t }) { ++ function ChatView({ useSession, useChat, useChatNode, useChatNodeProcess, useChatGroup, useConversation, useSessions, useStore, actions, renderSlot, sessionId, openFile, openSkill, openExternalLink, loadOlder, loadThrough, loadImage, inspectCall, chatScroll, forkAt, fileMentions, usePresentation, useProjection, openUploadedFile, t }) { + const order = useChat((s) => s.order); + const groupedEntries = useConversation((snapshot) => snapshot.views.grouped("chat")?.entries); + const entries = (0, react.useMemo)(() => groupedEntries ?? order.map((key) => ({ +@@ -5087,6 +5114,23 @@ window.__ModuleLoader__.load({ + setFileOpenBusy(false); + }); + }, [openFile, t]); ++ const requestOpenUploadedFile = (0, react.useCallback)((attachmentId) => { ++ if (openUploadedFile === void 0) return; ++ const id = ++fileOpenRequest.current; ++ setFileOpenBusy(true); ++ openUploadedFile(attachmentId).then(() => { ++ if (id !== fileOpenRequest.current) return; ++ setFileOpenError(null); ++ setFileOpenBusy(false); ++ }, (error) => { ++ if (id !== fileOpenRequest.current) return; ++ setFileOpenError({ ++ path: String(attachmentId), ++ message: openFailureMessage(error, t("fileOpen.unknown")) ++ }); ++ setFileOpenBusy(false); ++ }); ++ }, [openUploadedFile, t]); + const closeFileOpenError = (0, react.useCallback)(() => { + fileOpenRequest.current += 1; + setFileOpenError(null); +@@ -5209,6 +5253,7 @@ window.__ModuleLoader__.load({ + renderMessageImages, + fileMentions, + renderSlot, ++ onOpenUploadedFile: requestOpenUploadedFile, + t + }) + }) +@@ -5426,7 +5471,8 @@ window.__ModuleLoader__.load({ + "message.accountStopped": "任务已停止", + "message.failure.accountSignedOut": "任务已因退出 DeepSeek 登录而停止。", + "message.failure.accountSignInRequired": "请先登录 DeepSeek,并确认请求地址支持账号认证。", +- "message.failure.quota": "当前请求的额度已用尽", ++ "message.failure.quota": "账户额度或余额不足,请充值或检查服务商的用量限制。", ++ "message.failure.forbidden": "模型服务商拒绝了本次请求,请检查账号权限、地区限制或模型开通情况。", + "message.turnError": "本轮运行失败", + "message.maxTokens": "已达到输出 token 上限", + "message.maxTokens.hint": "回答被截断,已有输出保留在对话中。发送“继续”可让模型接着输出。", +@@ -5615,7 +5661,8 @@ window.__ModuleLoader__.load({ + "message.accountStopped": "Task stopped", + "message.failure.accountSignedOut": "Stopped because you signed out of DeepSeek.", + "message.failure.accountSignInRequired": "Sign in to DeepSeek and ensure the request destination supports account authentication.", +- "message.failure.quota": "Request quota exhausted.", ++ "message.failure.quota": "Your account has insufficient quota or balance. Add credits or check your provider's usage limits.", ++ "message.failure.forbidden": "The model provider denied this request. Check your account permissions, region, or model access.", + "message.turnError": "This turn failed", + "message.maxTokens": "Output token limit reached", + "message.maxTokens.hint": "The reply was cut off; earlier output is preserved in the conversation. Send \"continue\" to let the model resume.", +@@ -12178,7 +12225,8 @@ window.__ModuleLoader__.load({ + "configForms", + "remote", + "remote.session", +- "sidebarRight" ++ "sidebarRight", ++ "sidebarRightTabs" + ]; + /** + * Mount all Chat-owned contributions. +@@ -12268,6 +12316,14 @@ window.__ModuleLoader__.load({ + }, LinkOpeningRow)); + }); + const transcriptView = new TranscriptViewPolicy(chatSettings); ++ ctx.provide("openUploadedAttachment", { open: async (sessionId, attachmentId) => { ++ const binding = ctx.sessions.binding(sessionId); ++ if (binding === void 0) throw new Error(`ui-chat: unknown session "${sessionId}"`); ++ const result = await binding.session.readFileHostPath(attachmentId); ++ if (!result.ok) throw new Error(`${result.error.code}: ${result.error.message}`); ++ const cwd = ctx.sessions.list.getSnapshot().byId[sessionId]?.cwd; ++ await openResolvedHostFile(ctx, sessionId, cwd, result.value.path); ++ } }); + const presentation = derivePresentationPolicy(transcriptView.mode); + const performancePolicy = new PerformanceUsagePolicy(chatSettings); + ctx.effect(() => () => { +@@ -12335,10 +12391,17 @@ window.__ModuleLoader__.load({ + fileMentions: (owner) => ctx.get("chatFileMentions")?.forClosing(owner, sessionId), + openFile: async (path, options) => { + const cwd = ctx.sessions.list.getSnapshot().byId[sessionId]?.cwd; +- const url = fileAddressFor(sessionId, cwd, path); +- if (options?.line === void 0) ctx.sidebarRight.openResource(url); +- else ctx.sidebarRight.openResource(url, { params: { line: options.line } }); +- await Promise.resolve(); ++ const byName = await session.readFileHostPath({ name: path }); ++ if (byName.ok) { ++ await openResolvedHostFile(ctx, sessionId, cwd, byName.value.path); ++ return; ++ } ++ await openResolvedHostFile(ctx, sessionId, cwd, hostPathForOpen(cwd, path), options); ++ }, ++ openUploadedFile: async (attachmentId) => { ++ const opener = ctx.get("openUploadedAttachment"); ++ if (opener === void 0) throw new Error("ui-chat: openUploadedAttachment is unavailable"); ++ await opener.open(sessionId, attachmentId); + }, + openSkill: (name) => { + const scope = ctx.sessions.scope(sessionId); diff --git a/patches/@deepseek-ai+dsh-client-ui-conversation+0.1.7-rc.2.patch b/patches/@deepseek-ai+dsh-client-ui-conversation+0.1.7-rc.2.patch new file mode 100644 index 000000000..fa90e00b2 --- /dev/null +++ b/patches/@deepseek-ai+dsh-client-ui-conversation+0.1.7-rc.2.patch @@ -0,0 +1,287 @@ +diff --git a/node_modules/@deepseek-ai/dsh-client-ui-conversation/lib/client.js b/node_modules/@deepseek-ai/dsh-client-ui-conversation/lib/client.js +index 2107bbb..6b4defc 100644 +--- a/node_modules/@deepseek-ai/dsh-client-ui-conversation/lib/client.js ++++ b/node_modules/@deepseek-ai/dsh-client-ui-conversation/lib/client.js +@@ -15719,12 +15719,13 @@ window.__ModuleLoader__.load({ + //#endregion + //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-conversation/src/client/skeleton/ConversationRoot.module.css.mjs + const css$4 = ".wSkVaW_root{background:var(--dsw-alias-bg-base);flex-direction:column;min-width:0;height:100%;display:flex;position:relative}.wSkVaW_header{box-sizing:border-box;border-bottom:.5px solid var(--dsw-alias-border-l3);flex:none;grid-template-columns:auto minmax(0,1fr);min-height:76px;padding:10px 28px 0 20px;display:grid}.wSkVaW_header:where(:not(:has(.wSkVaW_tabs))){min-height:0;padding-bottom:10px}.wSkVaW_headerBlank{border-bottom:none;min-height:0;padding-bottom:0}.wSkVaW_headerBlank .wSkVaW_headerCorner{margin-left:auto}html:not([data-platform=darwin]) .wSkVaW_headerSessionless{padding-top:0}html:not([data-platform=darwin]) .wSkVaW_headerSessionless .wSkVaW_titleRow{min-height:0}[data-platform=darwin] .wSkVaW_headerLeading,[data-platform=darwin] .wSkVaW_headerActions,[data-platform=darwin] .wSkVaW_headerUtilities,[data-platform=darwin] .wSkVaW_headerCorner{-webkit-app-region:no-drag}.wSkVaW_titleRow{min-height:30px;grid-column:2;align-items:center;gap:0;padding-inline-start:max(0px, calc(var(--dsh-frame-leading-clearance,0px) - 20px));display:flex;container-type:inline-size}.wSkVaW_titleCluster{flex:1;align-items:center;gap:10px;min-width:0;display:flex}.wSkVaW_headerLeading{flex:none;grid-area:1/1;align-items:center;gap:8px;display:flex}.wSkVaW_crumbs{white-space:nowrap;align-items:center;gap:4px;min-width:0;display:flex;overflow:hidden}.wSkVaW_crumbSeg{align-items:center;gap:4px;min-width:0;display:inline-flex}.wSkVaW_crumbSep{color:var(--dsw-alias-label-caption);font-size:14px;line-height:20px}.wSkVaW_crumb{border-radius:var(--dsw-radius-md);max-width:220px;color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;cursor:pointer;background:0 0;border:none;padding:4px 8px;font-size:14px;line-height:20px;display:inline-block;overflow:hidden}.wSkVaW_crumbSubagent{font-size:12px;line-height:18px}button.wSkVaW_crumb:hover{background:var(--dsw-alias-interactive-bg-hover)}.wSkVaW_crumbCurrent{color:var(--dsw-alias-label-primary);cursor:default;font-weight:500}.wSkVaW_headerActions{flex:none;align-items:center;gap:8px;display:flex}.wSkVaW_headerUtilities{flex:none;align-items:center;gap:8px;margin-left:20px;display:flex}.wSkVaW_headerUtilities:empty{display:none}.wSkVaW_headerCorner{flex:none;align-items:center;margin-left:8px;margin-right:-16px;display:flex}.wSkVaW_headerCorner:empty{display:none}.wSkVaW_tabs{z-index:1;grid-column:1/-1;gap:36px;margin-top:10px;padding-left:8px;display:flex;position:relative}.wSkVaW_tab{color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;padding:0 0 9px;font-size:13px;font-weight:500;line-height:16px;position:relative}.wSkVaW_tab:after{content:\"\";background:0 0;border-radius:2px;height:2px;position:absolute;bottom:-1px;left:0;right:0}.wSkVaW_tabActive{color:var(--dsw-alias-state-business-primary)}.wSkVaW_tabActive:after{background:var(--dsw-alias-state-business-primary)}.wSkVaW_viewArea{flex-direction:column;flex:1;min-height:0;display:flex}.wSkVaW_widthHandle{z-index:0;width:min(10px, calc((100% - var(--dsh-chat-content-width)) / 2 - 24px - 24px));cursor:col-resize;position:absolute;top:0;bottom:0}.wSkVaW_widthHandle[data-side=left]{right:calc(50% + var(--dsh-chat-content-width) / 2 + 24px)}.wSkVaW_widthHandle[data-side=right]{left:calc(50% + var(--dsh-chat-content-width) / 2 + 24px)}.wSkVaW_widthHandle:after{content:\"\";background:linear-gradient(to bottom, transparent calc(var(--dsh-width-handle-pointer-y,50%) - 36px), var(--dsw-alias-scrollbar-bg-l1) calc(var(--dsh-width-handle-pointer-y,50%) - 8px), var(--dsw-alias-scrollbar-bg-l1) calc(var(--dsh-width-handle-pointer-y,50%) + 8px), transparent calc(var(--dsh-width-handle-pointer-y,50%) + 36px));opacity:0;pointer-events:none;border-radius:2px;width:2px;position:absolute;top:0;bottom:0}.wSkVaW_widthHandle[data-side=left]:after{right:4px}.wSkVaW_widthHandle[data-side=right]:after{left:4px}.wSkVaW_widthHandle:hover:after,.wSkVaW_widthHandle[data-dragging]:after{opacity:1}.wSkVaW_widthHandle[data-dragging]{z-index:8}.wSkVaW_root:has([data-conversation-composer-overlay]) .wSkVaW_widthHandle{display:none}.wSkVaW_composerStack{--dsh-composer-stack-gap:6px;gap:var(--dsh-composer-stack-gap);flex-direction:column;display:flex}.wSkVaW_composerSeat{--dsh-composer-text-max-height:336px;flex-direction:column;flex:none;display:flex}.wSkVaW_root[data-phase=active]{overflow:hidden}.wSkVaW_root[data-phase=active] .wSkVaW_header{flex:none}.wSkVaW_body{--dsh-chat-content-width:var(--dsh-chat-user-width,clamp(680px, calc(var(--dsh-conversation-column-width,0px) * .64), 920px));--dsh-composer-card-max-width:calc(var(--dsh-chat-content-width) + 32px);--dsh-composer-side-clearance:16px;--dsh-composer-dock-inset:8px;flex-direction:column;flex:1;min-height:0;display:flex;position:relative}.wSkVaW_embeddedBody{--dsh-chat-content-width:min(calc(100% - 32px), 920px);--dsh-composer-card-max-width:min(calc(100% - 16px), 952px);--dsh-composer-side-clearance:8px;--dsh-composer-dock-inset:8px;overflow:hidden}.wSkVaW_scrollBody{scrollbar-gutter:stable;flex-direction:column;flex:1;min-height:0;margin-right:2px;display:flex;overflow-y:auto}.wSkVaW_scrollBody::-webkit-scrollbar-track{margin:2px}.wSkVaW_root[data-phase=active] .wSkVaW_viewArea,.wSkVaW_embeddedBody[data-content-phase=active] .wSkVaW_viewArea{flex:1 0 auto;min-height:auto}.wSkVaW_root[data-phase=active] .wSkVaW_composerSeat,.wSkVaW_embeddedBody[data-content-phase=active] .wSkVaW_composerSeat{z-index:7;background:linear-gradient(180deg, color-mix(in srgb, var(--dsw-alias-bg-base) 0%, transparent) 0px, var(--dsw-alias-bg-base) 36px);position:sticky;bottom:0}.wSkVaW_root[data-phase=active] .wSkVaW_composerSeat:has([data-trigger-menu]){z-index:9}.wSkVaW_scrollBody:has([data-conversation-composer-overlay]){scrollbar-gutter:auto;position:relative;overflow:hidden auto}.wSkVaW_scrollBody:has([data-conversation-composer-overlay])>[data-slot=conversation\\.session]>.wSkVaW_viewArea{flex:1 1 0;min-height:0;overflow:hidden}.wSkVaW_scrollBody:has([data-conversation-composer-overlay])>.wSkVaW_composerSeat{right:var(--dsh-scrollbar-width);position:absolute;bottom:0;left:0}.wSkVaW_composerHero{width:min(calc(var(--dsh-composer-card-max-width) + 2 * var(--dsh-composer-side-clearance)), 100%);z-index:1;align-self:center;gap:8px;padding-bottom:32px}.wSkVaW_heroWorkspaceRow{align-items:center;gap:2px;min-width:0;margin-top:4px;padding:0 16px 0 20px;display:flex}.wSkVaW_root[data-phase=hero] .wSkVaW_scrollBody,.wSkVaW_embeddedBody[data-content-phase=hero] .wSkVaW_scrollBody{justify-content:center;overflow-y:auto}.wSkVaW_root[data-phase=settling] .wSkVaW_composerSeat,.wSkVaW_embeddedBody[data-content-phase=settling] .wSkVaW_composerSeat{visibility:hidden}"; ++ const heroModeClusterCss = ".wSkVaW_heroWorkspaceRow [data-slot=conversation\\.hero\\.agentPreset]>span{width:max-content!important;min-width:0!important;max-width:240px;flex:none}.wSkVaW_heroModeCluster{width:max-content;max-width:100%;flex:none;align-items:center;gap:2px;display:flex}.wSkVaW_heroModeCluster button{box-sizing:border-box;height:28px;padding:0 8px!important;border:0!important;border-radius:8px!important;background:transparent!important;color:var(--dsw-alias-label-primary)!important;font:inherit;font-size:13px;font-weight:500;line-height:20px;gap:6px;cursor:pointer;transition:background-color .12s ease,color .12s ease,transform .12s ease}.wSkVaW_heroModeCluster button:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)!important;color:var(--dsw-alias-label-primary)!important}.wSkVaW_heroModeCluster button[data-selected=true]{background:color-mix(in srgb,var(--dsw-alias-state-business-primary) 10%,transparent)!important;color:var(--dsw-alias-state-business-primary)!important}.wSkVaW_heroModeCluster button:active:not(:disabled){transform:scale(.98)}.wSkVaW_heroModeCluster button:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}.wSkVaW_heroWorkspaceRow{padding-right:20px;box-sizing:border-box}"; + const tagId$4 = "@deepseek-ai/dsh-client-ui-conversation/ConversationRoot.module.css"; + if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$4) + "]") === null) { + const tag = document.createElement("style"); + tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-conversation"; + tag.dataset.pluginCss = tagId$4; +- tag.textContent = css$4; ++ tag.textContent = css$4 + heroModeClusterCss; + document.head.appendChild(tag); + } + var ConversationRoot_module_css_default = { +@@ -15746,6 +15747,7 @@ window.__ModuleLoader__.load({ + "headerLeading": "wSkVaW_headerLeading", + "headerSessionless": "wSkVaW_headerSessionless", + "headerUtilities": "wSkVaW_headerUtilities", ++ "heroModeCluster": "wSkVaW_heroModeCluster", + "heroWorkspaceRow": "wSkVaW_heroWorkspaceRow", + "root": "wSkVaW_root", + "scrollBody": "wSkVaW_scrollBody", +@@ -16203,12 +16205,17 @@ window.__ModuleLoader__.load({ + setPickerOpen(false); + } + }), +- renderSlot("conversation.hero.agentPreset", {}) ++ renderSlot("conversation.hero.agentPreset", {}), ++ (0, react_jsx_runtime.jsx)("div", { ++ className: ConversationRoot_module_css_default.heroModeCluster, ++ children: renderSlot("conversation.hero.modeActions", zone ?? {}) ++ }) + ] + }); + const inert = sessionId === void 0 || hero && chipTitle === void 0; + const inputBar = renderSlot("conversation.composer.bar", { + variant: hero ? "hero" : "composer", ++ extensionZone: zone, + ...inert ? { + disabled: true, + placeholder: t("placeholder.workspace"), +@@ -16230,7 +16237,8 @@ window.__ModuleLoader__.load({ + }), + hero && heroWorkspaceRow, + zone !== void 0 && renderSlot("conversation.input.dock", zone), +- inputBar ++ inputBar, ++ sessionId === void 0 ? renderSlot("conversation.hero.dock", zone ?? {}) : null + ] + }); + const composer = renderSlotChain("conversation.composer", { +@@ -16290,6 +16298,7 @@ window.__ModuleLoader__.load({ + const blank = session === void 0 || conversation === void 0 || session.blank && conversationPhase(session, conversation) === "blank"; + return (0, react_jsx_runtime.jsxs)("header", { + className: clsx(ConversationRoot_module_css_default.header, blank && ConversationRoot_module_css_default.headerBlank, sessionId === void 0 && ConversationRoot_module_css_default.headerSessionless), ++ "data-dsh-conversation-header": "", + "data-window-drag": true, + children: [(0, react_jsx_runtime.jsx)("div", { + className: ConversationRoot_module_css_default.headerLeading, +@@ -17092,13 +17101,14 @@ window.__ModuleLoader__.load({ + } + //#endregion + //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-conversation/src/client/skeleton/InputBar.module.css.mjs ++ const pptAccessoryCss = ".uV2eYG_promptRow{width:100%;min-width:0;align-items:flex-start;display:flex}.uV2eYG_promptRow>.uV2eYG_accessory{flex:none;padding:4px 0 0 12px}.uV2eYG_promptRow>.uV2eYG_accessory:empty{display:none}.uV2eYG_promptRow>.uV2eYG_scroll{flex:1;min-width:0}"; + const css$1 = ".uV2eYG_root{padding:0 var(--dsh-composer-side-clearance) 4px;flex-direction:column;align-items:center;display:flex}.uV2eYG_dock{justify-content:center;align-items:center;gap:12px;max-width:100%;padding-top:4px;display:flex}.uV2eYG_hero .uV2eYG_dock:empty{display:none}.uV2eYG_hero{padding:0 var(--dsh-composer-side-clearance)}.uV2eYG_notice{width:100%;max-width:var(--dsh-composer-card-max-width);border-radius:var(--dsw-radius-md);background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary);margin-bottom:6px;padding:4px 8px;font-size:12px;line-height:18px}.uV2eYG_card{box-sizing:border-box;width:100%;max-width:var(--dsh-composer-card-max-width);--dsw-elevation-stroke-color:var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-panel);background:var(--dsw-specific-input-major);box-shadow:var(--dsw-elevation-soft);font-size:var(--dsh-content-font-size,14px);line-height:calc(24px + var(--dsh-content-font-delta,0px));--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border:0;flex-direction:column;gap:12px;padding-top:8px;display:flex;position:relative}.uV2eYG_cardWorkspaceTrigger{--dsw-elevation-stroke-color:transparent;cursor:pointer}.uV2eYG_cardWorkspaceTrigger:after{content:\"\";box-sizing:border-box;border-radius:var(--dsw-radius-panel);color:var(--dsw-alias-border-l4);pointer-events:none;border:1px dashed;transition:color .1s;position:absolute;inset:0}.uV2eYG_cardWorkspaceTrigger :disabled{pointer-events:none}.uV2eYG_cardWorkspaceTrigger:hover:after{color:var(--dsw-alias-state-business-primary)}.uV2eYG_accessory{align-items:center;gap:8px;padding:10px 12px 0;display:flex}.uV2eYG_overlayAnchor{height:0;position:absolute;inset:0 0 auto}.uV2eYG_scroll{max-height:var(--dsh-composer-text-max-height);margin-right:4px;overflow-y:auto}.uV2eYG_scroll::-webkit-scrollbar-track{margin-top:8px}.uV2eYG_grow{position:relative}.uV2eYG_pending{corner-shape:round;background:var(--dsw-alias-state-business-primary);border-radius:50%;width:8px;height:8px;animation:1s ease-in-out infinite alternate uV2eYG_input-pending}@keyframes uV2eYG_input-pending{0%{opacity:.35}to{opacity:1}}.uV2eYG_input{box-sizing:border-box;min-height:36px;font-family:var(--dsw-font-family);font-size:inherit;line-height:inherit;white-space:pre-wrap;word-break:break-word;overflow-wrap:anywhere;color:var(--dsw-alias-label-primary);caret-color:var(--dsw-alias-state-business-primary);outline:none;padding:4px 8px 0 14px}.uV2eYG_input p{margin:0}.uV2eYG_input p:last-child:after{content:var(--dsh-composer-hint);color:var(--dsw-alias-label-caption)}.uV2eYG_input[data-composer-composing] p:last-child:after{content:none}.uV2eYG_input[data-composer-composing]+.uV2eYG_placeholder{visibility:hidden}.uV2eYG_placeholder{color:var(--dsw-alias-label-caption);white-space:nowrap;text-overflow:ellipsis;pointer-events:none;user-select:none;position:absolute;inset:4px 8px auto 14px;overflow:hidden}.uV2eYG_inputDisabled{color:var(--dsw-alias-label-tertiary);cursor:not-allowed}.uV2eYG_input[aria-haspopup=menu]{cursor:pointer}.uV2eYG_hero .uV2eYG_input{min-height:52px}.uV2eYG_hero .uV2eYG_placeholder{white-space:normal;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box}.uV2eYG_row{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:12px;min-width:0;padding:2px 8px 6px;display:flex;container-type:inline-size}.uV2eYG_row[data-model-compact]{--dsh-composer-model-text-display:none;--dsh-composer-model-icon-display:block}.uV2eYG_tools,.uV2eYG_modes,.uV2eYG_trailing{align-items:center;min-width:0;display:flex}.uV2eYG_tools,.uV2eYG_modes{gap:12px}.uV2eYG_trailing{flex:none;gap:12px;margin-left:auto}@container (width<=560px){.uV2eYG_tools,.uV2eYG_modes,.uV2eYG_trailing{gap:8px}}.uV2eYG_add{corner-shape:round;background:var(--dsw-specific-selector);width:28px;height:28px;color:var(--dsw-alias-label-primary);cursor:pointer;border:none;border-radius:999px;flex:none;place-items:center;display:grid}.uV2eYG_add:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-solid)}.uV2eYG_add:disabled{opacity:.5;cursor:default}.uV2eYG_select{border-radius:var(--dsw-radius-sm);max-width:220px;height:28px;color:var(--dsw-alias-label-secondary);white-space:nowrap;cursor:pointer;appearance:none;background-color:#0000;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M3 4.5L6 7.5L9 4.5' stroke='%2381858C' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E\");background-position:right 4px center;background-repeat:no-repeat;background-size:12px 12px;border:none;outline:none;padding:0 20px 0 8px;font-size:13px;font-weight:500;line-height:20px}.uV2eYG_select:hover:not(:disabled){background-color:var(--dsw-alias-interactive-bg-hover)}.uV2eYG_select:disabled{opacity:.5;cursor:default}.uV2eYG_primary{corner-shape:round;background:var(--dsw-alias-button-info-fill);color:#fff;cursor:pointer;border:none;border-radius:999px;flex:none;place-items:center;width:34px;height:34px;transition:background-color .1s;display:grid;transform:translateY(-2px)}.uV2eYG_primary:hover:not(:disabled){background:var(--dsw-alias-button-info-hover)}.uV2eYG_primary:disabled{opacity:.4;cursor:default}.uV2eYG_retry{border-radius:var(--dsw-radius-sm);color:inherit;cursor:pointer;background:0 0;border:1px solid;margin-left:8px;padding:1px 8px;font-size:12px}.uV2eYG_standardControls{align-items:center;gap:12px;min-width:0;display:flex}.uV2eYG_tools[hidden],.uV2eYG_standardControls[hidden]{display:none}.uV2eYG_trailingActive{flex:1;margin-left:0}.uV2eYG_activity{flex:none;align-items:center;display:flex}.uV2eYG_activity:empty{display:none}.uV2eYG_activityExpanded{flex:1;min-width:0}"; + const tagId$1 = "@deepseek-ai/dsh-client-ui-conversation/InputBar.module.css"; + if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) { + const tag = document.createElement("style"); + tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-conversation"; + tag.dataset.pluginCss = tagId$1; +- tag.textContent = css$1; ++ tag.textContent = css$1 + pptAccessoryCss; + document.head.appendChild(tag); + } + var InputBar_module_css_default = { +@@ -17120,6 +17130,7 @@ window.__ModuleLoader__.load({ + "pending": "uV2eYG_pending", + "placeholder": "uV2eYG_placeholder", + "primary": "uV2eYG_primary", ++ "promptRow": "uV2eYG_promptRow", + "retry": "uV2eYG_retry", + "root": "uV2eYG_root", + "row": "uV2eYG_row", +@@ -17146,7 +17157,7 @@ window.__ModuleLoader__.load({ + * The no-session state renders the SAME div inert as the Workspace-picker + * trigger instead of a parallel tree. + */ +- const InputBar = (0, react.memo)(function InputBar({ useSession, useInput, inputActions, keyboard, addFiles, removeAttachment, resolveDraftAttachments, retryFileUpload, toggleCommandMenu, stop, t, renderSlot, useBusyEnter, useFileUploads, useNotices, useLexicon, useMenuLauncher, useStopShortcut, useProjection, sessionId, variant, disabled: inert = false, blocked, workspacePickerOpen = false, onRequestWorkspace, placeholder, accessory }) { ++ const InputBar = (0, react.memo)(function InputBar({ useSession, useInput, inputActions, keyboard, addFiles, removeAttachment, resolveDraftAttachments, retryFileUpload, toggleCommandMenu, stop, t, renderSlot, useBusyEnter, useFileUploads, useNotices, useLexicon, useMenuLauncher, useStopShortcut, useProjection, sessionId, variant, disabled: inert = false, blocked, workspacePickerOpen = false, onRequestWorkspace, placeholder, accessory, extensionZone, openUploadedFile }) { + const input = useInput((s) => s); + const notice = useNotices((s) => s); + const busyEnter = useBusyEnter((s) => s); +@@ -17374,10 +17385,6 @@ window.__ModuleLoader__.load({ + className: InputBar_module_css_default.overlayAnchor, + children: renderSlot("conversation.input.overlay", {}) + }), +- accessory !== void 0 && (0, react_jsx_runtime.jsx)("div", { +- className: InputBar_module_css_default.accessory, +- children: accessory +- }), + renderSlot("conversation.input.attachments", { + attachments, + canAcceptDrop, +@@ -17389,25 +17396,35 @@ window.__ModuleLoader__.load({ + onRetryFile: (id) => { + retryFileUpload?.(id); + }, ++ onOpenUploadedFile: openUploadedFile, + dropLimits: imageLimits === void 0 ? void 0 : { + count: imageLimits.maxImagesPerMessage, + size: imageSizeText(imageLimits.maxImageBytes) + } + }), +- (0, react_jsx_runtime.jsx)(DraftEditor, { +- classNames: InputBar_module_css_default, +- editor, +- scrollRef, +- editable, +- editorDisabled, +- phase: input?.phase ?? "inert", +- placeholderText, +- ariaLabel: workspaceTrigger ? t("hero.chooseWorkspace") : placeholderText, +- workspaceTrigger, +- workspacePickerOpen, +- onWorkspaceKeyDown, +- hint, +- showPlaceholder: draft === "" && attachments.length === 0 && !claimActive ++ (0, react_jsx_runtime.jsxs)("div", { ++ className: InputBar_module_css_default.promptRow, ++ children: [ ++ (0, react_jsx_runtime.jsx)("div", { ++ className: InputBar_module_css_default.accessory, ++ children: accessory ?? (sessionId === void 0 ? null : renderSlot("conversation.input.accessory", extensionZone)) ++ }), ++ (0, react_jsx_runtime.jsx)(DraftEditor, { ++ classNames: InputBar_module_css_default, ++ editor, ++ scrollRef, ++ editable, ++ editorDisabled, ++ phase: input?.phase ?? "inert", ++ placeholderText, ++ ariaLabel: workspaceTrigger ? t("hero.chooseWorkspace") : placeholderText, ++ workspaceTrigger, ++ workspacePickerOpen, ++ onWorkspaceKeyDown, ++ hint, ++ showPlaceholder: draft === "" && attachments.length === 0 && !claimActive ++ }) ++ ] + }), + (0, react_jsx_runtime.jsxs)("div", { + ref: rowRef, +@@ -17535,7 +17552,7 @@ window.__ModuleLoader__.load({ + }), + (0, react_jsx_runtime.jsxs)("div", { + className: InputBar_module_css_default.dock, +- children: [variant === "composer" && input !== void 0 && sessionId !== void 0 ? renderSlot("conversation.composer.dock", {}) : null, activity ? null : (0, react_jsx_runtime.jsx)(ContextMeter, { ++ children: [input !== void 0 && sessionId !== void 0 ? renderSlot("conversation.composer.dock", extensionZone ?? {}) : null, activity ? null : (0, react_jsx_runtime.jsx)(ContextMeter, { + useProjection, + t + })] +@@ -18102,6 +18119,14 @@ window.__ModuleLoader__.load({ + "conversation.hero.agentPreset": { + kind: "single", + scope: "session-maybe" ++ }, ++ "conversation.hero.modeActions": { ++ kind: "list", ++ scope: "session-maybe" ++ }, ++ "conversation.hero.dock": { ++ kind: "list", ++ scope: "session-maybe" + } + }, + slots: { +@@ -18225,6 +18250,10 @@ window.__ModuleLoader__.load({ + kind: "list", + scope: "session" + }, ++ "conversation.input.accessory": { ++ kind: "list", ++ scope: "session" ++ }, + "conversation.input.permission": { + kind: "single", + scope: "session" +@@ -18261,6 +18290,7 @@ window.__ModuleLoader__.load({ + removeAttachment: void 0, + resolveDraftAttachments: void 0, + retryFileUpload: void 0, ++ openUploadedFile: void 0, + toggleCommandMenu: void 0, + stop: void 0, + hooks: { +@@ -18327,6 +18357,11 @@ window.__ModuleLoader__.load({ + retryFileUpload: (id) => { + if (sessions.binding(sessionId) !== void 0) conversation.retryFileUpload(sessionId, id); + }, ++ openUploadedFile: async (attachmentId) => { ++ const opener = ctx.get("openUploadedAttachment"); ++ if (opener === void 0) throw new Error("ui-conversation: openUploadedAttachment is unavailable"); ++ await opener.open(sessionId, attachmentId); ++ }, + toggleCommandMenu: inputTriggers === void 0 ? void 0 : (selection) => { + shell.dismissPopup(); + const snapshot = shell.snapshot; +@@ -18359,10 +18394,7 @@ window.__ModuleLoader__.load({ + yield slots.register({ + name: "main", + key: "conversation", +- children: { "main.conversation": { +- kind: "single", +- scope: "session-maybe" +- } } ++ children: { "main.conversation": { kind: "single", scope: "session-maybe" } } + }, ConversationPanel); + yield registerConversationRoot(); + yield registerConversationContent(); +diff --git a/node_modules/@deepseek-ai/dsh-client-ui-conversation/lib/types/client/contract/slots.d.ts b/node_modules/@deepseek-ai/dsh-client-ui-conversation/lib/types/client/contract/slots.d.ts +index 74f5846..c26522d 100644 +--- a/node_modules/@deepseek-ai/dsh-client-ui-conversation/lib/types/client/contract/slots.d.ts ++++ b/node_modules/@deepseek-ai/dsh-client-ui-conversation/lib/types/client/contract/slots.d.ts +@@ -210,6 +210,18 @@ declare module '@deepseek-ai/dsh-client-ui-slots' { + scope: 'session-maybe'; + owner: HeroAgentPresetOwnerProps; + }; ++ /** Product-mode controls beside the blank-session agent preset. */ ++ 'conversation.hero.modeActions': { ++ kind: 'list'; ++ scope: 'session-maybe'; ++ owner: InputZone; ++ }; ++ /** Entries below the new-conversation input before a session exists. */ ++ 'conversation.hero.dock': { ++ kind: 'list'; ++ scope: 'session-maybe'; ++ owner: InputZone; ++ }; + /** Full-width entries above the composer card. */ + 'conversation.input.dock': { + kind: 'list'; +@@ -221,10 +233,17 @@ declare module '@deepseek-ai/dsh-client-ui-slots' { + kind: 'list'; + scope: 'session'; + }; ++ /** Compact template and reference material rendered before the editable prompt. */ ++ 'conversation.input.accessory': { ++ kind: 'list'; ++ scope: 'session'; ++ owner: InputZone; ++ }; + /** Ambient entries below the composer card. */ + 'conversation.composer.dock': { + kind: 'list'; + scope: 'session'; ++ owner: InputZone; + }; + /** Compact controls at the left of the composer tool row. */ + 'conversation.input.left': { +@@ -440,8 +459,10 @@ export interface ComposerBarOwnerProps { + /** Open the Workspace picker from the inert composer surface. */ + onRequestWorkspace?: () => void; + placeholder?: string; +- /** Optional content rendered above the composer surface. */ ++ /** Optional compact content rendered before the editable prompt. */ + accessory?: ReactNode; ++ /** Point-in-time Session and input state supplied to Composer extension slots. */ ++ extensionZone?: InputZone; + } + /** Package-private operations injected into the resident composer bar. */ + export interface ComposerBarInjected { +@@ -486,7 +507,7 @@ export interface InputActivityOwnerProps extends InputControlOwnerProps { + onActiveChange: (active: boolean) => void; + } + /** Full props of the resident composer bar. */ +-export type ComposerBarProps = PropsRuntime<'conversation.composer.bar'> & PropsRenderSlots<'conversation.input.attachments' | 'conversation.input.overlay' | 'conversation.input.permission' | 'conversation.input.left' | 'conversation.input.plan' | 'conversation.input.right' | 'conversation.input.model' | 'conversation.input.activity' | 'conversation.composer.dock'> & InjectFace & PropsLocale<'conversation'>; ++export type ComposerBarProps = PropsRuntime<'conversation.composer.bar'> & PropsRenderSlots<'conversation.input.attachments' | 'conversation.input.overlay' | 'conversation.input.accessory' | 'conversation.input.permission' | 'conversation.input.left' | 'conversation.input.plan' | 'conversation.input.right' | 'conversation.input.model' | 'conversation.input.activity' | 'conversation.composer.dock'> & InjectFace & PropsLocale<'conversation'>; + /** Owner values used to elect a composer takeover. */ + export interface ComposerChainProps { + /** Current Session identity used by temporary business-owned entries. */ diff --git a/patches/@deepseek-ai+dsh-client-ui-deliverables+0.1.7-rc.2.patch b/patches/@deepseek-ai+dsh-client-ui-deliverables+0.1.7-rc.2.patch new file mode 100644 index 000000000..290f0931b --- /dev/null +++ b/patches/@deepseek-ai+dsh-client-ui-deliverables+0.1.7-rc.2.patch @@ -0,0 +1,51 @@ +diff --git a/node_modules/@deepseek-ai/dsh-client-ui-deliverables/lib/client.js b/node_modules/@deepseek-ai/dsh-client-ui-deliverables/lib/client.js +index 619ff8c..7659e17 100644 +--- a/node_modules/@deepseek-ai/dsh-client-ui-deliverables/lib/client.js ++++ b/node_modules/@deepseek-ai/dsh-client-ui-deliverables/lib/client.js +@@ -1271,7 +1271,7 @@ window.__ModuleLoader__.load({ + */ + function producedFileMentions(paths, openFile, label) { + return { resolve(value) { +- const path = paths.includes(value) ? value : onlyPathWithBasename(paths, value); ++ const path = paths.includes(value) ? value : onlyPathWithBasename(paths, value) ?? localPathReference(value); + if (path === void 0) return void 0; + return { + open: () => { +@@ -1282,6 +1282,29 @@ window.__ModuleLoader__.load({ + }; + } }; + } ++ /** ++ * Resolve Codex-style local path references that were not produced by a tool ++ * in the current turn. Keep bare identifiers inert: without a slash, an ++ * absolute-path prefix, or a conventional filename suffix, inline code is ++ * much more likely to be a command, package, or symbol than a local path. ++ * ++ * A leading `@` plus a single slash is a scoped package name, and a bare ++ * `local@domain.tld` is an email address; both are far more common in ++ * assistant prose than files with those exact shapes, and neither is ++ * openable. An explicit `./@scope/pkg` still resolves as a path above. ++ */ ++ function localPathReference(value) { ++ const candidate = value.trim(); ++ if (candidate === "" || /[\r\n]/.test(candidate) || /^(?:https?|data|javascript):/i.test(candidate)) return void 0; ++ const path = candidate.replace(/(?:#L\d+(?:C\d+)?|:\d+(?::\d+)?)$/, ""); ++ if (/^(?:\/|~[\\/]|\.{1,2}[\\/]|[A-Za-z]:[\\/]|\\\\)/.test(path)) return path; ++ if (/^@[^\\/@\s]+\/[^\\/@\s]+(?:@[^\\/\s]+)?$/.test(path)) return void 0; ++ if (/^[^@\s\\/]+@[^@\s\\/]+\.[A-Za-z]{2,}$/.test(path)) return void 0; ++ if (/^v?\d+(?:\.\d+){1,4}(?:-[A-Za-z0-9.-]+)?$/.test(path)) return void 0; ++ if (/[\\/]/.test(path) || /[\\/]$/.test(path)) return path; ++ if (/^[^\\/]+\.[A-Za-z0-9][A-Za-z0-9._-]{0,15}$/.test(path)) return path; ++ return void 0; ++ } + /** The single supplied path whose basename is exactly `value`, else undefined. */ + function onlyPathWithBasename(paths, value) { + const matches = paths.filter((path) => basename(path) === value); +@@ -2320,7 +2343,6 @@ window.__ModuleLoader__.load({ + ctx.provide("chatFileMentions", { forClosing(owner) { + const paths = selectProducedFiles(owner); + const presented = presentedForClosing(owner); +- if (paths === null && presented.length === 0) return void 0; + return producedFileMentions([...new Set([...paths ?? [], ...presented.map((file) => file.path)])], owner.openFile, (path) => t("presented.previewButton", { name: path })); + } }); + } diff --git a/patches/@deepseek-ai+dsh-client-ui-model-selection+0.1.7-rc.2.patch b/patches/@deepseek-ai+dsh-client-ui-model-selection+0.1.7-rc.2.patch new file mode 100644 index 000000000..ef629603a --- /dev/null +++ b/patches/@deepseek-ai+dsh-client-ui-model-selection+0.1.7-rc.2.patch @@ -0,0 +1,218 @@ +diff --git a/node_modules/@deepseek-ai/dsh-client-ui-model-selection/lib/client.js b/node_modules/@deepseek-ai/dsh-client-ui-model-selection/lib/client.js +index c904a89..e7d4297 100644 +--- a/node_modules/@deepseek-ai/dsh-client-ui-model-selection/lib/client.js ++++ b/node_modules/@deepseek-ai/dsh-client-ui-model-selection/lib/client.js +@@ -484,15 +484,71 @@ window.__ModuleLoader__.load({ + * store/verbs) + the standard locale seat. + * @returns the trigger and, while open, the two-level menu. + */ ++ const searchStyles = ` ++.dshModelSelectSearch { ++ box-sizing: border-box; ++ height: 36px; ++ color: var(--dsw-alias-label-tertiary); ++ background: var(--dsw-alias-bg-module-platform); ++ border: 1px solid transparent; ++ border-radius: 9px; ++ align-items: center; ++ gap: 7px; ++ margin: 2px 4px 4px; ++ padding: 0 9px; ++ display: flex; ++ flex: none; ++} ++.dshModelSelectSearch:focus-within { ++ border-color: var(--dsw-alias-border-l2); ++ background: var(--dsw-specific-menu); ++} ++.dshModelSelectSearchIcon { ++ flex: none; ++} ++.dshModelSelectSearchInput { ++ width: 100%; ++ min-width: 0; ++ color: var(--dsw-alias-label-primary); ++ font: inherit; ++ background: 0 0; ++ border: none; ++ outline: none; ++ padding: 0; ++ font-size: 13px; ++ line-height: 20px; ++} ++.dshModelSelectSearchInput::placeholder { ++ color: var(--dsw-alias-label-caption); ++} ++`; ++ if (typeof document !== "undefined" && document.getElementById("dsh-model-select-search-style") === null) { ++ const tag = document.createElement("style"); ++ tag.id = "dsh-model-select-search-style"; ++ tag.textContent = searchStyles; ++ document.head.appendChild(tag); ++ } ++ /** Keep provider grouping while narrowing a large model catalog. */ ++ function filterModelGroups(groups, query) { ++ const needle = query.trim().toLowerCase(); ++ if (needle.length === 0) return groups; ++ return groups.flatMap((group) => { ++ const providerMatches = [group.id, group.name].some((value) => value.toLowerCase().includes(needle)); ++ const models = providerMatches ? group.models : group.models.filter((model) => [model.id, model.name, model.description ?? ""].some((value) => value.toLowerCase().includes(needle))); ++ return models.length === 0 ? [] : [{ ...group, models }]; ++ }); ++ } + function ModelSelect({ locked, available, directory, load, select, t }) { + const state = (0, react.useSyncExternalStore)((fn) => directory.subscribe(fn), () => directory.getSnapshot()); + const [open, setOpen] = (0, react.useState)(false); + const [pane, setPane] = (0, react.useState)("root"); ++ const [modelQuery, setModelQuery] = (0, react.useState)(""); + const lastActionRef = (0, react.useRef)("load"); + const [toast, setToast] = (0, react.useState)(null); + const toastSeq = (0, react.useRef)(0); + const rootRef = (0, react.useRef)(null); + const triggerRef = (0, react.useRef)(null); ++ const searchRef = (0, react.useRef)(null); + const menuRef = (0, react.useRef)(null); + const [menuPos, setMenuPos] = (0, react.useState)(null); + const itemRefs = (0, react.useRef)([]); +@@ -507,6 +563,7 @@ window.__ModuleLoader__.load({ + ...model.reasoning?.defaultEffort === void 0 ? {} : { reasoningEffort: model.reasoning.defaultEffort } + } + }))), [groups]); ++ const filteredGroups = (0, react.useMemo)(() => filterModelGroups(groups, modelQuery), [groups, modelQuery]); + const currentChoice = choices[state.current === null ? -1 : choices.findIndex((c) => c.selection.provider === state.current?.provider && c.selection.model === state.current.model)]; + const reasoning = currentChoice?.model.reasoning; + const effectiveEffort = state.current?.reasoningEffort ?? reasoning?.defaultEffort; +@@ -583,17 +640,22 @@ window.__ModuleLoader__.load({ + pane, + state + ]); ++ (0, react.useEffect)(() => { ++ if (open && pane === "model") searchRef.current?.focus(); ++ }, [open, pane]); + if (!available) return null; + const show = () => { + triggerRef.current?.focus(); + if (state.current === null) paneFocus.current = "drill"; + setPane(state.current === null ? "model" : "root"); ++ setModelQuery(""); + setOpen(true); + reload(); + }; + const close = (restoreFocus = false) => { + setOpen(false); + setPane("root"); ++ setModelQuery(""); + if (restoreFocus) queueMicrotask(() => { + triggerRef.current?.focus(); + }); +@@ -606,17 +668,22 @@ window.__ModuleLoader__.load({ + const back = (from) => { + paneFocus.current = from; + setPane("root"); ++ setModelQuery(""); + }; + const moveFocus = (offset) => { + const items = itemRefs.current.filter((item) => item !== null); + if (items.length === 0) return; + const active = items.findIndex((item) => item === document.activeElement); +- items[active === -1 ? offset > 0 ? 0 : items.length - 1 : (active + offset + items.length) % items.length]?.focus(); ++ const next = active < 0 ? offset > 0 ? 0 : items.length - 1 : (active + offset + items.length) % items.length; ++ items[next]?.focus(); + }; + const onRootKeyDown = (event) => { + if (event.key === "Escape" && open) { + event.preventDefault(); +- if (pane !== "root" && state.current !== null) back(pane); ++ if (pane !== "root" && state.current !== null) { ++ back(pane); ++ setModelQuery(""); ++ } + else close(true); + return; + } +@@ -756,6 +823,7 @@ window.__ModuleLoader__.load({ + role: "menuitem", + className: ModelSelect_module_css_default.cell, + onClick: () => { ++ setModelQuery(""); + drill("model"); + }, + children: [ +@@ -790,6 +858,23 @@ window.__ModuleLoader__.load({ + ] + })] }), + pane === "model" && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [ ++ (0, react_jsx_runtime.jsxs)("label", { ++ className: "dshModelSelectSearch", ++ children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSearchOutlineRegular, { className: "dshModelSelectSearchIcon" }), (0, react_jsx_runtime.jsx)("input", { ++ ref: searchRef, ++ type: "search", ++ role: "searchbox", ++ className: "dshModelSelectSearchInput", ++ value: modelQuery, ++ placeholder: t("search.placeholder"), ++ "aria-label": t("search.aria"), ++ autoComplete: "off", ++ spellCheck: false, ++ onChange: (event) => { ++ setModelQuery(event.target.value); ++ } ++ })] ++ }), + state.status === "loading" && (0, react_jsx_runtime.jsx)("div", { + className: ModelSelect_module_css_default.status, + children: t("status.loading") +@@ -817,7 +902,7 @@ window.__ModuleLoader__.load({ + }, failure.id)), + (0, react_jsx_runtime.jsx)("div", { + className: clsx(ModelSelect_module_css_default.groups, "scrollable"), +- children: groups.map((group) => { ++ children: filteredGroups.map((group) => { + const headingId = `${id}-${group.id}`; + return (0, react_jsx_runtime.jsxs)("section", { + role: "group", +@@ -861,6 +946,10 @@ window.__ModuleLoader__.load({ + state.status === "ready" && choices.length === 0 && (0, react_jsx_runtime.jsx)("div", { + className: ModelSelect_module_css_default.empty, + children: t("empty.models") ++ }), ++ state.status === "ready" && choices.length > 0 && filteredGroups.length === 0 && (0, react_jsx_runtime.jsx)("div", { ++ className: ModelSelect_module_css_default.empty, ++ children: t("empty.search") + }) + ] }), + pane === "effort" && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [state.error !== null && lastActionRef.current === "load" && (0, react_jsx_runtime.jsxs)("div", { +@@ -935,6 +1024,8 @@ window.__ModuleLoader__.load({ + "menu.aria": "模型与推理等级", + "menu.model": "模型", + "menu.effort": "推理等级", ++ "search.placeholder": "搜索模型或服务商", ++ "search.aria": "搜索模型或服务商", + "effort.providerDefault": "Default", + "status.loading": "正在刷新模型列表…", + "error.action": "模型操作失败:{message}", +@@ -942,6 +1033,7 @@ window.__ModuleLoader__.load({ + "action.reload": "重新加载", + "warning.groupLoad": "{name} 加载失败:{message}", + "empty.models": "没有可用的模型。", ++ "empty.search": "没有找到匹配的模型。", + "empty.efforts": "当前模型未提供推理等级。" + }; + /** English dictionary, checked complete against the zh key set. */ +@@ -960,6 +1052,8 @@ window.__ModuleLoader__.load({ + "menu.aria": "Model and reasoning effort", + "menu.model": "Model", + "menu.effort": "Effort", ++ "search.placeholder": "Search models or providers", ++ "search.aria": "Search models or providers", + "effort.providerDefault": "Default", + "status.loading": "Refreshing model list…", + "error.action": "Model operation failed: {message}", +@@ -967,6 +1061,7 @@ window.__ModuleLoader__.load({ + "action.reload": "Reload", + "warning.groupLoad": "{name} failed to load: {message}", + "empty.models": "No models available.", ++ "empty.search": "No matching models.", + "empty.efforts": "This model provides no reasoning effort levels." + }; + //#endregion diff --git a/patches/@deepseek-ai+dsh-client-ui-settings-general+0.1.7-rc.2.patch b/patches/@deepseek-ai+dsh-client-ui-settings-general+0.1.7-rc.2.patch new file mode 100644 index 000000000..508ecd686 --- /dev/null +++ b/patches/@deepseek-ai+dsh-client-ui-settings-general+0.1.7-rc.2.patch @@ -0,0 +1,25 @@ +diff --git a/node_modules/@deepseek-ai/dsh-client-ui-settings-general/lib/client.js b/node_modules/@deepseek-ai/dsh-client-ui-settings-general/lib/client.js +index 8f5fe80..1857e2a 100644 +--- a/node_modules/@deepseek-ai/dsh-client-ui-settings-general/lib/client.js ++++ b/node_modules/@deepseek-ai/dsh-client-ui-settings-general/lib/client.js +@@ -63,7 +63,7 @@ window.__ModuleLoader__.load({ + const tag = document.createElement("style"); + tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-settings-general"; + tag.dataset.pluginCss = tagId$6; +- tag.textContent = css$6; ++ tag.textContent = css$6 + "\n.VOzbGW_nav{min-height:0;overflow-y:auto;padding-bottom:22px}"; + document.head.appendChild(tag); + } + var SettingsRoot_module_css_default = { +@@ -356,10 +356,7 @@ window.__ModuleLoader__.load({ + const connectionState = useConnectionState((state) => state); + const previousConnectionState = (0, react.useRef)(connectionState); + const onboardingSteps = useOnboardingSteps((s) => s); +- const onboardingActive = useSessions((state) => { +- const main = Object.values(state.byId).find((session) => (session.retainedBy.mainView ?? 0) > 0); +- return state.phase === "ready" && (main === void 0 || main.blank); +- }); ++ const onboardingActive = useSessions((state) => state.phase === "ready"); + const onboardingStep = requestedOnboarding !== void 0 ? onboardingSteps.find((step) => step.id === requestedOnboarding) : onboardingActive ? onboardingSteps.find((step) => !completedOnboarding.has(step.id)) : void 0; + (0, react.useEffect)(() => { + if (onboardingActive) return; diff --git a/patches/@deepseek-ai+dsh-client-ui-settings-models+0.1.7-rc.2.patch b/patches/@deepseek-ai+dsh-client-ui-settings-models+0.1.7-rc.2.patch new file mode 100644 index 000000000..cffbc577b --- /dev/null +++ b/patches/@deepseek-ai+dsh-client-ui-settings-models+0.1.7-rc.2.patch @@ -0,0 +1,909 @@ +diff --git a/node_modules/@deepseek-ai/dsh-client-ui-settings-models/lib/client.js b/node_modules/@deepseek-ai/dsh-client-ui-settings-models/lib/client.js +index 5cb34cb..b2b837a 100644 +--- a/node_modules/@deepseek-ai/dsh-client-ui-settings-models/lib/client.js ++++ b/node_modules/@deepseek-ai/dsh-client-ui-settings-models/lib/client.js +@@ -64,6 +64,38 @@ window.__ModuleLoader__.load({ + tag.textContent = css$3; + document.head.appendChild(tag); + } ++ const providerPickerTagId = "@deepseek-ai/dsh-client-ui-settings-models/ProviderPicker"; ++ if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(providerPickerTagId) + "]") === null) { ++ const tag = document.createElement("style"); ++ tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-settings-models"; ++ tag.dataset.pluginCss = providerPickerTagId; ++ tag.textContent = ".dshProviderPicker{flex-direction:column;gap:10px;display:flex}.dshProviderSearch{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);width:100%;height:36px;font:inherit;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 11px;font-size:13px}.dshProviderSearch:focus{border-color:var(--dsw-alias-border-l1);outline:none}.dshProviderSearch::placeholder{color:var(--dsw-alias-label-dimmed)}.dshProviderGrid{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;display:grid}.dshProviderCard{box-sizing:border-box;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;flex-direction:column;align-items:flex-start;min-height:58px;padding:10px 12px;display:flex;cursor:pointer;text-align:left;font:inherit}.dshProviderCard:hover{background:var(--dsw-alias-interactive-bg-hover)}.dshProviderCard[aria-pressed=true]{border-color:var(--dsw-alias-border-l1);background:var(--dsw-alias-interactive-bg-hover)}.dshProviderCard:focus-visible{outline:none;box-shadow:0 0 0 2px var(--dsw-alias-border-l3)}.dshProviderName{font-size:14px;font-weight:500;line-height:20px}.dshProviderRoute{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px}.dshProviderSummary{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);border-radius:8px;align-items:center;gap:12px;min-height:52px;padding:8px 10px 8px 12px;display:flex}.dshProviderSummaryText{flex-direction:column;min-width:0;display:flex}.dshProviderChange{color:var(--dsw-alias-label-secondary);background:transparent;border:1px solid var(--dsw-alias-border-l2);border-radius:14px;margin-left:auto;padding:4px 10px;font:inherit;font-size:12px;cursor:pointer}.dshProviderChange:hover{background:var(--dsw-alias-interactive-bg-hover)}@media (width<=620px){.dshProviderGrid{grid-template-columns:1fr}}"; ++ document.head.appendChild(tag); ++ } ++ const modelModalityTagId = "@deepseek-ai/dsh-client-ui-settings-models/ModelModalityToggle"; ++ if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(modelModalityTagId) + "]") === null) { ++ const tag = document.createElement("style"); ++ tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-settings-models"; ++ tag.dataset.pluginCss = modelModalityTagId; ++ tag.textContent = ".dshModelModalityToggle{grid-column:1/-1;align-items:flex-start;gap:9px;min-height:36px;padding:4px;display:flex;cursor:pointer}.dshModelModalityToggle[aria-disabled=true]{cursor:default;opacity:.6}.dshModelModalityToggle input{accent-color:var(--dsw-alias-brand-primary);flex:none;width:16px;height:16px;margin:2px 0 0}.dshModelModalityCopy{flex-direction:column;gap:1px;display:flex}.dshModelModalityTitle{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:500;line-height:18px}.dshModelModalityHint{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px}.dshModelModalityToggleCompact{grid-column:auto;align-items:center;gap:5px;min-height:28px;white-space:nowrap;border-radius:6px;padding:0 4px;position:relative}.dshModelModalityToggleCompact:hover{background:var(--dsw-alias-interactive-bg-hover)}.dshModelModalityToggleCompact input{width:14px;height:14px;margin:0}.dshModelModalityToggleCompact .dshModelModalityCopy{display:block}.dshModelModalityToggleCompact .dshModelModalityTitle{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px}.dshModelModalityToggleCompact:after{content:attr(data-tooltip);z-index:12;pointer-events:none;box-sizing:border-box;width:max-content;max-width:260px;color:var(--dsw-alias-label-primary-foreground);background:var(--dsw-alias-label-primary);border-radius:6px;padding:6px 8px;font-size:11px;font-weight:400;line-height:16px;white-space:normal;visibility:hidden;opacity:0;position:absolute;top:calc(100% + 5px);right:0}.dshModelModalityToggleCompact:hover:after,.dshModelModalityToggleCompact:focus-within:after{visibility:visible;opacity:1}.qy-_KG_modelRow{grid-template-columns:minmax(0,1.3fr) minmax(0,1fr) auto auto auto}"; ++ document.head.appendChild(tag); ++ } ++ const modelCatalogUxTagId = "@deepseek-ai/dsh-client-ui-settings-models/ModelCatalogUx"; ++ if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(modelCatalogUxTagId) + "]") === null) { ++ const tag = document.createElement("style"); ++ tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-settings-models"; ++ tag.dataset.pluginCss = modelCatalogUxTagId; ++ tag.textContent = ".dshModelCatalogSearch{box-sizing:border-box;position:relative;align-items:center;display:flex}.dshModelCatalogSearchIcon{position:absolute;left:10px;color:var(--dsw-alias-label-tertiary);pointer-events:none}.dshModelCatalogSearch input{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);width:100%;height:34px;font:inherit;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 11px 0 34px;font-size:13px;line-height:20px}.dshModelCatalogSearch input:focus{border-color:var(--dsw-alias-brand-primary);outline:none}.dshModelCatalogSearch input::placeholder{color:var(--dsw-alias-label-dimmed)}.dshProviderEditorExpanded .qy-_KG_customizedBody{padding-bottom:72px}.dshProviderEditorStickyFooter{z-index:4;position:sticky;bottom:-24px;background:var(--dsw-alias-bg-module-platform);border-top:1px solid var(--dsw-alias-border-l2);box-shadow:0 -10px 18px -18px #0009;align-items:center;justify-content:space-between;gap:12px;margin:0 -16px -14px;padding:12px 16px 14px;display:flex}.dshProviderEditorStickyFooter .qy-_KG_editorActions{margin-left:auto}@media (width<=620px){.dshProviderEditorStickyFooter{align-items:stretch;flex-wrap:wrap}.dshProviderEditorStickyFooter .qy-_KG_editorActions{margin-left:auto}}"; ++ document.head.appendChild(tag); ++ } ++ const modelReasoningTagId = "@deepseek-ai/dsh-client-ui-settings-models/ModelReasoningEffortsField"; ++ if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(modelReasoningTagId) + "]") === null) { ++ const tag = document.createElement("style"); ++ tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-settings-models"; ++ tag.dataset.pluginCss = modelReasoningTagId; ++ tag.textContent = ".dshModelReasoningField{grid-column:1/-1;flex-direction:column;gap:6px;display:flex}.dshModelReasoningHint{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px}"; ++ document.head.appendChild(tag); ++ } + var ModelsSection_module_css_default = { + "addActions": "zGbnIq_addActions", + "addBlock": "zGbnIq_addBlock", +@@ -200,6 +232,68 @@ window.__ModuleLoader__.load({ + }); + } + //#endregion ++ //#region lib/types/client/ModelImageInputToggle.js ++ /** Whether one model explicitly declares image input in the adapter-owned field. */ ++ function imageInputEnabled(model, field) { ++ const modalities = model[field]; ++ return Array.isArray(modalities) && modalities.includes("image"); ++ } ++ /** The explicit modality list written by the binary image-input control. */ ++ function imageInputModalities(enabled) { ++ return enabled ? ["text", "image"] : ["text"]; ++ } ++ /** Render the shared per-model image-input declaration control. */ ++ function ModelImageInputToggle(props) { ++ return (0, react_jsx_runtime.jsxs)("label", { ++ className: props.compact ? "dshModelModalityToggle dshModelModalityToggleCompact" : "dshModelModalityToggle", ++ "aria-disabled": props.disabled, ++ "data-tooltip": props.compact ? `${props.t("modelImageInput")}: ${props.t("modelImageInputHint")}` : void 0, ++ children: [(0, react_jsx_runtime.jsx)("input", { ++ type: "checkbox", ++ checked: imageInputEnabled(props.model, props.field), ++ "aria-label": `${props.t("modelImageInput")} ${String(props.index + 1)}`, ++ disabled: props.disabled, ++ onChange: (event) => { ++ props.onChange(event.target.checked); ++ } ++ }), (0, react_jsx_runtime.jsxs)("span", { ++ className: "dshModelModalityCopy", ++ children: [(0, react_jsx_runtime.jsx)("span", { ++ className: "dshModelModalityTitle", ++ children: props.t(props.compact ? "modelImageInputShort" : "modelImageInput") ++ }), props.compact ? null : (0, react_jsx_runtime.jsx)("span", { ++ className: "dshModelModalityHint", ++ children: props.t("modelImageInputHint") ++ })] ++ })] ++ }); ++ } ++ //#endregion ++ //#region lib/types/client/ModelCatalogSearch.js ++ /** Filter a model catalog without losing the source index used by edit actions. */ ++ function searchableModelEntries(models, query) { ++ const needle = query.trim().toLowerCase(); ++ return models.map((model, index) => ({ model, index })).filter(({ model }) => needle.length === 0 || [model.id, model.name].some((value) => typeof value === "string" && value.toLowerCase().includes(needle))); ++ } ++ /** Shared search field for both adapter-owned model catalog editors. */ ++ function ModelCatalogSearch(props) { ++ return (0, react_jsx_runtime.jsxs)("label", { ++ className: "dshModelCatalogSearch", ++ children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSearchOutlineRegular, { className: "dshModelCatalogSearchIcon" }), (0, react_jsx_runtime.jsx)("input", { ++ type: "search", ++ role: "searchbox", ++ value: props.value, ++ placeholder: props.t("modelSearch"), ++ "aria-label": props.t("modelSearch"), ++ autoComplete: "off", ++ spellCheck: false, ++ onChange: (event) => { ++ props.onChange(event.target.value); ++ } ++ })] ++ }); ++ } ++ //#endregion + //#region lib/types/client/ModelRow.js + /** + * Render consistent model identity, capacity, and input-type controls. +@@ -278,6 +372,87 @@ window.__ModuleLoader__.load({ + }); + } + //#endregion ++ //#region lib/types/client/ModelReasoningEffortsField.js ++ /** ++ * Persisted model capability configuration uses `reasoningEfforts`; the ++ * adapter later resolves it into the runtime `model.reasoning` shape used by ++ * the composer. ++ */ ++ /** Read the canonical per-model reasoning capability declaration. */ ++ function configuredReasoningEfforts(model) { ++ const configured = model.reasoningEfforts; ++ return configured !== null && typeof configured === "object" && !Array.isArray(configured) ? configured : {}; ++ } ++ /** Parse a comma-separated list of effort ids into a clean string array. */ ++ function parseEffortList(text) { ++ return text.split(",").map((value) => value.trim()).filter((value) => value.length > 0); ++ } ++ /** ++ * Read the IDs shown in the editor. Legacy #215 rows remain visible long ++ * enough for an edit to migrate them to the canonical configuration field. ++ */ ++ function reasoningEffortIds(model) { ++ const configuredIds = Object.keys(configuredReasoningEfforts(model)); ++ if (configuredIds.length > 0) return configuredIds; ++ const legacy = model.reasoning?.efforts; ++ if (!Array.isArray(legacy)) return []; ++ return legacy.filter((level) => level !== null && typeof level === "object" && typeof level.id === "string" && level.id.trim().length > 0).map((level) => level.id); ++ } ++ /** ++ * Build the next persisted capability map. Existing wire values are retained; ++ * newly entered IDs use identity mapping. ++ * @param model - the current model row. ++ * @param ids - cleaned ids from the comma-separated field. ++ * @returns the next reasoning-efforts map, or undefined to drop it. ++ */ ++ function nextReasoningEfforts(model, ids) { ++ if (ids.length === 0) return void 0; ++ const configured = configuredReasoningEfforts(model); ++ return Object.fromEntries(ids.map((id) => [id, Object.prototype.hasOwnProperty.call(configured, id) ? configured[id] : id])); ++ } ++ /** ++ * Render the per-model reasoning effort declaration control. One ++ * comma-separated text field carries the effort IDs; clearing it drops the ++ * per-model capability declaration. ++ * @param props - model row, row index, copy callback, disabled flag, and writer. ++ * @returns the reasoning control. ++ */ ++ function ModelReasoningEffortsField(props) { ++ const ids = reasoningEffortIds(props.model); ++ const canonical = ids.join(", "); ++ const [draft, setDraft] = (0, react.useState)(null); ++ const value = draft !== null ? draft : canonical; ++ return (0, react_jsx_runtime.jsxs)("div", { ++ className: "dshModelReasoningField", ++ children: [ ++ (0, react_jsx_runtime.jsxs)("label", { ++ className: ModelsSection_module_css_default["modelField"], ++ children: [(0, react_jsx_runtime.jsx)("span", { ++ className: ModelsSection_module_css_default["modelFieldLabel"], ++ children: props.t("modelReasoningLevels") ++ }), (0, react_jsx_runtime.jsx)("input", { ++ className: ModelsSection_module_css_default["input"], ++ type: "text", ++ value, ++ placeholder: props.t("modelReasoningLevelsPlaceholder"), ++ "aria-label": `${props.t("modelReasoningLevels")} ${String(props.index + 1)}`, ++ disabled: props.disabled, ++ onChange: (event) => { ++ setDraft(event.target.value); ++ props.onChange(nextReasoningEfforts(props.model, parseEffortList(event.target.value))); ++ }, ++ onBlur: () => { ++ setDraft(null); ++ } ++ }), (0, react_jsx_runtime.jsx)("span", { ++ className: "dshModelReasoningHint", ++ children: props.t("modelReasoningLevelsHint") ++ })] ++ }) ++ ] ++ }); ++ } ++ //#endregion + //#region lib/types/client/DeepSeekModelsEditor.js + /** + * Curated editor for the direct DeepSeek adapter's advisory model catalog. +@@ -379,6 +554,7 @@ window.__ModuleLoader__.load({ + function DeepSeekModelsEditor(props) { + const [editing, setEditing] = (0, react.useState)(() => /* @__PURE__ */ new Map()); + const [expanded, setExpanded] = (0, react.useState)(() => /* @__PURE__ */ new Set()); ++ const visibleModels = (0, react.useMemo)(() => searchableModelEntries(props.models, props.modelQuery), [props.models, props.modelQuery]); + const update = (index, key, value) => { + const next = props.models.map((model, at) => { + const copy = { ...model }; +@@ -451,6 +627,27 @@ window.__ModuleLoader__.load({ + settleCapacity(index, field); + } + }); ++ // Keep the row-level controls while using the 0.1.7 capacity input contract. ++ const capacityField = (model, index, field, fallback) => { ++ const input = capacityInput(model, index, field, fallback); ++ return (0, react_jsx_runtime.jsxs)("label", { ++ className: ModelsSection_module_css_default["modelField"], ++ children: [(0, react_jsx_runtime.jsx)("span", { ++ className: ModelsSection_module_css_default["modelFieldLabel"], ++ children: props.t(field) ++ }), (0, react_jsx_runtime.jsx)("input", { ++ className: ModelsSection_module_css_default["input"], ++ type: "text", ++ inputMode: "numeric", ++ value: input.value, ++ placeholder: input.placeholder, ++ "aria-label": `${props.t(field)} ${String(index + 1)}`, ++ disabled: props.disabled, ++ onChange: (event) => input.onChange(event.target.value), ++ onBlur: input.onBlur ++ })] ++ }, field); ++ }; + return (0, react_jsx_runtime.jsxs)("section", { + className: ModelsSection_module_css_default["modelCatalog"], + "aria-label": props.t("models"), +@@ -474,46 +671,89 @@ window.__ModuleLoader__.load({ + children: props.t("resetModels") + }) : null] + }), ++ (0, react_jsx_runtime.jsx)(ModelCatalogSearch, { ++ value: props.modelQuery, ++ onChange: props.onModelQueryChange, ++ t: props.t ++ }), + props.models.length === 0 ? (0, react_jsx_runtime.jsx)("p", { + className: ModelsSection_module_css_default["modelEmpty"], + children: props.t("modelsEmpty") ++ }) : visibleModels.length === 0 ? (0, react_jsx_runtime.jsx)("p", { ++ className: ModelsSection_module_css_default["modelEmpty"], ++ children: props.t("modelSearchEmpty") + }) : (0, react_jsx_runtime.jsx)("div", { + className: ModelsSection_module_css_default["modelList"], +- children: props.models.map((model, index) => (0, react_jsx_runtime.jsx)(ModelRow, { +- model, +- position: index + 1, +- inputField: "inputModalities", +- expanded: expanded.has(index), +- disabled: props.disabled, +- t: props.t, +- contextWindow: capacityInput(model, index, "contextWindow", props.defaultContextWindow), +- maxTokens: capacityInput(model, index, "maxTokens", props.defaultMaxTokens), +- onFieldChange: (field, value) => { +- update(index, field, value); +- }, +- onIdBlur: (value) => { +- const trimmed = value.trim(); +- if (trimmed !== value) update(index, "id", trimmed); +- }, +- onChange: (next) => { +- props.onChange(props.models.map((row, at) => at === index ? next : row)); +- }, +- onToggle: () => { +- toggle(index); +- }, +- onRemove: () => { +- remove(index); +- } +- }, index)) ++ children: visibleModels.map(({ model, index }) => (0, react_jsx_runtime.jsxs)("div", { ++ className: ModelsSection_module_css_default["modelEntry"], ++ children: [(0, react_jsx_runtime.jsxs)("div", { ++ className: ModelsSection_module_css_default["modelRow"], ++ children: [ ++ (0, react_jsx_runtime.jsx)("input", { ++ className: ModelsSection_module_css_default["input"], ++ type: "text", ++ value: typeof model["id"] === "string" ? model["id"] : "", ++ placeholder: props.t("modelId"), ++ "aria-label": `${props.t("modelId")} ${String(index + 1)}`, ++ disabled: props.disabled, ++ onChange: (event) => { ++ update(index, "id", event.target.value); ++ }, ++ onBlur: (event) => { ++ const trimmed = event.target.value.trim(); ++ if (trimmed !== event.target.value) update(index, "id", trimmed); ++ } ++ }), ++ (0, react_jsx_runtime.jsx)("input", { ++ className: ModelsSection_module_css_default["input"], ++ type: "text", ++ value: typeof model["name"] === "string" ? model["name"] : "", ++ placeholder: props.t("modelName"), ++ "aria-label": `${props.t("modelName")} ${String(index + 1)}`, ++ disabled: props.disabled, ++ onChange: (event) => { ++ update(index, "name", event.target.value === "" ? void 0 : event.target.value); ++ } + }), +- (0, react_jsx_runtime.jsxs)("button", { +- type: "button", +- className: ModelsSection_module_css_default["addModelButton"], ++ (0, react_jsx_runtime.jsx)(ModelImageInputToggle, { ++ model, ++ field: "inputModalities", ++ index, ++ t: props.t, + disabled: props.disabled, +- onClick: () => { +- props.onChange([...props.models.map((model) => ({ ...model })), { id: "" }]); +- }, +- children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPlusOutlineRegular, { size: 14 }), props.t("addModel")] ++ compact: true, ++ onChange: (enabled) => { ++ update(index, "inputModalities", imageInputModalities(enabled)); ++ } ++ }), ++ (0, react_jsx_runtime.jsx)("button", { ++ type: "button", ++ className: ModelsSection_module_css_default["iconButton"], ++ "aria-label": `${props.t("modelAdvanced")} ${String(index + 1)}`, ++ "aria-expanded": expanded.has(index), ++ title: props.t("modelAdvanced"), ++ onClick: () => { ++ toggle(index); ++ }, ++ children: expanded.has(index) ? (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutlineRegular, {}) : (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutlineRegular, {}) ++ }), ++ (0, react_jsx_runtime.jsx)("button", { ++ type: "button", ++ className: `${ModelsSection_module_css_default["iconButton"]} ${ModelsSection_module_css_default["iconButtonDanger"]}`, ++ "aria-label": `${props.t("removeModel")} ${String(index + 1)}`, ++ title: props.t("removeModel"), ++ disabled: props.disabled, ++ onClick: () => { ++ remove(index); ++ }, ++ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconTrashOutlineRegular, { size: 14 }) ++ }) ++ ] ++ }), expanded.has(index) ? (0, react_jsx_runtime.jsxs)("div", { ++ className: ModelsSection_module_css_default["modelAdvanced"], ++ children: [capacityField(model, index, "contextWindow", props.defaultContextWindow), capacityField(model, index, "maxTokens", props.defaultMaxTokens)] ++ }) : null] ++ }, index)) + }) + ] + }); +@@ -620,6 +860,7 @@ window.__ModuleLoader__.load({ + const [candidateQuery, setCandidateQuery] = (0, react.useState)(""); + const [expanded, setExpanded] = (0, react.useState)(/* @__PURE__ */ new Set()); + const [editing, setEditing] = (0, react.useState)(/* @__PURE__ */ new Map()); ++ const visibleModels = (0, react.useMemo)(() => searchableModelEntries(models, props.modelQuery), [models, props.modelQuery]); + /** Buffer key for one capacity field; the row half moves when rows do. */ + const bufferKey = (index, field) => `${String(index)}:${field}`; + const editCapacity = (index, field, text) => { +@@ -758,65 +999,133 @@ window.__ModuleLoader__.load({ + }) + ] + }), ++ (0, react_jsx_runtime.jsx)(ModelCatalogSearch, { ++ value: props.modelQuery, ++ onChange: props.onModelQueryChange, ++ t ++ }), + models.length === 0 ? (0, react_jsx_runtime.jsx)("p", { + className: ModelsSection_module_css_default["modelEmpty"], + children: t("modelsEmpty") ++ }) : visibleModels.length === 0 ? (0, react_jsx_runtime.jsx)("p", { ++ className: ModelsSection_module_css_default["modelEmpty"], ++ children: t("modelSearchEmpty") + }) : null, +- (0, react_jsx_runtime.jsx)("div", { +- className: ModelsSection_module_css_default["modelList"], +- children: models.map((model, index) => (0, react_jsx_runtime.jsx)(ModelRow, { +- model, +- position: index + 1, +- inputField: "input", +- inputFallback: inputDefaults.get(textOf(model, "id")) ?? props.defaultInput, +- inputLoading: catalogProvider !== void 0 && catalog === void 0, +- expanded: expanded.has(index), +- disabled, +- t, +- contextWindow: { +- value: capacityText(model, index, "contextWindow"), +- placeholder: CAPACITY_HINT.contextWindow, +- onChange: (text) => { +- editCapacity(index, "contextWindow", text); +- } +- }, +- maxTokens: { +- value: capacityText(model, index, "maxTokens"), +- placeholder: CAPACITY_HINT.maxTokens, +- onChange: (text) => { +- editCapacity(index, "maxTokens", text); +- } +- }, +- onFieldChange: (field, value) => { +- patch(index, { [field]: value }); +- }, +- onChange: (next) => { +- onChange(models.map((row, at) => at === index ? next : row)); +- }, +- onToggle: () => { +- toggleExpanded(index); +- }, +- onRemove: () => { +- onChange(models.filter((_model, at) => at !== index)); +- setExpanded((current) => { +- const next = /* @__PURE__ */ new Set(); +- for (const at of current) if (at < index) next.add(at); +- else if (at > index) next.add(at - 1); +- return next; +- }); +- setEditing((current) => reindexOnRemove(current, index)); +- } +- }, index)) ++ visibleModels.map(({ model, index }) => (0, react_jsx_runtime.jsxs)("div", { ++ className: ModelsSection_module_css_default["modelEntry"], ++ children: [(0, react_jsx_runtime.jsxs)("div", { ++ className: ModelsSection_module_css_default["modelRow"], ++ children: [ ++ (0, react_jsx_runtime.jsx)("input", { ++ className: ModelsSection_module_css_default["input"], ++ type: "text", ++ value: textOf(model, "id"), ++ placeholder: t("modelId"), ++ "aria-label": `${t("modelId")} ${index + 1}`, ++ disabled, ++ onChange: (event) => { ++ patch(index, { id: event.target.value }); ++ } ++ }), ++ (0, react_jsx_runtime.jsx)("input", { ++ className: ModelsSection_module_css_default["input"], ++ type: "text", ++ value: textOf(model, "name"), ++ placeholder: t("modelName"), ++ "aria-label": `${t("modelName")} ${index + 1}`, ++ disabled, ++ onChange: (event) => { ++ patch(index, { name: event.target.value === "" ? void 0 : event.target.value }); ++ } + }), +- (0, react_jsx_runtime.jsxs)("button", { +- type: "button", +- className: ModelsSection_module_css_default["addModelButton"], ++ (0, react_jsx_runtime.jsx)(ModelImageInputToggle, { ++ model, ++ field: "input", ++ index, ++ t, + disabled, +- onClick: () => { +- onChange([...models, { id: "" }]); +- }, +- children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPlusOutlineRegular, { size: 14 }), t("addModel")] ++ compact: true, ++ onChange: (enabled) => { ++ patch(index, { input: imageInputModalities(enabled) }); ++ } + }), ++ (0, react_jsx_runtime.jsx)("button", { ++ type: "button", ++ className: ModelsSection_module_css_default["iconButton"], ++ "aria-label": `${t("modelAdvanced")} ${index + 1}`, ++ "aria-expanded": expanded.has(index), ++ title: t("modelAdvanced"), ++ onClick: () => { ++ toggleExpanded(index); ++ }, ++ children: (0, react_jsx_runtime.jsx)(expanded.has(index) ? _deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutlineRegular : _deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutlineRegular, {}) ++ }), ++ (0, react_jsx_runtime.jsx)("button", { ++ type: "button", ++ className: `${ModelsSection_module_css_default["iconButton"]} ${ModelsSection_module_css_default["iconButtonDanger"]}`, ++ "aria-label": `${t("removeModel")} ${index + 1}`, ++ title: t("removeModel"), ++ disabled, ++ onClick: () => { ++ onChange(models.filter((_model, at) => at !== index)); ++ setExpanded((current) => { ++ const next = /* @__PURE__ */ new Set(); ++ for (const at of current) if (at < index) next.add(at); ++ else if (at > index) next.add(at - 1); ++ return next; ++ }); ++ setEditing((current) => reindexOnRemove(current, index)); ++ }, ++ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconTrashOutlineRegular, {}) ++ }) ++ ] ++ }), expanded.has(index) ? (0, react_jsx_runtime.jsxs)("div", { ++ className: ModelsSection_module_css_default["modelAdvanced"], ++ children: [(0, react_jsx_runtime.jsxs)("label", { ++ className: ModelsSection_module_css_default["modelField"], ++ children: [(0, react_jsx_runtime.jsx)("span", { ++ className: ModelsSection_module_css_default["modelFieldLabel"], ++ children: t("modelContextWindow") ++ }), (0, react_jsx_runtime.jsx)("input", { ++ className: ModelsSection_module_css_default["input"], ++ type: "text", ++ inputMode: "numeric", ++ value: capacityText(model, index, "contextWindow"), ++ placeholder: CAPACITY_HINT.contextWindow, ++ "aria-label": `${t("modelContextWindow")} ${index + 1}`, ++ disabled, ++ onChange: (event) => { ++ editCapacity(index, "contextWindow", event.target.value); ++ } ++ })] ++ }), (0, react_jsx_runtime.jsxs)("label", { ++ className: ModelsSection_module_css_default["modelField"], ++ children: [(0, react_jsx_runtime.jsx)("span", { ++ className: ModelsSection_module_css_default["modelFieldLabel"], ++ children: t("modelMaxTokens") ++ }), (0, react_jsx_runtime.jsx)("input", { ++ className: ModelsSection_module_css_default["input"], ++ type: "text", ++ inputMode: "numeric", ++ value: capacityText(model, index, "maxTokens"), ++ placeholder: CAPACITY_HINT.maxTokens, ++ "aria-label": `${t("modelMaxTokens")} ${index + 1}`, ++ disabled, ++ onChange: (event) => { ++ editCapacity(index, "maxTokens", event.target.value); ++ } ++ })] ++ }), (0, react_jsx_runtime.jsx)(ModelReasoningEffortsField, { ++ model, ++ index, ++ t, ++ disabled, ++ onChange: (next) => { ++ patch(index, { reasoningEfforts: next, reasoning: void 0 }); ++ } ++ })] ++ }) : null] ++ }, index)), + failure !== void 0 ? (0, react_jsx_runtime.jsx)("p", { + className: ModelsSection_module_css_default["error"], + children: failure +@@ -1216,6 +1525,7 @@ window.__ModuleLoader__.load({ + const [protocol, setProtocol] = (0, react.useState)(protocols[0] ?? ""); + const [keyDraft, setKeyDraft] = (0, react.useState)(""); + const [models, setModels] = (0, react.useState)([]); ++ const [modelQuery, setModelQuery] = (0, react.useState)(""); + const [busy, setBusy] = (0, react.useState)(false); + const [listBusy, setListBusy] = (0, react.useState)(false); + (0, react.useEffect)(() => { +@@ -1283,6 +1593,11 @@ window.__ModuleLoader__.load({ + setBusy(false); + } + }; ++ /** Add an explicit model row to the custom-provider draft. */ ++ const addModel = () => { ++ setModels((current) => [...current.map((model) => ({ ...model })), { id: "" }]); ++ setModelQuery(""); ++ }; + return (0, react_jsx_runtime.jsxs)("div", { + className: ModelsSection_module_css_default["editor"], + children: [ +@@ -1396,6 +1711,8 @@ window.__ModuleLoader__.load({ + (0, react_jsx_runtime.jsx)(ModelListEditor, { + models, + onChange: setModels, ++ modelQuery, ++ onModelQueryChange: setModelQuery, + probe: { + settingsNs: NS$1, + baseURL: normalizedBaseURL, +@@ -1416,18 +1733,27 @@ window.__ModuleLoader__.load({ + className: ModelsSection_module_css_default["advancedHint"], + children: hint + }), +- (0, react_jsx_runtime.jsx)(EditorFooter, { +- t, +- busy, +- submitDisabled: disabled || !ready, +- submitLabelKey: "create", +- submitBusyLabelKey: "creating", +- onCancel: () => { +- props.onClose(committed); +- }, +- onSubmit: () => { +- create(); +- } ++ (0, react_jsx_runtime.jsxs)("div", { ++ className: "dshProviderEditorStickyFooter", ++ children: [(0, react_jsx_runtime.jsx)("button", { ++ type: "button", ++ className: ModelsSection_module_css_default["addModelButton"], ++ disabled: profileDisabled, ++ onClick: addModel, ++ children: t("addModel") ++ }), (0, react_jsx_runtime.jsx)(EditorFooter, { ++ t, ++ busy, ++ submitDisabled: disabled || !ready, ++ submitLabelKey: "create", ++ submitBusyLabelKey: "creating", ++ onCancel: () => { ++ props.onClose(committed); ++ }, ++ onSubmit: () => { ++ create(); ++ } ++ })] + }) + ] + }); +@@ -1522,6 +1848,8 @@ window.__ModuleLoader__.load({ + onBusyChange + ]); + const [failure, setFailure] = (0, react.useState)(void 0); ++ const [modelQuery, setModelQuery] = (0, react.useState)(""); ++ const [customizedOpen, setCustomizedOpen] = (0, react.useState)(false); + const [committedOriginal, setCommittedOriginal] = (0, react.useState)(() => schema.getPath(namespace.user, settingsPath)); + const [expectedRevision, setExpectedRevision] = (0, react.useState)(() => namespace.revision); + const root = (0, react.useMemo)(() => schema.rehydrate(namespace.schema), [namespace.schema, schema]); +@@ -1648,6 +1976,15 @@ window.__ModuleLoader__.load({ + const inheritedModels = () => { + return schema.getPath(namespace.base, [...settingsPath, "models"]) ?? schema.nodeAtPath(root, [...settingsPath, "models"])?.meta.default; + }; ++ /** Materialize the visible catalog override and reveal the newly added row. */ ++ const addModel = () => { ++ const customModels = schema.getPath(draft, ["models"]); ++ const modelsOverridden = schema.hasPath(draft, ["models"]); ++ const models = modelDrafts(modelsOverridden ? customModels : inheritedModels()); ++ setDraft((current) => schema.setPath(current, ["models"], [...models.map((model) => ({ ...model })), { id: "" }])); ++ setModelQuery(""); ++ setCustomizedOpen(true); ++ }; + /** + * The curated fields of one known adapter family. The family arrives + * narrowed so the per-family branches below are total: an unknown namespace +@@ -1666,6 +2003,8 @@ window.__ModuleLoader__.load({ + const catalogProps = { + models, + overridden: modelsOverridden, ++ modelQuery, ++ onModelQueryChange: setModelQuery, + t, + disabled, + onChange: (next) => { +@@ -1709,6 +2048,10 @@ window.__ModuleLoader__.load({ + ] + }), props.credentialOnly === true ? null : (0, react_jsx_runtime.jsxs)("details", { + className: ModelsSection_module_css_default["customized"], ++ open: customizedOpen, ++ onToggle: (event) => { ++ setCustomizedOpen(event.currentTarget.open); ++ }, + children: [(0, react_jsx_runtime.jsx)("summary", { + className: ModelsSection_module_css_default["customizedSummary"], + children: t("customized") +@@ -1797,8 +2140,22 @@ window.__ModuleLoader__.load({ + })] + })] }); + }; ++ const footerProps = { ++ t, ++ busy, ++ submitDisabled: disabled || layout === "unknown" || props.credentialOnly !== true && modelFailure !== void 0 || shownKeyFailure !== void 0 || props.credentialRequired === true && keyValue.length === 0, ++ submitLabelKey: props.submitLabelKey ?? "apply", ++ submitBusyLabelKey: props.submitBusyLabelKey ?? "applying", ++ ...props.cancelLabelKey === void 0 ? {} : { cancelLabelKey: props.cancelLabelKey }, ++ onCancel: () => { ++ props.onClose(false); ++ }, ++ onSubmit: () => { ++ apply(); ++ } ++ }; + return (0, react_jsx_runtime.jsxs)("div", { +- className: props.credentialOnly === true ? ModelsSection_module_css_default["addBlock"] : ModelsSection_module_css_default["editor"], ++ className: props.credentialOnly === true ? ModelsSection_module_css_default["addBlock"] : `${ModelsSection_module_css_default["editor"]}${customizedOpen ? " dshProviderEditorExpanded" : ""}`, + children: [ + props.hideTitle === true ? null : (0, react_jsx_runtime.jsxs)("div", { + className: ModelsSection_module_css_default["editorHeader"], +@@ -1822,19 +2179,15 @@ window.__ModuleLoader__.load({ + className: ModelsSection_module_css_default["advancedHint"], + children: `${t("model")} ${String(modelFailure.index + 1)}: ${t(modelFailure.key)}` + }), +- (0, react_jsx_runtime.jsx)(EditorFooter, { +- t, +- busy, +- submitDisabled: disabled || layout === "unknown" || props.credentialOnly !== true && modelFailure !== void 0 || shownKeyFailure !== void 0 || props.credentialRequired === true && keyValue.length === 0, +- submitLabelKey: props.submitLabelKey ?? "apply", +- submitBusyLabelKey: props.submitBusyLabelKey ?? "applying", +- ...props.cancelLabelKey === void 0 ? {} : { cancelLabelKey: props.cancelLabelKey }, +- onCancel: () => { +- props.onClose(false); +- }, +- onSubmit: () => { +- apply(); +- } ++ props.credentialOnly === true || !customizedOpen || layout === "unknown" ? (0, react_jsx_runtime.jsx)(EditorFooter, { ...footerProps }) : (0, react_jsx_runtime.jsxs)("div", { ++ className: "dshProviderEditorStickyFooter", ++ children: [(0, react_jsx_runtime.jsxs)("button", { ++ type: "button", ++ className: ModelsSection_module_css_default["addModelButton"], ++ disabled, ++ onClick: addModel, ++ children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPlusOutlineRegular, { size: 14 }), t("addModel")] ++ }), (0, react_jsx_runtime.jsx)(EditorFooter, { ...footerProps })] + }) + ] + }); +@@ -1940,6 +2293,26 @@ window.__ModuleLoader__.load({ + function providerCopy(template, target) { + return template.replace("{provider}", () => providerTargetLabel(target)); + } ++ /** Common providers first; specialized routes follow alphabetically. */ ++ const SETTINGS_PROVIDER_PRIORITY = [ ++ "deepseek-official", ++ "deepseek", ++ "openai", ++ "anthropic", ++ "google", ++ "openrouter", ++ "xai", ++ "moonshotai-cn", ++ "moonshotai", ++ "minimax-cn", ++ "minimax", ++ "zai-coding-cn", ++ "zai", ++ "mistral", ++ "groq", ++ "together" ++ ]; ++ const SETTINGS_PROVIDER_RANK = new Map(SETTINGS_PROVIDER_PRIORITY.map((provider, index) => [provider, index])); + /** + * Render the Models section content column. + * @param props - slot-delivered injected dependencies. +@@ -1986,6 +2359,7 @@ window.__ModuleLoader__.load({ + const [deleting, setDeleting] = (0, react.useState)(false); + const [deleteFailure, setDeleteFailure] = (0, react.useState)(void 0); + const [savedTarget, setSavedTarget] = (0, react.useState)(void 0); ++ + const [dismissedSetup, setDismissedSetup] = (0, react.useState)(() => /* @__PURE__ */ new Set()); + const announceSaved = (target) => { + controller.load().then(() => { +@@ -2073,6 +2447,10 @@ window.__ModuleLoader__.load({ + row, + namespace + }]; ++ }).sort((left, right) => { ++ const leftRank = SETTINGS_PROVIDER_RANK.get(left.row.entry.provider) ?? Number.MAX_SAFE_INTEGER; ++ const rightRank = SETTINGS_PROVIDER_RANK.get(right.row.entry.provider) ?? Number.MAX_SAFE_INTEGER; ++ return leftRank - rightRank || left.row.entry.displayName.localeCompare(right.row.entry.displayName); + }); + const piAi = state.namespaces.get("llm-pi-ai"); + const protocols = protocolChoices(piAi, schema); +@@ -2483,9 +2861,24 @@ window.__ModuleLoader__.load({ + function assertNever$1(_value) { + throw new Error("unexpected DeepSeek onboarding state"); + } ++ /** Mainstream catalog routes exposed during first-run setup. */ ++ const ONBOARDING_PROVIDERS = [ ++ { provider: "deepseek-official", displayName: "DeepSeek", kind: "onboardingManufacturer" }, ++ { provider: "openai", displayName: "OpenAI", kind: "onboardingManufacturer" }, ++ { provider: "anthropic", displayName: "Anthropic", kind: "onboardingManufacturer" }, ++ { provider: "google", displayName: "Google Gemini", kind: "onboardingManufacturer" }, ++ { provider: "openrouter", displayName: "OpenRouter", kind: "onboardingAggregator" }, ++ { provider: "xai", displayName: "xAI", kind: "onboardingManufacturer" }, ++ { provider: "moonshotai-cn", displayName: "Moonshot / Kimi", kind: "onboardingManufacturer" }, ++ { provider: "minimax-cn", displayName: "MiniMax", kind: "onboardingManufacturer" }, ++ { provider: "zai-coding-cn", displayName: "智谱 GLM", kind: "onboardingManufacturer" }, ++ { provider: "mistral", displayName: "Mistral AI", kind: "onboardingManufacturer" }, ++ { provider: "groq", displayName: "Groq", kind: "onboardingInference" }, ++ { provider: "together", displayName: "Together AI", kind: "onboardingInference" } ++ ]; + /** +- * Prompt a first-run user for the official DeepSeek credential while no +- * provider can serve requests and that credential is writable. ++ * Prompt a first-run user to choose a supported mainstream provider and store ++ * its credential while no configured route can serve requests. + * @param props - settings-shell owner state and Models feature dependencies. + * @returns the onboarding modal or null when onboarding needs no intervention. + */ +@@ -2494,6 +2887,16 @@ window.__ModuleLoader__.load({ + const [apiKey, setApiKey] = (0, react.useState)(explicit); + const state = useModels((snapshot) => snapshot); + const readiness = onboardingReadiness(state); ++ const [selectedProvider, setSelectedProvider] = (0, react.useState)("deepseek-official"); ++ const choices = ONBOARDING_PROVIDERS.flatMap((choice) => { ++ const row = state.rows.find((candidate) => candidate.entry.provider === choice.provider && candidate.entry.settingsNs !== ""); ++ return row === void 0 || state.namespaces.get(row.entry.settingsNs) === void 0 ? [] : [{ ++ ...choice, ++ row ++ }]; ++ }); ++ const selected = choices.find((choice) => choice.provider === selectedProvider) ?? choices[0]; ++ const anyUsable = state.rows.some(providerUsable); + (0, react.useEffect)(() => { + if ((automatic || explicit) && state.status === "idle") controller.load(); + }, [ +@@ -2867,6 +3270,8 @@ window.__ModuleLoader__.load({ + addCatalogExhausted: "Every catalog provider is already configured.", + addCustomUnavailable: "No API protocol is available to declare.", + provider: "Provider", ++ providerSearch: "Search providers", ++ changeProvider: "Change", + close: "Close", + cancel: "Cancel", + apply: "Apply", +@@ -2904,6 +3309,14 @@ window.__ModuleLoader__.load({ + modelInputTypes: "Input types", + modelInputText: "Text", + modelInputImage: "Image", ++ modelImageInput: "Image input", ++ modelImageInputShort: "Vision", ++ modelImageInputHint: "Declare that this model accepts images; the endpoint must support them.", ++ modelSearch: "Search models", ++ modelSearchEmpty: "No matching models.", ++ modelReasoningLevels: "Reasoning effort levels", ++ modelReasoningLevelsPlaceholder: "e.g. low, medium, high", ++ modelReasoningLevelsHint: "Comma-separated effort ids. These levels become selectable in chat; leave blank to remove the per-model declaration.", + addModel: "Add model", + removeModel: "Delete model", + modelsEmpty: "No models will be shown in the selector. Unlisted IDs can still be sent directly.", +@@ -2952,10 +3365,14 @@ window.__ModuleLoader__.load({ + welcomeBody: "DeepSeek Harness 0.1 remains in testing for Harness developers. Many areas need further improvement, and we welcome feedback from the developer community. DeepSeek Harness's core plugins and foundational APIs will continue to evolve rapidly over the coming months.\n\nWe look forward to exploring the limits of intelligence with developers around the world, building on open-source, open, reusable, and composable infrastructure. We welcome Harness developers everywhere to join the DSH plugin ecosystem.", + welcomeContinue: "Continue", + welcomeError: "The acknowledgement could not be saved. Please try again.", +- onboardingTitle: "Add an API key to get started", +- onboardingDescription: "Configure the official DeepSeek provider to start building.", ++ onboardingTitle: "Connect a model provider", ++ onboardingDescription: "Choose a provider and enter its API key. DSH will enable that provider's built-in model catalog automatically.", ++ onboardingProvider: "Model provider", ++ onboardingManufacturer: "Model developer", ++ onboardingAggregator: "Model aggregation platform", ++ onboardingInference: "Inference platform", + onboardingLater: "Configure later", +- onboardingSave: "Save and continue", ++ onboardingSave: "Connect and continue", + onboardingSaving: "Saving…", + keyRequired: "Enter an API key to continue." + }; +@@ -3020,6 +3437,14 @@ window.__ModuleLoader__.load({ + modelInputTypes: "输入类型", + modelInputText: "文本", + modelInputImage: "图片", ++ modelImageInput: "支持图片输入", ++ modelImageInputShort: "视觉", ++ modelImageInputHint: "声明该模型可接收图片;请确认接口实际支持。", ++ modelSearch: "搜索模型", ++ modelSearchEmpty: "没有找到匹配的模型。", ++ modelReasoningLevels: "推理等级", ++ modelReasoningLevelsPlaceholder: "例如:low, medium, high", ++ modelReasoningLevelsHint: "使用英文逗号分隔推理等级;这些等级将在会话中可选择,留空则移除此模型的推理等级声明。", + addModel: "添加模型", + removeModel: "删除模型", + modelsEmpty: "模型选择器中将不显示任何模型;目录外 ID 仍可直接发送。", +@@ -3068,10 +3493,14 @@ window.__ModuleLoader__.load({ + welcomeBody: "DeepSeek Harness 目前的 0.1 版本仍处在面向 Harness 开发者进行测试的阶段,还有许多地方需要持续改进和打磨,希望听取广大开发者的反馈建议。预计 DeepSeek Harness 的核心插件以及基础 API 都会在接下来的一段时间内快速迭代、持续演化。\n\n我们期待与全球开发者一起,在开源、开放、可复用、可组合的基础设施之上,共同探索智能上限。欢迎全球 Harness 开发者加入 DSH 插件生态。", + welcomeContinue: "继续", + welcomeError: "暂时无法保存确认状态,请重试。", +- onboardingTitle: "添加一个 API Key 开始使用", +- onboardingDescription: "配置 DeepSeek 官方模型,即可开始使用。", ++ onboardingTitle: "接入模型提供方", ++ onboardingDescription: "选择提供方并填写 API Key,DSH 会自动启用该提供方的内置模型目录。之后可在「设置 → 模型」中添加更多提供方。", ++ onboardingProvider: "选择模型提供方", ++ onboardingManufacturer: "模型厂商", ++ onboardingAggregator: "模型聚合平台", ++ onboardingInference: "推理服务平台", + onboardingLater: "稍后配置", +- onboardingSave: "保存并继续", ++ onboardingSave: "接入并继续", + onboardingSaving: "保存中…", + keyRequired: "请输入 API 密钥后继续。" + }; +@@ -4075,22 +4504,7 @@ window.__ModuleLoader__.load({ + } + } + }, ModelsSection)); +- if (!("dshDesktop" in globalThis)) ctx.slots.inject("settings.onboarding", () => ctx.slots.register({ +- name: "settings.onboarding", +- id: "welcome-notice", +- order: -100, +- inject: welcomeInjected +- }, WelcomeNotice)); +- ctx.slots.inject("settings.onboarding", () => ctx.slots.register({ +- name: "settings.onboarding", +- id: "deepseek-official", +- children: { "settings.models.sign-in": { +- kind: "single", +- scope: "root" +- } }, +- order: 0, +- inject: deepSeekOnboardingInjected +- }, DeepSeekOnboardingDialog)); ++ // DSH Desktop owns the first-run wizard and embeds this package's ModelsSection. + } + //#endregion + exports.apply = apply; diff --git a/patches/@deepseek-ai+dsh-client-ui-sidebar+0.1.7-rc.2.patch b/patches/@deepseek-ai+dsh-client-ui-sidebar+0.1.7-rc.2.patch new file mode 100644 index 000000000..89e70c66e --- /dev/null +++ b/patches/@deepseek-ai+dsh-client-ui-sidebar+0.1.7-rc.2.patch @@ -0,0 +1,38 @@ +diff --git a/node_modules/@deepseek-ai/dsh-client-ui-sidebar/lib/client.js b/node_modules/@deepseek-ai/dsh-client-ui-sidebar/lib/client.js +index 1c2bc08..c5122d3 100644 +--- a/node_modules/@deepseek-ai/dsh-client-ui-sidebar/lib/client.js ++++ b/node_modules/@deepseek-ai/dsh-client-ui-sidebar/lib/client.js +@@ -94,7 +94,7 @@ window.__ModuleLoader__.load({ + const tag = document.createElement("style"); + tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-sidebar"; + tag.dataset.pluginCss = tagId; +- tag.textContent = css; ++ tag.textContent = css + "html:not([data-platform=darwin]) [data-dsh-sidebar-root][data-dsh-sidebar-wide=\"true\"]{padding-top:32px}[data-dsh-sidebar-brand-identity]{gap:4px}"; + document.head.appendChild(tag); + } + var SidebarRoot_module_css_default = { +@@ -288,6 +288,8 @@ window.__ModuleLoader__.load({ + }); + return (0, react_jsx_runtime.jsxs)("div", { + ref: column, ++ "data-dsh-sidebar-root": "", ++ "data-dsh-sidebar-wide": wide ? "true" : "false", + className: clsx(SidebarRoot_module_css_default.root, !wide && SidebarRoot_module_css_default.collapsed, !wide && everWide.current && SidebarRoot_module_css_default.railIn, collapsed && wide && SidebarRoot_module_css_default.fading, !pointerInside && SidebarRoot_module_css_default.quietBars), + style: wide ? { width: collapsed ? lastWideWidth.current : width } : void 0, + onPointerEnter: () => { +@@ -309,6 +311,7 @@ window.__ModuleLoader__.load({ + children: [wide && (() => { + const identity = (0, react_jsx_runtime.jsxs)("span", { + className: SidebarRoot_module_css_default.brandIdentity, ++ "data-dsh-sidebar-brand-identity": "", + "aria-hidden": "true", + children: [(0, react_jsx_runtime.jsx)("span", { + className: SidebarRoot_module_css_default.brandMark, +@@ -407,6 +410,7 @@ window.__ModuleLoader__.load({ + className: SidebarRoot_module_css_default.footerActions, + children: renderSlot("sidebar.footer.action", { wide }) + }), (0, react_jsx_runtime.jsx)("div", { ++ "data-dsh-sidebar-settings": "", + className: SidebarRoot_module_css_default.settingsArea, + children: renderSlot("sidebar.settings", { wide }) + })] diff --git a/patches/@deepseek-ai+dsh-client-ui-trajectory+0.1.7-rc.2.patch b/patches/@deepseek-ai+dsh-client-ui-trajectory+0.1.7-rc.2.patch new file mode 100644 index 000000000..eedf7a511 --- /dev/null +++ b/patches/@deepseek-ai+dsh-client-ui-trajectory+0.1.7-rc.2.patch @@ -0,0 +1,31 @@ +diff --git a/node_modules/@deepseek-ai/dsh-client-ui-trajectory/lib/client.js b/node_modules/@deepseek-ai/dsh-client-ui-trajectory/lib/client.js +index e5e636c..6034b1d 100644 +--- a/node_modules/@deepseek-ai/dsh-client-ui-trajectory/lib/client.js ++++ b/node_modules/@deepseek-ai/dsh-client-ui-trajectory/lib/client.js +@@ -212,6 +212,8 @@ window.__ModuleLoader__.load({ + "details.subtoolCalls": "子工具调用", + "details.error": "错误", + "details.failure.auth": "API 密钥无效", ++ "details.failure.quota": "账户额度或余额不足,请充值或检查服务商的用量限制。", ++ "details.failure.forbidden": "模型服务商拒绝了本次请求,请检查账号权限、地区限制或模型开通情况。", + "details.retry": "重试", + "details.scheduled": "已计划", + "details.retryDelay": "重试延迟", +@@ -407,6 +409,8 @@ window.__ModuleLoader__.load({ + "details.subtoolCalls": "Subtool calls", + "details.error": "Error", + "details.failure.auth": "API key is invalid", ++ "details.failure.quota": "Your account has insufficient quota or balance. Add credits or check your provider's usage limits.", ++ "details.failure.forbidden": "The model provider denied this request. Check your account permissions, region, or model access.", + "details.retry": "Retry", + "details.scheduled": "Scheduled", + "details.retryDelay": "Retry delay", +@@ -4416,6 +4420,8 @@ window.__ModuleLoader__.load({ + } + function requestErrorMessage(request, t) { + if (request.errorCode === "AUTH") return t("details.failure.auth"); ++ if (request.errorCode === "QUOTA") return t("details.failure.quota"); ++ if (request.errorCode === "FORBIDDEN") return t("details.failure.forbidden"); + if (request.error === "trajectory.compaction-interrupted") return t("layout.compactionInterrupted"); + return request.error; + } diff --git a/patches/@deepseek-ai+dsh-client-ui-workspace+0.1.7-rc.2.patch b/patches/@deepseek-ai+dsh-client-ui-workspace+0.1.7-rc.2.patch new file mode 100644 index 000000000..764e5b4d6 --- /dev/null +++ b/patches/@deepseek-ai+dsh-client-ui-workspace+0.1.7-rc.2.patch @@ -0,0 +1,453 @@ +diff --git a/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/client.js b/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/client.js +index 76cd793..455643d 100644 +--- a/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/client.js ++++ b/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/client.js +@@ -660,10 +660,18 @@ window.__ModuleLoader__.load({ + orderBy: "updated", + groupExpansion: {}, + sessionOrderByAccount: {}, ++ unreadSessionIds: [], + archivedFilter: "default" + }), + persist: "dsh.workspace.view.v5", + actions: { ++ markSessionUnread: (d, sessionId) => { ++ const unread = d.unreadSessionIds ?? (d.unreadSessionIds = []); ++ if (!unread.includes(sessionId)) unread.push(sessionId); ++ }, ++ markSessionRead: (d, sessionId) => { ++ d.unreadSessionIds = (d.unreadSessionIds ?? []).filter((id) => id !== sessionId); ++ }, + setGroupBy: (d, mode) => { + d.groupBy = mode; + }, +@@ -758,6 +766,9 @@ window.__ModuleLoader__.load({ + lifetime = new AbortController(); + selection = (0, _deepseek_ai_dsh_client_store.createSnapshotStore)({}, { persist: { name: "dsh.sessions.current" } }); + mainReference; ++ sessionOpener = null; ++ sessionStarter = null; ++ sessionReuseFilter = null; + /** + * @param ctx - Client root Context. + * @param directoryPicker - the directory-picking Remote namespace. +@@ -784,23 +795,23 @@ window.__ModuleLoader__.load({ + }; + }, "ui-workspace: Workspace navigation policy"); + } +- async connectWorkspace(workspaceId) { ++ async connectWorkspace(workspaceId, fresh = false) { + const workspace = this.workspaces.list.getSnapshot().items.find((item) => item.workspaceId === workspaceId); + if (workspace === void 0) throw new Error(`uiWorkspace.connectWorkspace: unknown workspace ${workspaceId}`); + const inflight = this.connecting.get(workspaceId); + if (inflight !== void 0) return inflight; +- const attempt = this.reuseOrCreateBlank(workspace).finally(() => { ++ const attempt = this.reuseOrCreateBlank(workspace, fresh).finally(() => { + this.connecting.delete(workspaceId); + }); + this.connecting.set(workspaceId, attempt); + return attempt; + } +- reuseOrCreateBlank(workspace) { ++ reuseOrCreateBlank(workspace, fresh = false) { + const archived = this.workspaces.list.getSnapshot().archivedSessionIds; + const sessions = this.sessions.list.getSnapshot(); +- for (const id of sessions.ids) { ++ if (!fresh) for (const id of sessions.ids) { + const summary = sessions.byId[id]; +- if (summary === void 0 || !summary.blank || summary.cwd !== workspace.path || !workspace.sessionIds.includes(id) || archived.includes(id)) continue; ++ if (summary === void 0 || !summary.blank || summary.cwd !== workspace.path || !workspace.sessionIds.includes(id) || archived.includes(id) || this.sessionReuseFilter?.(id) === false) continue; + return this.reuseBlank(workspace.workspaceId, id); + } + return this.sessions.create({ workspaceId: workspace.workspaceId }); +@@ -816,14 +827,33 @@ window.__ModuleLoader__.load({ + return this.sessions.create({ workspaceId }); + } + } +- openSession(target) { ++ registerSessionOpener(handler) { ++ if (this.sessionOpener !== null) throw new Error("uiWorkspace session opener already registered"); ++ this.sessionOpener = handler; ++ let active = true; ++ return () => { ++ if (!active) return; ++ active = false; ++ if (this.sessionOpener === handler) this.sessionOpener = null; ++ }; ++ } ++ registerSessionReuseFilter(handler) { ++ if (this.sessionReuseFilter !== null) throw new Error("uiWorkspace session reuse filter already registered"); ++ this.sessionReuseFilter = handler; ++ return () => { ++ if (this.sessionReuseFilter === handler) this.sessionReuseFilter = null; ++ }; ++ } ++ openSession(target, source = "explicit-session") { ++ if (typeof target === "string") this.view.markSessionRead(target); ++ if (typeof target === "string" && this.sessionOpener?.(target, source) === true) return; + this.replaceMain(target, this.lifetime.signal, "reveal"); + } +- async openWorkspace(workspaceId, beforeOpen) { ++ async openWorkspace(workspaceId, beforeOpen, fresh = false) { + const navigation = AbortSignal.any([this.ctx.layout.beginNavigation(), this.lifetime.signal]); + let sessionId; + try { +- sessionId = await this.connectWorkspace(workspaceId); ++ sessionId = await this.connectWorkspace(workspaceId, fresh); + } catch (error) { + if (!navigation.aborted) this.notify({ + kind: "createFailed", +@@ -832,6 +862,8 @@ window.__ModuleLoader__.load({ + throw error; + } + if (navigation.aborted) return; ++ this.view.markSessionRead(sessionId); ++ if (this.sessionOpener?.(sessionId, "workspace") === true) return; + this.replaceMain(sessionId, navigation, "reveal", beforeOpen); + } + async forkSession(sessionId) { +@@ -840,7 +872,18 @@ window.__ModuleLoader__.load({ + increaseTitle: true + }); + } ++ registerSessionStarter(handler) { ++ if (this.sessionStarter !== null) throw new Error("uiWorkspace session starter already registered"); ++ this.sessionStarter = handler; ++ let active = true; ++ return () => { ++ if (!active) return; ++ active = false; ++ if (this.sessionStarter === handler) this.sessionStarter = null; ++ }; ++ } + startSession(workspaceId) { ++ if (this.sessionStarter?.(workspaceId) === true) return; + const workspace = this.workspaces.list.getSnapshot(); + const sessions = this.sessions.list.getSnapshot(); + const current = this.mainReference?.sessionId; +@@ -851,7 +894,7 @@ window.__ModuleLoader__.load({ + this.clearMain(); + return; + } +- this.openWorkspace(target).catch((reason) => { ++ this.openWorkspace(target, void 0, true).catch((reason) => { + console.warn("new session failed:", reason); + }); + } +@@ -862,6 +905,24 @@ window.__ModuleLoader__.load({ + async unarchiveSession(sessionId) { + await this.workspaces.unarchiveSession(sessionId); + } ++ /** Release the main view before deleting its durable Session. */ ++ async deleteSession(sessionId) { ++ if (this.mainReference?.sessionId === sessionId) { ++ this.clearMain(); ++ const retention = this.sessions.retainInfo(sessionId); ++ if (retention.getSnapshot().referenceCount > 0) await new Promise((resolve) => { ++ let unsubscribe = () => {}; ++ let timer; ++ const finish = () => { clearTimeout(timer); unsubscribe(); resolve(); }; ++ unsubscribe = retention.subscribe(() => { ++ if (retention.getSnapshot().referenceCount === 0) finish(); ++ }); ++ timer = setTimeout(finish, 250); ++ if (retention.getSnapshot().referenceCount === 0) finish(); ++ }); ++ } ++ await this.sessions.delete(sessionId); ++ } + async pinSession(sessionId) { + await this.workspaces.pinSession(sessionId); + const { items, pinnedSessionIds, archivedSessionIds } = this.workspaces.list.getSnapshot(); +@@ -1490,7 +1551,7 @@ window.__ModuleLoader__.load({ + * @param props.t - Workspace-browser translation seat. + * @returns the result row. + */ +- function SearchResultItem({ result, currentId, onOpen, onUnarchive, t }) { ++ function SearchResultItem({ result, currentId, onOpen, onUnarchive, renderSlot, t }) { + const selected = result.id === currentId; + const statuses = sessionStatuses(result, t); + const primaryStatus = statuses[0]; +@@ -1505,6 +1566,7 @@ window.__ModuleLoader__.load({ + children: [(0, react_jsx_runtime.jsxs)("span", { + className: Rows_module_css_default.searchResultHeading, + children: [ ++ + (0, react_jsx_runtime.jsx)("span", { + className: Rows_module_css_default.slot, + children: !result.archived && primaryStatus.state !== "idle" && (0, react_jsx_runtime.jsx)(SessionStatusDots, { statuses }) +@@ -1565,7 +1627,7 @@ window.__ModuleLoader__.load({ + * @param props.t - the browser root's locale seat. + * @returns the session row. + */ +- function SessionNodeItem({ node, currentId, now, onOpen, onRenameRequest, renderSlot, onReveal, drag, t }) { ++ function SessionNodeItem({ node, currentId, now, onOpen, onRenameRequest, renderSlot, onReveal, drag, unread = false, onUnreadChange, t }) { + const row = node; + const title = displayTitle(node, t); + const selected = node.id === currentId; +@@ -1594,6 +1656,11 @@ window.__ModuleLoader__.load({ + onClick: () => { + onOpen(node.id); + }, ++ onContextMenu: (event) => { ++ event.preventDefault(); ++ event.stopPropagation(); ++ if (!row.blank) setMenuOpen(true); ++ }, + onPointerEnter: marquee.enter, + onPointerLeave: marquee.leave, + draggable, +@@ -1617,11 +1684,12 @@ window.__ModuleLoader__.load({ + children: [ + (0, react_jsx_runtime.jsx)("span", { + className: Rows_module_css_default.slot, +- children: !row.archived && !row.blank && (showStatus ? (0, react_jsx_runtime.jsx)(SessionStatusDots, { statuses }) : renderSlot("sidebar.session.row.leading", { sessionId: node.id })) ++ children: !row.archived && !row.blank && (showStatus ? (0, react_jsx_runtime.jsx)(SessionStatusDots, { statuses }) : unread ? (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.StateDot, { state: "done" }), (0, react_jsx_runtime.jsx)("span", { className: Rows_module_css_default.visuallyHidden, children: t("status.unread") })] }) : renderSlot("sidebar.session.row.leading", { sessionId: node.id })) + }), + (0, react_jsx_runtime.jsx)("span", { + ref: titleRef, + className: Rows_module_css_default.title, ++ style: unread ? { fontWeight: 600 } : void 0, + onDoubleClick: row.blank ? void 0 : (e) => { + e.stopPropagation(); + onRenameRequest(node.id, row.title); +@@ -1657,7 +1725,9 @@ window.__ModuleLoader__.load({ + }), + children: renderSlot("sidebar.workspaces.session.menu.item", { + sessionId: node.id, +- displayTitle: row.title ++ displayTitle: row.title, ++ unread, ++ onUnreadChange + }, { hookContext: menuOpenState }) + }), renderSlot("sidebar.workspaces.session.row.action", { + sessionId: node.id, +@@ -2310,7 +2380,7 @@ window.__ModuleLoader__.load({ + }); + } + /** The scrolling session tree; unmounting drops the sessions subscription and local row limits. */ +- function SessionTree({ list, useSessionStatus, startSession, open, workspaces, ungroupedSessionIds, rowState, onLeaveArchivedOnly, workspaceReady, animationResetKey, usePanelInfo, onRenameRequest, onDeleteRequest, onSessionRenameRequest, renderSlot, insertWorkspaceBefore, nestWorkspaces, groupExpansion, setGroupExpanded, setSessionOrder, home, t, revealSessionId, onSessionRevealed, shortcuts }) { ++ function SessionTree({ list, useSessionStatus, startSession, open, workspaces, ungroupedSessionIds, rowState, unreadSessionIds, onUnreadChange, onLeaveArchivedOnly, workspaceReady, animationResetKey, usePanelInfo, onRenameRequest, onDeleteRequest, onSessionRenameRequest, renderSlot, insertWorkspaceBefore, nestWorkspaces, groupExpansion, setGroupExpanded, setSessionOrder, home, t, revealSessionId, onSessionRevealed, shortcuts }) { + const panelActive = usePanelInfo((info) => info.activePanelId !== null); + const statuses = useSessionStatus((s) => s); + const current = panelActive ? void 0 : Object.values(list.byId).find((session) => (session.retainedBy.mainView ?? 0) > 0)?.id; +@@ -2585,6 +2655,8 @@ window.__ModuleLoader__.load({ + onOpen: open, + onRenameRequest: onSessionRenameRequest, + renderSlot, ++ unread: unreadSessionIds.includes(node.id), ++ onUnreadChange, + onReveal: node.id === revealSessionId && group.key === revealGroup ? () => { + onSessionRevealed(node.id); + } : void 0, +@@ -2633,7 +2705,7 @@ window.__ModuleLoader__.load({ + }); + } + /** The flat "In one list" body: every session is one draggable top-level row. */ +- function FlatList({ list, sessionIds, rowState, onLeaveArchivedOnly, useSessionStatus, open, onSessionRenameRequest, usePanelInfo, setSessionOrder, workspaceReady, animationResetKey, revealSessionId, onSessionRevealed, renderSlot, t }) { ++ function FlatList({ list, sessionIds, rowState, unreadSessionIds, onUnreadChange, onLeaveArchivedOnly, useSessionStatus, open, onSessionRenameRequest, usePanelInfo, setSessionOrder, workspaceReady, animationResetKey, revealSessionId, onSessionRevealed, renderSlot, t }) { + const panelActive = usePanelInfo((info) => info.activePanelId !== null); + const statuses = useSessionStatus((s) => s); + const rows = (0, react.useMemo)(() => deriveFlat(list, sessionIds, rowState, statuses), [ +@@ -2674,8 +2746,10 @@ window.__ModuleLoader__.load({ + currentId, + now, + onOpen: open, +- onRenameRequest: onSessionRenameRequest, +- renderSlot, ++ onRenameRequest: onSessionRenameRequest, ++ renderSlot, ++ unread: unreadSessionIds.includes(node.id), ++ onUnreadChange, + onReveal: node.id === revealSessionId ? () => { + onSessionRevealed(node.id); + } : void 0, +@@ -2719,7 +2793,7 @@ window.__ModuleLoader__.load({ + }); + } + /** Flat search body: local metadata matches plus the current Host result page. */ +- function SearchResults({ useSessions, useSessionStatus, open, onUnarchive, workspaces, archivedSessionIds, archivedFilter, query, remote, resultLimit, usePanelInfo, t }) { ++ function SearchResults({ useSessions, useSessionStatus, open, onUnarchive, workspaces, archivedSessionIds, archivedFilter, query, remote, resultLimit, usePanelInfo, renderSlot, t }) { + const panelActive = usePanelInfo((info) => info.activePanelId !== null); + const list = useSessions((s) => s); + const statuses = useSessionStatus((s) => s); +@@ -2755,6 +2829,7 @@ window.__ModuleLoader__.load({ + currentId, + onOpen: open, + onUnarchive, ++ renderSlot, + t + }, result.id)) + }), +@@ -2810,6 +2885,11 @@ window.__ModuleLoader__.load({ + const archivedFilter = useStore((s) => s.archivedFilter ?? "default"); + const groupExpansion = useStore((s) => s.groupExpansion); + const sessionOrderByAccount = useStore((s) => s.sessionOrderByAccount); ++ const unreadSessionIds = useStore((s) => s.unreadSessionIds ?? []); ++ const onUnreadChange = (sessionId, unread) => { ++ if (unread) actions.markSessionUnread(sessionId); ++ else actions.markSessionRead(sessionId); ++ }; + const guardedOpen = (sessionId) => { + if (archivedSessionIds.includes(sessionId)) { + notifyArchivedNotOpenable(); +@@ -3261,6 +3341,8 @@ window.__ModuleLoader__.load({ + list, + sessionIds: orderedFlatSessionIds, + rowState, ++ unreadSessionIds, ++ onUnreadChange, + onLeaveArchivedOnly: leaveArchivedOnly, + workspaceReady, + animationResetKey: `${groupBy}/${orderBy}/${archivedFilter}`, +@@ -3288,6 +3370,8 @@ window.__ModuleLoader__.load({ + setGroupExpanded: actions.setGroupExpanded, + setSessionOrder: saveSessionOrder, + rowState, ++ unreadSessionIds, ++ onUnreadChange, + onLeaveArchivedOnly: leaveArchivedOnly, + startSession, + open: guardedOpen, +@@ -3963,6 +4047,7 @@ window.__ModuleLoader__.load({ + "status.compact.planReview": "计划待审", + "status.compact.answer": "待回答", + "status.completed": "已完成", ++ "status.unread": "未读", + "hover.created": "创建于 {time}", + "hover.copied": "已复制", + "date.ymd": "{y}年{m}月{d}日", +@@ -4077,6 +4162,7 @@ window.__ModuleLoader__.load({ + "status.compact.planReview": "Plan review", + "status.compact.answer": "Answer", + "status.completed": "Completed", ++ "status.unread": "Unread", + "hover.created": "Created {time}", + "hover.copied": "Copied", + "date.ymd": "{y}-{m}-{d}", +diff --git a/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/locales.d.ts b/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/locales.d.ts +index 26ee25b..df98396 100644 +--- a/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/locales.d.ts ++++ b/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/locales.d.ts +@@ -106,6 +106,7 @@ export declare const zh: { + 'status.compact.planReview': string; + 'status.compact.answer': string; + 'status.completed': string; ++ 'status.unread': string; + 'hover.created': string; + 'hover.copied': string; + 'date.ymd': string; +@@ -222,6 +223,7 @@ export declare const en: { + 'status.compact.planReview': string; + 'status.compact.answer': string; + 'status.completed': string; ++ 'status.unread': string; + 'hover.created': string; + 'hover.copied': string; + 'date.ymd': string; +diff --git a/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/navigation.d.ts b/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/navigation.d.ts +index 9afabc2..3a1cc04 100644 +--- a/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/navigation.d.ts ++++ b/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/navigation.d.ts +@@ -4,6 +4,7 @@ import type { ClientRemote, DirectoryListing, RemoteFailure } from '@deepseek-ai + import type { ISessions, SessionTarget } from '@deepseek-ai/dsh-api-session-controller/client'; + import type { IWorkspaces, WorkspaceId } from '@deepseek-ai/dsh-api-workspace-controller/client'; + import type { SessionId } from '@deepseek-ai/dsh-session/types'; ++export type SessionNavigationSource = 'explicit-session' | 'workspace'; + import type { RowToast } from './contract/slots.ts'; + import type { WorkspaceViewStoreActions } from './stores.ts'; + /** Workspace archive and directory operations consumed by Client UI domains. */ +@@ -12,7 +13,9 @@ export interface UiWorkspace { + * Select a Session and show its Conversation as one UI navigation action. + * @param target - known Session identity or durable direct-parent subagent address to display. + */ +- openSession(target: SessionTarget): void; ++ registerSessionOpener(handler: (sessionId: SessionId, source?: SessionNavigationSource) => boolean): () => void; ++ registerSessionReuseFilter(handler: (sessionId: SessionId) => boolean): () => void; ++ openSession(target: SessionTarget, source?: SessionNavigationSource): void; + /** + * Connect a Workspace and open its Session unless a later navigation supersedes it. + * @param workspaceId - target Workspace. +@@ -22,24 +25,26 @@ export interface UiWorkspace { + * @throws on failure; a refused creation is also shown through the Workspace + * notice unless a later navigation or disposal superseded the request. + */ +- openWorkspace(workspaceId: WorkspaceId, beforeOpen?: (sessionId: SessionId) => void): Promise; ++ openWorkspace(workspaceId: WorkspaceId, beforeOpen?: (sessionId: SessionId) => void, fresh?: boolean): Promise; + /** + * Fork a Session without changing the current selection. + * @param sessionId - source Session. + * @returns completion after child creation and inherited-title increment. + */ + forkSession(sessionId: SessionId): Promise; ++ deleteSession(sessionId: SessionId): Promise; + /** + * Resolve the reusable or newly created blank Session for a Workspace. + * @param workspaceId - target Workspace. + * @returns a Session already addressable through the Session Controller. + */ +- connectWorkspace(workspaceId: WorkspaceId): Promise; ++ connectWorkspace(workspaceId: WorkspaceId, fresh?: boolean): Promise; + /** + * Start a New Session flow and navigate to its Session; a creation the Host + * refuses is shown through the Workspace notice and leaves the selection as it was. + * @param workspaceId - explicit target; absent inherits the current or most recent Workspace. + */ ++ registerSessionStarter(handler: (workspaceId?: WorkspaceId) => boolean): () => void; + startSession(workspaceId?: WorkspaceId): void; + /** + * Archive a Session and clear it when it is the current selection. +@@ -111,6 +116,9 @@ declare class UiWorkspaceService extends Service implements UiWorkspace { + private readonly lifetime; + private readonly selection; + private mainReference; ++ private sessionOpener; ++ private sessionStarter; ++ private sessionReuseFilter; + /** + * @param ctx - Client root Context. + * @param directoryPicker - the directory-picking Remote namespace. +@@ -119,13 +127,17 @@ declare class UiWorkspaceService extends Service implements UiWorkspace { + * @param view - the browser's viewing-store write set (one instance shared with its registration). + * @param notify - show one notice through the Workspace notice channel. + */ +- constructor(ctx: Context, directoryPicker: ClientRemote['directoryPicker'], workspaces: IWorkspaces, sessions: ISessions, view: Pick, notify: (toast: RowToast) => void); +- connectWorkspace(workspaceId: WorkspaceId): Promise; ++ constructor(ctx: Context, directoryPicker: ClientRemote['directoryPicker'], workspaces: IWorkspaces, sessions: ISessions, view: Pick, notify: (toast: RowToast) => void); ++ connectWorkspace(workspaceId: WorkspaceId, fresh?: boolean): Promise; + private reuseOrCreateBlank; + private reuseBlank; +- openSession(target: SessionTarget): void; +- openWorkspace(workspaceId: WorkspaceId, beforeOpen?: (sessionId: SessionId) => void): Promise; ++ registerSessionOpener(handler: (sessionId: SessionId, source?: SessionNavigationSource) => boolean): () => void; ++ registerSessionReuseFilter(handler: (sessionId: SessionId) => boolean): () => void; ++ openSession(target: SessionTarget, source?: SessionNavigationSource): void; ++ openWorkspace(workspaceId: WorkspaceId, beforeOpen?: (sessionId: SessionId) => void, fresh?: boolean): Promise; + forkSession(sessionId: SessionId): Promise; ++ deleteSession(sessionId: SessionId): Promise; ++ registerSessionStarter(handler: (workspaceId?: WorkspaceId) => boolean): () => void; + startSession(workspaceId?: WorkspaceId): void; + archiveSession(sessionId: SessionId, options?: { + readonly stopActivity?: boolean; +diff --git a/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/stores.d.ts b/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/stores.d.ts +index 4e20866..d4d260f 100644 +--- a/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/stores.d.ts ++++ b/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/stores.d.ts +@@ -23,6 +23,8 @@ type WorkspaceViewState = { + groupExpansion: Record; + /** Saved manual order per Workspace group plus the browser-local flat-list account. */ + sessionOrderByAccount: Record; ++ /** Desktop unread markers; absent in older persisted v5 snapshots. */ ++ unreadSessionIds?: string[]; + /** Archived-row visibility; omitted in pre-filter v5 snapshots and read as 'default'. */ + archivedFilter?: ArchivedFilter; + }; +@@ -36,6 +38,8 @@ type SessionOrderSource = { + * return type); drift fails assignability at the defineStore call. + */ + type WorkspaceViewActions = { ++ markSessionUnread: (draft: WorkspaceViewState, sessionId: string) => void; ++ markSessionRead: (draft: WorkspaceViewState, sessionId: string) => void; + setGroupBy: (draft: WorkspaceViewState, mode: SessionGroupBy) => void; + setOrderBy: (draft: WorkspaceViewState, mode: SessionOrderBy, initialOrders: Readonly>) => void; + setGroupExpanded: (draft: WorkspaceViewState, key: string, expanded: boolean) => void; diff --git a/patches/@deepseek-ai+dsh-llm-deepseek+0.1.7-rc.2.patch b/patches/@deepseek-ai+dsh-llm-deepseek+0.1.7-rc.2.patch new file mode 100644 index 000000000..9c8dfb4a3 --- /dev/null +++ b/patches/@deepseek-ai+dsh-llm-deepseek+0.1.7-rc.2.patch @@ -0,0 +1,16 @@ +diff --git a/node_modules/@deepseek-ai/dsh-llm-deepseek/lib/index.js b/node_modules/@deepseek-ai/dsh-llm-deepseek/lib/index.js +index 4deb593..23656cc 100644 +--- a/node_modules/@deepseek-ai/dsh-llm-deepseek/lib/index.js ++++ b/node_modules/@deepseek-ai/dsh-llm-deepseek/lib/index.js +@@ -1742,8 +1742,9 @@ function providerError(raw, status, headers) { + const type = typeof error.type === "string" ? error.type : ""; + const detail = `${type} ${typeof error.code === "string" ? error.code : ""} ${message}`; + let code; +- if (status === 401 || status === 403 || ["authentication_error", "permission_error"].includes(type)) code = "AUTH"; +- else if (isQuotaExceededError(detail) || status === 402) code = "QUOTA"; ++ if (isQuotaExceededError(detail) || status === 402) code = "QUOTA"; ++ else if (status === 401 || type === "authentication_error") code = "AUTH"; ++ else if (status === 403 || type === "permission_error") code = "FORBIDDEN"; + else if (status === 429 || type === "rate_limit_error") code = "RATE_LIMIT"; + else if (isContextWindowExceededError(detail)) code = "CONTEXT_WINDOW_EXCEEDED"; + else if (status === 400 || status === 413 || type === "invalid_request_error") code = "INVALID_REQUEST"; diff --git a/patches/@deepseek-ai+dsh-llm-pi-ai+0.1.7-rc.2.patch b/patches/@deepseek-ai+dsh-llm-pi-ai+0.1.7-rc.2.patch new file mode 100644 index 000000000..c77aa8a96 --- /dev/null +++ b/patches/@deepseek-ai+dsh-llm-pi-ai+0.1.7-rc.2.patch @@ -0,0 +1,157 @@ +diff --git a/node_modules/@deepseek-ai/dsh-llm-pi-ai/lib/index.js b/node_modules/@deepseek-ai/dsh-llm-pi-ai/lib/index.js +index 1692082..8f41310 100644 +--- a/node_modules/@deepseek-ai/dsh-llm-pi-ai/lib/index.js ++++ b/node_modules/@deepseek-ai/dsh-llm-pi-ai/lib/index.js +@@ -1374,8 +1374,9 @@ function mapUsage(usage) { + }; + } + function classifyPiAiError(message) { +- if (/\b(?:401|403)\b/.test(message)) return "AUTH"; + if (isQuotaExceededError(message)) return QUOTA_EXCEEDED_CODE; ++ if (/\b401\b/.test(message)) return "AUTH"; ++ if (/\b403\b/.test(message)) return "FORBIDDEN"; + if (/\b429\b|rate.?limit/i.test(message)) return "RATE_LIMIT"; + if (/\b413\b|failed to buffer the request body:\s*length limit exceeded|payload too large|request body too large/i.test(message)) return "INVALID_REQUEST"; + if (/\b400\b|invalid.?request/i.test(message)) return "INVALID_REQUEST"; +@@ -1450,6 +1451,14 @@ function mapStopReason(message, contextWindow) { + } + } + } ++/** Restore the terminal content array from completed stream blocks when a provider omits it. */ ++function completeTerminalMessage(message, completed) { ++ if (Array.isArray(message.content)) return message; ++ return { ++ ...message, ++ content: [...completed.entries()].sort(([left], [right]) => left - right).map(([, block]) => block) ++ }; ++} + /** + * Translate the pi-ai event stream into StreamChunks. pi-ai never throws + * mid-stream — failures arrive as `error` events, which become error/aborted +@@ -1464,6 +1473,7 @@ function mapStopReason(message, contextWindow) { + */ + async function* toStreamChunks(events, contextWindow, callerSignal, requestedModel) { + const toolIds = /* @__PURE__ */ new Map(); ++ const completed = /* @__PURE__ */ new Map(); + for await (const event of events) switch (event.type) { + case "start": break; + case "text_start": +@@ -1480,16 +1490,19 @@ async function* toStreamChunks(events, contextWindow, callerSignal, requestedMod + text: event.delta + }; + break; +- case "text_end": ++ case "text_end": { ++ const block = { ++ type: "text", ++ text: event.content ++ }; ++ completed.set(event.contentIndex, event.partial?.content?.[event.contentIndex] ?? { type: "text", text: event.content }); + yield { + type: "block-end", + index: event.contentIndex, +- block: { +- type: "text", +- text: event.content +- } ++ block + }; + break; ++ } + case "thinking_start": + yield { + type: "block-start", +@@ -1504,16 +1517,19 @@ async function* toStreamChunks(events, contextWindow, callerSignal, requestedMod + text: event.delta + }; + break; +- case "thinking_end": ++ case "thinking_end": { ++ const block = { ++ type: "reasoning", ++ text: event.content ++ }; ++ completed.set(event.contentIndex, event.partial?.content?.[event.contentIndex] ?? { type: "thinking", thinking: event.content }); + yield { + type: "block-end", + index: event.contentIndex, +- block: { +- type: "reasoning", +- text: event.content +- } ++ block + }; + break; ++ } + case "toolcall_start": { + const partial = event.partial.content[event.contentIndex]; + const id = partial?.type === "toolCall" ? partial.id : ""; +@@ -1540,29 +1556,34 @@ async function* toStreamChunks(events, contextWindow, callerSignal, requestedMod + }; + break; + } +- case "toolcall_end": ++ case "toolcall_end": { ++ const block = { ++ type: "tool-call", ++ id: brandString(event.toolCall.id), ++ name: event.toolCall.name, ++ arguments: JSON.stringify(event.toolCall.arguments) ++ }; ++ completed.set(event.contentIndex, event.toolCall); + yield { + type: "block-end", + index: event.contentIndex, +- block: { +- type: "tool-call", +- id: brandString(event.toolCall.id), +- name: event.toolCall.name, +- arguments: JSON.stringify(event.toolCall.arguments) +- } ++ block + }; + break; +- case "done": ++ } ++ case "done": { ++ const message = completeTerminalMessage(event.message, completed); + yield { + type: "usage", +- usage: mapUsage(event.message.usage) ++ usage: mapUsage(message.usage) + }; + yield { + type: "finish", +- reason: mapStopReason(event.message, contextWindow), +- replayState: toPiReplayState(event.message, requestedModel) ++ reason: mapStopReason(message, contextWindow), ++ replayState: toPiReplayState(message, requestedModel) + }; + return; ++ } + case "error": + yield { + type: "usage", +@@ -1730,8 +1751,11 @@ function reasoningInfo(model, defaultLevel) { + } }; + } + /** Merge deployment headers while removing case-insensitive attribution collisions. */ +-function requestHeaders(headers) { +- const attribution = attributionHeaders(); ++function requestHeaders(headers, sessionId) { ++ const attribution = { ++ ...attributionHeaders(), ++ ...sessionId === void 0 ? {} : { "x-deepseek-harness-session-id": String(sessionId) } ++ }; + const reserved = new Set(Object.keys(attribution).map((name) => name.toLowerCase())); + return { + ...Object.fromEntries(Object.entries(headers ?? {}).filter(([name]) => !reserved.has(name.toLowerCase()))), +@@ -1880,7 +1904,7 @@ var PiAiAdapter = class extends LlmAdapter { + ...options.maxTokens === void 0 ? {} : { maxTokens: options.maxTokens }, + ...options.sessionId === void 0 ? {} : { sessionId: String(options.sessionId) }, + signal: watchdog.signal, +- headers: requestHeaders(profile.headers) ++ headers: requestHeaders(profile.headers, options.sessionId) + }), model.contextWindow, options.signal, model.id)[Symbol.asyncIterator](); + let exhausted = false; + try { diff --git a/patches/@deepseek-ai+dsh-plugin-manager+0.1.7-rc.2.patch b/patches/@deepseek-ai+dsh-plugin-manager+0.1.7-rc.2.patch new file mode 100644 index 000000000..d4feadb97 --- /dev/null +++ b/patches/@deepseek-ai+dsh-plugin-manager+0.1.7-rc.2.patch @@ -0,0 +1,231 @@ +diff --git a/node_modules/@deepseek-ai/dsh-plugin-manager/lib/index.js b/node_modules/@deepseek-ai/dsh-plugin-manager/lib/index.js +index 7ebf353..b680aa5 100644 +--- a/node_modules/@deepseek-ai/dsh-plugin-manager/lib/index.js ++++ b/node_modules/@deepseek-ai/dsh-plugin-manager/lib/index.js +@@ -7,7 +7,7 @@ import { withFileLock, writeFileAtomic } from "@deepseek-ai/dsh-atomic-write"; + import z from "@deepseek-ai/schemastery"; + import { Remote, TypertRemoteService } from "@deepseek-ai/dsh-typert-protocol"; + import { pluginEntryId, readPluginInventory } from "@deepseek-ai/dsh-host-plugin-inventory"; +-import { OPTIONAL_BUNDLES, PROFILE_COMPATIBILITY_FILENAME, bundlePatchPaths, composeEntries, evaluatePluginCompatibility, loadOptionalPatches, loadOverlayPatches, pluginCompatibilityWarning, readPluginMeta, readProfileCompatibility, readProfileManifest, readProfilePatches, readProfileVersionExemptions, reconcileProfilePatches, resolveBundleDir, resolveProfileDir, setProfileVersionExemption } from "@deepseek-ai/dsh-app-boot"; ++import { OPTIONAL_BUNDLES, PROFILE_COMPATIBILITY_FILENAME, bundlePatchPaths, composeEntries, evaluatePluginCompatibility, reportPluginCompatibility, loadOptionalPatches, loadOverlayPatches, pluginCompatibilityWarning, readPluginMeta, readProfileCompatibility, readProfileManifest, readProfilePatches, readProfileVersionExemptions, reconcileProfilePatches, resolveBundleDir, resolveProfileDir, setProfileVersionExemption } from "@deepseek-ai/dsh-app-boot"; + import { once } from "node:events"; + import { execa } from "execa"; + import { scrubbedParentEnv } from "@deepseek-ai/dsh-subprocess"; +@@ -505,8 +505,11 @@ async function runProfilePnpm(context, args, options) { + if (manifest === void 0) continue; + const issue = evaluatePluginCompatibility(manifest, exemptions); + if (issue !== void 0 && !issue.exempted) { +- preflight.push(pluginCompatibilityWarning(issue)); +- incompatible.push(incompatiblePlugin(issue)); ++ reportPluginCompatibility(issue); ++ const notice = `dsh: warning: ${pluginCompatibilityWarning(issue)}\n`; ++ await log.write(notice); ++ options.onOutput?.(notice, "stderr"); ++ append(Buffer.from(notice)); + } + } catch (error) { + continue; +@@ -627,8 +630,11 @@ async function runProfilePnpm(context, args, options) { + for (const candidate of [manifest, ...bundleComponentManifests(manifest, packageDir, context.installAnchor)]) { + const issue = evaluatePluginCompatibility(candidate, readProfileVersionExemptions(dir)); + if (issue !== void 0 && !issue.exempted) { +- found.push(pluginCompatibilityWarning(issue)); +- issues.push(incompatiblePlugin(issue)); ++ reportPluginCompatibility(issue); ++ const notice = `dsh: warning: ${pluginCompatibilityWarning(issue)}\n`; ++ await log.write(notice); ++ options.onOutput?.(notice, "stderr"); ++ append(Buffer.from(notice)); + } + } + } catch (error) { +@@ -639,7 +645,7 @@ async function runProfilePnpm(context, args, options) { + warnings.push(...found); + incompatible.push(...issues); + } else { +- const notice = `\ndsh: warning: ${found.join("\n")}\ndsh: it stays installed but profile startup denies it until you grant an exemption for those exact versions.\n`; ++ const notice = `\ndsh: warning: ${found.join("\n")}\ndsh: it stays installed; repair the invalid manifest before loading it.\n`; + await log.write(notice); + options.onOutput?.(notice, "stderr"); + } +@@ -1488,7 +1494,7 @@ let PluginManager = (() => { + continue; + } + const compatibility = evaluatePluginCompatibility(info, exemptions); +- if (compatibility !== void 0 && !compatibility.exempted) throw new ManagementFailure("incompatible-version", [incompatiblePlugin(compatibility)]); ++ if (compatibility !== void 0 && !compatibility.exempted) reportPluginCompatibility(compatibility); + const dir = resolveBundleDir("dsh", name, this.profile.installAnchor, this.profile.dir); + const meta = readPluginMeta(info.name ?? name, pathToFileURL(join(dir, "package.json")).href); + bundles.push({ +@@ -1705,7 +1711,13 @@ let PluginManager = (() => { + }); + }; + const result = this.change(async (result) => { +- if (spec.trim() === "" || spec.startsWith("-")) throw new ManagementFailure("invalid-spec"); ++ let parsed; ++ try { ++ parsed = parseInstallSpec(spec); ++ } catch (error) { ++ if (error instanceof InvalidInstallSpecError) throw new ManagementFailure("invalid-spec", error.reason); ++ throw error; ++ } + if (stopped()) throw new InstallCancelledError(); + if (options?.approvedBuilds !== void 0) { + await approveBuilds(this.profile.dir, options.approvedBuilds); +@@ -1713,9 +1725,13 @@ let PluginManager = (() => { + } + const files = await this.readRestoredFiles(); + const before = readProfileManifest("dsh", this.profile.dir).dependencies ?? {}; ++ const backend = this.ownerContext.get("profileBundlePackageBackend"); ++ let mutation; + let name; + try { + result.registries = []; ++ let run; ++ if (backend === void 0) { + const connection = checkGithubConnection(parsedForRegistry(spec), this.profile.dir, { + timeoutMs: this.githubConnectionTimeoutMs, + outputBytes: this.outputBytes, +@@ -1736,7 +1752,6 @@ let PluginManager = (() => { + throw new Error(connectionFailure.output); + } + const plan = registryPlan(options?.registry, await this.registries()); +- let run; + for (const [index, registry] of plan.entries()) { + if (index > 0) await this.restoreFiles(files); + if (stopped()) throw new InstallCancelledError(); +@@ -1765,10 +1780,27 @@ let PluginManager = (() => { + } + /* v8 ignore next -- the plan is never empty, so a run always settled */ + if (run === void 0) throw new Error("no registry was asked"); ++ } else { ++ announce("installing"); ++ mutation = await backend.install({ ++ spec: parsed.spec, ++ kind: parsed.kind, ++ path: parsed.path, ++ registry: options?.registry, ++ expectedName: parsed.name, ++ signal: control.abort.signal, ++ onOutput: (text, stream) => this.emitPackageOutput(requestId, text, stream, ["pnpm", "add", parsed.spec]) ++ }); ++ run = mutation.packageResult; ++ result.packageResult = run; ++ if (stopped()) throw new InstallCancelledError(); ++ if (run.incompatible !== void 0) throw new ManagementFailure("incompatible-version", run.incompatible); ++ } + const succeeded = run.exitCode === 0 && run.timedOut !== true; + if (succeeded) delete result.failedAt; + if (!succeeded) { +- try { ++ if (mutation?.pendingBuilds !== void 0) result.pendingBuilds = mutation.pendingBuilds; ++ else try { + result.pendingBuilds = await readPendingBuilds(this.profile.dir); + } catch (error) { + this.ownerContext.logger.warn("Could not read pending build approvals after pnpm failed", error); +@@ -1776,8 +1808,8 @@ let PluginManager = (() => { + throw new Error(run.output); + } + const after = readProfileManifest("dsh", this.profile.dir).dependencies ?? {}; +- const installed = Object.keys(after).filter((name) => before[name] !== after[name]); +- if (installed.length === 0) installed.push(...Object.keys(after).filter((name) => spec === name || spec.startsWith(`${name}@`))); ++ const installed = mutation?.bundle === void 0 ? Object.keys(after).filter((name) => before[name] !== after[name]) : [mutation.bundle]; ++ if (installed.length === 0) installed.push(...Object.keys(after).filter((name) => parsed.spec === name || parsed.spec.startsWith(`${name}@`))); + const target = installed[0]; + if (installed.length !== 1 || target === void 0) throw new ManagementFailure("ambiguous-install"); + name = target; +@@ -1785,9 +1817,10 @@ let PluginManager = (() => { + const manifest = bundleManifest(name, this.profile.dir, this.profile.installAnchor); + if (manifest?.dsh?.bundle === void 0) throw new ManagementFailure("not-bundle"); + const compatibility = evaluatePluginCompatibility(manifest, readProfileVersionExemptions(this.profile.dir)); +- if (compatibility !== void 0 && !compatibility.exempted) throw new ManagementFailure("incompatible-version", [incompatiblePlugin(compatibility)]); ++ if (compatibility !== void 0 && !compatibility.exempted) reportPluginCompatibility(compatibility); + for (const file of bundlePatchPaths(dir, manifest.dsh.bundle)) loadOverlayPatches("dsh", file); + } catch (error) { ++ await mutation?.rollback?.(); + await this.restoreFiles(files); + throw error; + } +@@ -1796,11 +1829,19 @@ let PluginManager = (() => { + result.bundle = name; + result.target = name; + result.stage = "enable"; +- return this.configure(async () => { +- if (options?.enabled !== false) await this.selectBundle(name, true); +- if (Object.hasOwn(before, name)) return "restart-required"; +- if (options?.enabled !== false) result.warnings = await this.reload(); +- }); ++ try { ++ const application = await this.configure(async () => { ++ if (options?.enabled !== false) await this.selectBundle(name, true); ++ if (mutation?.replaced === true || Object.hasOwn(before, name)) return "restart-required"; ++ if (options?.enabled !== false) result.warnings = await this.reload(); ++ }); ++ mutation?.commit?.(); ++ return application; ++ } catch (error) { ++ await mutation?.rollback?.(); ++ await this.restoreFiles(files); ++ throw error; ++ } + }, { + stage: "install", + target: spec, +@@ -1854,7 +1895,13 @@ let PluginManager = (() => { + } + if ([...this.ctx.loader.entries()].some((entry) => entry.fiber?.uid != null && contributions.some((row) => row.id === entry.options.id && row.name === entry.options.name))) throw new ManagementFailure("bundle-in-use"); + }); +- result.packageResult = await this.runPnpm(["remove", name]); ++ const backend = this.ownerContext.get("profileBundlePackageBackend"); ++ const mutation = backend === void 0 ? void 0 : await backend.remove({ ++ name, ++ signal: this.abort.signal, ++ onOutput: (text, stream) => this.emitPackageOutput(void 0, text, stream, ["pnpm", "remove", name]) ++ }); ++ result.packageResult = mutation?.packageResult ?? await this.runPnpm(["remove", name]); + if (result.packageResult.exitCode !== 0 || result.packageResult.timedOut === true) throw new Error(result.packageResult.output); + }, { + stage: "remove", +@@ -1899,6 +1946,17 @@ let PluginManager = (() => { + overrides: [...new Set(patches.flatMap((item) => item.insert === void 0 && typeof item.id === "string" && !declared.has(item.id) ? [item.id] : []))] + }; + } ++ /** Emit host backend output through the same remote event contract as pnpm. */ ++ emitPackageOutput(requestId, text, stream, argv) { ++ this.ownerContext.emit("plugin-manager/install-log", { ++ ...requestId === void 0 ? {} : { requestId }, ++ jobId: randomUUID(), ++ argv, ++ cwd: this.profile.dir, ++ stream, ++ text ++ }); ++ } + /** Run one pnpm command in the profile, streaming its output as install-log chunks. */ + async runPnpm(args, signal, requestId) { + const jobId = randomUUID(); +@@ -1984,7 +2042,7 @@ let PluginManager = (() => { + if (metadata === void 0) throw new ManagementFailure("not-bundle"); + if (enabled) { + const compatibility = evaluatePluginCompatibility(metadata, readProfileVersionExemptions(this.profile.dir)); +- if (compatibility !== void 0 && !compatibility.exempted) throw new ManagementFailure("incompatible-version", [incompatiblePlugin(compatibility)]); ++ if (compatibility !== void 0 && !compatibility.exempted) reportPluginCompatibility(compatibility); + this.bundleRows(name); + } + } +diff --git a/node_modules/@deepseek-ai/dsh-plugin-manager/lib/types/index.d.ts b/node_modules/@deepseek-ai/dsh-plugin-manager/lib/types/index.d.ts +index e47ee2b..2f0abe5 100644 +--- a/node_modules/@deepseek-ai/dsh-plugin-manager/lib/types/index.d.ts ++++ b/node_modules/@deepseek-ai/dsh-plugin-manager/lib/types/index.d.ts +@@ -6,6 +6,11 @@ export type * from './types.ts'; + export { classifyInstallFailure, type InstallFailureFacts } from './install-failure.ts'; + export { InvalidInstallSpecError, parseInstallSpec, type ParsedInstallSpec } from './install-spec.ts'; + /** The pnpm executable, registries, and limits for diagnostics, lookups and connection checks. */ ++/** Host-owned package mutation backend for immutable Desktop generations. */ ++export interface ProfileBundlePackageBackend { ++ install(request: { spec: string; kind: 'registry' | 'path' | 'git' | 'tarball'; path?: string; registry?: string; expectedName?: string; signal: AbortSignal; onOutput(text: string, stream: 'stdout' | 'stderr'): void; }): Promise<{ packageResult: import('./types.ts').PackageResult; bundle?: string; replaced?: boolean; pendingBuilds?: string[]; rollback?(): Promise; commit?(): void; }>; ++ remove(request: { name: string; signal: AbortSignal; onOutput(text: string, stream: 'stdout' | 'stderr'): void; }): Promise<{ packageResult: import('./types.ts').PackageResult; }>; ++} + export interface Config { + /** The pnpm executable name or path; resolved through `PATH` like the `dsh plugin` command. */ + pnpmCommand?: string; diff --git a/patches/@deepseek-ai+dsh-session-persistence+0.1.7-rc.2.patch b/patches/@deepseek-ai+dsh-session-persistence+0.1.7-rc.2.patch new file mode 100644 index 000000000..13ff75b73 --- /dev/null +++ b/patches/@deepseek-ai+dsh-session-persistence+0.1.7-rc.2.patch @@ -0,0 +1,57 @@ +diff --git a/node_modules/@deepseek-ai/dsh-session-persistence/lib/index.js b/node_modules/@deepseek-ai/dsh-session-persistence/lib/index.js +index 5fa994b..6358ccd 100644 +--- a/node_modules/@deepseek-ai/dsh-session-persistence/lib/index.js ++++ b/node_modules/@deepseek-ai/dsh-session-persistence/lib/index.js +@@ -264,6 +264,16 @@ var SessionPersistence = class extends Service { + constructor(ctx) { + super(ctx, "sessionPersistence"); + } ++ /** ++ * Permanently remove one stored Session identity when the backend supports ++ * deletion. Backends that cannot delete keep this refusal. ++ * @param _id - the stored session to remove. ++ * @param _options - optional cancellation. ++ * @returns whether a durable artifact was removed. ++ */ ++ delete(_id, _options) { ++ return Promise.reject(/* @__PURE__ */ new Error("this session persistence backend does not support deletion")); ++ } + }; + //#endregion + export { SessionAlreadyExistsError, SessionAlreadyOwnedError, SessionFormatUnsupportedError, SessionHandleClosedError, SessionOwnershipLostError, SessionPersistence, SessionPersistence as default, SessionPersistenceCorruptionError, SessionPersistenceNotFoundError, SessionPersistenceRevision, SessionReadOnlyError, assertContiguous, assertStoredId, assertVersion, materializeAppendBatch, materializeCreateHeader, sessionFormatVersionRefusal, validateStoredEvents }; +diff --git a/node_modules/@deepseek-ai/dsh-session-persistence/lib/types/index.d.ts b/node_modules/@deepseek-ai/dsh-session-persistence/lib/types/index.d.ts +index 428feb0..e406385 100644 +--- a/node_modules/@deepseek-ai/dsh-session-persistence/lib/types/index.d.ts ++++ b/node_modules/@deepseek-ai/dsh-session-persistence/lib/types/index.d.ts +@@ -66,6 +66,11 @@ export interface SessionPersistenceStatOptions { + /** Optional cancellation for backend metadata reads. */ + readonly signal?: AbortSignal; + } ++/** Options for {@link SessionPersistence.delete}. */ ++export interface SessionPersistenceDeleteOptions { ++ /** Optional cancellation observed before backend work starts. */ ++ readonly signal?: AbortSignal; ++} + /** Options for {@link SessionPersistence.list}. */ + export interface SessionPersistenceListOptions { + /** Optional cancellation for backend listing work. */ +@@ -155,6 +160,18 @@ export declare abstract class SessionPersistence extends Service { + * @returns one snapshot per stored session. + */ + abstract list(options?: SessionPersistenceListOptions): Promise; ++ /** ++ * Permanently remove one stored Session identity. ++ * ++ * Deletion is optional: the base implementation refuses, and a backend that ++ * can delete overrides it. Refuses while this process holds write ownership ++ * of the session, so a live writer never loses its artifact underneath it. ++ * @param _id - the stored session to remove. ++ * @param _options - optional cancellation. ++ * @returns whether a durable artifact was removed; `false` when the session ++ * was already absent. ++ */ ++ delete(_id: SessionId, _options?: SessionPersistenceDeleteOptions): Promise; + } + export default SessionPersistence; + //# sourceMappingURL=index.d.ts.map +\ No newline at end of file diff --git a/patches/@deepseek-ai+dsh-session-persistence-jsonl+0.1.7-rc.2.patch b/patches/@deepseek-ai+dsh-session-persistence-jsonl+0.1.7-rc.2.patch new file mode 100644 index 000000000..4e8802717 --- /dev/null +++ b/patches/@deepseek-ai+dsh-session-persistence-jsonl+0.1.7-rc.2.patch @@ -0,0 +1,79 @@ +diff --git a/node_modules/@deepseek-ai/dsh-session-persistence-jsonl/lib/index.js b/node_modules/@deepseek-ai/dsh-session-persistence-jsonl/lib/index.js +index a42f2a2..3e7e082 100644 +--- a/node_modules/@deepseek-ai/dsh-session-persistence-jsonl/lib/index.js ++++ b/node_modules/@deepseek-ai/dsh-session-persistence-jsonl/lib/index.js +@@ -2526,6 +2526,40 @@ var JsonlSessionPersistence = class extends SessionPersistence { + flush() { + return this.tracker.flushAll(); + } ++ /** Remove one durable session while holding its write claim and directory lease. */ ++ async delete(id, options) { ++ options?.signal?.throwIfAborted(); ++ await this.ensureRootEncoding(); ++ options?.signal?.throwIfAborted(); ++ if (this.tracker.hasPending(id)) throw new Error(`cannot delete session "${id}" while its unmaterialized create is live`); ++ this.tracker.claimWrite(id); ++ let lease; ++ try { ++ const resolved = await this.findLog(id, options?.signal); ++ if (resolved === void 0) return false; ++ const path = resolved.currentPath; ++ lease = await this.acquireLease(id, void 0, dirname(path)); ++ try { ++ await rm(path); ++ } catch (error) { ++ if (isENOENT(error)) return false; ++ throw error; ++ } ++ if (process.platform !== "win32") await this.syncDirPosix(dirname(path)); ++ return true; ++ } finally { ++ this.coldLogMemo.delete(id); ++ this.migrationPreparations.delete(id); ++ let releaseFailure; ++ try { ++ await lease?.release(); ++ } catch (raw) { ++ releaseFailure = raw instanceof Error ? raw : new Error(String(raw)); ++ } ++ this.tracker.releaseClaim(id); ++ if (releaseFailure !== void 0) throw releaseFailure; ++ } ++ } + /** + * Observe one stored session without reading its event log. + * @param id - the stored session to observe. +@@ -3040,8 +3074,10 @@ var JsonlSessionPersistence = class extends SessionPersistence { + try { + header = await this.readGenerationHeader(selected, void 0, signal); + } catch (error) { +- if (error instanceof SessionFormatUnsupportedError || error instanceof SessionPersistenceCorruptionError) continue; +- throw error; ++ if (error instanceof SessionFormatUnsupportedError) continue; ++ signal?.throwIfAborted(); ++ this.ctx.logger.warn(`${this.name}: skipped unreadable session log ${selected.sourcePath}: ${error instanceof Error ? error.message : String(error)}`); ++ continue; + } + if (header === void 0) continue; + if (ids.has(header.id)) throw new Error(`duplicate JSONL session id "${header.id}" appears in multiple project directories`); +diff --git a/node_modules/@deepseek-ai/dsh-session-persistence-jsonl/lib/types/index.d.ts b/node_modules/@deepseek-ai/dsh-session-persistence-jsonl/lib/types/index.d.ts +index 48f0351..f5ef30e 100644 +--- a/node_modules/@deepseek-ai/dsh-session-persistence-jsonl/lib/types/index.d.ts ++++ b/node_modules/@deepseek-ai/dsh-session-persistence-jsonl/lib/types/index.d.ts +@@ -7,7 +7,7 @@ + */ + import { Context } from '@deepseek-ai/cordis'; + import z from '@deepseek-ai/schemastery'; +-import { SessionPersistence, type SessionAccess, type SessionHandle, type SessionHandleReadResult, type SessionPersistenceCreateOptions, type SessionPersistenceListOptions, type SessionPersistenceOpenOptions, type SessionPersistenceSnapshot, type SessionPersistenceStatOptions, type SessionPersistenceRevision as PersistenceRevision } from '@deepseek-ai/dsh-session-persistence'; ++import { SessionPersistence, type SessionAccess, type SessionHandle, type SessionHandleReadResult, type SessionPersistenceCreateOptions, type SessionPersistenceDeleteOptions, type SessionPersistenceListOptions, type SessionPersistenceOpenOptions, type SessionPersistenceSnapshot, type SessionPersistenceStatOptions, type SessionPersistenceRevision as PersistenceRevision } from '@deepseek-ai/dsh-session-persistence'; + import { JsonlSessionHandle } from './storage.ts'; + import { SessionWriteLease } from './lease.ts'; + import type { SessionEvent, SessionId, SessionHeader, SessionLogOffset as SessionLogOffsetType } from '@deepseek-ai/dsh-session'; +@@ -103,6 +103,7 @@ declare class JsonlSessionPersistence extends SessionPersistence { + * @returns resolution once every write handle active at the call has flushed. + */ + flush(): Promise; ++ delete(id: SessionId, options?: SessionPersistenceDeleteOptions): Promise; + /** + * Observe one stored session without reading its event log. + * @param id - the stored session to observe. diff --git a/patches/@deepseek-ai+dsh-workspace+0.1.7-rc.2.patch b/patches/@deepseek-ai+dsh-workspace+0.1.7-rc.2.patch new file mode 100644 index 000000000..d9b6f07d6 --- /dev/null +++ b/patches/@deepseek-ai+dsh-workspace+0.1.7-rc.2.patch @@ -0,0 +1,80 @@ +diff --git a/node_modules/@deepseek-ai/dsh-workspace/lib/index.js b/node_modules/@deepseek-ai/dsh-workspace/lib/index.js +index 9e3936a..77ed234 100644 +--- a/node_modules/@deepseek-ai/dsh-workspace/lib/index.js ++++ b/node_modules/@deepseek-ai/dsh-workspace/lib/index.js +@@ -538,6 +538,26 @@ var WorkspaceRegistry = class extends Service { + if (options.stopActivity === true) await this.stopSessionActivity(sessionId); + }); + } ++ /** Remove a permanently deleted Session from Workspace and archive state. */ ++ forgetSession(sessionId) { ++ return this.enqueueOperation(async () => { ++ for (const [workspaceId, record] of this.requireTable().entries()) { ++ if (!record.sessionIds.includes(sessionId)) continue; ++ const entity = this.entities.get(workspaceId); ++ if (entity === void 0) throw new Error(`cannot forget session '${sessionId}': workspace '${workspaceId}' is not published`); ++ await entity.detachSession(sessionId); ++ break; ++ } ++ const state = this.requireState(); ++ if (state.archivedSessionIds.includes(sessionId)) await this.setState({ ++ ...state, ++ archivedSessionIds: state.archivedSessionIds.filter((id) => id !== sessionId) ++ }); ++ this.headers.delete(sessionId); ++ this.sessionPaths.delete(sessionId); ++ this.invalidSessionPaths.delete(sessionId); ++ }); ++ } + /** + * Unarchive one session durably by dropping it from the registry-global + * archive set; the accounting slot was never touched, so the session +diff --git a/node_modules/@deepseek-ai/dsh-workspace/lib/types/index.d.ts b/node_modules/@deepseek-ai/dsh-workspace/lib/types/index.d.ts +index daa6916..9687fcb 100644 +--- a/node_modules/@deepseek-ai/dsh-workspace/lib/types/index.d.ts ++++ b/node_modules/@deepseek-ai/dsh-workspace/lib/types/index.d.ts +@@ -211,6 +211,8 @@ export declare class WorkspaceRegistry extends Service { + * @returns resolution after durability and, with `stopActivity`, after every stop request was issued. + */ + archiveSession(sessionId: SessionId, options?: ArchiveSessionOptions): Promise; ++ /** Remove a permanently deleted Session from Workspace and archive state. */ ++ forgetSession(sessionId: SessionId): Promise; + /** + * Unarchive one session durably by dropping it from the registry-global + * archive set; the accounting slot was never touched, so the session +diff --git a/node_modules/@deepseek-ai/dsh-workspace/lib/types/index.js b/node_modules/@deepseek-ai/dsh-workspace/lib/types/index.js +index fa1c9a7..9be12f8 100644 +--- a/node_modules/@deepseek-ai/dsh-workspace/lib/types/index.js ++++ b/node_modules/@deepseek-ai/dsh-workspace/lib/types/index.js +@@ -301,6 +301,31 @@ export class WorkspaceRegistry extends Service { + await this.stopSessionActivity(sessionId); + }); + } ++ /** Remove a permanently deleted Session from Workspace and archive state. */ ++ forgetSession(sessionId) { ++ return this.enqueueOperation(async () => { ++ for (const [workspaceId, record] of this.requireTable().entries()) { ++ if (!record.sessionIds.includes(sessionId)) ++ continue; ++ const entity = this.entities.get(workspaceId); ++ if (entity === undefined) { ++ throw new Error(`cannot forget session '${sessionId}': workspace '${workspaceId}' is not published`); ++ } ++ await entity.detachSession(sessionId); ++ break; ++ } ++ const state = this.requireState(); ++ if (state.archivedSessionIds.includes(sessionId)) { ++ await this.setState({ ++ ...state, ++ archivedSessionIds: state.archivedSessionIds.filter(id => id !== sessionId), ++ }); ++ } ++ this.headers.delete(sessionId); ++ this.sessionPaths.delete(sessionId); ++ this.invalidSessionPaths.delete(sessionId); ++ }); ++ } + /** + * Unarchive one session durably by dropping it from the registry-global + * archive set; the accounting slot was never touched, so the session diff --git a/patches/undici+8.11.2.patch b/patches/undici+8.11.2.patch new file mode 100644 index 000000000..d30c138af --- /dev/null +++ b/patches/undici+8.11.2.patch @@ -0,0 +1,33 @@ +diff --git a/node_modules/undici/lib/dispatcher/dispatcher1-wrapper.js b/node_modules/undici/lib/dispatcher/dispatcher1-wrapper.js +index e206984..5319312 100644 +--- a/node_modules/undici/lib/dispatcher/dispatcher1-wrapper.js ++++ b/node_modules/undici/lib/dispatcher/dispatcher1-wrapper.js +@@ -17,12 +17,16 @@ class LegacyHandlerWrapper { + } + + onRequestUpgrade (controller, statusCode, headers, socket) { +- const rawHeaders = controller?.rawHeaders ?? toRawHeaders(headers ?? {}) ++ const rawHeaders = Array.isArray(controller?.rawHeaders) ++ ? controller.rawHeaders ++ : toRawHeaders(controller?.rawHeaders ?? headers ?? {}) + this.#handler.onUpgrade?.(statusCode, rawHeaders, socket) + } + + onResponseStart (controller, statusCode, headers, statusMessage) { +- const rawHeaders = controller?.rawHeaders ?? toRawHeaders(headers ?? {}) ++ const rawHeaders = Array.isArray(controller?.rawHeaders) ++ ? controller.rawHeaders ++ : toRawHeaders(controller?.rawHeaders ?? headers ?? {}) + + if (this.#handler.onHeaders?.(statusCode, rawHeaders, () => controller.resume(), statusMessage) === false) { + controller.pause() +@@ -36,6 +40,8 @@ class LegacyHandlerWrapper { + } + + onResponseEnd (controller, trailers) { +- const rawTrailers = controller?.rawTrailers ?? toRawHeaders(trailers ?? {}) ++ const rawTrailers = Array.isArray(controller?.rawTrailers) ++ ? controller.rawTrailers ++ : toRawHeaders(controller?.rawTrailers ?? trailers ?? {}) + this.#handler.onComplete?.(rawTrailers) + } diff --git a/scripts/build-ppt-runtime.mjs b/scripts/build-ppt-runtime.mjs index 3af705dde..b5fbcd394 100644 --- a/scripts/build-ppt-runtime.mjs +++ b/scripts/build-ppt-runtime.mjs @@ -1,84 +1,116 @@ -/** Rebuild the shipped PPT plugin from the maintained sources and explicit sixteen-pack catalog. */ -import fs from 'node:fs/promises'; -import path from 'node:path'; -import os from 'node:os'; -import { promisify } from 'node:util'; -import { execFile } from 'node:child_process'; -import crypto from 'node:crypto'; -import sharp from 'sharp'; -const run = promisify(execFile); -const root = path.resolve('packages/ppt-runtime'); -const dest = path.resolve('packages/ppt-bundles'); -const scratch = await fs.mkdtemp(path.join(os.tmpdir(), 'dsh-ppt-build-')); -const specs = []; -for (const c of await fs.readdir(root + '/templates')) - for (const d of await fs.readdir(root + '/templates/' + c)) - specs.push(JSON.parse(await fs.readFile(root + '/templates/' + c + '/' + d + '/metadata.json', 'utf8'))); -specs.sort((a, b) => a.definition.id.localeCompare(b.definition.id)); -if (specs.length !== 16) - throw Error('Expected exactly sixteen maintained templates'); -const previews = {}; -const previewFiles = {}; -const checks = []; +/** Build the shipped PPT plugins from maintained sources into ignored staging output. */ +import fs from 'node:fs/promises' +import path from 'node:path' +import os from 'node:os' +import { promisify } from 'node:util' +import { execFile } from 'node:child_process' +import crypto from 'node:crypto' +import sharp from 'sharp' +import { replaceInstalledPackages } from './ppt-package-projection.mjs' + +const run = promisify(execFile) +const root = path.resolve('packages/ppt-runtime') +const templateRoot = path.resolve(process.env.DSH_PPT_TEMPLATE_OUTPUT ?? '.build/ppt-runtime/templates') +const outputRoot = path.resolve('.build/ppt-runtime/packages') +// Use npm_node_execpath so bin.js subprocesses use the real Node, not the `node` +// npm package binary that npm injects into PATH via node_modules/.bin. +const nodeExec = process.env.npm_node_execpath ?? process.execPath +const scratch = await fs.mkdtemp(path.join(os.tmpdir(), 'dsh-ppt-build-')) +const specs = [] +for (const category of await fs.readdir(templateRoot)) { + for (const directory of await fs.readdir(path.join(templateRoot, category))) { + specs.push(JSON.parse(await fs.readFile(path.join(templateRoot, category, directory, 'metadata.json'), 'utf8'))) + } +} +specs.sort((a, b) => a.definition.id.localeCompare(b.definition.id)) +if (specs.length !== 16) throw Error('Expected exactly sixteen maintained templates') + +const previews = {} +const previewFiles = {} +const generatedPages = new Map() +const checks = [] + try { - for (const { definition, provenance } of specs) { - const dir = root + '/templates/' + definition.referenceDirectory; - const { stdout } = await run(process.execPath, [root + '/core/lib/bin.js', 'check', dir + '/source', '--json']); - const check = JSON.parse(stdout); - if (check.errorCount) - throw Error(definition.id + ': ' + stdout); - checks.push({ id: definition.id, ...check }); - if (!process.argv.includes('--reuse-previews')) { - const pngDir = scratch + '/' + definition.id; - await run(process.execPath, [root + '/core/lib/bin.js', 'screenshot', dir + '/source', '-o', pngDir, '--scale', '1.3333333333', '--json']); - const pngs = JSON.parse(await fs.readFile(pngDir + '/index.json', 'utf8')).pages.map(p => p.file); - if (pngs.length !== definition.referencePageCount) - throw Error('Incomplete preview set'); - await fs.mkdir(dir + '/pages', { recursive: true }); - for (const [i, f] of pngs.entries()) - await sharp(pngDir + '/' + f).jpeg({ quality: 87 }).toFile(dir + '/pages/' + String(i + 1).padStart(2, '0') + '.jpg'); - } - previews[definition.id] = await Promise.all(definition.previewSlides.map(async number => { - const relative = definition.referenceDirectory + '/pages/' + String(number).padStart(2, '0') + '.jpg'; - const bytes = await fs.readFile(root + '/templates/' + relative); - const hash = crypto.createHash('sha256').update(bytes).digest('hex'); - previewFiles[hash] = relative; - return '/dsh-ppt/previews/' + hash + '.jpg'; - })); + await fs.rm(outputRoot, { recursive: true, force: true }) + await fs.mkdir(outputRoot, { recursive: true }) + + for (const { definition } of specs) { + const directory = path.join(templateRoot, definition.referenceDirectory) + const { stdout } = await run(nodeExec, [path.join(root, 'core/lib/bin.js'), 'check', path.join(directory, 'source'), '--json']) + const check = JSON.parse(stdout) + if (check.errorCount) throw Error(definition.id + ': ' + stdout) + checks.push({ id: definition.id, ...check }) + + const pngDirectory = path.join(scratch, 'screenshots', definition.id) + await run(nodeExec, [path.join(root, 'core/lib/bin.js'), 'screenshot', path.join(directory, 'source'), '-o', pngDirectory, '--scale', '1.3333333333', '--json']) + const pngs = JSON.parse(await fs.readFile(path.join(pngDirectory, 'index.json'), 'utf8')).pages.map(page => page.file) + if (pngs.length !== definition.referencePageCount) throw Error('Incomplete preview set') + + const pageDirectory = path.join(scratch, 'previews', definition.id) + await fs.mkdir(pageDirectory, { recursive: true }) + for (const [index, file] of pngs.entries()) { + await sharp(path.join(pngDirectory, file)) + .jpeg({ quality: 87 }) + .toFile(path.join(pageDirectory, `${String(index + 1).padStart(2, '0')}.jpg`)) } - const artifacts = {}; - for (const kind of ['core', 'adapter']) { - const stage = scratch + '/' + kind; - await fs.cp(root + '/' + kind, stage, { recursive: true, filter: p => !path.basename(p).startsWith('._') && path.basename(p) !== '.DS_Store' }); - await fs.cp(root + '/upstream', stage + '/licenses', { recursive: true }); - let client = await fs.readFile(stage + '/lib/client.js', 'utf8'); - if (!client.includes('/* PERSONAL_TEMPLATE_MANAGER */')) throw Error('Missing personal template client marker'); - client = client.replace('/* PERSONAL_TEMPLATE_MANAGER */', await fs.readFile(root + '/client/personal-template-manager.js', 'utf8')); - if (!client.includes('/* GENERATED_PPT_PREVIEWS */ {}')) - throw Error('Missing preview insertion marker'); - client = client.replace('/* GENERATED_PPT_PREVIEWS */ {}', JSON.stringify(previews)); - await fs.writeFile(stage + '/lib/client.js', client); - if (kind === 'core') { - await fs.writeFile(stage + '/lib/preview-manifest.js', '// Build allowlist: paths resolve only inside the bundled template references.\nexport const previewFiles = ' + JSON.stringify(previewFiles) + ';\n'); - await fs.writeFile(stage + '/lib/catalog.js', '// Generated only from the maintained template catalog.\nexport const definitions = ' + JSON.stringify(specs.map(s => s.definition)) + ';\nexport const semantics = ' + JSON.stringify(Object.fromEntries(specs.map(s => [s.definition.id, s.semantics]))) + ';\n'); - for (const { definition } of specs) { - const target = stage + '/skills/dsh-ppt/references/' + definition.referenceDirectory; - await fs.cp(root + '/templates/' + definition.referenceDirectory, target, { recursive: true }); - await fs.rm(target + '/metadata.json'); - } - } - const { stdout } = await run('npm', ['pack', stage, '--ignore-scripts', '--json', '--pack-destination', scratch]); - const packed = JSON.parse(stdout)[0]; - const file = kind === 'core' ? 'dsh-ppt-0.1.1-rc.2-desktop-20260906.tgz' : 'dsh-ppt-composer-0.1.1-rc.2-desktop-20260906.tgz'; - const bytes = await fs.readFile(scratch + '/' + packed.filename); - await fs.writeFile(dest + '/' + file, bytes); - artifacts[kind] = { file, sha256: crypto.createHash('sha256').update(bytes).digest('hex'), integrity: 'sha512-' + crypto.createHash('sha512').update(bytes).digest('base64') }; + generatedPages.set(definition.id, pageDirectory) + + previews[definition.id] = await Promise.all(definition.previewSlides.map(async number => { + const relative = path.join(definition.referenceDirectory, 'pages', `${String(number).padStart(2, '0')}.jpg`).split(path.sep).join('/') + const bytes = await fs.readFile(path.join(pageDirectory, `${String(number).padStart(2, '0')}.jpg`)) + const hash = crypto.createHash('sha256').update(bytes).digest('hex') + previewFiles[hash] = relative + return `/dsh-ppt/previews/${hash}.jpg` + })) + } + + const packages = {} + const packageStages = [] + for (const kind of ['core', 'adapter']) { + const packageName = kind === 'core' ? 'dsh-ppt' : 'dsh-ppt-composer' + const stage = path.join(outputRoot, packageName) + await fs.cp(path.join(root, kind), stage, { + recursive: true, + filter: source => !path.basename(source).startsWith('._') && path.basename(source) !== '.DS_Store' && path.basename(source) !== 'node_modules' + }) + await fs.cp(path.join(root, 'upstream'), path.join(stage, 'licenses'), { recursive: true }) + + let client = await fs.readFile(path.join(stage, 'lib/client.js'), 'utf8') + if (!client.includes('/* PERSONAL_TEMPLATE_MANAGER */')) throw Error('Missing personal template client marker') + client = client.replace('/* PERSONAL_TEMPLATE_MANAGER */', await fs.readFile(path.join(root, 'client/personal-template-manager.js'), 'utf8')) + if (!client.includes('/* GENERATED_PPT_PREVIEWS */ {}')) throw Error('Missing preview insertion marker') + client = client.replace('/* GENERATED_PPT_PREVIEWS */ {}', JSON.stringify(previews)) + await fs.writeFile(path.join(stage, 'lib/client.js'), client) + + if (kind === 'core') { + await fs.writeFile(path.join(stage, 'lib/preview-manifest.js'), '// Generated from the current preview build; paths stay inside bundled template references.\nexport const previewFiles = ' + JSON.stringify(previewFiles) + ';\n') + await fs.writeFile(path.join(stage, 'lib/catalog.js'), '// Generated from the maintained template catalog.\nexport const definitions = ' + JSON.stringify(specs.map(spec => spec.definition)) + ';\nexport const semantics = ' + JSON.stringify(Object.fromEntries(specs.map(spec => [spec.definition.id, spec.semantics]))) + ';\n') + for (const { definition } of specs) { + const target = path.join(stage, 'skills/dsh-ppt/references', definition.referenceDirectory) + const referenceSource = path.join(templateRoot, definition.referenceDirectory) + await fs.cp(referenceSource, target, { + recursive: true, + filter: source => source !== path.join(referenceSource, 'metadata.json') && source !== path.join(referenceSource, 'pages') + }) + await fs.cp(generatedPages.get(definition.id), path.join(target, 'pages'), { recursive: true }) + } } - await fs.writeFile(root + '/artifacts.json', JSON.stringify(artifacts, null, 2) + '\n'); - await fs.mkdir('doc/ppt-remediation', { recursive: true }); - await fs.writeFile('doc/ppt-remediation/source-checks.json', JSON.stringify(checks, null, 2) + '\n'); - console.log(JSON.stringify({ artifacts, checks: checks.map(c => ({ id: c.id, pages: c.pageCount, errors: c.errorCount, warnings: c.warningCount })) }, null, 2)); -} -finally { - await fs.rm(scratch, { recursive: true, force: true }); + + packageStages.push({ packageName, source: stage }) + packages[kind] = { + name: packageName, + path: path.relative(process.cwd(), stage).split(path.sep).join('/') + } + } + + await replaceInstalledPackages(packageStages) + + const manifest = { + packages, + checks: checks.map(check => ({ id: check.id, pages: check.pageCount, errors: check.errorCount, warnings: check.warningCount })) + } + await fs.writeFile(path.join(outputRoot, 'build.json'), JSON.stringify(manifest, null, 2) + '\n') + console.log(JSON.stringify(manifest, null, 2)) +} finally { + await fs.rm(scratch, { recursive: true, force: true }) } diff --git a/scripts/download-artifact-ranges.mjs b/scripts/download-artifact-ranges.mjs new file mode 100644 index 000000000..fa554ec14 --- /dev/null +++ b/scripts/download-artifact-ranges.mjs @@ -0,0 +1,109 @@ +import { spawn, execFile } from 'node:child_process' +import { createHash } from 'node:crypto' +import { createReadStream, createWriteStream } from 'node:fs' +import { mkdir, mkdtemp, rename, rm, stat } from 'node:fs/promises' +import { dirname, join, resolve } from 'node:path' +import { Readable, Transform } from 'node:stream' +import { pipeline } from 'node:stream/promises' +import { promisify } from 'node:util' +import { pathToFileURL } from 'node:url' + +const CHUNK_SIZE = 32 * 1024 * 1024 + +/** Assemble bounded ranges only after every response has its expected length. */ +export async function downloadInRanges({ size, digest, outputPath, downloadRange, concurrency = 6 }) { + if (!Number.isSafeInteger(size) || size <= 0 || !/^sha256:[a-f0-9]{64}$/.test(digest ?? '')) { + throw new Error('Artifact must declare a positive size and SHA-256 digest') + } + if (!Number.isInteger(concurrency) || concurrency < 1 || concurrency > 8) throw new Error('Invalid download concurrency') + await mkdir(dirname(outputPath), { recursive: true }) + const scratch = await mkdtemp(join(dirname(outputPath), '.artifact-download-')) + const parts = Array.from({ length: Math.ceil(size / CHUNK_SIZE) }, (_, index) => ({ + start: index * CHUNK_SIZE, + end: Math.min(size, (index + 1) * CHUNK_SIZE) - 1, + path: join(scratch, String(index)) + })) + let next = 0 + let failure + try { + await Promise.all(Array.from({ length: Math.min(concurrency, parts.length) }, async () => { + while (!failure && next < parts.length) { + const part = parts[next++] + try { + await downloadRange(part.start, part.end, part.path) + if ((await stat(part.path)).size !== part.end - part.start + 1) throw new Error('Unexpected range response size') + } catch (error) { + failure ??= error + } + } + })) + if (failure) throw failure + const hash = createHash('sha256') + const combined = join(scratch, 'artifact.zip') + async function* chunks() { + for (const part of parts) { + for await (const chunk of createReadStream(part.path)) { + hash.update(chunk) + yield chunk + } + } + } + await pipeline(Readable.from(chunks()), createWriteStream(combined)) + if (`sha256:${hash.digest('hex')}` !== digest) throw new Error('Artifact SHA-256 mismatch') + await rename(combined, outputPath) + } finally { + await rm(scratch, { recursive: true, force: true }) + } +} + +async function ghRange(route, start, end, destination) { + for (let attempt = 1; attempt <= 3; attempt++) { + const child = spawn('gh', ['api', route, '-H', `Range: bytes=${start}-${end}`], { stdio: ['ignore', 'pipe', 'ignore'] }) + let bytes = 0 + const bounded = new Transform({ transform(chunk, encoding, callback) { + bytes += chunk.length + callback(bytes > end - start + 1 ? new Error('Storage ignored the bounded Range request') : null, chunk) + } }) + const exited = new Promise((resolveExit, reject) => { + child.once('error', reject) + child.once('exit', code => code === 0 ? resolveExit() : reject(new Error(`gh range request exited with code ${code}`))) + }) + const timer = setTimeout(() => child.kill('SIGTERM'), 180_000) + try { + const transfer = pipeline(child.stdout, bounded, createWriteStream(destination)).catch(error => { + child.kill('SIGTERM') + throw error + }) + const results = await Promise.allSettled([exited, transfer]) + const rejected = results.find(result => result.status === 'rejected') + if (rejected) throw rejected.reason + if (bytes !== end - start + 1) throw new Error('Incomplete range response') + return + } catch (error) { + child.kill('SIGTERM') + if (attempt === 3) throw error + } finally { + clearTimeout(timer) + } + } +} + +async function main() { + const [repository, runId, name, output] = process.argv.slice(2) + if (!/^[\w.-]+\/[\w.-]+$/.test(repository ?? '') || !/^\d+$/.test(runId ?? '') || !name || !output) { + throw new Error('Usage: download-artifact-ranges.mjs ') + } + const { stdout } = await promisify(execFile)('gh', ['api', `repos/${repository}/actions/runs/${runId}/artifacts`, '--paginate', '--slurp'], { maxBuffer: 1024 * 1024 }) + const pages = JSON.parse(stdout) + const artifact = pages.flatMap(page => page.artifacts ?? []).find(item => item.name === name && !item.expired) + if (!artifact || !Number.isSafeInteger(artifact.id)) throw new Error(`Available artifact not found: ${name}`) + const started = Date.now() + await downloadInRanges({ size: artifact.size_in_bytes, digest: artifact.digest, outputPath: resolve(output), + downloadRange: (start, end, path) => ghRange(`repos/${repository}/actions/artifacts/${artifact.id}/zip`, start, end, path) + }) + console.log(`Verified ${name}: ${artifact.size_in_bytes} bytes in ${Math.round((Date.now() - started) / 1000)}s (SHA-256 matched)`) +} + +if (process.argv[1] && import.meta.url === pathToFileURL(resolve(process.argv[1])).href) { + main().catch(error => { console.error(error.message); process.exitCode = 1 }) +} diff --git a/scripts/enrich-ppt-templates.mjs b/scripts/enrich-ppt-templates.mjs index c1595fd2e..cc7d0e007 100644 --- a/scripts/enrich-ppt-templates.mjs +++ b/scripts/enrich-ppt-templates.mjs @@ -5,7 +5,7 @@ import path from 'node:path'; import crypto from 'node:crypto'; import yaml from 'js-yaml'; import {createCompositions, compositionPlans} from './ppt/composition-library.mjs'; -const root=path.resolve('packages/ppt-runtime/templates'); +const root=path.resolve(process.env.DSH_PPT_TEMPLATE_OUTPUT ?? '.build/ppt-runtime/templates'); const json=async file=>JSON.parse(await fs.readFile(file,'utf8')); for(const category of await fs.readdir(root)) for(const slug of await fs.readdir(path.join(root,category))){ if(!compositionPlans[slug])continue; diff --git a/scripts/generate-ppt-templates.mjs b/scripts/generate-ppt-templates.mjs index 15ba57480..a6dcb887b 100644 --- a/scripts/generate-ppt-templates.mjs +++ b/scripts/generate-ppt-templates.mjs @@ -3,7 +3,7 @@ import fs from 'node:fs/promises'; import path from 'node:path'; import crypto from 'node:crypto'; import yaml from 'js-yaml'; -const root = path.resolve('packages/ppt-runtime/templates'); +const root = path.resolve(process.env.DSH_PPT_TEMPLATE_OUTPUT ?? '.build/ppt-runtime/templates'); const upstream = 'https://github.com/nexu-io/html-anything/tree/c31204544230578ac814026fecc153c6e36587ae'; const specs = [ { slug: 'dsh-engineering-blueprint', category: 'work', name: '工程蓝图 · Engineering Blueprint', short: 'ENGINEERING NOTES', paper: 'F0EAE0', ink: '252824', accent: 'B5392A', muted: '68665F', surface: 'E7E0D4', source: 'deck-blueprint', summary: '纸张底色、工程网格、流程盒和反馈路径;用于架构评审、技术方案及执行计划。' }, diff --git a/scripts/generate-zara-ppt-templates.mjs b/scripts/generate-zara-ppt-templates.mjs index 6a60cb772..b0f2c2807 100644 --- a/scripts/generate-zara-ppt-templates.mjs +++ b/scripts/generate-zara-ppt-templates.mjs @@ -10,7 +10,8 @@ import path from 'node:path'; import crypto from 'node:crypto'; import yaml from 'js-yaml'; import { createRichLayouts, richLayoutGuidance, richLayoutSlugs } from './ppt/rich-layouts.mjs'; -const root = path.resolve('packages/ppt-runtime'); +const sourceRoot = path.resolve('packages/ppt-runtime'); +const templateRoot = path.resolve(process.env.DSH_PPT_TEMPLATE_OUTPUT ?? '.build/ppt-runtime/templates'); export const zaraSpecs = [ ['soft-editorial', 'Soft Editorial', '柔和编辑部', 'editorial', 'F2EEDF', '2A241B', 'E1A4C2', 'D6DD63', 'E8C9B6', 'Georgia', 'Arial', 'serif'], ['editorial-forest', 'Editorial Forest', '森林季刊', 'work', '2E4A2A', 'EFE7D4', 'E89CB1', '3A5A36', 'E6DCC4', 'Georgia', 'Arial', 'serif'], @@ -25,9 +26,9 @@ export const zaraSpecs = [ ].map(([slug, name, zh, category, bg, ink, accent, surface, secondary, title, body, kind]) => ({ slug, name, zh, category, bg, ink, accent, surface, secondary, title, body, kind })); const ref = 'e5e204fb1f3b06290846e7dcd7aceddabeceec8c'; for (const s of zaraSpecs) { - const out = path.join(root, 'templates', s.category, 'dsh-' + s.slug); + const out = path.join(templateRoot, s.category, 'dsh-' + s.slug); await fs.mkdir(out, { recursive: true }); - const upstreamDesign = await fs.readFile(path.join(root, 'upstream/zara/templates', s.slug, 'design.md'), 'utf8'); + const upstreamDesign = await fs.readFile(path.join(sourceRoot, 'upstream/zara/templates', s.slug, 'design.md'), 'utf8'); const fontTokens = [...upstreamDesign.matchAll(/fontFamily: ["']?([^\n]+)/g)].map(m => m[1].split(',')[0].replace(/["']/g, '').trim()); const fonts = { en: { title: s.title, body: s.body }, zh: { title: s.kind === 'serif' ? 'Songti SC' : 'PingFang SC', body: 'PingFang SC' }, fallbacks: { en: { title: s.kind === 'serif' ? 'Georgia' : 'Arial', body: 'Arial' }, zh: { macOS: { serif: 'Songti SC', sans: 'PingFang SC' }, Windows: { serif: 'SimSun', sans: 'Microsoft YaHei' }, Linux: { serif: 'Noto Serif CJK SC', sans: 'Noto Sans CJK SC' } } }, upstreamTitle: fontTokens[0] }; const palette = { background: s.bg, text: s.ink, accent: s.accent, surface: s.surface, secondary: s.secondary, muted: s.secondary }; diff --git a/scripts/localize-ppt-templates.mjs b/scripts/localize-ppt-templates.mjs index d404f23e0..666431f06 100644 --- a/scripts/localize-ppt-templates.mjs +++ b/scripts/localize-ppt-templates.mjs @@ -3,17 +3,19 @@ import fs from 'node:fs/promises'; import path from 'node:path'; import yaml from 'js-yaml'; import crypto from 'node:crypto'; -const root = path.resolve('packages/ppt-runtime/templates'); +const root = path.resolve(process.env.DSH_PPT_TEMPLATE_OUTPUT ?? '.build/ppt-runtime/templates'); const overrides = JSON.parse(await fs.readFile('scripts/ppt/english-layout-overrides.json', 'utf8')); const dictionary = JSON.parse(await fs.readFile('scripts/ppt/english-text.json', 'utf8')); Object.assign(dictionary, { '出口': 'Exports', '进口': 'Imports', '美国': 'US', '英国': 'UK', '德国': 'Germany', '日本': 'Japan', '年': 'Year', '平台': 'Platform', '独立站': 'Own store', '本地履约': 'Local fulfillment' }); -for (const c of await fs.readdir(root)) - for (const d of await fs.readdir(path.join(root, c))) { - if (!d.startsWith('curated-') && !['dsh-engineering-blueprint', 'dsh-course-workshop', 'dsh-editorial-notebook'].includes(d)) - continue; - const dir = path.join(root, c, d), zh = path.join(dir, 'source-zh'); - // Read immutable authored seeds, never the previously enriched output. - const seed = path.resolve('scripts/ppt/base-templates', d); +const seedRoot = path.resolve('scripts/ppt/base-templates'); +for (const entry of await fs.readdir(seedRoot, { withFileTypes: true })) { + if (!entry.isDirectory()) continue; + const d = entry.name; + // Read immutable authored seeds, never previously generated output. + const seed = path.join(seedRoot, d); + const seedMetadata = JSON.parse(await fs.readFile(path.join(seed, 'metadata.json'), 'utf8')); + const dir = path.join(root, seedMetadata.definition.referenceDirectory), zh = path.join(dir, 'source-zh'); + await fs.mkdir(dir, { recursive: true }); for (const folder of ['source', 'source-zh']) { await fs.rm(path.join(dir, folder), { recursive: true, force: true }); await fs.cp(path.join(seed, 'source-zh'), path.join(dir, folder), { recursive: true }); diff --git a/scripts/ppt-package-projection.d.mts b/scripts/ppt-package-projection.d.mts new file mode 100644 index 000000000..091d92887 --- /dev/null +++ b/scripts/ppt-package-projection.d.mts @@ -0,0 +1,14 @@ +export interface PptPackageStage { + packageName: string + source: string +} + +export interface PptPackageProjectionOptions { + nodeModulesRoot?: string + beforeReplace?: (packageName: string, index: number) => void | Promise +} + +export function replaceInstalledPackages( + stages: PptPackageStage[], + options?: PptPackageProjectionOptions +): Promise diff --git a/scripts/ppt-package-projection.mjs b/scripts/ppt-package-projection.mjs new file mode 100644 index 000000000..8a3fc7d62 --- /dev/null +++ b/scripts/ppt-package-projection.mjs @@ -0,0 +1,59 @@ +import fs from 'node:fs/promises' +import path from 'node:path' + +async function pathExists(candidate) { + try { + await fs.lstat(candidate) + return true + } catch (error) { + if (error?.code === 'ENOENT') return false + throw error + } +} + +/** Replace all generated package directories as one rollback-capable transaction. */ +export async function replaceInstalledPackages(stages, options = {}) { + const nodeModulesRoot = options.nodeModulesRoot ?? path.resolve('node_modules') + const prepared = [] + const moved = [] + let preserveBackups = false + try { + for (const { packageName, source } of stages) { + const target = path.join(nodeModulesRoot, packageName) + const temporary = path.join(nodeModulesRoot, `.${packageName}-generated-${process.pid}`) + const backup = path.join(nodeModulesRoot, `.${packageName}-backup-${process.pid}`) + await fs.rm(temporary, { recursive: true, force: true }) + await fs.rm(backup, { recursive: true, force: true }) + await fs.cp(source, temporary, { recursive: true }) + prepared.push({ packageName, target, temporary, backup }) + } + + for (const [index, item] of prepared.entries()) { + await options.beforeReplace?.(item.packageName, index) + item.hadTarget = await pathExists(item.target) + if (item.hadTarget) await fs.rename(item.target, item.backup) + moved.push(item) + await fs.rename(item.temporary, item.target) + } + } catch (error) { + const rollbackErrors = [] + for (const item of moved.reverse()) { + try { + await fs.rm(item.target, { recursive: true, force: true }) + if (item.hadTarget && await pathExists(item.backup)) await fs.rename(item.backup, item.target) + } catch (rollbackError) { + rollbackErrors.push(rollbackError) + } + } + if (rollbackErrors.length > 0) { + preserveBackups = true + throw new AggregateError([error, ...rollbackErrors], 'PPT package projection failed and rollback was incomplete') + } + throw error + } finally { + for (const item of prepared) { + await fs.rm(item.temporary, { recursive: true, force: true }) + if (!preserveBackups) await fs.rm(item.backup, { recursive: true, force: true }) + } + } +} diff --git a/scripts/prepare-ppt-runtime.mjs b/scripts/prepare-ppt-runtime.mjs new file mode 100644 index 000000000..81adcc530 --- /dev/null +++ b/scripts/prepare-ppt-runtime.mjs @@ -0,0 +1,37 @@ +/** Generate templates and assemble the installed PPT runtime from a clean staging root. */ +import { rm, mkdir } from 'node:fs/promises' +import { spawn } from 'node:child_process' +import path from 'node:path' + +const outputRoot = path.resolve('.build/ppt-runtime') +const templateRoot = path.join(outputRoot, 'templates') + +// npm prepends node_modules/.bin to PATH, which can shadow the real `node` binary +// with the `node` npm package. Use npm_node_execpath (set by npm to the actual Node +// running npm itself) so child scripts resolve modules against the real installation. +const nodeExec = process.env.npm_node_execpath ?? process.execPath + +function run(script) { + return new Promise((resolve, reject) => { + const child = spawn(nodeExec, [path.resolve(script)], { + stdio: 'inherit', + env: { ...process.env, DSH_PPT_TEMPLATE_OUTPUT: templateRoot } + }) + child.once('error', reject) + child.once('exit', (code, signal) => { + if (code === 0) resolve() + else reject(new Error(script + ' failed (' + (signal ?? ('exit ' + code)) + ')')) + }) + }) +} + +await rm(outputRoot, { recursive: true, force: true }) +await mkdir(templateRoot, { recursive: true }) +for (const script of [ + 'scripts/generate-zara-ppt-templates.mjs', + 'scripts/localize-ppt-templates.mjs', + 'scripts/enrich-ppt-templates.mjs', + 'scripts/build-ppt-runtime.mjs' +]) { + await run(script) +} diff --git a/scripts/verify-packaged-ppt-runtime.cjs b/scripts/verify-packaged-ppt-runtime.cjs new file mode 100644 index 000000000..3c8e120ca --- /dev/null +++ b/scripts/verify-packaged-ppt-runtime.cjs @@ -0,0 +1,90 @@ +const fs = require('node:fs/promises') +const path = require('node:path') +const { createRequire } = require('node:module') +const { execFile } = require('node:child_process') +const { pathToFileURL } = require('node:url') +const { promisify } = require('node:util') + +const execFileAsync = promisify(execFile) + +async function countFiles(root, suffix) { + let count = 0 + for (const entry of await fs.readdir(root, { withFileTypes: true })) { + const child = path.join(root, entry.name) + if (entry.isDirectory()) count += await countFiles(child, suffix) + else if (entry.isFile() && entry.name.endsWith(suffix)) count++ + } + return count +} + +async function verifyRuntime(appRoot) { + for (const packageName of ['dsh-ppt', 'dsh-ppt-composer']) { + const packageRoot = path.join(appRoot, 'node_modules', packageName) + const info = await fs.lstat(packageRoot) + if (info.isSymbolicLink()) throw new Error(packageName + ' was packaged as a checkout symlink') + const manifest = JSON.parse(await fs.readFile(path.join(packageRoot, 'package.json'), 'utf8')) + if (manifest.name !== packageName) throw new Error(packageName + ' manifest is missing or mismatched') + await fs.access(path.join(packageRoot, 'lib', 'client.js')) + await fs.access(path.join(packageRoot, 'cordis.patch.yml')) + } + + const core = path.join(appRoot, 'node_modules', 'dsh-ppt') + const adapter = path.join(appRoot, 'node_modules', 'dsh-ppt-composer') + const references = path.join(core, 'skills', 'dsh-ppt', 'references') + await fs.access(path.join(core, 'skills', 'dsh-ppt', 'SKILL.md')) + + const adapterRequire = createRequire(path.join(adapter, 'package.json')) + const resolvedCore = await fs.realpath(adapterRequire.resolve('dsh-ppt/package.json')) + if (resolvedCore !== await fs.realpath(path.join(core, 'package.json'))) { + throw new Error('Packaged dsh-ppt-composer does not resolve its staged dsh-ppt sibling') + } + + const coreRequire = createRequire(path.join(core, 'package.json')) + const sharp = coreRequire('sharp') + if (!sharp?.versions?.vips) throw new Error('Packaged dsh-ppt cannot load the sharp native runtime') + await import(pathToFileURL(path.join(core, 'lib', 'index.js')).href) + await import(pathToFileURL(path.join(adapter, 'lib', 'index.js')).href) + + const { definitions } = await import(pathToFileURL(path.join(core, 'lib', 'catalog.js')).href) + if (!Array.isArray(definitions) || definitions.length !== 16) { + throw new Error('Packaged dsh-ppt catalog does not contain sixteen templates') + } + for (const definition of definitions) { + await fs.access(path.join(references, definition.referenceDirectory, 'source', 'deck.pptd')) + await fs.access(path.join(references, definition.referenceDirectory, 'source-zh', 'deck.pptd')) + } + + const { previewFiles } = await import(pathToFileURL(path.join(core, 'lib', 'preview-manifest.js')).href) + for (const relative of Object.values(previewFiles)) await fs.access(path.join(references, relative)) + const previewCount = await countFiles(references, '.jpg') + if (previewCount !== 192) throw new Error('Packaged dsh-ppt contains ' + previewCount + ' previews; expected 192') +} + +module.exports = async function verifyPackagedPptRuntime(context) { + const product = context.packager.appInfo.productFilename + const macContents = path.join(context.appOutDir, product + '.app', 'Contents') + const candidates = [ + path.join(context.appOutDir, 'resources', 'app'), + path.join(macContents, 'Resources', 'app'), + path.join(context.appOutDir, 'resources', 'app.asar.unpacked'), + path.join(macContents, 'Resources', 'app.asar.unpacked') + ] + const appRoot = candidates.find(candidate => require('node:fs').existsSync(candidate)) + if (!appRoot) throw new Error('Cannot locate the packaged physical runtime') + const executable = path.join(appRoot, 'node_modules', 'node', 'bin', process.platform === 'win32' ? 'node.exe' : 'node') + if (!require('node:fs').existsSync(executable)) throw new Error('Cannot locate the packaged Node runtime') + // Harness needs physical package paths. Electron's ASAR-aware filesystem + // would incorrectly accept generated plugins left entirely in app.asar. + await execFileAsync(executable, [__filename, '--verify-runtime', appRoot], { + cwd: appRoot, + timeout: 120_000, + maxBuffer: 1024 * 1024 + }) +} + +if (require.main === module && process.argv[2] === '--verify-runtime') { + verifyRuntime(path.resolve(process.argv[3])).catch(error => { + console.error(error) + process.exitCode = 1 + }) +} diff --git a/src/main/index.ts b/src/main/index.ts index c6feda118..2e2b8f788 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -1,4 +1,6 @@ import { initializeDesktopService, desktopDiagnostics } from './desktop-service' +import { applyMacosWindowBackdrop } from './macos-window-backdrop' +import { runtimePackageRoot } from './runtime-package-root' import { checkBlockingPluginUpdates, selectPluginRecoveryTarget, PluginRecoveryEvidence, planPluginRecovery, runPluginRecoveryPlan, type PluginRecoveryCheck } from './plugin-recovery-market' import { RepairAgentService, type CrashEvidence } from './repair-agent' import { spawn } from 'node:child_process' @@ -95,6 +97,7 @@ import { resetPluginProfile } from './state/plugin-recovery' import { ensureSafeModeProfile, SAFE_MODE_PROFILE } from './state/safe-mode-profile' +import { migrateLegacyAgentPresets } from './state/legacy-preset-migration' import { WindowStateManager } from './state/window-state' import { isProjectedGenerationPlugin, @@ -499,7 +502,8 @@ function windowsTitleBarOverlay(isDark: boolean): Electron.TitleBarOverlayOption function applyWindowChromeTheme(window: BrowserWindow, isDark: boolean): void { if (window.isDestroyed()) return - window.setBackgroundColor(isDark ? '#141416' : '#ffffff') + if (process.platform === 'darwin') applyMacosWindowBackdrop(window, isDark) + else window.setBackgroundColor(isDark ? '#141416' : '#ffffff') if (process.platform === 'win32') { windowsMenuDark = isDark window.setTitleBarOverlay(windowsTitleBarOverlay(isDark)) @@ -600,34 +604,11 @@ function configureAppIdentity(): void { async function syncNativeTheme(window: BrowserWindow): Promise { if (window.isDestroyed()) return - // The sidebar already reserves enough room for macOS traffic lights. Read - // Harness's resolved theme before showing the window so the native surface - // matches the first rendered frame. The transparent drag strip restores the - // native window gesture without adding a visual titlebar or covering the - // traffic lights and right-side header actions. + // Harness's marked chrome rows own window dragging. Its resolved body theme + // also works when macOS renders a transparent page over native vibrancy. const isDark = await window.webContents.executeJavaScript( `(() => { - if (${process.platform === 'darwin'}) { - let dragRegion = document.getElementById('dsh-desktop-drag-region') - if (!dragRegion) { - dragRegion = document.createElement('div') - dragRegion.id = 'dsh-desktop-drag-region' - dragRegion.setAttribute('aria-hidden', 'true') - Object.assign(dragRegion.style, { - position: 'fixed', - zIndex: '18', - top: '0', - left: '80px', - right: '220px', - height: '24px', - background: 'transparent', - pointerEvents: 'auto', - userSelect: 'none' - }) - dragRegion.style.setProperty('-webkit-app-region', 'drag') - document.body.appendChild(dragRegion) - } - } + if (${process.platform === 'darwin'}) return document.body.hasAttribute('data-ds-dark-theme') if (document.body.hasAttribute('data-ds-dark-theme')) return true const color = getComputedStyle(document.body).backgroundColor const channels = color.match(/[\\d.]+/g)?.slice(0, 3).map(Number) @@ -641,24 +622,17 @@ async function syncNativeTheme(window: BrowserWindow): Promise { applyWindowChromeTheme(window, isDark) } +function bundledRuntimeRoot(): string { + return runtimePackageRoot(app.getAppPath(), app.isPackaged) +} + function dshEntryPath(): string { - if (app.isPackaged) { - return join( - process.resourcesPath, - 'app', - 'node_modules', - '@deepseek-ai', - 'dsh', - 'lib', - 'bin.js' - ) - } - return join(app.getAppPath(), 'node_modules', '@deepseek-ai', 'dsh', 'lib', 'bin.js') + return join(bundledRuntimeRoot(), 'node_modules', '@deepseek-ai', 'dsh', 'lib', 'bin.js') } function bundledNodePath(): string { const executable = process.platform === 'win32' ? 'node.exe' : 'node' - return join(app.getAppPath(), 'node_modules', 'node', 'bin', executable) + return join(bundledRuntimeRoot(), 'node_modules', 'node', 'bin', executable) } /** @@ -669,7 +643,7 @@ function bundledNodePath(): string { */ function bundledPnpmRunnerPath(): string { return join( - app.getAppPath(), + bundledRuntimeRoot(), 'node_modules', 'dsh-desktop-market-installer', 'pnpm-runner.mjs' @@ -677,7 +651,7 @@ function bundledPnpmRunnerPath(): string { } function bundledPnpmEntryPath(): string { - const root = join(app.getAppPath(), 'node_modules', 'pnpm', 'bin') + const root = join(bundledRuntimeRoot(), 'node_modules', 'pnpm', 'bin') const candidates = [join(root, 'pnpm.cjs'), join(root, 'pnpm.mjs')] return candidates.find((candidate) => existsSync(candidate)) ?? join(root, 'pnpm.cjs') } @@ -720,7 +694,7 @@ function desktopIconPath(): string { function dshBrandLogoPath(variant: 'light' | 'dark'): string { return join( - app.getAppPath(), + bundledRuntimeRoot(), 'node_modules', '@deepseek-ai', 'dsh-web-frontend', @@ -1062,8 +1036,12 @@ function createWindow(): BrowserWindow { show: false, title: '', icon: desktopIconPath(), - frame: process.platform !== 'darwin', - ...(process.platform === 'darwin' ? { titleBarStyle: 'hidden' as const } : {}), + ...(process.platform === 'darwin' ? { + titleBarStyle: 'hiddenInset' as const, + trafficLightPosition: { x: 16, y: 18 }, + vibrancy: 'sidebar' as const, + visualEffectState: 'active' as const + } : {}), ...(isWindows ? { titleBarStyle: 'hidden' as const, @@ -1071,7 +1049,7 @@ function createWindow(): BrowserWindow { autoHideMenuBar: true } : {}), - backgroundColor: nativeTheme.shouldUseDarkColors ? '#141416' : '#f8f8f6', + backgroundColor: process.platform === 'darwin' ? '#00000000' : nativeTheme.shouldUseDarkColors ? '#141416' : '#f8f8f6', webPreferences: { contextIsolation: true, nodeIntegration: false, @@ -1082,18 +1060,18 @@ function createWindow(): BrowserWindow { }) if (process.platform === 'darwin') { window.setWindowButtonVisibility(true) - // Match the sidebar inset at the current zoom, with a 2px optical correction - // for the round native buttons relative to the logo's visible left edge. - const alignWindowButtons = (): void => { + const applyBackdrop = (): void => applyMacosWindowBackdrop(window, nativeTheme.shouldUseDarkColors) + window.on('minimize', applyBackdrop) + window.on('hide', applyBackdrop) + window.on('restore', applyBackdrop) + window.on('show', applyBackdrop) + const syncFullscreen = (): void => { if (window.isDestroyed()) return - window.setWindowButtonPosition({ - x: Math.round(16 * window.webContents.getZoomFactor()) - 2, - y: 9 - }) + window.webContents.send('dsh-desktop:window-fullscreen', window.isFullScreen()) } - alignWindowButtons() - window.webContents.on('did-finish-load', alignWindowButtons) - window.webContents.on('zoom-changed', () => setImmediate(alignWindowButtons)) + window.webContents.on('did-finish-load', syncFullscreen) + window.on('enter-full-screen', syncFullscreen) + window.on('leave-full-screen', syncFullscreen) } else if (isWindows) { window.setMenuBarVisibility(false) } @@ -1559,7 +1537,10 @@ function launchHarness(): Promise { ) }) desktopStorageManager?.switchProfile(join(dshHome, 'profiles', 'web')) + runtime.note('[desktop] starting preset migrations') await migratePersonaPrefixesBeforeStart(dshHome) + await migrateLegacyAgentPresets(dshHome, (line) => runtime.note(line)) + runtime.note('[desktop] preset migrations done; starting Harness') await runtime.start(launchDirectory) // A failed launch must not rewrite the user's enabled plugin set. Recovery @@ -1876,7 +1857,7 @@ function registerHarnessHandlers(): void { return { desktopVersion: app.getVersion(), harnessVersion: - bundledHarnessVersion(app.getAppPath()) ?? (locale === 'zh' ? '未知' : 'Unknown'), + bundledHarnessVersion(bundledRuntimeRoot()) ?? (locale === 'zh' ? '未知' : 'Unknown'), locale } }) @@ -1938,7 +1919,7 @@ async function showAbout(window: BrowserWindow): Promise { const info = { desktopVersion: app.getVersion(), harnessVersion: - bundledHarnessVersion(app.getAppPath()) ?? (locale === 'zh' ? '未知' : 'Unknown'), + bundledHarnessVersion(bundledRuntimeRoot()) ?? (locale === 'zh' ? '未知' : 'Unknown'), locale } if (window && !window.isDestroyed() && window.webContents && !window.webContents.isDestroyed()) { @@ -1957,7 +1938,7 @@ async function showAbout(window: BrowserWindow): Promise { message: locale === 'zh' ? '关于 DSH Desktop' : 'About DSH Desktop', detail: aboutDetail( app.getVersion(), - bundledHarnessVersion(app.getAppPath()), + bundledHarnessVersion(bundledRuntimeRoot()), locale ), buttons: [checkForUpdatesLabel, locale === 'zh' ? '关闭' : 'Close'], @@ -2104,6 +2085,8 @@ async function waitForPluginRecoveryAction(options: { function showUnexpectedError(error: unknown): void { const message = error instanceof Error ? error.stack ?? error.message : String(error) + runtime?.note(`[desktop] unexpected error: ${message}`) + console.error('[desktop] unexpected error:', message) dialog.showErrorBox('DSH Desktop encountered an error', message) } @@ -2161,7 +2144,7 @@ async function showPluginRecovery(options?: { startupFailures: followRendererLogs ? undefined : snapshot.pluginFailures, readLatestLogs: followRendererLogs ? () => rendererPluginFailureLogs : undefined, excludedPlugins: removedPlugins, - slotProviderNodeModulesPaths: [join(app.getAppPath(), 'node_modules')], + slotProviderNodeModulesPaths: [join(bundledRuntimeRoot(), 'node_modules')], timeoutMs: waitForRendererEvidence ? PLUGIN_RECOVERY_EVIDENCE_TIMEOUT_MS : 0 }) detection.plugins = evidence.targets(detection.plugins, removedPlugins) @@ -2194,7 +2177,7 @@ async function showPluginRecovery(options?: { if (applyPendingFrontendEvidence()) continue const runtimeVersion = - (await readBundledDshVersion(join(app.getAppPath(), 'node_modules'))) || '0.1.2-alpha.1' + (await readBundledDshVersion(join(bundledRuntimeRoot(), 'node_modules'))) || '0.1.2-alpha.1' const pluginChecks = await checkBlockingPluginUpdates({ plugins: detection.plugins, attemptedUpgrades, @@ -2392,7 +2375,7 @@ async function showPluginRecovery(options?: { const compatibility = await inspectProfileCompatibility( dshHome, - join(app.getAppPath(), 'node_modules') + join(bundledRuntimeRoot(), 'node_modules') ) evidence.inspect(compatibility.issues) const blockingIssues = compatibility.issues.filter((issue) => issue.severity === 'blocking') @@ -2455,7 +2438,7 @@ async function showPluginRecovery(options?: { } const compatibility = await inspectProfileCompatibility( dshHome, - join(app.getAppPath(), 'node_modules') + join(bundledRuntimeRoot(), 'node_modules') ) evidence.inspect(compatibility.issues) const blockingIssues = compatibility.issues.filter((issue) => issue.severity === 'blocking') @@ -2717,7 +2700,7 @@ async function removeProfilePluginCompletely( await markProfileInstallComplete(dshHome) const compatibility = await inspectProfileCompatibility( dshHome, - join(app.getAppPath(), 'node_modules') + join(bundledRuntimeRoot(), 'node_modules') ) runtime.note( `[${logPrefix}] rebuilt the web profile after removing ${pluginName}; ` + @@ -2794,7 +2777,7 @@ async function showSafeModeManager(initial?: { pendingRemovals = await listPendingPluginRemovals(dshHome) compatibility = await inspectProfileCompatibility( dshHome, - join(app.getAppPath(), 'node_modules') + join(bundledRuntimeRoot(), 'node_modules') ) } } catch (error) { @@ -2826,7 +2809,7 @@ async function showSafeModeManager(initial?: { healthCheck = checkupAllProfilePlugins({ plugins: active, dshHome, - bundledNodeModulesPath: join(app.getAppPath(), 'node_modules'), + bundledNodeModulesPath: join(bundledRuntimeRoot(), 'node_modules'), incompatiblePlugins: [...new Set([...safeModeSuspectedPlugins, ...incompatiblePluginNames])], failureTtlMs: SAFE_MODE_MARKET_FAILURE_TTL_MS, fetchFn: (input, init) => net.fetch(input instanceof URL ? input.href : input, init), @@ -3452,7 +3435,7 @@ async function bootstrap(): Promise { }, workspaceDirectory: join(app.getPath('userData'), 'harness'), harnessLogPath: join(app.getPath('logs'), 'harness.log'), - shippedPresetsDirectory: join(app.getAppPath(), 'node_modules', '@deepseek-ai', 'dsh-agent-presets', 'presets'), + shippedPresetsDirectory: join(bundledRuntimeRoot(), 'node_modules', '@deepseek-ai', 'dsh-agent-presets', 'presets'), locale: harnessLocale, crashEvidence: () => lastCrashEvidence, appVersion: () => app.getVersion() @@ -3643,7 +3626,7 @@ async function bootstrap(): Promise { } const compatibility = await inspectProfileCompatibility( dshHome, - join(app.getAppPath(), 'node_modules') + join(bundledRuntimeRoot(), 'node_modules') ) if (compatibility.issues.some((issue) => issue.severity === 'blocking')) { void showSafeModeManager().catch(showUnexpectedError) diff --git a/src/main/macos-window-backdrop.ts b/src/main/macos-window-backdrop.ts new file mode 100644 index 000000000..de6eca816 --- /dev/null +++ b/src/main/macos-window-backdrop.ts @@ -0,0 +1,16 @@ +import type { BrowserWindow } from 'electron' + +/** Match Harness's native sidebar material and avoid transparent restore flashes. */ +export function applyMacosWindowBackdrop( + window: Pick, + isDark: boolean +): void { + if (window.isDestroyed()) return + if (window.isMinimized() || !window.isVisible()) { + window.setVibrancy(null) + window.setBackgroundColor(isDark ? '#1b1b1c' : '#f9fafb') + } else { + window.setVibrancy('sidebar') + window.setBackgroundColor('#00000000') + } +} diff --git a/src/main/runtime/harness-runtime.ts b/src/main/runtime/harness-runtime.ts index 64063d25b..059b20fbd 100644 --- a/src/main/runtime/harness-runtime.ts +++ b/src/main/runtime/harness-runtime.ts @@ -304,9 +304,8 @@ export function buildHarnessSpawnOptions( const pathApi = platform === 'win32' ? win32 : posix // ELECTRON_RUN_AS_NODE must not reach the Harness process itself: the macOS - // utility process is launched with Chromium switches (--type=utility, …) - // that Node rejects as bad options. The Harness entry re-declares Node mode - // from the inside, for its children only. + // utility process starts with Chromium switches that Node rejects. The + // Harness entry declares Node mode only for its Electron children. // // On Windows, `detached: true` puts the Harness in its own process group // and console. Without it, a child process that calls `os.kill(pid, 0)` @@ -463,7 +462,7 @@ export class HarnessRuntime { return } if (!existsSync(this.options.nodeExecutablePath)) { - this.setState('failed', `Bundled Node.js runtime was not found: ${this.options.nodeExecutablePath}`) + this.setState('failed', `Harness Node executable was not found: ${this.options.nodeExecutablePath}`) return } if (!existsSync(this.options.nodeEntryPath)) { @@ -482,7 +481,7 @@ export class HarnessRuntime { await mkdir(this.options.dshHome, { recursive: true }) const patchPath = profile === SAFE_MODE_PROFILE ? sourcePatchPath - : await prepareHostPluginSourcesPatch(this.options.dshHome, sourcePatchPath) + : await prepareHostPluginSourcesPatch(this.options.dshHome, sourcePatchPath, this.options.dshEntryPath) const marketPatchPath = this.options.dshMarketPatchPath const patchPaths = profile !== SAFE_MODE_PROFILE && marketPatchPath !== undefined && diff --git a/src/main/state/generation-migration.ts b/src/main/state/generation-migration.ts index f51dbf5e1..b5f2ebda5 100644 --- a/src/main/state/generation-migration.ts +++ b/src/main/state/generation-migration.ts @@ -511,7 +511,7 @@ async function rewriteManifest(dshHome: string): Promise { for (const [name, spec] of Object.entries(snapshot.dependencies ?? {})) { if (KEEP_IN_SHARED_TREE.has(name)) keptDeps[name] = spec as string } - if (keptDeps.dshmarket === undefined) keptDeps.dshmarket = '^1.45.1' + if (keptDeps.dshmarket === undefined) keptDeps.dshmarket = '^1.65.1' // Bundles are left to projection, which runs next and knows the generations. // Here we only trim to the shared-tree packages and keep in-box bundles. diff --git a/src/main/state/host-plugin-sources.ts b/src/main/state/host-plugin-sources.ts index 8a96e4bec..ebef7adc3 100644 --- a/src/main/state/host-plugin-sources.ts +++ b/src/main/state/host-plugin-sources.ts @@ -1,7 +1,7 @@ import { randomUUID } from 'node:crypto' import { createRequire } from 'node:module' import { readFile, rename, rm, writeFile } from 'node:fs/promises' -import { dirname, join } from 'node:path' +import { join } from 'node:path' import { pathToFileURL } from 'node:url' import { isMap, isScalar, isSeq, parseDocument } from 'yaml' import { readDisabledHostPlugins } from './host-plugin-state' @@ -73,7 +73,8 @@ function withoutDisabledInsertions(source: string, disabled: readonly string[]): */ export async function prepareHostPluginSourcesPatch( dshHome: string, - desktopPatchPath: string + desktopPatchPath: string, + hostModuleAnchor: string ): Promise { const original = await readFile(desktopPatchPath, 'utf8') const source = withoutDisabledInsertions( @@ -82,11 +83,18 @@ export async function prepareHostPluginSourcesPatch( ) const names = hostPluginNames(source) if (names.length === 0 && source === original) return desktopPatchPath - const appManifest = join(dirname(desktopPatchPath), '..', 'package.json') - const resolveHost = createRequire(appManifest).resolve + // Packaged patches live in resources, while dependencies live under + // app.asar.unpacked. Use the same installation anchor as Harness itself. + const resolveHost = createRequire(hostModuleAnchor).resolve let text = source for (const { name, start, end } of names.reverse()) { - const sourceUrl = pathToFileURL(resolveHost(name)).href + let sourceUrl: string + try { + sourceUrl = pathToFileURL(resolveHost(name)).href + } catch (cause) { + const detail = cause instanceof Error ? cause.message : String(cause) + throw new Error(`Desktop host plugin source resolution failed for ${name} from ${hostModuleAnchor}: ${detail}`, { cause }) + } text = text.slice(0, start) + JSON.stringify(sourceUrl) + text.slice(end) } const outputPath = join(dshHome, 'desktop-host-sources.patch.yml') diff --git a/src/main/state/legacy-preset-migration.ts b/src/main/state/legacy-preset-migration.ts new file mode 100644 index 000000000..333437d35 --- /dev/null +++ b/src/main/state/legacy-preset-migration.ts @@ -0,0 +1,121 @@ +import { constants } from 'node:fs' +import { cp, copyFile, mkdir, readFile, readdir, rename, rm, stat } from 'node:fs/promises' +import { join } from 'node:path' +import { isSeq, parse, parseDocument } from 'yaml' +import { writeTextAtomically } from './persona-prefix-migration' + +const PRESET_ID = /^[a-z0-9][a-z0-9-]*$/ +const START = '# dsh-desktop legacy presets begin' +const END = '# dsh-desktop legacy presets end' +const BUILT_IN_PRESETS = new Set(['standard', 'ptc', 'minimal', 'cordis']) + +function yamlString(value: string): string { + return JSON.stringify(value) +} + +/** Preserve the original composition text, including Cordis !!js expressions. */ +function presetPatch(id: string, composition: string, metadata: unknown): string { + const data = typeof metadata === 'object' && metadata !== null ? metadata as Record : {} + const fields = [` id: ${id}`] + for (const key of ['name', 'description'] as const) { + if (typeof data[key] === 'string') fields.push(` ${key}: ${yamlString(data[key])}`) + } + if (typeof data.order === 'number' && Number.isFinite(data.order)) fields.push(` order: ${data.order}`) + const rows = composition.trimEnd().split(/\r?\n/u).map((line) => line.length ? ` ${line}` : '').join('\n') + const header = BUILT_IN_PRESETS.has(id) + ? `- id: preset-${id}\n config:` + : `- insert:\n - id: preset-${id}\n name: '@deepseek-ai/dsh-agent-preset'\n config:` + const indent = BUILT_IN_PRESETS.has(id) ? '' : ' ' + return `${header}\n${fields.map((line) => indent + line).join('\n')}\n${indent} plugins:\n${rows.split('\n').map((line) => indent + line).join('\n')}\n` +} + +/** Publish old directory presets into the 0.1.7 profile without touching their source. */ +export async function migrateLegacyAgentPresets(dshHome: string, note: (line: string) => void): Promise { + const sourceRoot = join(dshHome, '.agent-presets') + let entries + try { + entries = await readdir(sourceRoot, { withFileTypes: true }) + } catch (error) { + if ((error as NodeJS.ErrnoException).code === 'ENOENT') return + throw error + } + const sections: Array<{ id: string; patch: string }> = [] + for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) { + if (!entry.isDirectory() || !PRESET_ID.test(entry.name)) continue + try { + const composition = await readFile(join(sourceRoot, entry.name, 'agent.cordis.yml'), 'utf8') + const document = parseDocument(composition.replace(/^\uFEFF/u, '')) + if (document.errors.length || !isSeq(document.contents)) throw new Error('agent.cordis.yml must contain a YAML plugin list') + const metadata = await readFile(join(sourceRoot, entry.name, 'preset.yml'), 'utf8') + .then((text) => parse(text) as unknown) + .catch((error: unknown) => { + if ((error as NodeJS.ErrnoException).code === 'ENOENT') return {} + throw error + }) + sections.push({ id: entry.name, patch: presetPatch(entry.name, composition, metadata) }) + } catch (error) { + note(`[desktop] legacy preset ${entry.name} could not be converted: ${error instanceof Error ? error.message : String(error)}`) + } + } + if (sections.length === 0) return + + const profilePatch = join(dshHome, 'profiles', 'web', 'cordis.patch.yml') + await mkdir(join(dshHome, 'profiles', 'web'), { recursive: true }) + const previous = await readFile(profilePatch, 'utf8').catch((error: unknown) => { + if ((error as NodeJS.ErrnoException).code === 'ENOENT') return '' + throw error + }) + // A fresh Profile may contain comments followed by `[]`. Appending block + // entries after that flow sequence creates a second YAML root document. + const previousDocument = parseDocument(previous) + const emptyFlowList = previousDocument.errors.length === 0 && isSeq(previousDocument.contents) && + previousDocument.contents.items.length === 0 && previousDocument.contents.flow + const emptyListRange = emptyFlowList ? previousDocument.contents?.range : undefined + const base = emptyListRange && previous.slice(emptyListRange[0], emptyListRange[1]).trim() === '[]' + ? previous.slice(0, emptyListRange[0]) + previous.slice(emptyListRange[1]) + : previous + const start = base.indexOf(START) + const end = base.indexOf(END) + if ((start === -1) !== (end === -1) || (start !== -1 && end < start)) { + throw new Error('legacy preset section in the web Profile patch is incomplete') + } + // A converted row belongs to the new Profile from now on. Preserve edits + // made through the new editor; only append legacy IDs not yet present. + const existingIds = new Set( + [...base.matchAll(/^(?:- id:| - id:) preset-([a-z0-9-]+)\s*$/gmu)].map((match) => match[1]) + ) + const pending = sections.filter(({ id }) => !existingIds.has(id)) + if (pending.length === 0) return + const generated = start === -1 ? '' : base.slice(start + START.length, end).trim() + const withoutGenerated = start === -1 ? base : base.slice(0, start) + base.slice(end + END.length).replace(/^\r?\n/u, '') + const generatedRows = [generated, ...pending.map(({ patch }) => patch.trimEnd())].filter(Boolean).join('\n\n') + const next = `${withoutGenerated.trimEnd()}\n\n${START}\n${generatedRows}\n${END}\n` + if (next === previous) return + + const backupRoot = join(dshHome, '.agent-presets.pre-0.1.7-backup') + const backupExists = await stat(backupRoot).then(() => true).catch((error: unknown) => { + if ((error as NodeJS.ErrnoException).code === 'ENOENT') return false + throw error + }) + if (!backupExists) { + const staging = `${backupRoot}.${process.pid}.${Date.now()}.tmp` + try { + await cp(sourceRoot, staging, { recursive: true, errorOnExist: true, force: false, dereference: false }) + await rename(staging, backupRoot) + } catch (error) { + await rm(staging, { recursive: true, force: true }) + throw error + } + } + if (previous) { + try { + await copyFile(profilePatch, `${profilePatch}.pre-0.1.7-backup`, constants.COPYFILE_EXCL) + } catch (error) { + if ((error as NodeJS.ErrnoException).code !== 'EEXIST') throw error + } + } + const document = parseDocument(next) + if (document.errors.length || !isSeq(document.contents)) throw new Error('converted preset patch is not a YAML patch list') + await writeTextAtomically(profilePatch, next) + note(`[desktop] converted ${pending.length} legacy agent presets for the web Profile; originals and backup retained`) +} diff --git a/src/main/state/market-baseline.ts b/src/main/state/market-baseline.ts index 666b61101..3ecc615b2 100644 --- a/src/main/state/market-baseline.ts +++ b/src/main/state/market-baseline.ts @@ -1,13 +1,13 @@ import { lstat, readFile, readlink, realpath, rm, writeFile } from 'node:fs/promises' import { dirname, join } from 'node:path' -import { healProfilesModuleFallback, resolveBundleDir } from '@deepseek-ai/dsh-app-boot' +import { resolveBundleDir } from '@deepseek-ai/dsh-app-boot' import { listGenerations, readDesired, writeDesired } from 'dsh-desktop-market-installer/generations/registry' import { compareSemver, parseSemver, readInstalledPluginVersion } from './plugin-market-check' import { profilePackageJsonPath } from './plugin-recovery' import { clearProfileInstallMarker } from './profile-install-marker' import { hasPendingMarketInstall, upgradeMarketInSharedTree, type MarketSharedTreeUpgradeOptions } from './plugin-upgrade' -export const VERIFIED_MARKET_BASELINE = '1.45.1' +export const VERIFIED_MARKET_BASELINE = '1.65.1' const MARKET_PACKAGE = 'dshmarket' @@ -252,12 +252,6 @@ export async function ensureMarketBaseline( await writeFile(workspaceYamlPath, 'packages:\n - .\n\nnodeLinker: hoisted\nautoInstallPeers: false\n', 'utf8') } - // This normally happens inside Harness boot, which has not run yet. Ensure - // generation peer validation sees this installation's host packages first. - await healProfilesModuleFallback({ - installAnchor, - home: options.dshHome - }) await clearProfileInstallMarker(options.dshHome) const result = await upgrade({ ...options, targetVersion }) if (!result.ok) throw new Error(result.detail ?? 'dshmarket installation failed') diff --git a/src/preload/index.ts b/src/preload/index.ts index 347abeb41..ca6e1b4d7 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -10,6 +10,18 @@ import { import { isPluginLoadError } from './plugin-error-view' import { findBootFailureText } from './boot-failure' import { mountWindowsTitlebarLayout } from './windows-titlebar' +import { mountMacosWindowChrome } from './macos-window-chrome' + +if (process.platform === 'darwin') { + const dispose = mountMacosWindowChrome(document, listener => { + const receive = (_event: Electron.IpcRendererEvent, value: unknown): void => { + if (typeof value === 'boolean') listener(value) + } + ipcRenderer.on('dsh-desktop:window-fullscreen', receive) + return () => ipcRenderer.removeListener('dsh-desktop:window-fullscreen', receive) + }) + window.addEventListener('unload', dispose, { once: true }) +} // Intercept and persist localStorage to disk storage before any page script executes setupDesktopStoragePersistence() @@ -148,7 +160,7 @@ function runDomSync(): void { } else checkBootFailureInDom() } -contextBridge.exposeInMainWorld('dshDesktopDirectoryPicker', { +contextBridge.exposeInMainWorld('__DSH_DIRECTORY_PICKER__', { pick: (): Promise => ipcRenderer.invoke('directory-picker:open') }) diff --git a/src/preload/macos-window-chrome.ts b/src/preload/macos-window-chrome.ts new file mode 100644 index 000000000..a62861d9d --- /dev/null +++ b/src/preload/macos-window-chrome.ts @@ -0,0 +1,27 @@ +/** Enable Harness's native macOS layout before its client modules mount. */ +export function mountMacosWindowChrome( + doc: Document, + subscribe: (listener: (fullscreen: boolean) => void) => () => void +): () => void { + let fullscreen = false + const mark = (): void => { + const root = doc.documentElement + if (!root) return + // This host retains Harness's browser keyboard adapter, not the official + // desktop's native keyboard/settings bridge. Layout and keyboard are separate. + root.dataset.dshDesktopWebShortcuts = 'true' + root.dataset.platform = 'darwin' + if (fullscreen) root.dataset.fullscreen = 'true' + else delete root.dataset.fullscreen + } + mark() + doc.addEventListener('DOMContentLoaded', mark, { once: true }) + const unsubscribe = subscribe(value => { + fullscreen = value + mark() + }) + return () => { + doc.removeEventListener('DOMContentLoaded', mark) + unsubscribe() + } +} diff --git a/src/preload/windows-titlebar.ts b/src/preload/windows-titlebar.ts index 96722943c..e4e11f9e1 100644 --- a/src/preload/windows-titlebar.ts +++ b/src/preload/windows-titlebar.ts @@ -54,7 +54,7 @@ function installLayout(document: Document): void { min-height: 0 !important; } :root { - --dsh-titlebar-safe-inset-top: 36px; + --dsh-titlebar-safe-inset-top: max(36px, env(titlebar-area-height, 36px)); --dsh-titlebar-safe-inset-right: calc(var(${CAPTION_WIDTH_PROPERTY}, 140px) + 44px); } body.dsh-desktop-windows-titlebar-layout [data-dsh-sidebar-root][data-dsh-sidebar-wide="true"] { @@ -67,50 +67,11 @@ function installLayout(document: Document): void { top: var(--dsh-titlebar-safe-inset-top, 36px) !important; height: calc(100% - var(--dsh-titlebar-safe-inset-top, 36px)) !important; } - body.dsh-desktop-windows-titlebar-layout [data-slot="conversation.session.header"] > header { - position: relative !important; + /* rc.2 owns the header outside the session slot. Keep all header + contributions in normal flow below the native caption/menu strip. */ + body.dsh-desktop-windows-titlebar-layout [data-dsh-conversation-header] { min-height: 76px !important; - padding-top: 6px !important; - padding-right: 20px !important; - box-sizing: border-box !important; - } - body.dsh-desktop-windows-titlebar-layout [data-slot="conversation.session.header"] > header > div:first-child { - padding-right: calc(var(${CAPTION_WIDTH_PROPERTY}, 140px) + 52px) !important; - box-sizing: border-box !important; - } - body.dsh-desktop-windows-titlebar-layout [data-slot="conversation.session.header"] > header div[data-conversation-header-corner], - body.dsh-desktop-windows-titlebar-layout [data-slot="conversation.session.header"] > header [class*="headerCorner"] { - position: absolute !important; - top: 38px !important; - right: 20px !important; - margin: 0 !important; - z-index: 20 !important; - display: flex !important; - align-items: center !important; - } - body.dsh-desktop-windows-titlebar-layout [data-slot="conversation.session.header"] > header [class*="headerUtilities"] { - position: absolute !important; - top: 38px !important; - right: 56px !important; - margin: 0 !important; - z-index: 20 !important; - display: flex !important; - align-items: center !important; - gap: 8px !important; - } - body.dsh-desktop-windows-titlebar-layout [data-slot="conversation.session.header"] > header [class*="headerUtilities"]:has(+ [data-conversation-header-corner]:empty), - body.dsh-desktop-windows-titlebar-layout [data-slot="conversation.session.header"] > header [class*="headerUtilities"]:has(+ [class*="headerCorner"]:empty), - body.dsh-desktop-windows-titlebar-layout [data-slot="conversation.session.header"] > header [class*="headerUtilities"]:has(+ div:empty), - body.dsh-desktop-windows-titlebar-layout [data-slot="conversation.session.header"] > header [class*="headerUtilities"]:last-child { - right: 20px !important; - } - body.dsh-desktop-windows-titlebar-layout [class*="headerUtilities"] button[aria-label="更多操作"], - body.dsh-desktop-windows-titlebar-layout [class*="headerUtilities"] button[aria-label="More actions"], - body.dsh-desktop-windows-titlebar-layout [class*="headerUtilities"] [class*="moreButton"] { - display: none !important; - } - body.dsh-desktop-windows-titlebar-layout [data-slot="conversation.session.header"] > header div[role="tablist"] { - padding-right: 180px !important; + padding-top: calc(var(--dsh-titlebar-safe-inset-top, 36px) + 6px) !important; box-sizing: border-box !important; } body.dsh-desktop-windows-titlebar-layout button, diff --git a/test/desktop-client-ui.test.ts b/test/desktop-client-ui.test.ts index 33a88bfd9..1129957fe 100644 --- a/test/desktop-client-ui.test.ts +++ b/test/desktop-client-ui.test.ts @@ -23,9 +23,11 @@ describe('DSH Desktop client slot occupants', () => { } } | undefined const appended: Array<{ textContent?: string }> = [] + const removeStyle = vi.fn() + let disposeStyle: (() => void) | undefined const document = { getElementById: vi.fn(() => null), - createElement: vi.fn(() => ({ id: '', dataset: {}, textContent: '' })), + createElement: vi.fn(() => ({ id: '', dataset: {}, textContent: '', remove: removeStyle })), head: { appendChild: (node: { textContent?: string }) => appended.push(node) } } vm.runInNewContext(source, { @@ -82,16 +84,23 @@ describe('DSH Desktop client slot occupants', () => { return () => undefined } } - plugin.apply({ slots }) + plugin.apply({ slots, effect: (setup: () => (() => void) | undefined) => { disposeStyle = setup() } }) - expect(plugin.inject).toEqual(['slots']) + expect(plugin.inject).toEqual(['slots', 'remote.session', 'sessions', 'uiWorkspace']) expect(registrations.map(({ config }) => config.name)).toEqual([ 'sidebar.brand.mark', 'sidebar.brand.name', - 'conversation.hero.brand.mark' + 'conversation.hero.brand.mark', + 'sidebar.right.tab.document.unpreviewable', + 'sidebar.workspaces.session.menu.item', + 'sidebar.workspaces.session.menu.item', + 'sidebar.workspaces.session.menu.item' ]) - // The mark is drawn in currentColor, so no theme stylesheet is injected. - expect(appended).toHaveLength(0) + // Desktop toolbar styles have an owned lifetime; branding stays in currentColor. + expect(appended).toHaveLength(1) + expect(appended[0]?.textContent).toContain("[data-dsh-preset-search]") + disposeStyle?.() + expect(removeStyle).toHaveBeenCalledOnce() const sidebarName = registrations.find( ({ config }) => config.name === 'sidebar.brand.name' diff --git a/test/download-artifact-ranges.test.mjs b/test/download-artifact-ranges.test.mjs new file mode 100644 index 000000000..c1ffe0851 --- /dev/null +++ b/test/download-artifact-ranges.test.mjs @@ -0,0 +1,51 @@ +import { createHash } from 'node:crypto' +import { mkdtemp, readFile, readdir, rm, writeFile } from 'node:fs/promises' +import { tmpdir } from 'node:os' +import { join } from 'node:path' +import { afterEach, expect, it } from 'vitest' +import { downloadInRanges } from '../scripts/download-artifact-ranges.mjs' + +const roots = [] +afterEach(async () => { await Promise.all(roots.splice(0).map(root => rm(root, {recursive:true,force:true}))) }) +const digest = bytes => `sha256:${createHash('sha256').update(bytes).digest('hex')}` +async function output() { + const root = await mkdtemp(join(tmpdir(), 'dsh-artifact-ranges-')) + roots.push(root) + return join(root, 'artifact.zip') +} + +it('assembles concurrently completed ranges in byte order and verifies the complete digest', async () => { + const bytes = Buffer.alloc(32 * 1024 * 1024 + 31, 37) + bytes.fill(93, 32 * 1024 * 1024) + const outputPath = await output() + const completed = [] + await downloadInRanges({size:bytes.length, digest:digest(bytes), outputPath, + downloadRange: async (start, end, path) => { + if (start === 0) await new Promise(resolve => setTimeout(resolve, 30)) + await writeFile(path, bytes.subarray(start, end + 1)) + completed.push(start) + } + }) + expect(completed).toEqual([32 * 1024 * 1024, 0]) + expect((await readFile(outputPath)).equals(bytes)).toBe(true) + expect(await readdir(roots[0])).toEqual(['artifact.zip']) +}) + +it.each(['short response', 'wrong digest', 'transport error'])('preserves an existing archive on %s and removes temporary parts', async failure => { + const outputPath = await output() + await writeFile(outputPath, 'previous verified archive') + await expect(downloadInRanges({size:3, digest:digest(Buffer.from('abc')), outputPath, + downloadRange: async (start, end, path) => { + if (failure === 'transport error') throw new Error('offline') + await writeFile(path, failure === 'short response' ? 'a' : 'xyz') + } + })).rejects.toThrow() + expect(await readFile(outputPath, 'utf8')).toBe('previous verified archive') + expect(await readdir(roots[roots.length - 1])).toEqual(['artifact.zip']) +}) + +it('rejects metadata without a SHA-256 digest before making any request', async () => { + let called = false + await expect(downloadInRanges({size:3, digest:null, outputPath:await output(), downloadRange:async () => {called=true}})).rejects.toThrow('SHA-256') + expect(called).toBe(false) +}) diff --git a/test/generation-installer.test.ts b/test/generation-installer.test.ts index 83e92ea00..a0231d332 100644 --- a/test/generation-installer.test.ts +++ b/test/generation-installer.test.ts @@ -549,6 +549,40 @@ describe('the generation installer', () => { ) }) + it('validates current host entries when legacy Profile links point at an older installation', async () => { + const home = await freshHome() + const checkout = join(home, 'current-installation') + const dshEntryPath = join(checkout, 'node_modules', '@deepseek-ai', 'dsh', 'lib', 'bin.js') + const directory = join(checkout, '.generations', 'plugin') + const plugin = join(directory, 'node_modules', 'root-plugin') + const name = '@deepseek-ai/dsh-llm' + const oldPackage = join(home, 'old-installation', 'node_modules', name) + const currentPackage = join(checkout, 'node_modules', name) + for (const root of [oldPackage, currentPackage]) { + await mkdir(root, { recursive: true }) + await writeFile(join(root, 'package.json'), JSON.stringify({ name, main: 'index.js' })) + await writeFile(join(root, 'index.js'), 'module.exports = {}') + } + const closure = join(home, 'profiles', 'node_modules') + await mkdir(join(closure, '@deepseek-ai'), { recursive: true }) + await symlink(oldPackage, join(closure, name), 'junction') + await mkdir(plugin, { recursive: true }) + await writeFile(join(plugin, 'package.json'), JSON.stringify({ name: 'root-plugin', peerDependencies: { [name]: '*' } })) + const generation = { id: 'plugin', pluginName: 'root-plugin', version: '1.0.0', directory } + expect((await verifyGenerationPeers(home, generation)).ok).toBe(false) + expect(await verifyGenerationPeers(home, generation, { dshEntryPath })).toEqual({ ok: true, problems: [] }) + + // Merely being in the current checkout does not authorize arbitrary dependencies. + const other = join(checkout, 'node_modules', 'unrelated') + await mkdir(other, { recursive: true }) + await writeFile(join(other, 'package.json'), JSON.stringify({ name: 'unrelated', main: 'index.js' })) + await writeFile(join(other, 'index.js'), 'module.exports = {}') + await writeFile(join(plugin, 'package.json'), JSON.stringify({ name: 'root-plugin', dependencies: { unrelated: '*' } })) + expect((await verifyGenerationPeers(home, generation, { dshEntryPath })).problems).toEqual([ + expect.stringContaining('unrelated resolves outside the generation and installation closure') + ]) + }) + it('validates host singletons declared by a transitive package, not only the root plugin', async () => { const home = await freshHome() const directory = join(home, 'profiles', '.generations', 'live', 'transitive-peer') @@ -636,6 +670,35 @@ describe('the generation installer', () => { ) }) + it('validates CLI-only host peers by their executable while retaining closure checks', async () => { + const home = await freshHome() + const directory = join(home, 'profiles', '.generations', 'live', 'cli-peer') + const plugin = join(directory, 'node_modules', 'root-plugin') + const host = join(home, 'profiles', 'node_modules', '@deepseek-ai', 'dsh') + await mkdir(plugin, { recursive: true }) + await mkdir(join(host, 'lib'), { recursive: true }) + await writeFile(join(plugin, 'package.json'), JSON.stringify({ name: 'root-plugin', + peerDependencies: { '@deepseek-ai/dsh': '>=0.1.7-rc.2' } })) + await writeFile(join(host, 'package.json'), JSON.stringify({ name: '@deepseek-ai/dsh', + version: '0.1.7-rc.2', type: 'module', bin: { dsh: 'lib/bin.js' } })) + const entry = join(host, 'lib', 'bin.js') + await writeFile(entry, 'throw new Error("validation must not execute the CLI")') + const generation = { id: 'cli-peer', pluginName: 'root-plugin', version: '1.0.0', directory } + expect(await verifyGenerationPeers(home, generation, { dshEntryPath: entry })).toEqual({ ok: true, problems: [] }) + await rm(entry) + expect((await verifyGenerationPeers(home, generation)).ok).toBe(false) + await mkdir(entry) + expect((await verifyGenerationPeers(home, generation)).ok).toBe(false) + await rm(entry, { recursive: true }) + await writeFile(entry, '') + await writeFile(join(host, 'package.json'), JSON.stringify({ name: '@deepseek-ai/dsh', + main: 'missing.js', bin: { dsh: 'lib/bin.js' } })) + expect((await verifyGenerationPeers(home, generation)).ok).toBe(false) + await writeFile(join(host, 'package.json'), JSON.stringify({ name: '@deepseek-ai/dsh', bin: '../escape.js' })) + await writeFile(join(host, '..', 'escape.js'), '') + expect((await verifyGenerationPeers(home, generation)).ok).toBe(false) + }) + it('does not accept a broken root entry merely because its package manifest exists', async () => { const home = await freshHome() const directory = join(home, 'profiles', '.generations', 'live', 'broken-entry') diff --git a/test/generation-runtime-resolution.test.mjs b/test/generation-runtime-resolution.test.mjs new file mode 100644 index 000000000..d1602e9cf --- /dev/null +++ b/test/generation-runtime-resolution.test.mjs @@ -0,0 +1,51 @@ +import { mkdtemp, mkdir, writeFile, symlink, rm } from 'node:fs/promises' +import { tmpdir } from 'node:os' +import { join, resolve } from 'node:path' +import { spawnSync } from 'node:child_process' +import { pathToFileURL } from 'node:url' +import { expect, it } from 'vitest' + +it('validates peers with real Harness interception despite stale shared links', async () => { + const home = await mkdtemp(join(tmpdir(), 'dsh-peer-runtime-')) + try { + const directory = join(home, 'profiles/.generations/live/plugin') + const plugin = join(directory, 'node_modules/fixture') + await mkdir(plugin, { recursive: true }) + await mkdir(join(home, 'profiles/web'), { recursive: true }) + await mkdir(join(home, 'profiles/node_modules/@deepseek-ai'), { recursive: true }) + const old = join(home, 'old/dsh') + await mkdir(join(old, 'lib'), { recursive: true }) + await writeFile(join(old, 'package.json'), JSON.stringify({ name: '@deepseek-ai/dsh', bin: { dsh: 'lib/bin.js' } })) + await writeFile(join(old, 'lib/bin.js'), 'throw new Error("stale CLI must not run")') + await symlink(old, join(home, 'profiles/node_modules/@deepseek-ai/dsh'), 'junction') + await writeFile(join(plugin, 'package.json'), JSON.stringify({ name: 'fixture', + peerDependencies: { '@deepseek-ai/dsh': '*', react: '*', 'react-dom': '*' } })) + await writeFile(join(home, 'profiles/web/package.json'), '{}') + const moduleUrl = name => pathToFileURL(resolve(name)).href + const entry = join(home, 'check.mjs') + await writeFile(entry, ` + import { Context } from ${JSON.stringify(moduleUrl('node_modules/@deepseek-ai/cordis/lib/index.js'))}; + import { createRuntimeResolution, PluginPackages, loadProfileDirectory } from ${JSON.stringify(moduleUrl('node_modules/@deepseek-ai/dsh-app-boot/lib/index.js'))}; + import { verifyGenerationPeers } from ${JSON.stringify(moduleUrl('packages/dsh-desktop-market-installer/generations/installer.mjs'))}; + import { createRequire } from 'node:module'; + const home = ${JSON.stringify(home)}; + const anchor = ${JSON.stringify(resolve('node_modules/@deepseek-ai/dsh/package.json'))}; + const profile = loadProfileDirectory('test', home + '/profiles/web', anchor); + const resolution = await createRuntimeResolution({ home, installAnchor: anchor, profile }); + const ctx = new Context(); + await ctx.plugin(PluginPackages, { resolution }); + try { + const req = createRequire(${JSON.stringify(join(plugin, 'package.json'))}); + // Test real runtime resolution, including the ReactDOM client subpath. + if (req.resolve('react-dom/client') !== createRequire(anchor).resolve('react-dom/client')) throw new Error('wrong ReactDOM'); + const result = await verifyGenerationPeers(home, ${JSON.stringify({ directory, id: 'plugin', pluginName: 'fixture', version: '1' })}, { dshEntryPath: ${JSON.stringify(resolve('node_modules/@deepseek-ai/dsh/lib/bin.js'))} }); + console.log(JSON.stringify(result)); + if (!result.ok) process.exitCode = 1; + } finally { await ctx.fiber.dispose(); } + `) + const child = spawnSync(process.execPath, [entry], { encoding: 'utf8', timeout: 15000 }) + expect(child.error).toBeUndefined() + expect(child.status, child.stderr + child.stdout).toBe(0) + expect(JSON.parse(child.stdout.trim())).toEqual({ ok: true, problems: [] }) + } finally { await rm(home, { recursive: true, force: true }) } +}) diff --git a/test/host-disabled-plugins.test.ts b/test/host-disabled-plugins.test.ts index c2016f0e6..d36c6b33d 100644 --- a/test/host-disabled-plugins.test.ts +++ b/test/host-disabled-plugins.test.ts @@ -95,6 +95,7 @@ describe('disabled Profile packages in Desktop host patch', () => { dshSafePatchPath: join(projectRoot, 'build', 'dsh-desktop-safe.patch.yml'), dshHome: home, logPath: join(home, 'harness.log'), + preferredPort: 0, startupTimeoutMs: 30_000, launchProcess: (executable, args, options) => spawn(executable, args, options), onChanged() {} @@ -134,6 +135,7 @@ describe('disabled Profile packages in Desktop host patch', () => { dshSafePatchPath: join(projectRoot, 'build', 'dsh-desktop-safe.patch.yml'), dshHome: home, logPath: join(home, 'harness.log'), + preferredPort: 0, startupTimeoutMs: 30_000, launchProcess: (executable, args, options) => spawn(executable, args, options), onChanged() {} @@ -151,6 +153,7 @@ describe('disabled Profile packages in Desktop host patch', () => { manifest.dependencies['dsh-image-generation'] = '0.1.1' manifest.dsh.profile.bundles.push('dsh-image-generation') await writeFile(manifestPath, JSON.stringify(manifest)) + await mkdir(join(profile, 'node_modules'), { recursive: true }) await symlink(join(projectRoot, 'node_modules', 'dsh-image-generation'), join(profile, 'node_modules', 'dsh-image-generation'), 'junction') await mkdir(join(profile, '.dsh-market'), { recursive: true }) @@ -187,6 +190,7 @@ describe('disabled Profile packages in Desktop host patch', () => { dshSafePatchPath: join(projectRoot, 'build', 'dsh-desktop-safe.patch.yml'), dshHome: home, logPath: join(home, 'harness.log'), + preferredPort: 0, startupTimeoutMs: 30_000, launchProcess: (executable, args, options) => spawn(executable, args, options), onChanged() {} @@ -204,6 +208,7 @@ describe('disabled Profile packages in Desktop host patch', () => { manifest.dependencies['dsh-image-generation'] = '0.1.1' manifest.dsh.profile.bundles.push('dsh-image-generation') await writeFile(manifestPath, JSON.stringify(manifest)) + await mkdir(join(profile, 'node_modules'), { recursive: true }) await symlink(join(projectRoot, 'node_modules', 'dsh-image-generation'), join(profile, 'node_modules', 'dsh-image-generation'), 'junction') expect(await inspectProfileBootInputs(home, entryPath, desktopPatchPath)).toBeUndefined() diff --git a/test/host-plugin-sources.test.ts b/test/host-plugin-sources.test.ts index 6257161d7..cb662ca2d 100644 --- a/test/host-plugin-sources.test.ts +++ b/test/host-plugin-sources.test.ts @@ -1,7 +1,10 @@ import { mkdir, mkdtemp, readFile, realpath, rm, writeFile } from 'node:fs/promises' +import { createRequire } from 'node:module' +import { execFile } from 'node:child_process' +import { promisify } from 'node:util' import { tmpdir } from 'node:os' import { join } from 'node:path' -import { pathToFileURL } from 'node:url' +import { fileURLToPath, pathToFileURL } from 'node:url' import { afterEach, describe, expect, it } from 'vitest' import { parse } from 'yaml' import { hostInsertedPluginNames, prepareHostPluginSourcesPatch } from '../src/main/state/host-plugin-sources' @@ -21,35 +24,68 @@ describe('Desktop host plugin sources', () => { await mkdir(home) await writeFile(join(app, 'package.json'), '{"name":"test-desktop"}\n') const names = ['host-first', 'host-second'] - const entries: string[] = [] for (const name of names) { const directory = join(app, 'node_modules', name) await mkdir(directory, { recursive: true }) await writeFile(join(directory, 'package.json'), JSON.stringify({ name, main: 'index.js' })) const entry = join(directory, 'index.js') - entries.push(entry) await writeFile(entry, `module.exports = '${name}'\n`) } const source = `# Keep this comment\n- insert:\n - id: first\n name: host-first\n - id: second\n name: 'host-second'\n config:\n path: !!js dshHomePath('data')\n- id: another\n name: profile-plugin\n` await writeFile(patchPath, source) expect(hostInsertedPluginNames(source)).toEqual(names) - const outputPath = await prepareHostPluginSourcesPatch(home, patchPath) + const outputPath = await prepareHostPluginSourcesPatch(home, patchPath, join(app, 'package.json')) const output = await readFile(outputPath, 'utf8') const rows = parse(output, { logLevel: 'silent' }) as { insert?: { name: string }[]; name?: string }[] - expect(rows[0]?.insert?.map(row => row.name)).toEqual(await Promise.all(entries.map(async path => pathToFileURL(await realpath(path)).href))) + const resolveHost = createRequire(join(app, 'package.json')).resolve + expect(rows[0]?.insert?.map(row => row.name)).toEqual(names.map(name => pathToFileURL(resolveHost(name)).href)) expect(rows[1]?.name).toBe('profile-plugin') expect(output).toContain("path: !!js dshHomePath('data')") expect(output).toContain('# Keep this comment') - expect(await prepareHostPluginSourcesPatch(home, patchPath)).toBe(outputPath) + expect(await prepareHostPluginSourcesPatch(home, patchPath, join(app, 'package.json'))).toBe(outputPath) expect(await readFile(patchPath, 'utf8')).toBe(source) }) + it('loads host plugins from unpacked resources outside the installation cwd and preserves missing-package causes', async () => { + const root = await mkdtemp(join(tmpdir(), 'dsh-installed-host-sources-')) + directories.push(root) + const resources = join(root, 'installation', 'resources') + const runtime = join(resources, 'app.asar.unpacked') + const home = join(root, 'profile') + const launchRoot = join(root, 'launch-root') + const anchor = join(runtime, 'node_modules', '@deepseek-ai', 'dsh', 'lib', 'bin.js') + const plugin = join(runtime, 'node_modules', 'host-plugin') + await mkdir(plugin, { recursive: true }) + await mkdir(home) + await mkdir(launchRoot) + await writeFile(join(plugin, 'package.json'), JSON.stringify({ name: 'host-plugin', type: 'module', exports: './entry.js' })) + await writeFile(join(plugin, 'entry.js'), 'export default "installed-host"\n') + const patchPath = join(resources, 'desktop.patch.yml') + await writeFile(patchPath, '- insert:\n - id: host\n name: host-plugin\n') + const output = await prepareHostPluginSourcesPatch(home, patchPath, anchor) + const rows = parse(await readFile(output, 'utf8')) as { insert: { name: string }[] }[] + const entry = rows[0]?.insert[0]?.name + if (!entry) throw new Error('Missing resolved host plugin source') + // Windows may preserve an 8.3 temp path in require.resolve's result. + expect(await realpath(fileURLToPath(entry))).toBe(await realpath(join(plugin, 'entry.js'))) + const result = await promisify(execFile)(process.execPath, ['--input-type=module', '-e', `console.log((await import(${JSON.stringify(entry)})).default)`], { cwd: launchRoot }) + expect(result.stdout.trim()).toBe('installed-host') + + const previous = await readFile(output, 'utf8') + await writeFile(patchPath, '- insert:\n - id: missing\n name: absent-host-plugin\n') + await expect(prepareHostPluginSourcesPatch(home, patchPath, anchor)).rejects.toMatchObject({ + message: expect.stringContaining(`Desktop host plugin source resolution failed for absent-host-plugin from ${anchor}: Cannot find module`), + cause: { code: 'MODULE_NOT_FOUND' } + }) + expect(await readFile(output, 'utf8')).toBe(previous) + }) + it('leaves patches without host package insertions untouched', async () => { const root = await mkdtemp(join(tmpdir(), 'dsh-host-sources-')) directories.push(root) const patchPath = join(root, 'patch.yml') await writeFile(patchPath, '- insert:\n - id: local\n name: file:///tmp/plugin.js\n') - expect(await prepareHostPluginSourcesPatch(root, patchPath)).toBe(patchPath) + expect(await prepareHostPluginSourcesPatch(root, patchPath, join(root, 'package.json'))).toBe(patchPath) }) it('omits a switched-off host insertion while retaining other host sources', async () => { @@ -66,9 +102,10 @@ describe('Desktop host plugin sources', () => { await writeFile(join(other, 'index.js'), 'module.exports = {}\n') await writeFile(patchPath, '- insert:\n - id: image\n name: dsh-image-generation\n - id: other\n name: host-other\n') await setHostPluginEnabled(home, 'dsh-image-generation', false) - const output = await readFile(await prepareHostPluginSourcesPatch(home, patchPath), 'utf8') + const output = await readFile(await prepareHostPluginSourcesPatch(home, patchPath, join(app, 'package.json')), 'utf8') const rows = parse(output, { logLevel: 'silent' }) as { insert: { id: string; name: string }[] }[] - expect(rows[0]?.insert).toEqual([{ id: 'other', name: pathToFileURL(await realpath(join(other, 'index.js'))).href }]) + const resolveHost = createRequire(join(app, 'package.json')).resolve + expect(rows[0]?.insert).toEqual([{ id: 'other', name: pathToFileURL(resolveHost('host-other')).href }]) expect(output).not.toContain('dsh-image-generation') expect(hostInsertedPluginNames(await readFile(patchPath, 'utf8'), ['dsh-image-generation'])).toEqual(['host-other']) }) @@ -78,7 +115,7 @@ describe('Desktop host plugin sources', () => { directories.push(root) const patchPath = join(root, 'desktop.patch.yml') await writeFile(patchPath, '- insert:\n - id: image\n name: dsh-image-generation\n') - const outputPath = await prepareHostPluginSourcesPatch(root, patchPath) + const outputPath = await prepareHostPluginSourcesPatch(root, patchPath, join(root, 'package.json')) expect(outputPath).not.toBe(patchPath) expect(parse(await readFile(outputPath, 'utf8'))).toEqual([]) expect(await readFile(patchPath, 'utf8')).toContain('dsh-image-generation') diff --git a/test/image-generation-settings-ui.test.mjs b/test/image-generation-settings-ui.test.mjs new file mode 100644 index 000000000..de14a8ffb --- /dev/null +++ b/test/image-generation-settings-ui.test.mjs @@ -0,0 +1,61 @@ +// @vitest-environment jsdom +import { readFile } from 'node:fs/promises' +import { createRequire } from 'node:module' +import { resolve } from 'node:path' +import React, { act } from 'react' +import { createRoot } from 'react-dom/client' +import { expect, it, vi } from 'vitest' +import { DEFAULTS, MODEL_CATALOG } from '../packages/dsh-image-generation/lib/provider.js' + +globalThis.IS_REACT_ACT_ENVIRONMENT = true + +it('registers the image settings tab in 0.1.7 and opens the configuration form', async () => { + const source = await readFile(resolve('packages/dsh-image-generation/client.js'), 'utf8') + const primitives = await readFile(createRequire(resolve('package.json')).resolve('@deepseek-ai/dsh-client-ui-primitives'), 'utf8') + const exports = primitives.match(/export \{([^}]+)\}/)[1].split(',').map(value => value.trim()) + let plugin + const require = name => { + if (name === 'react') return React + if (name === '@deepseek-ai/dsh-client-ui-primitives') return new Proxy({}, { get(_target, key) { + expect(exports).toContain(key) + if (key === 'Menu') return ({ anchor }) => anchor + return props => React.createElement('svg', props) + } }) + throw new Error(name) + } + new Function('window', source)({ __ModuleLoader__: { load({ factory }) { plugin = factory(require) } } }) + const entries = [], disposers = [] + plugin.apply({ + uiConversation: { events: { register() {} } }, + locale: { register() {}, bind: () => key => key }, + effect(fn) { const dispose = fn(); if (typeof dispose === 'function') disposers.push(dispose) }, + slots: { + inject(name, fn) { if (['settings.plugins.tab', 'conversation.chat.node'].includes(name)) fn() }, + register(options, Component) { entries.push({ options, Component }) } + } + }) + const entry = entries.find(item => item.options.name === 'settings.plugins.tab') + expect(entry.options.id).toBe('image-generation') + expect(entry.options.label()).toBe('title') + const settings = { revision: 0, provider: 'bytedance', writable: true, catalogs: MODEL_CATALOG, + profiles: Object.fromEntries(Object.entries(DEFAULTS).map(([name, defaults]) => [name, { ...defaults, configured: false }])) } + const fetchMock = vi.fn(async () => ({ ok: true, text: async () => JSON.stringify(settings) })) + vi.stubGlobal('fetch', fetchMock) + const container = document.createElement('div') + document.body.append(container) + const root = createRoot(container) + try { + await act(async () => root.render(React.createElement(entry.Component, { t: key => key, ...entry.options.inject() }))) + await act(async () => container.querySelector('button[aria-expanded]').click()) + expect(container.querySelector('form')).not.toBeNull() + expect(container.querySelector('input[type=password]')).not.toBeNull() + expect(container.querySelector('button[type=submit]').textContent).toBe('save') + expect(fetchMock).toHaveBeenCalledTimes(1) + expect(fetchMock.mock.calls[0][1].method).toBe('GET') + } finally { + await act(async () => root.unmount()) + container.remove() + disposers.reverse().forEach(dispose => dispose()) + vi.unstubAllGlobals() + } +}) diff --git a/test/legacy-preset-migration.test.ts b/test/legacy-preset-migration.test.ts new file mode 100644 index 000000000..11dcb6ea9 --- /dev/null +++ b/test/legacy-preset-migration.test.ts @@ -0,0 +1,150 @@ +import { mkdtemp, mkdir, readFile, rm, writeFile } from 'node:fs/promises' +import { spawn } from 'node:child_process' +import { tmpdir } from 'node:os' +import { join, resolve } from 'node:path' +import { afterEach, expect, it } from 'vitest' +import jsYaml from 'js-yaml' +import { applyEntryPatches, entryListSchema } from '@deepseek-ai/cordis-plugin-include' +import { migrateLegacyAgentPresets } from '../src/main/state/legacy-preset-migration' +import { HarnessRuntime } from '../src/main/runtime/harness-runtime' +import { resolveTestNodeExecutable } from './node-executable' + +const homes: string[] = [] +afterEach(async () => { + await Promise.all(homes.splice(0).map((home) => rm(home, { recursive: true, force: true }))) +}) + +it('converts legacy presets into the web Profile while retaining originals and first backups', async () => { + const home = await mkdtemp(join(tmpdir(), 'dsh-legacy-preset-')) + homes.push(home) + const source = join(home, '.agent-presets', 'custom') + const profile = join(home, 'profiles', 'web') + await mkdir(source, { recursive: true }) + await mkdir(profile, { recursive: true }) + const composition = '- id: persona\n name: "@deepseek-ai/dsh-persona"\n disabled: !!js process.platform === "win32"\n' + await writeFile(join(source, 'agent.cordis.yml'), composition) + await writeFile(join(source, 'preset.yml'), 'name: Custom mode\norder: 9\n') + await writeFile(join(profile, 'cordis.patch.yml'), '- id: untouched\n disabled: true\n') + const notes: string[] = [] + await migrateLegacyAgentPresets(home, (line) => notes.push(line)) + const patch = await readFile(join(profile, 'cordis.patch.yml'), 'utf8') + expect(patch).toContain('- id: untouched') + expect(patch).toContain('id: preset-custom') + expect(patch).toContain('id: custom') + expect(patch).toContain('disabled: !!js process.platform === "win32"') + expect(await readFile(join(home, '.agent-presets.pre-0.1.7-backup', 'custom', 'agent.cordis.yml'), 'utf8')).toBe(composition) + expect(await readFile(`${join(profile, 'cordis.patch.yml')}.pre-0.1.7-backup`, 'utf8')).toBe('- id: untouched\n disabled: true\n') + await migrateLegacyAgentPresets(home, (line) => notes.push(line)) + expect(await readFile(join(profile, 'cordis.patch.yml'), 'utf8')).toBe(patch) + expect(notes).toHaveLength(1) + + const edited = patch.replace('Custom mode', 'Edited in the new Profile') + await writeFile(join(profile, 'cordis.patch.yml'), edited) + await migrateLegacyAgentPresets(home, (line) => notes.push(line)) + expect(await readFile(join(profile, 'cordis.patch.yml'), 'utf8')).toBe(edited) + const imported = join(home, '.agent-presets', 'imported') + await mkdir(imported) + await writeFile(join(imported, 'agent.cordis.yml'), composition) + await migrateLegacyAgentPresets(home, (line) => notes.push(line)) + const extended = await readFile(join(profile, 'cordis.patch.yml'), 'utf8') + expect(extended).toContain('Edited in the new Profile') + expect(extended).toContain('id: preset-imported') + expect(notes).toHaveLength(2) +}) + +it('updates a shipped preset row and leaves an invalid legacy preset out of the generated patch', async () => { + const home = await mkdtemp(join(tmpdir(), 'dsh-legacy-preset-')) + homes.push(home) + for (const id of ['standard', 'broken']) await mkdir(join(home, '.agent-presets', id), { recursive: true }) + await writeFile(join(home, '.agent-presets', 'standard', 'agent.cordis.yml'), '- id: persona\n name: "@deepseek-ai/dsh-persona"\n') + await writeFile(join(home, '.agent-presets', 'broken', 'agent.cordis.yml'), 'not a plugin list\n') + const notes: string[] = [] + await migrateLegacyAgentPresets(home, (line) => notes.push(line)) + const patch = await readFile(join(home, 'profiles', 'web', 'cordis.patch.yml'), 'utf8') + expect(patch).toContain('- id: preset-standard\n config:') + expect(patch).not.toContain('id: preset-broken') + expect(notes.some((line) => line.includes('broken could not be converted'))).toBe(true) + + const shippedText = await readFile(join(import.meta.dirname, '../node_modules/@deepseek-ai/dsh-web-app/presets/standard.patch.yml'), 'utf8') + const shipped = jsYaml.load(shippedText, { schema: entryListSchema }) as Array> + const migrated = jsYaml.load(patch, { schema: entryListSchema }) as Array> + const warnings: string[] = [] + const entries = applyEntryPatches(applyEntryPatches([], shipped, (warning) => warnings.push(warning)), migrated, (warning) => warnings.push(warning)) + const standard = entries.find((entry) => entry.id === 'preset-standard') as { config?: { id?: string; plugins?: Array<{ id: string }> } } | undefined + expect(warnings).toEqual([]) + expect(standard?.config?.id).toBe('standard') + expect(standard?.config?.plugins?.map((entry) => entry.id)).toEqual(['persona']) +}) + +it('appends a legacy preset to a fresh Profile patch with comments and an empty flow list', async () => { + const home = await mkdtemp(join(tmpdir(), 'dsh-legacy-preset-')) + homes.push(home) + const source = join(home, '.agent-presets', 'custom') + const profile = join(home, 'profiles', 'web') + await mkdir(source, { recursive: true }) + await mkdir(profile, { recursive: true }) + await writeFile(join(source, 'agent.cordis.yml'), '- id: persona\n name: "@deepseek-ai/dsh-persona"\n') + const patchPath = join(profile, 'cordis.patch.yml') + await writeFile(patchPath, '# Existing Profile comment\n[]\n') + + await migrateLegacyAgentPresets(home, () => {}) + const patch = await readFile(patchPath, 'utf8') + expect(patch).toContain('# Existing Profile comment') + expect(patch).toContain('id: preset-custom') + expect(patch).not.toMatch(/^\[\]$/mu) + expect(jsYaml.load(patch, { schema: entryListSchema })).toBeInstanceOf(Array) + await migrateLegacyAgentPresets(home, () => {}) + expect(await readFile(patchPath, 'utf8')).toBe(patch) +}) + +it('publishes a migrated custom preset through the real Harness web registry', async () => { + const home = await mkdtemp(join(tmpdir(), 'dsh-legacy-preset-runtime-')) + homes.push(home) + const source = join(home, '.agent-presets', 'custom') + await mkdir(source, { recursive: true }) + await writeFile(join(source, 'agent.cordis.yml'), '- id: persona\n name: "@deepseek-ai/dsh-persona"\n config:\n prefix: Migrated runtime mode\n') + await writeFile(join(source, 'preset.yml'), 'name: Migrated runtime mode\n') + await migrateLegacyAgentPresets(home, () => {}) + const overlay = join(home, 'desktop.patch.yml') + await writeFile(overlay, '[]\n') + const root = resolve(import.meta.dirname, '..') + const runtime = new HarnessRuntime({ + dshEntryPath: join(root, 'node_modules/@deepseek-ai/dsh/lib/bin.js'), + nodeEntryPath: join(root, 'build/harness-node-entry.mjs'), + nodeExecutablePath: resolveTestNodeExecutable(), + dshPatchPath: overlay, + dshSafePatchPath: overlay, + dshHome: home, + logPath: join(home, 'runtime.log'), + preferredPort: 0, + startupTimeoutMs: 30_000, + launchProcess: (executable, args, options) => spawn(executable, args, options), + onChanged() {} + }) + try { + await runtime.start(home, 'web') + expect(runtime.snapshot().phase, runtime.snapshot().logs.join('\n')).toBe('ready') + const { url, authToken } = runtime.snapshot() + if (!url || !authToken) throw new Error('Harness did not announce its endpoint') + const login = await fetch(`${url}/?token=${encodeURIComponent(authToken)}`, { redirect: 'manual' }) + const cookie = login.headers.getSetCookie().map((value) => value.split(';')[0]).join('; ') + const roster = await fetch(new URL('/api/agentPresets/list', url), { + method: 'POST', + headers: { Cookie: cookie, 'content-type': 'application/json' }, + body: JSON.stringify({ type: 'client-request', rpcId: 'migrated-presets', method: 'agentPresets/list', payload: { args: {} } }) + }) + expect(roster.status).toBe(200) + expect(await roster.text()).toContain('"id":"custom"') + const html = await (await fetch(url, { headers: { Cookie: cookie } })).text() + expect(html).toContain('@deepseek-ai/dsh-client-ui-agent-preset') + const preload = [...html.matchAll(/]+>/gu)].map((match) => match[0]).find((tag) => tag.includes('@deepseek-ai/dsh-client-ui-agent-preset/client.js')) + expect(preload).toBeDefined() + const href = preload?.match(/href="([^"]+)"/u)?.[1] + if (!href) throw new Error(`Preset preload URL missing: ${preload}`) + const response = await fetch(new URL(href.replaceAll('&', '&'), url), { headers: { Cookie: cookie } }) + expect(response.status).toBe(200) + expect(await response.text()).toContain('const previewImport = async (file) =>') + } finally { + await runtime.stop() + } +}, 45_000) diff --git a/test/macos-window-backdrop.test.ts b/test/macos-window-backdrop.test.ts new file mode 100644 index 000000000..d56acbf2a --- /dev/null +++ b/test/macos-window-backdrop.test.ts @@ -0,0 +1,24 @@ +import { expect, it, vi } from 'vitest' +import { applyMacosWindowBackdrop } from '../src/main/macos-window-backdrop' + +it.each([false, true])('restores sidebar vibrancy after hiding or minimizing (dark=%s)', dark => { + let visible = true + let minimized = false + const window = { isDestroyed: () => false, isMinimized: () => minimized, isVisible: () => visible, + setVibrancy: vi.fn(), setBackgroundColor: vi.fn() } + applyMacosWindowBackdrop(window, dark) + expect(window.setVibrancy).toHaveBeenLastCalledWith('sidebar') + expect(window.setBackgroundColor).toHaveBeenLastCalledWith('#00000000') + for (const state of ['minimized', 'hidden']) { + minimized = state === 'minimized' + visible = state !== 'hidden' + applyMacosWindowBackdrop(window, dark) + expect(window.setVibrancy).toHaveBeenLastCalledWith(null) + expect(window.setBackgroundColor).toHaveBeenLastCalledWith(dark ? '#1b1b1c' : '#f9fafb') + } + visible = true + minimized = false + applyMacosWindowBackdrop(window, dark) + expect(window.setVibrancy).toHaveBeenLastCalledWith('sidebar') + expect(window.setBackgroundColor).toHaveBeenLastCalledWith('#00000000') +}) diff --git a/test/macos-window-chrome.test.ts b/test/macos-window-chrome.test.ts new file mode 100644 index 000000000..31f630511 --- /dev/null +++ b/test/macos-window-chrome.test.ts @@ -0,0 +1,46 @@ +// @vitest-environment jsdom +import { expect, it, vi } from 'vitest' +import { mountMacosWindowChrome } from '../src/preload/macos-window-chrome' + +it('marks the platform before mount and tracks fullscreen without retaining listeners', () => { + const doc = document.implementation.createHTMLDocument() + const unsubscribe = vi.fn() + let receive: (value: boolean) => void = () => {} + const dispose = mountMacosWindowChrome(doc, listener => { receive = listener; return unsubscribe }) + expect(doc.documentElement.dataset.platform).toBe('darwin') + expect(doc.documentElement.hasAttribute('data-fullscreen')).toBe(false) + receive(true) + expect(doc.documentElement.dataset.fullscreen).toBe('true') + receive(false) + expect(doc.documentElement.hasAttribute('data-fullscreen')).toBe(false) + dispose() + expect(unsubscribe).toHaveBeenCalledOnce() +}) + +it('retains fullscreen until the document root exists', () => { + const doc = document.implementation.createHTMLDocument() + const root = doc.documentElement + root.remove() + let receive: (value: boolean) => void = () => {} + const dispose = mountMacosWindowChrome(doc, listener => { receive = listener; return () => {} }) + receive(true) + doc.append(root) + doc.dispatchEvent(new Event('DOMContentLoaded')) + expect(root.dataset.platform).toBe('darwin') + expect(root.dataset.fullscreen).toBe('true') + dispose() +}) + +it('opts this host into Web shortcuts without changing official desktop detection', async () => { + const { readFile } = await import('node:fs/promises') + const source = await readFile('node_modules/@deepseek-ai/dsh-client-shortcuts/lib/client.js', 'utf8') + const fn = source.match(/function detectEnvironment\(document, navigator\) \{[\s\S]*?\n\t\t\}/)?.[0] + expect(fn).toBeDefined() + const detect = new Function(`${fn}; return detectEnvironment`)() + const doc = document.implementation.createHTMLDocument() + doc.documentElement.dataset.platform = 'darwin' + expect(detect(doc, { platform: 'MacIntel' })).toEqual({ runtime: 'desktop', platform: 'macos' }) + const dispose = mountMacosWindowChrome(doc, () => () => {}) + expect(detect(doc, { platform: 'MacIntel' })).toEqual({ runtime: 'web', platform: 'macos' }) + dispose() +}) diff --git a/test/market-baseline.test.ts b/test/market-baseline.test.ts index 8436dea05..b1dcab77e 100644 --- a/test/market-baseline.test.ts +++ b/test/market-baseline.test.ts @@ -51,7 +51,7 @@ describe('market baseline at normal startup', () => { }) it('reports when the installation shadows the profile market', async () => { - const { options } = await fixture('1.48.0') + const { options } = await fixture(VERIFIED_MARKET_BASELINE) const fakeApp = await mkdtemp(join(tmpdir(), 'dsh-shadowed-app-')) homes.push(fakeApp) const fakeMarket = join(fakeApp, 'node_modules', 'dshmarket') @@ -65,15 +65,15 @@ describe('market baseline at normal startup', () => { }) it('stays quiet when Harness loads the profile market', async () => { - const { home, options } = await fixture('1.48.0') + const { home, options } = await fixture('1.65.1') const lines: string[] = [] const dshEntryPath = join(home, 'app', 'lib', 'bin.js') await ensureMarketBaseline({ ...options, dshEntryPath, note: (line) => lines.push(line) }, vi.fn()) expect(lines).toEqual([]) }) - it('upgrades an already-migrated Profile in the shared tree, never as a generation', async () => { - const { home, profile, market, options } = await fixture() + it.each(['1.15.0', '1.65.0'])('upgrades an already-migrated Profile at %s in the shared tree, never as a generation', async (version) => { + const { home, profile, market, options } = await fixture(version) const upgrade = vi.fn(async () => { // dshmarket is never a generation: simulate the shared-tree reinstall // landing a newer real directory in place. @@ -130,7 +130,7 @@ describe('market baseline at normal startup', () => { expect(upgrade).not.toHaveBeenCalled() }) - it.each(['1.45.1', '1.46.0', '2.0.0'])('does not reinstall or downgrade active %s', async (version) => { + it.each(['1.65.1', '1.66.0', '2.0.0'])('does not reinstall or downgrade active %s', async (version) => { const { options } = await fixture(version) const upgrade = vi.fn() await ensureMarketBaseline(options, upgrade) @@ -358,38 +358,38 @@ describe('market baseline at normal startup', () => { expect(order).toEqual(['demote', 'market', 'projection']) }) - it('preserves an upgraded market version >= 1.45.1 when demoting back to shared tree', async () => { + it('preserves an upgraded market version >= 1.65.1 when demoting back to shared tree', async () => { const { home, profile, market } = await fixture() - const generationDir = join(registryLayout(home).generations, 'dshmarket+1.47.0+cafebabe') + const generationDir = join(registryLayout(home).generations, 'dshmarket+1.66.0+cafebabe') const generationPackage = join(generationDir, 'node_modules', 'dshmarket') await mkdir(generationPackage, { recursive: true }) - await writeFile(join(generationPackage, 'package.json'), JSON.stringify({ name: 'dshmarket', version: '1.47.0' })) - await writeGenerationMeta(generationDir, { pluginName: 'dshmarket', version: '1.47.0' }) - await writeDesired(home, ['dshmarket+1.47.0+cafebabe']) + await writeFile(join(generationPackage, 'package.json'), JSON.stringify({ name: 'dshmarket', version: '1.66.0' })) + await writeGenerationMeta(generationDir, { pluginName: 'dshmarket', version: '1.66.0' }) + await writeDesired(home, ['dshmarket+1.66.0+cafebabe']) await rm(market, { recursive: true, force: true }) await symlink(generationPackage, market, 'junction') const manifest = JSON.parse(await readFile(join(profile, 'package.json'), 'utf8')) manifest.dsh.desktop = { generationProjection: { version: 1, - plugins: { dshmarket: { generationId: 'dshmarket+1.47.0+cafebabe', visibleVersion: '1.47.0', previousOverride: { present: false } } } + plugins: { dshmarket: { generationId: 'dshmarket+1.66.0+cafebabe', visibleVersion: '1.66.0', previousOverride: { present: false } } } } } - manifest.dependencies.dshmarket = '1.47.0' + manifest.dependencies.dshmarket = '1.66.0' await writeFile(join(profile, 'package.json'), JSON.stringify(manifest, undefined, 2)) expect(await demoteMarketGeneration(home)).toBe(true) const after = JSON.parse(await readFile(join(profile, 'package.json'), 'utf8')) - expect(after.dependencies.dshmarket).toBe('1.47.0') + expect(after.dependencies.dshmarket).toBe('1.66.0') }) it('upgrades to the newer declared version when declared version exceeds the baseline', async () => { const { options, profile, market } = await fixture() - // Simulate generation link with broken/missing active version, but declared version is 1.47.0 + // Simulate generation link with broken/missing active version, but declared version is 1.66.0 await rm(market, { recursive: true, force: true }) const manifest = JSON.parse(await readFile(join(profile, 'package.json'), 'utf8')) - manifest.dependencies.dshmarket = '1.47.0' + manifest.dependencies.dshmarket = '1.66.0' await writeFile(join(profile, 'package.json'), JSON.stringify(manifest, undefined, 2)) const upgrade = vi.fn(async ({ dshHome, targetVersion }: { dshHome: string; targetVersion: string }) => { @@ -400,15 +400,15 @@ describe('market baseline at normal startup', () => { }) await ensureMarketBaseline(options, upgrade) - expect(upgrade).toHaveBeenCalledWith(expect.objectContaining({ targetVersion: '1.47.0' })) - expect(await readInstalledPluginVersion(options.dshHome, 'dshmarket')).toBe('1.47.0') + expect(upgrade).toHaveBeenCalledWith(expect.objectContaining({ targetVersion: '1.66.0' })) + expect(await readInstalledPluginVersion(options.dshHome, 'dshmarket')).toBe('1.66.0') }) it('pins the version a declared range names, since the installer verifies an exact version', async () => { const { options, profile, market } = await fixture() await rm(market, { recursive: true, force: true }) const manifest = JSON.parse(await readFile(join(profile, 'package.json'), 'utf8')) - manifest.dependencies.dshmarket = '^1.47.0' + manifest.dependencies.dshmarket = '^1.66.0' await writeFile(join(profile, 'package.json'), JSON.stringify(manifest, undefined, 2)) const upgrade = vi.fn(async ({ targetVersion }: { dshHome: string; targetVersion: string }) => { @@ -419,7 +419,7 @@ describe('market baseline at normal startup', () => { }) await ensureMarketBaseline(options, upgrade) - expect(upgrade).toHaveBeenCalledWith(expect.objectContaining({ targetVersion: '1.47.0' })) + expect(upgrade).toHaveBeenCalledWith(expect.objectContaining({ targetVersion: '1.66.0' })) }) }) diff --git a/test/market-installer.test.js b/test/market-installer.test.js index 9619709be..f5249a7d6 100644 --- a/test/market-installer.test.js +++ b/test/market-installer.test.js @@ -32,10 +32,10 @@ describe('desktop plugin market installer', () => { 'web', 'add', '--workspace-root', - 'dshmarket@^1.45.1' + 'dshmarket@^1.65.1' ]) expect(MARKET_PACKAGE).toBe('dshmarket') - expect(RECOMMENDED_MARKET_VERSION).toBe('^1.45.1') + expect(RECOMMENDED_MARKET_VERSION).toBe('^1.65.1') expect(STATUS_PATH).toBe('/dsh-desktop/market-installer/status') expect(INSTALL_PATH).toBe('/dsh-desktop/market-installer/install') expect(UNINSTALL_PATH).toBe('/dsh-desktop/market-installer/uninstall') diff --git a/test/model-selection-icons.test.mjs b/test/model-selection-icons.test.mjs new file mode 100644 index 000000000..06c6787dc --- /dev/null +++ b/test/model-selection-icons.test.mjs @@ -0,0 +1,14 @@ +import { createRequire } from 'node:module' +import { readFile } from 'node:fs/promises' +import { expect, it } from 'vitest' + +it.each(['dsh-client-ui-model-selection', 'dsh-client-ui-settings-models'])('%s uses only icons exported by the installed primitives package', async (packageName) => { + const require = createRequire(import.meta.url) + const client = await readFile(require.resolve(`@deepseek-ai/${packageName}/package.json`).replace('package.json', 'lib/client.js'), 'utf8') + const primitives = await readFile(require.resolve('@deepseek-ai/dsh-client-ui-primitives'), 'utf8') + const exports = primitives.match(/export \{([^}]+)\}/)?.[1].split(',').map(name => name.trim().split(/\s+as\s+/).at(-1)) + expect(exports).toBeDefined() + const icons = [...new Set([...client.matchAll(/_deepseek_ai_dsh_client_ui_primitives\.(Icon\w+)/g)].map(match => match[1]))] + expect(icons.length).toBeGreaterThan(0) + for (const icon of icons) expect(exports, `missing model selector icon ${icon}`).toContain(icon) +}) diff --git a/test/model-selection-search-patch.test.ts b/test/model-selection-search-patch.test.ts index 5bad6b5d1..a1a10ec8f 100644 --- a/test/model-selection-search-patch.test.ts +++ b/test/model-selection-search-patch.test.ts @@ -91,7 +91,7 @@ describe('composer model search', () => { ) expect(patch).toContain('function filterModelGroups(groups, query)') - expect(patch).toContain('IconSearchOutline16') + expect(patch).toContain('IconSearchOutlineRegular') expect(patch).toContain('children: filteredGroups.map((group)') }) }) diff --git a/test/model-settings-render.test.mjs b/test/model-settings-render.test.mjs new file mode 100644 index 000000000..67966c34c --- /dev/null +++ b/test/model-settings-render.test.mjs @@ -0,0 +1,71 @@ +import { readFile } from 'node:fs/promises' +import { createRequire } from 'node:module' +import vm from 'node:vm' +import { expect, it } from 'vitest' + +it.each(['DeepSeekModelsEditor', 'ModelListEditor'])('%s expands options and edits capacity without losing other capabilities', async (editorName) => { + const require = createRequire(import.meta.url) + const path = require.resolve('@deepseek-ai/dsh-client-ui-settings-models/package.json').replace('package.json', 'lib/client.js') + const source = (await readFile(path, 'utf8')).replace('exports.apply = apply;', `exports.editor = ${editorName}; exports.apply = apply;`) + const states = [] + let cursor = 0 + let editor + const jsx = (type, props) => { + if (type === undefined) throw new Error('Undefined rendered component') + return typeof type === 'function' ? type(props) : { type, props } + } + const react = { + useState(initial) { + const index = cursor++ + if (!(index in states)) states[index] = typeof initial === 'function' ? initial() : initial + return [states[index], value => { states[index] = typeof value === 'function' ? value(states[index]) : value }] + }, + useMemo: fn => fn(), useEffect() {}, useRef: value => ({ current: value }) + } + const primitivesSource = await readFile(require.resolve('@deepseek-ai/dsh-client-ui-primitives'), 'utf8') + const primitives = Object.fromEntries([...primitivesSource.matchAll(/const (Icon\w+) =/g)].map(match => [match[1], () => ({ type: 'svg', props: {} })])) + primitives.Button = props => ({ type: 'button', props }) + primitives.Modal = props => props.open ? ({ type: 'dialog', props }) : null + vm.runInNewContext(source, { window: { __ModuleLoader__: { load({ factory }) { + editor = factory(id => ({ react, 'react/jsx-runtime': { jsx, jsxs: jsx, Fragment: 'fragment' }, '@deepseek-ai/dsh-client-ui-primitives': primitives, '@deepseek-ai/dsh-client-store': {} })[id]).editor + } } } }) + let models = [{ id: 'model', inputModalities: ['text', 'image'], input: ['text', 'image'], contextWindow: 128000, maxTokens: 8000 }] + const props = { probe: { settingsNs: 'llm-pi-ai' }, operations: {}, onBusyChange() {}, models, modelQuery: '', t: key => key, onChange: value => { models = value }, onReset() {}, defaultContextWindow: 256000, defaultMaxTokens: 32000 } + const render = () => { cursor = 0; return editor({ ...props, models }) } + const flatten = node => !node || typeof node !== 'object' ? [] : Array.isArray(node) ? node.flatMap(flatten) : [node, ...flatten(node.props?.children)] + const find = (tree, label) => flatten(tree).find(node => node.props?.['aria-label'] === label) + const contextLabel = editorName === 'DeepSeekModelsEditor' ? 'contextWindow 1' : 'modelContextWindow 1' + const tokensLabel = editorName === 'DeepSeekModelsEditor' ? 'maxTokens 1' : 'modelMaxTokens 1' + let tree = render() + expect(find(tree, contextLabel)).toBeUndefined() + find(tree, 'modelAdvanced 1').props.onClick() + tree = render() + expect(find(tree, contextLabel).props.value).toBe('128K') + expect(find(tree, tokensLabel).props.value).toBe('8K') + find(tree, contextLabel).props.onChange({ target: { value: '256K' } }) + expect(models[0].contextWindow).toBe(256000) + expect(models[0].inputModalities).toEqual(['text', 'image']) + tree = render() + find(tree, contextLabel).props.onBlur?.() + expect(find(render(), contextLabel).props.value).toBe('256K') +}) + +it.each(['loading', 'missing-key', 'ready', 'error'])('onboarding handles %s without an undefined readiness state', async status => { + const require = createRequire(import.meta.url) + const path = require.resolve('@deepseek-ai/dsh-client-ui-settings-models/package.json').replace('package.json', 'lib/client.js') + const source = (await readFile(path, 'utf8')).replace('exports.apply = apply;', 'exports.dialog = DeepSeekOnboardingDialog; exports.apply = apply;') + let dialog + const effects = [] + const react = { useState: initial => [initial, () => {}], useEffect: fn => effects.push(fn) } + const jsx = (type, props) => ({ type, props }) + vm.runInNewContext(source, { window: { __ModuleLoader__: { load({ factory }) { + dialog = factory(id => ({ react, 'react/jsx-runtime': { jsx, jsxs: jsx }, '@deepseek-ai/dsh-client-ui-primitives': {}, '@deepseek-ai/dsh-client-store': {} })[id]).dialog + } } } }) + const row = { entry: { provider: 'deepseek-official', settingsNs: 'llm-deepseek', settingsPath: [], active: true }, apiKeyEnv: 'TEST_ONLY', credential: { configured: status === 'ready', writable: true } } + const state = { status: status === 'error' ? 'error' : status === 'loading' ? 'loading' : 'ready', rows: status === 'loading' ? [] : [row], namespaces: new Map([['llm-deepseek', {}]]), credentialError: null, writable: true } + let completed = 0 + const result = dialog({ automatic: true, explicit: false, useModels: fn => fn(state), complete: () => completed++, controller: { load() {} }, t: key => key, renderSlot: (_name, _props, options) => options.fallback }) + effects.forEach(fn => fn()) + expect(result === null).toBe(status !== 'missing-key') + expect(completed).toBe(['ready', 'error'].includes(status) ? 1 : 0) +}) diff --git a/test/open-in-finder.test.ts b/test/open-in-finder.test.ts index f6631b21c..2e39c721e 100644 --- a/test/open-in-finder.test.ts +++ b/test/open-in-finder.test.ts @@ -1,39 +1,44 @@ -import { readFile, readdir } from 'node:fs/promises' +import { readFile } from 'node:fs/promises' import path from 'node:path' -import { Script } from 'node:vm' -import { describe, expect, it } from 'vitest' -import { patchPath, projectRoot } from './patch-path' +import vm from 'node:vm' +import { describe, expect, it, vi } from 'vitest' -describe('workspace Open in Finder integration', () => { - it('keeps the workspace UI patch on the Harness 0.1.5 package', async () => { - const patch = await readFile( - patchPath('@deepseek-ai/dsh-client-ui-workspace'), - 'utf8' - ) - const patchNames = await readdir(path.join(projectRoot, 'patches')) +const projectRoot = path.resolve(import.meta.dirname, '..') - expect(patchNames).toContain( - '@deepseek-ai+dsh-client-ui-workspace+0.1.5-rc.2.patch' - ) - expect(patchNames).not.toContain( - '@deepseek-ai+dsh-client-ui-workspace+0.1.5-rc.1.patch' - ) - expect(patch).toContain('id: "openInFinder"') - expect(patch).toContain('t("menu.openInFinder")') - expect(patch).toContain('window.dshDesktop.openInFinder(row.cwd)') - expect(patch).toContain('"menu.openInFinder": "在 Finder 中打开"') - expect(patch).toContain('"menu.openInFinder": "Open in Finder"') - }) - - it('leaves the installed workspace bundle syntactically valid', async () => { - const bundle = await readFile( - path.join( - projectRoot, - 'node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/client.js' - ), - 'utf8' - ) - - expect(() => new Script(bundle)).not.toThrow() +describe('workspace Open in file manager integration', () => { + it('resolves the selected session directory through the current session list', async () => { + const source = await readFile(path.join(projectRoot, 'packages/dsh-desktop-client-ui/client.js'), 'utf8') + let definition: { factory: (require: (name: string) => unknown) => { apply: (ctx: unknown) => void } } | undefined + const openInFinder = vi.fn(async () => undefined) + const window = { + __ModuleLoader__: { load: (value: typeof definition) => { definition = value } }, + dshDesktop: { openInFinder } + } + vm.runInNewContext(source, { window, document: { documentElement: { lang: 'en' } } }) + const MenuItemButton = () => null + const registrations: Array<{ config: { id?: string; inject?: () => Record }; component: (props: Record) => unknown }> = [] + const plugin = definition!.factory((name) => { + if (name === 'react') return { createElement: (type: unknown, props: Record, ...children: unknown[]) => ({ type, props: { ...props, children } }) } + if (name === '@deepseek-ai/dsh-client-ui-primitives') return { MenuItemButton } + throw new Error(`Unexpected dependency ${name}`) + }) + plugin.apply({ + effect: vi.fn(), + slots: { + inject: (_name: string, callback: () => unknown) => callback(), + register: (config: (typeof registrations)[number]['config'], component: (props: Record) => unknown) => { + registrations.push({ config, component }) + } + }, + get: (name: string) => name === 'sessions' + ? { list: { getSnapshot: () => ({ byId: { session1: { cwd: '/workspace/project' } } }) } } + : undefined + }) + const folder = registrations.find(({ config }) => config.id === 'desktop-open-session-folder')! + const injected = folder.config.inject!() + const element = folder.component({ sessionId: 'session1', useMenuOpenState: () => [true, vi.fn()], ...injected }) as { type: unknown; props: { onSelect: () => void } } + expect(element.type).toBe(MenuItemButton) + element.props.onSelect() + await vi.waitFor(() => expect(openInFinder).toHaveBeenCalledWith('/workspace/project')) }) }) diff --git a/test/patch-hunk-counts.test.ts b/test/patch-hunk-counts.test.ts index c9848b587..11f6a7d7f 100644 --- a/test/patch-hunk-counts.test.ts +++ b/test/patch-hunk-counts.test.ts @@ -2,7 +2,7 @@ import { createRequire } from 'node:module' import { readdir, readFile } from 'node:fs/promises' import path from 'node:path' import { describe, expect, it } from 'vitest' -import { projectRoot } from './patch-path' +import { patchPath, projectRoot } from './patch-path' const require = createRequire(import.meta.url) const { parsePatchFile } = require('patch-package/dist/patch/parse') as { @@ -30,20 +30,20 @@ describe('patch hunk counts', () => { }) it('keeps image generation and the log bridge in the dsh package.json patch', async () => { - const patch = await readFile( - path.join(projectRoot, 'patches/@deepseek-ai+dsh+0.1.5-rc.2.patch'), - 'utf8' - ) - expect(patch).toContain('+ "dsh-image-generation": "0.1.0",') + const patch = await readFile(patchPath('@deepseek-ai/dsh'), 'utf8') + expect(patch).toContain('+ "dsh-image-generation": "0.1.0"') expect(patch).toContain('+ "dsh-desktop-log-bridge": "0.1.0",') }) it('rejects a dsh hunk header that undercounts the merged dependency lines', async () => { - const patch = await readFile( - path.join(projectRoot, 'patches/@deepseek-ai+dsh+0.1.5-rc.2.patch'), - 'utf8' + const patch = await readFile(patchPath('@deepseek-ai/dsh'), 'utf8') + const manifestStart = patch.indexOf('diff --git a/node_modules/@deepseek-ai/dsh/package.json') + expect(manifestStart).toBeGreaterThanOrEqual(0) + const broken = patch.slice(0, manifestStart) + patch.slice(manifestStart).replace( + /(@@ -\d+,\d+ \+\d+,)(\d+)( @@)/, + (_header: string, prefix: string, count: string, suffix: string) => + `${prefix}${Number(count) - 1}${suffix}` ) - const broken = patch.replace('@@ -28,6 +28,13 @@', '@@ -28,6 +28,12 @@') expect(broken).not.toBe(patch) expect(() => parsePatchFile(broken)).toThrow(/hunk header integrity check failed/) }) diff --git a/test/patch-runtime-compatibility.test.mjs b/test/patch-runtime-compatibility.test.mjs new file mode 100644 index 000000000..76b5c0bb3 --- /dev/null +++ b/test/patch-runtime-compatibility.test.mjs @@ -0,0 +1,50 @@ +import { readFileSync, readdirSync } from 'node:fs' +import { createRequire } from 'node:module' +import ts from 'typescript' +import { expect, it } from 'vitest' + +const require = createRequire(import.meta.url) +const patchedJs = [...new Set(readdirSync('patches').filter(name => name.endsWith('.patch')).flatMap(name => + [...readFileSync(`patches/${name}`, 'utf8').matchAll(/^\+\+\+ b\/(.*\.js)$/gm)].map(match => match[1]) +))] + +it('all patched JavaScript has no unresolved local identifiers', () => { + // Resolve lexical names without loading the dependency tree. Node globals are + // supplied by the actual host; this does not replace runtime behavior tests. + const program = ts.createProgram(patchedJs, { allowJs: true, checkJs: true, noEmit: true, + noResolve: true, target: ts.ScriptTarget.ESNext, module: ts.ModuleKind.ESNext, skipLibCheck: true }) + const failures = program.getSemanticDiagnostics().filter(diagnostic => { + if (![2304, 2552, 18004].includes(diagnostic.code)) return false + const name = diagnostic.file.text.slice(diagnostic.start, diagnostic.start + diagnostic.length) + return !['global', 'setImmediate'].includes(name) + }).map(diagnostic => `${diagnostic.file.fileName}:${diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start).line + 1}: ${ts.flattenDiagnosticMessageText(diagnostic.messageText, ' ')}`) + expect(failures).toEqual([]) +}, 30000) + +it('every patched client uses current primitives exports, including non-icon components', () => { + const source = ts.createSourceFile('primitives.js', readFileSync(require.resolve('@deepseek-ai/dsh-client-ui-primitives'), 'utf8'), ts.ScriptTarget.Latest, true) + const exported = new Set(source.statements.filter(ts.isExportDeclaration).flatMap(statement => + statement.exportClause && ts.isNamedExports(statement.exportClause) ? statement.exportClause.elements.map(element => element.name.text) : [])) + expect(exported.size).toBeGreaterThan(0) + for (const file of patchedJs.filter(file => file.endsWith('/client.js'))) { + const client = readFileSync(file, 'utf8') + for (const match of client.matchAll(/_deepseek_ai_dsh_client_ui_primitives\.(\w+)/g)) { + expect(exported.has(match[1]), `${file}: missing primitives export ${match[1]}`).toBe(true) + } + } +}) + +it('maintained Desktop clients inject only slots declared by the installed Harness clients', () => { + const clients = readdirSync('node_modules/@deepseek-ai').flatMap(name => { + try { return [readFileSync(`node_modules/@deepseek-ai/${name}/lib/client.js`, 'utf8')] } catch (error) { + if (error.code === 'ENOENT') return [] + throw error + } + }) + const declarations = new Set(clients.flatMap(source => [...source.matchAll(/["']([^"']+)["']\s*:\s*\{\s*kind:\s*["'](?:list|single|keyed|chain)["']/g)].map(match => match[1]))) + for (const file of ['packages/dsh-desktop-client-ui/client.js', 'packages/dsh-image-generation/client.js', 'packages/dsh-desktop-market-installer/client.js', 'packages/ppt-runtime/adapter/lib/client.js']) { + for (const match of readFileSync(file, 'utf8').matchAll(/slots\.inject\(["']([^"']+)["']/g)) { + expect(declarations.has(match[1]), `${file}: undeclared slot ${match[1]}`).toBe(true) + } + } +}) diff --git a/test/pi-ai-terminal-replay.test.mjs b/test/pi-ai-terminal-replay.test.mjs new file mode 100644 index 000000000..6f2eb268b --- /dev/null +++ b/test/pi-ai-terminal-replay.test.mjs @@ -0,0 +1,28 @@ +import { readFileSync } from 'node:fs' +import { expect, it } from 'vitest' + +it('reconstructs missing terminal content in native pi-ai format with replay signatures intact', async () => { + const source = readFileSync('node_modules/@deepseek-ai/dsh-llm-pi-ai/lib/index.js', 'utf8') + const helper = name => source.slice(source.indexOf(`function ${name}(`), source.indexOf('\n}', source.indexOf(`function ${name}(`)) + 2) + const streamStart = source.indexOf('async function* toStreamChunks(') + const stream = source.slice(streamStart, source.indexOf('\n}', streamStart) + 2) + const run = new Function('brandString', 'isContextOverflow', `${helper('toPiReplayState')}\n${helper('completeTerminalMessage')}\n${helper('mapUsage')}\n${helper('mapStopReason')}\n${stream}\nreturn toStreamChunks`)(value => value, () => false) + const thinking = { type: 'thinking', thinking: 'reason', thinkingSignature: 'test-signature' } + const text = { type: 'text', text: 'hello', textSignature: 'test-text-signature' } + const toolCall = { type: 'toolCall', id: 'call-1', name: 'example', arguments: { x: 1 }, thoughtSignature: 'test-tool-signature' } + const message = { api: 'test-api', provider: 'test-provider', model: 'test-model', stopReason: 'toolUse', usage: { input: 1, output: 1, cacheRead: 0, cacheWrite: 0, totalTokens: 2, cost: {} } } + const events = [ + { type: 'thinking_end', contentIndex: 0, content: thinking.thinking, partial: { content: [thinking] } }, + { type: 'text_end', contentIndex: 1, content: text.text, partial: { content: [thinking, text] } }, + { type: 'toolcall_end', contentIndex: 2, toolCall }, + { type: 'done', message } + ] + const chunks = [] + for await (const chunk of run(events, 128000, undefined, 'test-model')) chunks.push(chunk) + expect(chunks.filter(chunk => chunk.type === 'block-end').map(chunk => chunk.block.type)).toEqual(['reasoning', 'text', 'tool-call']) + expect(chunks.at(-1).replayState.blocks).toEqual([ + { type: 'reasoning', thinkingSignature: 'test-signature' }, + { type: 'text', textSignature: 'test-text-signature' }, + { type: 'tool-call', thoughtSignature: 'test-tool-signature' } + ]) +}) diff --git a/test/plugin-startup-failure.test.ts b/test/plugin-startup-failure.test.ts index 523ffecd9..1bbac2b05 100644 --- a/test/plugin-startup-failure.test.ts +++ b/test/plugin-startup-failure.test.ts @@ -26,7 +26,7 @@ async function removeTempDir(dir: string): Promise { const roots: string[] = [] afterEach(async () => { await Promise.all(roots.splice(0).map((root) => removeTempDir(root))) }) -async function fixture(sources: string[]) { +async function fixture(sources: string[], peerRange?: string) { const home = await mkdtemp(join(tmpdir(), 'dsh-startup-failure-')) roots.push(home) const profile = join(home, 'profiles', 'web') @@ -36,6 +36,7 @@ async function fixture(sources: string[]) { await mkdir(dir, { recursive: true }) await writeFile(join(dir, 'package.json'), JSON.stringify({ name: names[index], version: '1.2.3', type: 'module', main: './index.js', + ...(peerRange ? { peerDependencies: { '@deepseek-ai/dsh': peerRange } } : {}), dsh: { bundle: { patch: 'cordis.patch.yml' } } })) await writeFile(join(dir, 'index.js'), source) @@ -58,6 +59,7 @@ async function fixture(sources: string[]) { const profile = loadProfile('fixture', 'web', ${JSON.stringify(resolve('node_modules/@deepseek-ai/dsh/package.json'))}, ${JSON.stringify(home)}); await boot('fixture', ${JSON.stringify(join(profile, 'cordis.yml'))}, profile.layers.flatMap(layer => layer.patches), ctx => { ctx.provide('subagents', {}); + ${peerRange ? `ctx.provide('profileContext', { dir: ${JSON.stringify(profile)} });` : ''} }); `) return { home, entry, names } @@ -78,6 +80,29 @@ function run(entry: string) { } describe('structured startup failures through the real bundled loader', () => { + it.each(['0.1.7-rc.1', '0.1.5'])('loads a working plugin with an outdated %s declaration', async range => { + const { entry } = await fixture([ + 'export default function() { process.stdout.write("fixture activated\\n"); }' + ], range) + const result = spawnSync(process.execPath, [resolve('build/harness-node-entry.mjs'), entry], { + encoding: 'utf8', timeout: 15_000 + }) + expect(result.error).toBeUndefined() + expect(result.status, result.stderr).toBe(0) + expect(result.stdout).toContain('fixture activated') + expect(result.stderr).toContain('compatibility warning:') + expect(result.stderr).not.toContain(PLUGIN_FAILURE_PREFIX) + }) + + it('keeps actual API failures recoverable after warning about old declarations', async () => { + const { entry, names } = await fixture([ + 'export default function(ctx) { ctx.subagents.registerContinuableSetup(); }' + ], '0.1.7-rc.1') + const { failures, stderr } = run(entry) + expect(stderr).toContain('compatibility warning:') + expect(failures[0]).toMatchObject({ stage: 'apply', owner: { packageName: names[0] } }) + }) + it('attributes a nested missing-method failure to its root bundle and reuses recovery selection', async () => { const { home, entry, names } = await fixture([ 'export default function(ctx) { ctx.subagents.registerContinuableSetup(); }' diff --git a/test/plugin-upgrade.test.ts b/test/plugin-upgrade.test.ts index 73d2d2a96..6eb95517d 100644 --- a/test/plugin-upgrade.test.ts +++ b/test/plugin-upgrade.test.ts @@ -121,15 +121,15 @@ describe('upgradeMarketInSharedTree', () => { const { home, profile, market, options } = await fixture() const before = await readFile(join(profile, 'package.json'), 'utf8') installMock.mockImplementationOnce(async () => { - await writeFile(join(market, 'package.json'), JSON.stringify({ name: 'dshmarket', version: '1.48.0' })) + await writeFile(join(market, 'package.json'), JSON.stringify({ name: 'dshmarket', version: '1.66.0' })) return { ok: false, detail: 'interrupted after package extraction' } }) - expect((await upgradeMarketInSharedTree({ ...options, targetVersion: '1.48.0' })).ok).toBe(false) + expect((await upgradeMarketInSharedTree({ ...options, targetVersion: '1.66.0' })).ok).toBe(false) expect(JSON.parse(await readFile(marketInstallPendingPath(home), 'utf8')).previousManifest).toBe(before) installMock.mockResolvedValue({ ok: true }) await ensureMarketBaseline({ ...options, dshEntryPath: resolve('node_modules/@deepseek-ai/dsh/lib/bin.js') }) expect(installMock).toHaveBeenCalledTimes(2) - expect(JSON.parse(await readFile(join(profile, 'package.json'), 'utf8')).dependencies.dshmarket).toBe('1.48.0') + expect(JSON.parse(await readFile(join(profile, 'package.json'), 'utf8')).dependencies.dshmarket).toBe('1.66.0') await expect(readFile(marketInstallPendingPath(home))).rejects.toMatchObject({ code: 'ENOENT' }) }) diff --git a/test/plugin-version-policy.test.mjs b/test/plugin-version-policy.test.mjs new file mode 100644 index 000000000..e7e5835c7 --- /dev/null +++ b/test/plugin-version-policy.test.mjs @@ -0,0 +1,45 @@ +import { mkdtemp, mkdir, readFile, rm, writeFile } from 'node:fs/promises' +import { tmpdir } from 'node:os' +import { join, resolve } from 'node:path' +import { afterEach, expect, it } from 'vitest' +import { PluginManager } from '@deepseek-ai/dsh-plugin-manager' + +const roots = [] +afterEach(async () => { await Promise.all(roots.splice(0).map(root => rm(root, { recursive: true, force: true }))) }) + +it('installs old declared peers through the manager and reports a warning instead of rollback', async () => { + const dir = await mkdtemp(join(tmpdir(), 'dsh-version-install-')) + roots.push(dir) + await writeFile(join(dir, 'package.json'), '{}') + // Replace only the package-manager executable; exercise the real pre/post + // install checks, manifest transaction and output events without registry I/O. + const fakePnpm = join(dir, 'pnpm.mjs') + const manifest = { name: 'fixture-old-peers', version: '1.0.0', + peerDependencies: { '@deepseek-ai/dsh': '0.1.7-rc.1' }, + dsh: { bundle: { patch: 'cordis.patch.yml' } } } + await writeFile(fakePnpm, ` + import {mkdirSync, writeFileSync} from 'node:fs'; + const manifest = ${JSON.stringify(manifest)}; + if (process.argv.includes('view')) { console.log(JSON.stringify(manifest)); } + else { + mkdirSync('node_modules/fixture-old-peers', {recursive:true}); + writeFileSync('node_modules/fixture-old-peers/package.json', JSON.stringify(manifest)); + writeFileSync('node_modules/fixture-old-peers/cordis.patch.yml', '[]'); + writeFileSync('package.json', JSON.stringify({dependencies:{'fixture-old-peers':'1.0.0'}})); + } + `) + const events = [] + const manager = { + profile: { dir, name: 'web', installAnchor: resolve('node_modules/@deepseek-ai/dsh/package.json'), + packageManager: { command: process.execPath, args: [fakePnpm] } }, + abort: new AbortController(), outputBytes: 100000, idleTimeoutMs: 10000, + inspectTimeoutMs: 10000, packageOperations: new Set(), + ownerContext: { emit: (_event, payload) => events.push(payload) } + } + const result = await PluginManager.prototype.runPnpm.call(manager, ['add', 'fixture-old-peers@1.0.0']) + expect(result.exitCode).toBe(0) + expect(result.incompatible ?? []).toEqual([]) + expect(events.some(event => event.text.includes('Compatibility is unverified'))).toBe(true) + expect(JSON.parse(await readFile(join(dir, 'package.json'), 'utf8')).dependencies['fixture-old-peers']).toBe('1.0.0') + expect(JSON.parse(await readFile(join(dir, 'node_modules/fixture-old-peers/package.json'), 'utf8'))).toEqual(manifest) +}) diff --git a/test/ppt-activation.test.mjs b/test/ppt-activation.test.mjs index 2fc81dfcf..b7ae03c2c 100644 --- a/test/ppt-activation.test.mjs +++ b/test/ppt-activation.test.mjs @@ -94,8 +94,12 @@ async function fixture(existingRoot) { } function automaticMessages(agent) { - return agent.session.deriveMessages().filter(m => m.source.kind === 'plugin' - && ['dsh-ppt-skill', 'dsh-ppt-composer'].includes(m.source.plugin)) + return agent.session.deriveMessages().filter(m => { + const kind = m.source?.kind + const plugin = m.source?.plugin || (typeof kind === 'string' && kind.startsWith('plugin:') ? kind.slice('plugin:'.length) : kind) + return (kind === 'plugin' || (typeof kind === 'string' && kind.startsWith('plugin:')) || ['dsh-ppt-skill', 'dsh-ppt-composer'].includes(kind)) + && ['dsh-ppt-skill', 'dsh-ppt-composer'].includes(plugin) + }) } describe('PPT instructions follow the session composer button', () => { @@ -203,7 +207,7 @@ describe('PPT catalog without a session', () => { const f = await fixture() const catalog = await f.rpc('template/catalog', {}) expect(catalog.ok).toBe(true) - expect(catalog.value.status).toBe('ok') + expect(catalog.value.status, JSON.stringify(catalog.value)).toBe('ok') expect(catalog.value.data.templates.some(template => template.origin === 'built-in')).toBe(true) await expect(stat(path.join(f.root, 'sessions'))).rejects.toMatchObject({ code: 'ENOENT' }) const denied = await f.rpc('presentation/mode', {}) @@ -314,4 +318,53 @@ describe('PPT identity compatibility', () => { expect(surface).toContain('Please compare Kimi and other tools.') expect(automaticMessages(agent)).toHaveLength(0) }) + + it('emits format v4 producer-owned source kinds without bare plugin wrappers', async () => { + const f = await fixture() + const agent = await f.agent() + await f.toggle(agent, true) + await f.preStep(agent) + const messages = agent.session.deriveMessages().filter(m => m.role === 'user' && m.source?.kind !== 'user') + expect(messages.length).toBeGreaterThanOrEqual(2) + for (const msg of messages) { + expect(msg.source.kind).not.toBe('plugin') + expect(typeof msg.source.kind).toBe('string') + expect(msg.source.kind.startsWith('plugin:')).toBe(true) + } + const skillMsg = messages.find(m => m.source.kind === 'plugin:dsh-ppt-skill') + expect(skillMsg).toBeDefined() + expect(skillMsg.source.form).toBe('snapshot') + const composerMsg = messages.find(m => m.source.kind === 'plugin:dsh-ppt-composer') + expect(composerMsg).toBeDefined() + expect(composerMsg.source.form).toBe('snapshot') + }) + + it('recognizes format v4 rewritten historical sessions without duplicate skill injection', async () => { + const f = await fixture() + const agent = await f.agent() + await f.toggle(agent, true) + // In format v4, historical plugin messages have source.plugin dropped and source.kind rewritten to plugin: + agent.session.append('user/message', createUserMessage({ + content: [{ type: 'text', text: 'Existing PPT instructions' }], + source: { kind: 'plugin:dsh-ppt-skill', form: 'snapshot', sections: [{ name: 'dsh-ppt', text: 'Existing PPT instructions' }] } + }), { surfaceOp: 'append' }) + await f.preStep(agent) + const skillMessages = agent.session.deriveMessages().filter(m => m.source?.kind === 'plugin:dsh-ppt-skill' || m.source?.plugin === 'dsh-ppt-skill') + expect(skillMessages).toHaveLength(1) + }) + + it('clears format v4 rewritten historical automatic prompts when PPT is off', async () => { + const f = await fixture() + const agent = await f.agent() + agent.session.append('user/message', createUserMessage({ + content: [{ type: 'text', text: 'Old V4 rewritten composer state' }], + source: { kind: 'plugin:kimi-ppt-composer', form: 'snapshot', sections: [{ name: 'kimi-ppt-composer', text: 'Old V4 rewritten composer state' }] } + }), { surfaceOp: 'append' }) + await f.preStep(agent) + const surface = JSON.stringify(agent.session.deriveMessages()) + expect(surface).not.toContain('Old V4 rewritten composer state') + const cleared = agent.session.deriveMessages().find(m => m.source?.kind === 'plugin:dsh-ppt-context-cleared') + expect(cleared).toBeDefined() + expect(cleared.source.kind).not.toBe('plugin') + }) }) diff --git a/test/ppt-fonts.test.mjs b/test/ppt-fonts.test.mjs index d34b542d5..28d9565cd 100644 --- a/test/ppt-fonts.test.mjs +++ b/test/ppt-fonts.test.mjs @@ -21,7 +21,7 @@ it('uses the paired Chinese face for Chinese text and the Latin face for English describe('PPT bilingual catalog', () => { it('has English-only visible preview content and Chinese source examples in every pack', async () => { - const root = path.resolve(import.meta.dirname, '../packages/ppt-runtime/templates') + const root = path.resolve(import.meta.dirname, '../.build/ppt-runtime/templates') let count = 0 function inspect(value, file) { if (!value || typeof value !== 'object') return diff --git a/test/ppt-integration.test.ts b/test/ppt-integration.test.ts index a8fff0254..4dbea7169 100644 --- a/test/ppt-integration.test.ts +++ b/test/ppt-integration.test.ts @@ -1,57 +1,80 @@ import { createHash } from 'node:crypto' -import { readFile } from 'node:fs/promises' +import { lstat, readFile, readdir } from 'node:fs/promises' import path from 'node:path' -import { gunzipSync } from 'node:zlib' import { describe, expect, it } from 'vitest' import { patchPath, projectRoot } from './patch-path' -const artifacts = JSON.parse(await readFile(path.join(projectRoot, 'packages/ppt-runtime/artifacts.json'), 'utf8')) as Record<'core' | 'adapter', { file: string; sha256: string }> +type PackageName = 'core' | 'adapter' +const packageNames: Record = { core: 'dsh-ppt', adapter: 'dsh-ppt-composer' } -async function artifact(name: keyof typeof artifacts): Promise { - return readFile(path.join(projectRoot, 'packages', 'ppt-bundles', artifacts[name].file)) -} - -function tarEntries(archive: Buffer): Map { - const tar = gunzipSync(archive) +async function artifact(name: PackageName): Promise> { + const root = path.join(projectRoot, '.build', 'ppt-runtime', 'packages', packageNames[name]) const entries = new Map() - let offset = 0 - while (offset + 512 <= tar.length) { - const header = tar.subarray(offset, offset + 512) - const name = header.subarray(0, 100).toString('utf8').replace(/\0.*$/u, '') - if (name.length === 0) break - const prefix = header.subarray(345, 500).toString('utf8').replace(/\0.*$/u, '') - const sizeText = header.subarray(124, 136).toString('ascii').replace(/\0.*$/u, '').trim() - const size = Number.parseInt(sizeText || '0', 8) - const contentOffset = offset + 512 - const fullName = prefix.length === 0 ? name : `${prefix}/${name}` - entries.set(fullName, tar.subarray(contentOffset, contentOffset + size)) - offset = contentOffset + Math.ceil(size / 512) * 512 + async function visit(directory: string, relative = ''): Promise { + for (const entry of await readdir(directory, { withFileTypes: true })) { + const child = path.join(directory, entry.name) + const childRelative = path.posix.join(relative, entry.name) + if (entry.isDirectory()) await visit(child, childRelative) + else if (entry.isFile()) entries.set(`package/${childRelative}`, await readFile(child)) + } } + await visit(root) return entries } +function artifactText(entries: Map): string { + return Buffer.concat([...entries.values()]).toString('utf8') +} + describe('DSH PPT built-in plugin', () => { - it('pins the reviewed plugin artifacts byte-for-byte', async () => { + it('builds local source packages into staged and installed distributions', async () => { const lock = JSON.parse(await readFile(path.join(projectRoot, 'package-lock.json'), 'utf8')) as { - packages: Record + packages: Record + } + const sources: Record = { + core: 'packages/ppt-runtime/core', + adapter: 'packages/ppt-runtime/adapter' } - const packagePaths = { - core: 'node_modules/dsh-ppt', - adapter: 'node_modules/dsh-ppt-composer' - } as const - for (const name of Object.keys(artifacts) as (keyof typeof artifacts)[]) { - const archive = await artifact(name) - expect(createHash('sha256').update(archive).digest('hex')).toBe(artifacts[name].sha256) - expect(lock.packages[packagePaths[name]]?.integrity).toBe( - `sha512-${createHash('sha512').update(archive).digest('base64')}` + for (const name of Object.keys(packageNames) as PackageName[]) { + const packageName = packageNames[name] + expect(lock.packages[`node_modules/${packageName}`]).toMatchObject({ + resolved: sources[name], link: true + }) + expect((await lstat(path.join(projectRoot, 'node_modules', packageName))).isSymbolicLink()).toBe(false) + const staged = await artifact(name) + expect(await readFile(path.join(projectRoot, 'node_modules', packageName, 'lib/client.js'))).toEqual( + staged.get('package/lib/client.js') ) } }) + it('injects personal-template UI into both clients without bundling checkout dependencies', async () => { + for (const name of ['core', 'adapter'] as const) { + const entries = await artifact(name) + expect([...entries.keys()].some(file => file.startsWith('package/node_modules/'))).toBe(false) + const client = entries.get('package/lib/client.js')?.toString('utf8') ?? '' + expect(client).toContain('function PersonalTemplateManager(') + expect(client).not.toContain('/* PERSONAL_TEMPLATE_MANAGER */') + } + }) + + it('ships Harness 0.1.7-compatible peer ranges in both generated packages', async () => { + const expected = '^0.1.5-rc.1 || ^0.1.6-alpha.2 || ^0.1.7-rc.1 || ^0.1.7-rc.2' + const core = JSON.parse((await artifact('core')).get('package/package.json')!.toString('utf8')) + const adapter = JSON.parse((await artifact('adapter')).get('package/package.json')!.toString('utf8')) + expect(core.peerDependencies['@deepseek-ai/cordis']).toBe('~4.0.4') + expect(adapter.peerDependencies['@deepseek-ai/cordis']).toBe('~4.0.4') + + for (const [name, range] of Object.entries(core.peerDependencies as Record)) { + if (name.startsWith('@deepseek-ai/dsh-')) expect(range).toBe(expected) + } + expect(adapter.peerDependencies['@deepseek-ai/dsh-invariants']).toBe(expected) + }) + it('ships one PPT composer surface and excludes the Tencent route', async () => { - const core = gunzipSync(await artifact('core')).toString('utf8') - const adapter = gunzipSync(await artifact('adapter')).toString('utf8') + const core = artifactText(await artifact('core')) + const adapter = artifactText(await artifact('adapter')) const excluded = /\b(?:tencent|slidep|editor_sdk)\b|workbuddy[- ]runtime|\bppt_(?:create|render|write_page)\b/iu expect(core).toContain('dsh-ppt') @@ -64,15 +87,16 @@ describe('DSH PPT built-in plugin', () => { }) it('ships every JavaScript chunk imported by the Host entry', async () => { - const archive = gunzipSync(await artifact('core')).toString('utf8') - const chunk = /from "\.\/(pptd-[A-Za-z0-9_-]+\.js)"/u.exec(archive)?.[1] + const entries = await artifact('core') + const host = entries.get('package/lib/index.js')?.toString('utf8') ?? '' + const chunk = /from "\.\/(pptd-[A-Za-z0-9_-]+\.js)"/u.exec(host)?.[1] expect(chunk).toBeDefined() - expect(archive).toContain(`package/lib/${chunk}`) + expect(entries.has(`package/lib/${chunk}`)).toBe(true) }) it('exposes geometry-derived text capacity to the PPT authoring workflow', async () => { - const entries = tarEntries(await artifact('core')) + const entries = await artifact('core') const protocol = entries.get('package/lib/types/protocol.d.ts')?.toString('utf8') ?? '' const host = entries.get('package/lib/index.js')?.toString('utf8') ?? '' const skill = entries.get('package/skills/dsh-ppt/SKILL.md')?.toString('utf8') ?? '' @@ -85,7 +109,7 @@ describe('DSH PPT built-in plugin', () => { }) it('blocks overflowing text before rendering and preserves the authored font size', async () => { - const entries = tarEntries(await artifact('core')) + const entries = await artifact('core') const chunkName = [...entries.keys()].find(name => /^package\/lib\/pptd-[A-Za-z0-9_-]+\.js$/u.test(name)) const renderer = chunkName === undefined ? '' : entries.get(chunkName)?.toString('utf8') ?? '' const renderTextStart = renderer.indexOf('function renderText(') @@ -101,7 +125,7 @@ describe('DSH PPT built-in plugin', () => { }) it('ships sixteen maintained templates, English previews and Chinese sources', async () => { - const entries = tarEntries(await artifact('core')) + const entries = await artifact('core') const designs = [...entries.keys()].filter(name => /^package\/skills\/dsh-ppt\/references\/[^/]+\/[^/]+\/design\.md$/u.test(name)) const expected = [ ['work/curated-modular-logistics-system', 12], @@ -130,7 +154,7 @@ describe('DSH PPT built-in plugin', () => { it('excludes withdrawn bytes and shares build-listed local preview assets without embedded copies', async () => { const excluded = JSON.parse(await readFile(path.join(projectRoot, 'packages/ppt-runtime/excluded-assets.json'), 'utf8')) as { file: string; sha256: string }[] const denied = new Set(excluded.map(item => item.sha256)) - const core = tarEntries(await artifact('core')) + const core = await artifact('core') const referenceImages = [...core].filter(([name]) => name.startsWith('package/skills/dsh-ppt/references/') && name.endsWith('.jpg')) const allowed = new Set(referenceImages.map(([, bytes]) => createHash('sha256').update(bytes).digest('hex'))) expect(allowed.size).toBe(192) @@ -148,15 +172,13 @@ describe('DSH PPT built-in plugin', () => { } expect(core.get('package/lib/index.js')!.toString()).toContain('registerPreviewAssets(ctx, previewFiles') for (const name of ['core', 'adapter'] as const) { - const entries = tarEntries(await artifact(name)) + const entries = await artifact(name) for (const [file, bytes] of entries) { expect(denied.has(createHash('sha256').update(bytes).digest('hex')), file).toBe(false) expect(excluded.some(item => file === `package/${item.file}`), file).toBe(false) } const client = entries.get('package/lib/client.js')!.toString() expect(client).not.toContain('data:image/jpeg;base64,') - // Preview JPEGs stay out of the client. The cap only leaves room for the - // inlined personal-template manager and unbound staging logic. expect(Buffer.byteLength(client)).toBeLessThan(120_000) const urls = [...client.matchAll(/\/dsh-ppt\/previews\/([a-f0-9]{64})\.jpg/gu)] expect(urls).toHaveLength(192) @@ -165,7 +187,7 @@ describe('DSH PPT built-in plugin', () => { } }) - it('places the PPT action beside the agent preset and the catalog below the input', async () => { + it('keeps hero mode actions available while requiring a session for the shared composer dock', async () => { const client = await readFile(path.join( projectRoot, 'node_modules', @@ -183,7 +205,7 @@ describe('DSH PPT built-in plugin', () => { const owner = client.indexOf('extensionZone: zone') const input = client.indexOf('className: clsx(InputBar_module_css_default.card', owner) const catalog = client.indexOf( - 'extensionZone !== void 0 || sessionId === void 0 ? renderSlot("conversation.composer.dock", extensionZone ?? {}) : null', + 'input !== void 0 && sessionId !== void 0 ? renderSlot("conversation.composer.dock", extensionZone ?? {}) : null', input ) const modeScope = client.slice(client.indexOf('"conversation.hero.modeActions": {'), client.indexOf('"conversation.hero.modeActions": {') + 180) @@ -195,7 +217,7 @@ describe('DSH PPT built-in plugin', () => { expect(input).toBeGreaterThan(owner) expect(catalog).toBeGreaterThan(input) expect(modeScope).toContain('scope: "session-maybe"') - expect(dockScope).toContain('scope: "session-maybe"') + expect(dockScope).toContain('scope: "session"') }) it('integrates hero mode actions with the adjacent agent-preset control style', async () => { @@ -217,6 +239,22 @@ describe('DSH PPT built-in plugin', () => { expect(patch).toContain('button:focus-visible') }) + it('keeps the PPT slot kind and scope aligned with their published types', async () => { + const root = path.join(projectRoot, 'node_modules', '@deepseek-ai', 'dsh-client-ui-conversation', 'lib') + const runtime = await readFile(path.join(root, 'client.js'), 'utf8') + const types = await readFile(path.join(root, 'types/client/contract/slots.d.ts'), 'utf8') + for (const [name, scope] of [ + ['conversation.hero.modeActions', 'session-maybe'], + ['conversation.hero.dock', 'session-maybe'], + ['conversation.input.accessory', 'session'], + ['conversation.composer.dock', 'session'] + ] as const) { + const escaped = name.replaceAll('.', '\\.') + expect(runtime).toMatch(new RegExp(`"${escaped}": \\{\\s*kind: "list",\\s*scope: "${scope}"`)) + expect(types).toMatch(new RegExp(`'${escaped}': \\{\\s*kind: 'list';\\s*scope: '${scope}'`)) + } + }) + it('renders the selected template before editable prompt text', async () => { const client = await readFile(path.join( projectRoot, @@ -228,26 +266,22 @@ describe('DSH PPT built-in plugin', () => { ), 'utf8') const promptRow = client.indexOf('className: InputBar_module_css_default.promptRow') const accessory = client.indexOf('className: InputBar_module_css_default.accessory', promptRow) - const scroll = client.indexOf('ref: scrollRef', promptRow) + const editor = client.indexOf('(0, react_jsx_runtime.jsx)(DraftEditor, {', promptRow) expect(promptRow).toBeGreaterThan(-1) expect(accessory).toBeGreaterThan(promptRow) - expect(scroll).toBeGreaterThan(accessory) - expect(client).toContain('children: accessory ?? renderSlot("conversation.input.accessory", extensionZone)') + expect(editor).toBeGreaterThan(accessory) + expect(client).toContain('children: accessory ?? (sessionId === void 0 ? null : renderSlot("conversation.input.accessory", extensionZone))') }) - it('declares both local artifacts and mounts only the PPT composer', async () => { + it('declares both local source packages and mounts only the PPT composer', async () => { const manifest = JSON.parse(await readFile(path.join(projectRoot, 'package.json'), 'utf8')) as { dependencies: Record } const profilePatch = await readFile(path.join(projectRoot, 'build', 'dsh-desktop.patch.yml'), 'utf8') - expect(manifest.dependencies['dsh-ppt']).toBe( - `file:packages/ppt-bundles/${artifacts.core.file}` - ) - expect(manifest.dependencies['dsh-ppt-composer']).toBe( - `file:packages/ppt-bundles/${artifacts.adapter.file}` - ) + expect(manifest.dependencies['dsh-ppt']).toBe('file:packages/ppt-runtime/core') + expect(manifest.dependencies['dsh-ppt-composer']).toBe('file:packages/ppt-runtime/adapter') expect(profilePatch).toContain("name: 'dsh-ppt-composer'") expect(profilePatch).not.toContain('office-ppt-standard-adapter') expect(profilePatch).not.toContain('name: dsh-ppt') diff --git a/test/ppt-package-projection.test.ts b/test/ppt-package-projection.test.ts new file mode 100644 index 000000000..7842de03e --- /dev/null +++ b/test/ppt-package-projection.test.ts @@ -0,0 +1,52 @@ +import { mkdtemp, mkdir, readFile, rm, writeFile } from 'node:fs/promises' +import { tmpdir } from 'node:os' +import path from 'node:path' +import { afterEach, describe, expect, it } from 'vitest' +import { replaceInstalledPackages } from '../scripts/ppt-package-projection.mjs' + +const roots: string[] = [] + +async function fixture(): Promise<{ root: string; nodeModules: string; stages: { packageName: string; source: string }[] }> { + const root = await mkdtemp(path.join(tmpdir(), 'ppt-package-projection-')) + roots.push(root) + const nodeModules = path.join(root, 'node_modules') + await mkdir(nodeModules) + const stages = [] + for (const packageName of ['dsh-ppt', 'dsh-ppt-composer']) { + const current = path.join(nodeModules, packageName) + const source = path.join(root, 'stages', packageName) + await mkdir(current, { recursive: true }) + await mkdir(source, { recursive: true }) + await writeFile(path.join(current, 'generation.txt'), 'old') + await writeFile(path.join(source, 'generation.txt'), 'new') + stages.push({ packageName, source }) + } + return { root, nodeModules, stages } +} + +afterEach(async () => { + await Promise.all(roots.splice(0).map(root => rm(root, { recursive: true, force: true }))) +}) + +describe('PPT package projection transaction', () => { + it('publishes both staged packages together', async () => { + const { nodeModules, stages } = await fixture() + await replaceInstalledPackages(stages, { nodeModulesRoot: nodeModules }) + for (const { packageName } of stages) { + expect(await readFile(path.join(nodeModules, packageName, 'generation.txt'), 'utf8')).toBe('new') + } + }) + + it('restores the previous pair when the second replacement fails', async () => { + const { nodeModules, stages } = await fixture() + await expect(replaceInstalledPackages(stages, { + nodeModulesRoot: nodeModules, + beforeReplace: (_packageName: string, index: number) => { + if (index === 1) throw new Error('simulated second-package failure') + } + })).rejects.toThrow('simulated second-package failure') + for (const { packageName } of stages) { + expect(await readFile(path.join(nodeModules, packageName, 'generation.txt'), 'utf8')).toBe('old') + } + }) +}) diff --git a/test/ppt-personal-templates.test.mjs b/test/ppt-personal-templates.test.mjs index 9547392a6..07b093a91 100644 --- a/test/ppt-personal-templates.test.mjs +++ b/test/ppt-personal-templates.test.mjs @@ -1,6 +1,5 @@ import { randomUUID, randomBytes, createHash } from 'node:crypto'; -import { execFileSync } from 'node:child_process'; -import { mkdtemp, mkdir, readFile, writeFile, rm, readdir, symlink } from 'node:fs/promises'; +import { cp, mkdtemp, mkdir, readFile, writeFile, rm, readdir, symlink } from 'node:fs/promises'; import os from 'node:os'; import path from 'node:path'; import { Readable } from 'node:stream'; @@ -15,7 +14,7 @@ let apply, packageRoot, MAX_PERSONAL_TEMPLATE_BASE64_CHARS, MAX_PERSONAL_TEMPLAT const cleanups = []; beforeAll(async () => { packageRoot = await mkdtemp(path.resolve('node_modules/.ppt-personal-')); - execFileSync('tar', ['-xzf', 'packages/ppt-bundles/dsh-ppt-0.1.1-rc.2-desktop-20260906.tgz', '-C', packageRoot, '--strip-components=1']); + await cp(path.resolve('.build/ppt-runtime/packages/dsh-ppt'), packageRoot, { recursive: true }); ({ apply } = await import(pathToFileURL(path.join(packageRoot, 'lib/index.js')))); ({ MAX_PERSONAL_TEMPLATE_BASE64_CHARS, MAX_PERSONAL_TEMPLATE_HTTP_BODY_BYTES } = await import(pathToFileURL(path.join(packageRoot, 'lib/personal-templates.js')))); }); diff --git a/test/ppt-source-build-contract.test.ts b/test/ppt-source-build-contract.test.ts new file mode 100644 index 000000000..b2f9e8175 --- /dev/null +++ b/test/ppt-source-build-contract.test.ts @@ -0,0 +1,57 @@ +import { execFileSync } from 'node:child_process' +import { readFile } from 'node:fs/promises' +import path from 'node:path' +import { describe, expect, it } from 'vitest' +import { projectRoot } from './patch-path' + +const generatedPatterns = [ + 'packages/ppt-bundles', + 'packages/ppt-runtime/templates', + 'packages/ppt-runtime/artifacts.json' +] + +describe('PPT source build contract', () => { + it('does not track self-built packages, templates, previews, or hash manifests', () => { + const tracked = execFileSync('git', ['ls-files', ...generatedPatterns], { + cwd: projectRoot, + encoding: 'utf8' + }).trim() + expect(tracked).toBe('') + }) + + it('bootstraps from local source packages without generated tgz dependencies', async () => { + const manifest = JSON.parse(await readFile(path.join(projectRoot, 'package.json'), 'utf8')) + const lock = await readFile(path.join(projectRoot, 'package-lock.json'), 'utf8') + expect(manifest.dependencies['dsh-ppt']).toBe('file:packages/ppt-runtime/core') + expect(manifest.dependencies['dsh-ppt-composer']).toBe('file:packages/ppt-runtime/adapter') + expect(lock).not.toContain('ppt-bundles') + }) + + it('runs one preparation pipeline before dev, build, test, and package consumers', async () => { + const manifest = JSON.parse(await readFile(path.join(projectRoot, 'package.json'), 'utf8')) + expect(manifest.scripts['ppt:build']).toBe('node scripts/prepare-ppt-runtime.mjs') + expect(manifest.scripts.dev).toMatch(/^npm run ppt:build && /u) + expect(manifest.scripts.build).toMatch(/^npm run ppt:build && /u) + expect(manifest.scripts.pretest).toBe('npm run ppt:build') + expect(manifest.scripts['pretest:watch']).toBe('npm run ppt:build') + for (const name of Object.keys(manifest.scripts).filter(name => name.startsWith('package:'))) { + expect(manifest.scripts[name]).toContain('npm run build') + } + }) + + it('packages the current staged directories instead of node_modules links', async () => { + const manifest = JSON.parse(await readFile(path.join(projectRoot, 'package.json'), 'utf8')) + const files = manifest.build.files + expect(manifest.build.afterPack).toBe('scripts/verify-packaged-ppt-runtime.cjs') + expect(files).toContain('!node_modules/dsh-ppt{,/**}') + expect(files).toContain('!node_modules/dsh-ppt-composer{,/**}') + expect(files).toContainEqual(expect.objectContaining({ + from: '.build/ppt-runtime/packages/dsh-ppt', + to: 'node_modules/dsh-ppt' + })) + expect(files).toContainEqual(expect.objectContaining({ + from: '.build/ppt-runtime/packages/dsh-ppt-composer', + to: 'node_modules/dsh-ppt-composer' + })) + }) +}) diff --git a/test/ppt-unbound-mode.test.mjs b/test/ppt-unbound-mode.test.mjs index 151fdfae5..e868a4bb2 100644 --- a/test/ppt-unbound-mode.test.mjs +++ b/test/ppt-unbound-mode.test.mjs @@ -241,3 +241,61 @@ describe('unbound PPT mode', () => { expect(calls).toEqual([{ route: '/dsh-ppt', endpoint: 'template/catalog', payload: {} }]) }) }) + +describe('PPT hero and session dock routing', () => { + it('mounts only the hero dock without a session and only the shared dock with input', async () => { + const runtime = await readFile(path.resolve('node_modules/@deepseek-ai/dsh-client-ui-conversation/lib/client.js'), 'utf8') + const expression = /children: \[([^\n]+), activity \?/.exec(runtime)?.[1] + expect(expression).toBeDefined() + const render = new Function('sessionId', 'input', 'extensionZone', 'renderSlot', `return ${expression}`) + const zone = { marker: 'owner' } + const calls = [] + const renderSlot = (name, owner) => { calls.push({ name, owner }); return name } + const heroExpression = /sessionId === void 0 \? renderSlot\("conversation.hero.dock", zone \?\? \{\}\) : null/.exec(runtime)?.[0] + expect(heroExpression).toBeDefined() + const hero = new Function('sessionId', 'zone', 'renderSlot', `return ${heroExpression}`) + expect(hero(undefined, zone, renderSlot)).toBe('conversation.hero.dock') + expect(render(undefined, undefined, zone, renderSlot)).toBeNull() + expect(hero('session-a', zone, renderSlot)).toBeNull() + expect(render('session-a', {}, zone, renderSlot)).toBe('conversation.composer.dock') + expect(render('session-a', undefined, zone, renderSlot)).toBeNull() + expect(calls).toEqual([ + { name: 'conversation.hero.dock', owner: zone }, + { name: 'conversation.composer.dock', owner: zone } + ]) + }) + + it('registers the same chooser and shared mode store for both mutually exclusive docks', () => { + const registered = new Map() + const dock = () => null + const mode = new Store() + const injectHero = sessionId => ({ mode, sessionId }) + const apply = new Function('officePptHeroInjection', 'OfficePptStandardModeAction', 'OfficePptStandardInputAccessory', 'OfficePptStandardComposerDock', 'NS', + `${slice(adapter, 'function applyStandard(ctx)', '//#endregion')}\nreturn applyStandard;` + )(() => injectHero, () => null, () => null, dock, 'dsh-ppt') + apply({ slots: { inject: (_name, register) => register(), register: (config, component) => registered.set(config.name, { config, component }) } }) + for (const name of ['conversation.hero.dock', 'conversation.composer.dock']) { + expect(registered.get(name).component).toBe(dock) + expect(registered.get(name).config.inject(undefined).mode).toBe(mode) + } + mode.setMode(undefined, 'ppt') + expect(registered.get('conversation.hero.modeActions').config.inject(undefined).mode).toBe(mode) + }) +}) + +describe('PPT panel geometry', () => { + it('uses the composer width instead of the shrink-wrapped dock width and clamps to the viewport', () => { + const values = new Map() + const source = slice(adapter, 'const syncGeometry = () => {', 'const resizeObserver =') + const sync = new Function('root', 'scrollBody', 'composerCard', 'panel', 'TEMPLATE_PANEL_MIN_HEIGHT_PX', 'TEMPLATE_DOCK_BOTTOM_PX', `${source}\nreturn syncGeometry;`)( + { style: { setProperty: (name, value) => values.set(name, value) } }, + { getBoundingClientRect: () => ({ width: 720, bottom: 900 }) }, + { getBoundingClientRect: () => ({ width: 900 }) }, + { getBoundingClientRect: () => ({ top: 500, width: 32 }) }, + 120, 16 + ) + sync() + expect(values.get('--office-ppt-template-panel-width')).toBe('720px') + expect(values.get('--office-ppt-template-panel-height')).toBe('384px') + }) +}) diff --git a/test/ppt-validation.test.mjs b/test/ppt-validation.test.mjs index b183dc89e..5d11422c2 100644 --- a/test/ppt-validation.test.mjs +++ b/test/ppt-validation.test.mjs @@ -1,9 +1,9 @@ -import { beforeAll, afterAll, afterEach, describe, it, expect } from 'vitest' +import { beforeAll, afterEach, describe, it, expect } from 'vitest' import { mkdtemp, mkdir, writeFile, readFile, readdir, realpath, rm, symlink } from 'node:fs/promises' import path from 'node:path' import os from 'node:os' import { pathToFileURL } from 'node:url' -import { execFileSync, spawnSync } from 'node:child_process' +import { spawnSync } from 'node:child_process' import { randomUUID } from 'node:crypto' import yaml from 'js-yaml' import { unzipSync } from 'fflate' @@ -12,13 +12,11 @@ import { validateJsonSchemaValue } from '@deepseek-ai/dsh-tools' let packageRoot, apply, cli const cleanups = [] beforeAll(async () => { - // Test the distributable archive, with ordinary dependency resolution from node_modules. - packageRoot = await mkdtemp(path.resolve('node_modules/.ppt-validation-')) - execFileSync('tar', ['-xzf', 'packages/ppt-bundles/dsh-ppt-0.1.1-rc.2-desktop-20260906.tgz', '-C', packageRoot, '--strip-components=1']) + // Test the generated package that the unified build projected into node_modules. + packageRoot = path.resolve('node_modules/dsh-ppt') ;({ apply } = await import(pathToFileURL(path.join(packageRoot, 'lib/index.js')))) cli = path.join(packageRoot, 'lib/bin.js') }) -afterAll(async () => { if (packageRoot) await rm(packageRoot, { recursive: true, force: true }) }) afterEach(async () => { for (const dir of cleanups.splice(0)) await rm(dir, { recursive: true, force: true }) }) async function fixture({ broken = true, malformed = false } = {}) { diff --git a/test/preset-toolbar.test.mjs b/test/preset-toolbar.test.mjs new file mode 100644 index 000000000..784ea792e --- /dev/null +++ b/test/preset-toolbar.test.mjs @@ -0,0 +1,41 @@ +import { readFileSync } from 'node:fs' +import ts from 'typescript' +import { expect, it, vi } from 'vitest' + +const source = readFileSync('node_modules/@deepseek-ai/dsh-client-ui-agent-preset/lib/client.js', 'utf8') +const ast = ts.createSourceFile('client.js', source, ts.ScriptTarget.Latest, true) +let section +function visit(node) { + if (ts.isFunctionDeclaration(node) && node.name?.text === 'AgentPresetSection') section = node.getText(ast) + ts.forEachChild(node, visit) +} +visit(ast) + +it.each(['en', 'zh'])('keeps preset actions beside the heading with working search/import/browse (%s)', lang => { + const Button = () => {} + const open = vi.fn() + const setSearch = vi.fn() + let stateIndex = 0 + const jsx = (type, props) => ({ type, props }) + const render = new Function('react', 'react_jsx_runtime', '_deepseek_ai_dsh_client_ui_primitives', 'AgentPresetSection_module_css_default', 'document', 'window', `${section}; return AgentPresetSection`)( + { useState: initial => [initial, stateIndex++ === 0 ? setSearch : () => {}], useRef: current => ({ current }), useEffect() {}, useLayoutEffect() {} }, + { jsx, jsxs: jsx }, { Button, Modal: () => {} }, {}, { documentElement: { lang } }, { open } + ) + const tree = render({ useAgentPresetSection: fn => fn({ rows: [], view: null, error: null }), useDeveloperTools: fn => fn(false), t: key => key }) + const nodes = [] + function walk(node) { + if (Array.isArray(node)) return node.forEach(walk) + if (!node || typeof node !== 'object') return + nodes.push(node); walk(node.props?.children) + } + walk(tree) + const heading = nodes.find(n => n.props?.['data-dsh-preset-heading'] === '') + const actions = heading.props.children[1].props.children + expect(actions.every(n => n.type === Button && n.props.variant === 'outline')).toBe(true) + const input = nodes.find(n => n.props?.type === 'file') + const click = vi.fn(); input.props.ref.current = { click } + actions[0].props.onClick(); expect(click).toHaveBeenCalledOnce() + actions[1].props.onClick(); expect(open).toHaveBeenCalledWith('https://www.dshdesktop.com/preset/', '_blank', 'noopener,noreferrer') + nodes.find(n => n.props?.type === 'search').props.onChange({ target: { value: 'test' } }) + expect(setSearch).toHaveBeenCalledWith('test') +}) diff --git a/test/preset-transfer-patch.test.ts b/test/preset-transfer-patch.test.ts index 5cdf15931..87b49f2a7 100644 --- a/test/preset-transfer-patch.test.ts +++ b/test/preset-transfer-patch.test.ts @@ -44,6 +44,13 @@ function presetTransferApi(root: string) { const compositionPath = path.join(root, id, 'agent.cordis.yml') await readFile(compositionPath) return { id, trust: 'user', path: compositionPath, name: id } + }, + async readDocument(id: string) { + return { + agentPreset: id, + content: await readFile(path.join(root, id, 'agent.cordis.yml'), 'utf8'), + name: id + } } } applyPresetTransfer({ @@ -207,7 +214,7 @@ describe('agent preset package transfer', () => { format: 'dsh-preset', version: 1, id: sourceId, - sourceDshVersion: '0.1.2-rc.1' + sourceDshVersion: '0.1.7-rc.1' }) expect(exportedManifest.exportedAt).toEqual(expect.any(String)) expect(exportedManifest.dshVersion).toBeUndefined() @@ -541,12 +548,10 @@ describe('agent preset package transfer', () => { expect(patch).toContain('safePresetArchivePath') expect(patch).toContain('PRESET_ARCHIVE_IGNORED_FILES') expect(patch).toContain('.DS_Store') - expect(patch).toContain('info.isSymbolicLink()') - expect(patch).toContain('files[`preset/${rel}`]') + expect(patch).toContain('presets.readDocument(agentPreset)') + expect(patch).toContain('[`preset/${COMPOSITION_FILE}`]') expect(patch).toContain('safe.slice("preset/".length)') - expect(patch).toContain('scanRoot({') - expect(patch).toContain('scanned.find((candidate) => candidate.id === targetId)') - expect(patch).not.toContain('scanned.get(targetId)') + expect(patch).toContain('await presets.resolve(targetId)') expect(patch).toContain('await rename(imported, target)') expect(patch).toContain('A preset named') expect(patch).toContain('possible-secrets') @@ -556,8 +561,7 @@ describe('agent preset package transfer', () => { it('creates and resolves the writable preset root inside the structured import failure boundary', async () => { const patch = await presetTransferSource() - expect(patch).toContain('const root = writableRoot(presets.roots)') - expect(patch).not.toContain('const root = writableRoot();') + expect(patch).toContain('const root = legacyPresetRoot(presets)') expect(patch).toContain('await mkdir(root, { recursive: true })') expect(patch).toContain('let container;') expect(patch).toContain('container = await mkdtemp') @@ -570,62 +574,27 @@ describe('agent preset package transfer', () => { 'utf8' ) - expect(patch).toContain('ImportDialog') - expect(patch).toContain('previewImport(file)') - expect(patch).toContain('confirmImport()') - expect(patch).toContain('exportPreset(id)') - expect(patch).toContain('IconArchiveOutline20') - expect(patch).toContain('IconDownloadOutline16') + expect(patch).toContain('const previewImport = async (file) =>') + expect(patch).toContain('const confirmImport = async () =>') + expect(patch).toContain('const exportPreset = async (id) =>') expect(patch).toContain('Custom presets can run tools and commands') expect(patch).toContain('自定义预设可以使用与 Agent 相同权限的工具和命令') - expect(patch).toContain('draft.conflict ? "idTaken"') + expect(patch).toContain('importDraft.conflict') + expect(patch).toContain('setImportId(event.target.value)') expect(patch).toContain('.dshpreset') - expect(patch).toContain('importPreset: "Import"') - expect(patch).toContain('awesomePreset: "Awesome preset"') + expect(patch).toContain('copy.restart') expect(patch).toContain('https://www.dshdesktop.com/preset/') expect(patch).toContain('"_blank", "noopener,noreferrer"') - expect(patch).toContain('AgentPresetSection_module_css_default.sectionActions') - expect(patch).toContain('.dshPreset_sectionHead{align-items:center;gap:16px;display:flex}') - expect(patch).toContain('justify-content:flex-end') - expect(patch).toContain('margin-left:auto') - expect(patch).toContain('.dshPreset_hiddenInput{display:none}') + expect(patch).toContain('"aria-label": `${copy.export}: ${display.name}`') }) - it('adds desktop preset classes without restating upstream\u2019s class map', async () => { + it('leaves upstream preset stylesheet and class map intact', async () => { const patch = await readFile( patchPath('@deepseek-ai/dsh-client-ui-agent-preset'), 'utf8' ) - const added = patch - .split('\n') - .filter((line) => line.startsWith('+') && !line.startsWith('+++')) - .map((line) => line.slice(1)) - .join('\n') - - // Earlier revisions replaced the whole stylesheet and class map with a - // locally rebuilt copy, so an upstream rebuild silently left the page - // rendering classes with no matching selectors. The patch now only - // appends desktop-owned rules and entries, under a prefix upstream's - // content-derived hashes cannot collide with. - const desktopEntries = [...added.matchAll(/"([A-Za-z]+)": "dshPreset_([A-Za-z]+)"/g)] - expect(desktopEntries.length).toBeGreaterThan(0) - for (const [, key, cls] of desktopEntries) { - expect(key).toBe(cls) - expect(added, key).toContain(`.dshPreset_${cls}{`) - } - - // Every class-map entry the patch adds must be a NEW key: an entry that - // also appears as an unchanged context line would mean the patch is - // restating upstream's map, which is what used to go stale on a rebuild. - const context = new Set( - patch - .split('\n') - .filter((line) => line.startsWith(' ')) - .flatMap((line) => [...line.matchAll(/"([A-Za-z][A-Za-z0-9-]*)": "[A-Za-z0-9_-]+_/g)].map((m) => m[1])) - ) - for (const [, key] of added.matchAll(/"([A-Za-z][A-Za-z0-9-]*)": "[A-Za-z0-9_-]+_/g)) { - expect(context.has(key), key).toBe(false) - } + expect(patch).not.toContain('AgentPresetSection_module_css_default =') + expect(patch).not.toContain('const css$') }) it('keeps a large mode roster searchable, grouped, compact, and connected to Awesome Presets', async () => { @@ -634,22 +603,10 @@ describe('agent preset package transfer', () => { 'utf8' ) - expect(patch).toContain('searchPresets: "Search modes…"') - expect(patch).toContain('recentPresets: "Recent"') - expect(patch).toContain('RECENT_PRESETS_KEY') - expect(patch).toContain('option.trust === "system"') - expect(patch).toContain('option.trust === "user"') - expect(patch).toContain('text-overflow:ellipsis') - expect(patch).toContain('IconSearchOutline16') - expect(patch).toContain('IconSparkle16') - expect(patch).toContain('selectedItem') - expect(patch).toContain(':focus-within') - expect(patch).toContain('[role=menu]:has(') - expect(patch).toContain('max-height:min(360px') - expect(patch).toContain('side: "bottom"') - expect(patch).toContain('footer: [{') - expect(patch).toContain('id: AWESOME_PRESETS_ID') - expect(patch).toContain('browseAwesomePresets: "浏览 Awesome Presets…"') + expect(patch).toContain('type: "search", value: search') + expect(patch).toContain('isBuiltInPreset(row) === builtIn') + expect(patch).toContain('presetDisplayText(row, t).name') + expect(patch).toContain('Awesome preset') }) it('keeps the loopback API discoverable by an explicitly requested online Skill', async () => { diff --git a/test/profile-boot-preflight.test.ts b/test/profile-boot-preflight.test.ts index 7b309a308..90fe16978 100644 --- a/test/profile-boot-preflight.test.ts +++ b/test/profile-boot-preflight.test.ts @@ -24,6 +24,21 @@ async function fixture() { } describe('normal Profile boot preflight', () => { + it('allows stale version declarations without granting exemptions or changing manifests', async () => { + const { profile, bundle, check } = await fixture() + const manifestPath = join(bundle, 'package.json') + const manifest = JSON.stringify({ name: 'test-startup-bundle', version: '1.0.0', + peerDependencies: { '@deepseek-ai/dsh': '0.1.7-rc.1' }, + dsh: { bundle: { patch: 'cordis.patch.yml' } } }) + const before = await readFile(join(profile, 'package.json'), 'utf8') + await writeFile(manifestPath, manifest) + expect(await check()).toBeUndefined() + expect(await readFile(manifestPath, 'utf8')).toBe(manifest) + expect(await readFile(join(profile, 'package.json'), 'utf8')).toBe(before) + await writeFile(manifestPath, manifest.replace('"0.1.7-rc.1"', '123')) + expect((await check())?.message).toContain('must be a string') + }) + it('accepts readable layers without evaluating config or modifying user files', async () => { const { profile, check } = await fixture() const patch = '- id: test\n config:\n value: !!js (() => { throw new Error("must not execute") })()\n' diff --git a/test/release.test.ts b/test/release.test.ts index eefbc9329..65b1bcde5 100644 --- a/test/release.test.ts +++ b/test/release.test.ts @@ -1,6 +1,7 @@ import { readFile } from 'node:fs/promises' import { createRequire } from 'node:module' import path from 'node:path' +import { parse } from 'yaml' import { describe, expect, it } from 'vitest' const projectRoot = path.resolve(import.meta.dirname, '..') @@ -12,7 +13,7 @@ const releaseAssets = [ ] /** The exact Harness build every `@deepseek-ai/dsh-*` production dep is pinned to. */ -const HARNESS_VERSION = '0.1.5-rc.2' +const HARNESS_VERSION = '0.1.7-rc.2' describe('GitHub release contract', () => { it('keeps the package and lockfile versions aligned', async () => { @@ -156,6 +157,9 @@ describe('GitHub release contract', () => { ) as { build: { artifactName: string + asar: boolean + asarUnpack: string[] + afterPack?: string extraResources: Array<{ from: string; to: string }> win: { target: Array<{ target: string; arch: string[] }>; requestedExecutionLevel?: string } nsis: { artifactName: string; include: string } @@ -172,6 +176,8 @@ describe('GitHub release contract', () => { ) expect(packageJson.build.artifactName).toBe('dsh-desktop-${os}-${arch}.${ext}') + expect(packageJson.build.asar).toBe(true) + expect(packageJson.build.asarUnpack).toContain('node_modules/**/*') expect(packageJson.build.extraResources).toContainEqual({ from: 'build/app-icon.png', to: 'icon.png' @@ -244,7 +250,7 @@ describe('GitHub release contract', () => { dependencies: Record build: { publish: Array<{ provider: string; url?: string; owner?: string; repo?: string }> - win: { verifyUpdateCodeSignature: boolean } + win: { verifyUpdateCodeSignature: boolean; signtoolOptions: { publisherName: string } } } } const workflow = await readFile( @@ -256,14 +262,14 @@ describe('GitHub release contract', () => { expect(packageJson.build.publish).toEqual([ { provider: 'generic', url: 'https://dshdesktop.com/updates/latest/' } ]) - expect(packageJson.build.win.verifyUpdateCodeSignature).toBe(false) + expect(packageJson.build.win.verifyUpdateCodeSignature).toBe(true) + expect(packageJson.build.win.signtoolOptions.publisherName).toBe('Beijing Shuju Xiangsu Intelligence Technology Co., Ltd.') for (const asset of [ 'latest-mac-arm64.yml', 'latest-mac-x64.yml', 'latest-mac.yml', 'latest.yml', - 'dsh-desktop-mac-arm64.zip.blockmap', - 'dsh-desktop-mac-x64.zip.blockmap', + 'dsh-desktop-mac-${{ matrix.arch }}.zip.blockmap', 'dsh-desktop-windows-x64-setup.exe.blockmap' ]) { expect(workflow).toContain(asset) @@ -291,6 +297,18 @@ describe('GitHub release contract', () => { } }) + it('uses the staged-directory installer for both Windows builds and signed repackaging', async () => { + const packageJson = JSON.parse(await readFile(path.join(projectRoot, 'package.json'), 'utf8')) as { + scripts: Record + build: { nsis: { allowToChangeInstallationDirectory: boolean } } + } + const workflow = await readFile(path.join(projectRoot, '.github', 'workflows', 'release.yml'), 'utf8') + expect(packageJson.scripts['package:win']).toContain('electron-builder-windows.mjs') + expect(packageJson.scripts['package:dev:win']).toContain('electron-builder-windows.mjs') + expect(packageJson.build.nsis.allowToChangeInstallationDirectory).toBe(true) + expect(workflow).toContain('node scripts/electron-builder-windows.mjs --win --x64 --publish never') + }) + it('packages an isolated development channel from the current workspace', async () => { const packageJson = JSON.parse( await readFile(path.join(projectRoot, 'package.json'), 'utf8') @@ -327,10 +345,10 @@ describe('GitHub release contract', () => { 'utf8' ) - expect(workflow).toContain('runs-on: macos-15') - expect(workflow).toContain('runs-on: macos-15-intel') + expect(workflow).toContain('runner: macos-15') + expect(workflow).toContain('runner: macos-15-intel') expect(workflow).toContain('runs-on: windows-2022') - expect(workflow).toContain('npm run package:dev:win') + expect(workflow).toContain('--publish never --config electron-builder.dev.cjs') expect(workflow).toContain('Smoke test packaged Windows Harness') expect(workflow).toContain('$sourceExecutable = Get-Item $env:SMOKE_EXE') expect(workflow).toContain("$isolatedApp = Join-Path $env:RUNNER_TEMP") @@ -353,12 +371,13 @@ describe('GitHub release contract', () => { expect(workflow).toContain('--prerelease') expect(workflow).toContain('name: windows-x64-dev') expect(workflow).toContain('dist-dev/dsh-desktop-dev-windows-x64-setup.exe') - for (const asset of releaseAssets) expect(workflow).toContain(asset) + expect(workflow).toContain('dsh-desktop-mac-${{ matrix.arch }}.dmg') + expect(workflow).toContain('dsh-desktop-windows-x64-setup.exe') expect( workflow.match( /npm version --no-git-tag-version --allow-same-version "\$\{\{ github\.ref_name \}\}"/g ) - ).toHaveLength(4) + ).toHaveLength(3) }) it('signs and notarizes both macOS architectures on tag releases', async () => { @@ -377,22 +396,50 @@ describe('GitHub release contract', () => { ]) { expect(workflow).toContain(`secrets.${secret}`) } - expect(workflow.match(/Prepare macOS signing keychain/g)).toHaveLength(2) - expect(workflow.match(/xcrun stapler validate/g)).toHaveLength(4) - expect(workflow.match(/xcrun notarytool submit/g)).toHaveLength(2) - expect(workflow.match(/CSC_IDENTITY_AUTO_DISCOVERY: 'false'/g)).toHaveLength(2) + expect(workflow.match(/Prepare macOS signing keychain/g)).toHaveLength(1) + expect(workflow.match(/xcrun stapler validate/g)).toHaveLength(2) + expect(workflow.match(/xcrun notarytool submit/g)).toHaveLength(1) + expect(workflow.match(/CSC_IDENTITY_AUTO_DISCOVERY: 'false'/g)).toHaveLength(1) expect(workflow).not.toContain("CSC_LINK: ''") - expect(workflow).toMatch( - /macos-apple-silicon:\r?\n\s+name: macOS Apple Silicon\r?\n(?:[\s\S]*?)runs-on: macos-15\r?\n\s+steps:/ - ) - expect(workflow).toMatch( - /macos-intel:\r?\n\s+name: macOS Intel\r?\n(?:[\s\S]*?)runs-on: macos-15-intel\r?\n\s+steps:/ - ) + const config = parse(workflow) + expect(config.jobs.macos.strategy['fail-fast']).toBe(false) + expect(config.jobs.macos.strategy.matrix.include).toEqual([ + { arch: 'arm64', label: 'Apple Silicon', runner: 'macos-15', 'app-directory': 'mac-arm64', artifact: 'macos-apple-silicon' }, + { arch: 'x64', label: 'Intel', runner: 'macos-15-intel', 'app-directory': 'mac', artifact: 'macos-intel' } + ]) + expect(config.jobs.macos['runs-on']).toBe('${{ matrix.runner }}') + for (const job of ['publish', 'publish-prerelease']) { + expect(config.jobs[job].needs).toContain('macos') + expect(config.jobs[job].if).toContain("needs.macos.result == 'success'") + } expect(workflow).toMatch( /windows-x64:\r?\n\s+name: Windows x64\r?\n(?:[\s\S]*?)runs-on: windows-2022\r?\n\s+steps:/ ) }) + it('builds the runtime once per native job before tests and packaging', async () => { + const workflow = parse(await readFile(path.join(projectRoot, '.github/workflows/release.yml'), 'utf8')) as { + jobs: Record }> }> + } + for (const name of ['macos', 'windows-x64']) { + const steps = workflow.jobs[name]?.steps ?? [] + const buildIndex = steps.findIndex(step => step.run === 'npm run build') + const testIndex = steps.findIndex(step => step.run?.startsWith('npx --no-install vitest run')) + expect(buildIndex).toBeGreaterThanOrEqual(0) + expect(testIndex).toBeGreaterThan(buildIndex) + expect(steps.filter(step => step.run === 'npm run build')).toHaveLength(1) + const packages = steps.filter(step => step.run?.includes('--publish never')) + expect(packages).toHaveLength(2) + for (const step of packages) { + expect(step.run).toContain('verify-target.mjs') + expect(step.run).not.toContain('npm run build') + } + for (const step of steps.filter(step => step.uses === 'actions/upload-artifact@v4' && step.with?.['if-no-files-found'] === 'error')) { + expect(step.with?.['compression-level']).toBe(0) + } + } + }) + it('signs Windows installers on the local UKey runner before publishing', async () => { const workflow = await readFile( path.join(projectRoot, '.github', 'workflows', 'release.yml'), @@ -414,6 +461,13 @@ describe('GitHub release contract', () => { expect(workflow).toContain('sign-windows-unpacked.mjs') expect(workflow).toContain('win-unpacked.tar.gz') expect(workflow).toContain('--prepackaged') + expect(workflow).toContain('set -euo pipefail') + expect(workflow).not.toContain('Falling back to original installer') + expect(workflow).not.toContain('Restoring original Windows installer') + expect(workflow).toContain('smoke-signed-windows:') + expect(workflow).toContain('smoke-signed-windows-installer.ps1') + expect(workflow).toContain("needs.smoke-signed-windows.result == 'success'") + expect(workflow).toContain("if (-not (Test-Path $packagedNode)) { throw 'Packaged Windows node.exe is missing.' }") expect(workflow).toContain('version="${PRERELEASE_TAG#v}"') expect(workflow).toContain('version="${SIGNED_VERSION#v}"') expect(workflow).not.toContain('version="${PRERELEASE_TAG:-${GITHUB_REF_NAME#v}}"') @@ -423,6 +477,11 @@ describe('GitHub release contract', () => { ) }) + it('does not change Windows security settings during installation', async () => { + const installer = await readFile(path.join(projectRoot, 'build', 'installer.nsh'), 'utf8') + expect(installer).not.toMatch(/Add-MpPreference|HKLM|ExecShell\s+"runas"/) + }) + it('routes stable downloads through the website and previews through GitHub', async () => { const readmes = await Promise.all( ['README.md', 'README.zh.md', 'README.ja.md', 'README.ru.md', 'README.es.md', 'README.pt.md'].map((file) => @@ -491,7 +550,7 @@ describe('prerelease parity workflow', () => { yml.match( /npm version --no-git-tag-version --allow-same-version "\$\{\{ inputs\.signed_version \}\}"/g ) - ).toHaveLength(4) + ).toHaveLength(3) }) it('mirrors a prerelease to an isolated ModelScope directory', async () => { diff --git a/test/session-delete-patch.test.ts b/test/session-delete-patch.test.ts index 2a1214f25..b0be778a8 100644 --- a/test/session-delete-patch.test.ts +++ b/test/session-delete-patch.test.ts @@ -12,45 +12,45 @@ const projectRoot = path.resolve(import.meta.dirname, '..') const patchedPackages = [ { name: 'dsh-session-persistence', - version: '0.1.5-rc.2', + version: '0.1.7-rc.2', file: 'lib/index.js', markers: ['does not support deletion', 'delete(_id, _options)', 'Permanently remove one stored Session identity'] }, { name: 'dsh-session-persistence-jsonl', - version: '0.1.5-rc.2', + version: '0.1.7-rc.2', file: 'lib/index.js', markers: ['async delete(id, options)', 'this.tracker.claimWrite(id)', 'this.coldLogMemo.delete(id)'] }, { name: 'dsh-workspace', - version: '0.1.5-rc.2', + version: '0.1.7-rc.2', file: 'lib/index.js', markers: ['forgetSession(sessionId)', 'archivedSessionIds: state.archivedSessionIds.filter'] }, { name: 'dsh-api-session-controller', - version: '0.1.5-rc.2', + version: '0.1.7-rc.2', file: 'lib/index.js', markers: ['disposeOwned(sessionId)', 'await persistence.delete(request.sessionId)', 'workspaceRegistry.forgetSession(request.sessionId)'] }, { name: 'dsh-api-session-controller', - version: '0.1.5-rc.2', + version: '0.1.7-rc.2', file: 'lib/client.js', - markers: ['SessionDeleteError', 'this.remote.session.delete({ sessionId })', 'if (this.watched === sessionId) this.watched = void 0'] + markers: ['SessionDeleteError', 'this.remote.session.delete({ sessionId })', 'uiWorkspace, which releases its main view before calling this method'] }, { name: 'dsh-api-session-controller', - version: '0.1.5-rc.2', + version: '0.1.7-rc.2', file: 'lib/typert.host.js', markers: ["id: '@deepseek-ai/dsh-api-session-controller#session/delete'", "method: 'delete'"] }, { name: 'dsh-client-ui-workspace', - version: '0.1.5-rc.2', + version: '0.1.7-rc.2', file: 'lib/client.js', - markers: ['delete.session', 'danger: true', 'Workspace files are kept', 'await sessions.delete(sessionId)'] + markers: ['async deleteSession(sessionId)', 'this.clearMain()', 'const retention = this.sessions.retainInfo(sessionId)', 'timer = setTimeout(finish, 250)', 'await this.sessions.delete(sessionId)'] } ] as const @@ -67,11 +67,32 @@ describe('permanent session deletion dependency patches', () => { } }) - it('states the destructive retention boundary in both locales', async () => { + it('migrates unavailable persisted presets to standard mode', async () => { + const source = await readFile( + path.join(projectRoot, 'node_modules', '@deepseek-ai', 'dsh-api-session-controller', 'lib', 'index.js'), + 'utf8' + ) + + expect(source).toContain('error.code !== "agent-preset/not-found"') + expect(source).toContain('resolved = await presets.resolve("standard")') + expect(source).toContain('agent.session.append("agent-preset/selected", { agentPreset: composition.agentPreset })') + expect(source).toContain('migrated session "${sessionId}" from unavailable preset') + }) + + it('uses the same menu slot in flat and grouped session rows', async () => { const ui = await readFile( path.join(projectRoot, 'node_modules', '@deepseek-ai', 'dsh-client-ui-workspace', 'lib', 'client.js'), 'utf8' ) + expect(ui).toContain('renderSlot("sidebar.workspaces.session.menu.item", {') + expect(ui).toContain('groupBy === "flat"') + }) + + it('states the destructive retention boundary in both locales', async () => { + const ui = await readFile( + path.join(projectRoot, 'packages', 'dsh-desktop-client-ui', 'client.js'), + 'utf8' + ) expect(ui).toContain('工作区文件会保留。此操作无法撤销。') expect(ui).toContain('Workspace files are kept. This can’t be undone.') diff --git a/test/settings-account-launcher.test.js b/test/settings-account-launcher.test.js new file mode 100644 index 000000000..83b077126 --- /dev/null +++ b/test/settings-account-launcher.test.js @@ -0,0 +1,23 @@ +import { join } from 'node:path' +import { composeEntries, loadOverlayPatches } from '@deepseek-ai/dsh-app-boot' +import { describe, expect, it } from 'vitest' + +const root = process.cwd() + +describe('Desktop account UI composition', () => { + it.each(['dsh-desktop.patch.yml', 'dsh-desktop-safe.patch.yml'])( + '%s disables account UI while preserving model settings', + (filename) => { + const web = loadOverlayPatches('test', join(root, 'node_modules/@deepseek-ai/dsh-web-app/cordis.patch.yml')) + const desktop = loadOverlayPatches('test', join(root, 'build', filename)) + const upstream = composeEntries([web]) + expect(upstream.find((entry) => entry.id === 'ui-settings-account')?.name) + .toBe('@deepseek-ai/dsh-client-ui-settings-account') + const entries = composeEntries([web, desktop]) + expect(entries.find((entry) => entry.id === 'ui-settings-account')?.disabled).toBe(true) + for (const name of ['@deepseek-ai/dsh-client-ui-settings-general', '@deepseek-ai/dsh-client-ui-settings-models']) { + expect(entries.filter((entry) => entry.name === name && !entry.disabled)).toHaveLength(1) + } + } + ) +}) diff --git a/test/undici-legacy-headers.test.mjs b/test/undici-legacy-headers.test.mjs new file mode 100644 index 000000000..6598d2085 --- /dev/null +++ b/test/undici-legacy-headers.test.mjs @@ -0,0 +1,68 @@ +import { createRequire } from 'node:module' +import { gzipSync } from 'node:zlib' +import { expect, it } from 'vitest' + +const require = createRequire(import.meta.url) +const Dispatcher1Wrapper = require('undici/lib/dispatcher/dispatcher1-wrapper.js') + +it.each(['object', 'array'])('preserves %s response headers for legacy fetch and decompresses gzip', async (shape) => { + const headers = { 'content-type': 'application/json', 'content-encoding': 'gzip' } + const rawHeaders = shape === 'object' ? headers : Object.entries(headers).flat().map(value => Buffer.from(value)) + const controller = { rawHeaders, resume() {}, pause() {}, abort() {} } + const dispatcher = new Dispatcher1Wrapper({ dispatch(_options, handler) { + queueMicrotask(() => { + handler.onRequestStart(controller) + handler.onResponseStart(controller, 200, headers, 'OK') + handler.onResponseData(controller, gzipSync(JSON.stringify({ ok: true }))) + handler.onResponseEnd(controller, {}) + }) + return true + } }) + // Node's bundled fetch consumes the legacy Dispatcher API, as do older plugins. + const response = await fetch('https://example.test/diagnostic', { dispatcher }) + expect(response.headers.get('content-type')).toBe('application/json') + expect(response.headers.get('content-encoding')).toBe('gzip') + expect(await response.json()).toEqual({ ok: true }) +}) + +it('converts HTTP/2 trailer objects to the legacy flat array', () => { + let trailers + const handler = Dispatcher1Wrapper.wrapHandler({ onComplete(value) { trailers = value } }) + handler.onResponseEnd({ rawTrailers: { 'x-check': 'done' } }, {}) + expect(trailers.map(value => value.toString())).toEqual(['x-check', 'done']) +}) + +it('preserves duplicate headers, streaming chunks, and request options', async () => { + const requestBody = 'unchanged request' + const headers = { 'content-type': 'text/event-stream', 'set-cookie': ['one=1', 'two=2'] } + const controller = { rawHeaders: headers, resume() {}, pause() {}, abort() {} } + let request + const dispatcher = new Dispatcher1Wrapper({ dispatch(options, handler) { + request = options + queueMicrotask(() => { + handler.onRequestStart(controller) + handler.onResponseStart(controller, 200, headers, 'OK') + handler.onResponseData(controller, Buffer.from('data: first\n\n')) + handler.onResponseData(controller, Buffer.from('data: second\n\n')) + handler.onResponseEnd(controller, {}) + }) + return true + } }) + const response = await fetch('https://example.test/stream', { method: 'POST', body: requestBody, dispatcher }) + expect(request.method).toBe('POST') + expect(response.headers.getSetCookie()).toEqual(['one=1', 'two=2']) + expect(await response.text()).toBe('data: first\n\ndata: second\n\n') +}) + +it('keeps HTTP/1.1 upgrade headers and trailers arrays unchanged', () => { + const headers = [Buffer.from('upgrade'), Buffer.from('websocket')] + let receivedHeaders, receivedTrailers + const handler = Dispatcher1Wrapper.wrapHandler({ + onUpgrade(_status, value) { receivedHeaders = value }, + onComplete(value) { receivedTrailers = value } + }) + handler.onRequestUpgrade({ rawHeaders: headers }, 101, {}, {}) + handler.onResponseEnd({ rawTrailers: headers }, {}) + expect(receivedHeaders).toBe(headers) + expect(receivedTrailers).toBe(headers) +}) diff --git a/test/windows-titlebar-header.test.mjs b/test/windows-titlebar-header.test.mjs new file mode 100644 index 000000000..0315de9cd --- /dev/null +++ b/test/windows-titlebar-header.test.mjs @@ -0,0 +1,32 @@ +import { readFileSync } from 'node:fs' +import ts from 'typescript' +import { expect, it } from 'vitest' + +const source = readFileSync('node_modules/@deepseek-ai/dsh-client-ui-conversation/lib/client.js', 'utf8') +const ast = ts.createSourceFile('client.js', source, ts.ScriptTarget.Latest, true) +let headerSource +function visit(node) { + if (ts.isFunctionDeclaration(node) && node.name?.text === 'ConversationHeader') headerSource = node.getText(ast) + ts.forEachChild(node, visit) +} +visit(ast) +const jsx = (type, props) => ({ type, props }) +const Header = new Function('react_jsx_runtime', 'clsx', 'ConversationRoot_module_css_default', 'conversationPhase', `${headerSource}; return ConversationHeader`)( + { jsx, jsxs: jsx }, (...names) => names.filter(Boolean).join(' '), + { header: 'header', headerBlank: 'blank', headerSessionless: 'sessionless', headerLeading: 'leading', titleRow: 'title' }, () => 'active' +) + +it.each([undefined, 'session-1'])('marks the resident header without moving or duplicating slot contributions (%s)', sessionId => { + const calls = [] + const tree = Header({ sessionId, useSession: select => select(sessionId ? { blank: false } : undefined), + useConversation: select => select(sessionId ? {} : undefined), + renderSlot(name, props) { calls.push(name); return jsx('slot', { name, ...props }) } + }) + expect(tree.type).toBe('header') + expect(tree.props['data-dsh-conversation-header']).toBe('') + expect(tree.props['data-window-drag']).toBe(true) + expect(calls).toEqual(sessionId ? ['conversation.header.leading', 'conversation.session.header'] : ['conversation.header.leading']) + // rc.2 renders the session slot INSIDE the header. Styling a header inside + // that slot silently stopped working after the upgrade. + if (sessionId) expect(tree.props.children[1].props.name).toBe('conversation.session.header') +})