* fix(desktop): bridge Electron users on Windows and Linux
* test(desktop): satisfy bridge contract lint
* fix(desktop): harden Electron bridge migration
* chore(desktop): note sibling-script regex sync for bridge artifacts
* fix(desktop): satisfy release manifest lint
* fix(desktop): validate Electron uninstaller path before migration
The migration ExecWait target is assembled from the HKCU InstallLocation
registry value; require the uninstaller executable to exist before running
it, and pin the conjunct in the release contract suite.
* fix(desktop): hide the Windows runtime terminal and align reduced-motion startup
On Windows the bundled runtime (node.exe, a console application) was spawned
without CREATE_NO_WINDOW, so the desktop (a GUI application) allocated a
visible terminal window for it; closing that window stopped the runtime with
exit code 1 (#9043). Route the spawn through a platform-specific helper that
sets CREATE_NO_WINDOW via the command-group builder (group_spawn would
overwrite creation flags set directly on the command). Add a Windows-only
regression test that asserts the spawned child receives no console window.
The reduced-motion bootstrap fallback showed the logo left-aligned inside the
shell while the newly visible status text was centered in a wider card, so the
two did not share a horizontal center. Stack and center both inside the shell
and drop the leftover card chrome, mirroring the simplified startup view from
#8988, and extend the bootstrap release check to guard the centering rules.
* fix(desktop): simplify reduced-motion startup centering
* fix(core): hide daemon-side console spawns on Windows
With the bundled runtime spawned console-less, console-app children of
the daemon no longer inherit a console and each allocates a visible
window. Pass windowsHide at the git attribution, git notes, and
taskkill spawn sites in the shell tool, matching shellExecutionService.
Also loosen the reduced-motion bootstrap assertion so it no longer
hard-codes rule order inside the media block.
* fix(desktop): hide runtime descendant consoles
* test(desktop): pin the hidden-console spawn helper at the production call site
The Rust test exercises spawn_runtime_group directly; nothing guarded that
DesktopRuntime::start still routes through it. Assert the call site in the
release gate so a refactor reverting to group_spawn() fails the suite.
* fix(desktop): open external URL artifacts and markdown links
The Web Shell relied on the webview's implicit target="_blank" /
window.open handling for every external link. In the packaged desktop
shell that path silently drops failed new-window requests, so link
artifacts (type: link, storage: external_url) and markdown links in
assistant messages appeared styled but dead, with no error feedback.
Add an explicit open_external_url command to the Tauri shell (validated
against http/https/mailto, opened via the OS default browser) and route
external clicks through it when the Web Shell detects the desktop
bridge. The artifact details panel gains an "Open link" action next to
the Location URL, and failures surface as error toasts instead of
silent no-ops. Plain browsers keep native anchor behavior.
Fixes#9060; follows up on #8593 for the Tauri shell.
* test(web-shell): keep real ToastHost exports in App mock
The App test suite replaces ToastHost with a stub; after adding
TOAST_REQUEST_EVENT/requestToast to the module, the partial mock broke
every App test. Spread importActual so new exports stay available.
* fix(desktop): declare external URL permission
* fix(desktop): authorize remote external URL opens
* fix(desktop): normalize external opener URLs
* test(web-shell): pin desktop link click handling
* fix(desktop): route modified URL clicks
* feat(desktop): mirror releases to Aliyun OSS
* fix(desktop): harden OSS mirror workflow and tests
- Add ref guard to sync-desktop-to-oss.yml (dispatch only from main)
- Add diagnostic error messages for missing Windows/Linux installers
- Harden test: pin verify-index > 0 before ordering comparison
- Harden test: pin confirm-before-publish ordering and source comparison
- Add test: stable-only release validation in reusable sync job
* fix(desktop): harden OSS mirror permissions, stable-version guard, and non-latest repair
- Remove workflow-level actions:read; grant it only to the sync-oss caller job
- Reject suffixed versions for published stable releases in prepare
- Turn latest-feed comparison into a non-fatal check; condition publish/verify on match
- Assert both check_for_update call sites in release test
- Add jq stable-only guard assertion and endpoint default alignment test
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
---------
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
* feat(cli): add Local Control pairing
* fix(cli): address Local Control review feedback
* fix(cli): allow Local Control loopback origin
* feat(desktop): add Local Control pairing
* fix(local-control): bound unauthenticated connections
* test(desktop): allow Windows proxy cleanup
* test(desktop): avoid socket cleanup timing
* fix(desktop): surface Local Control status
* fix(desktop): simplify Local Control window
* fix(desktop): harden Local Control pairing
* fix(desktop): bind Mac wake lock to app
* fix(desktop): codesign ripgrep and node binaries before tauri build
macOS notarization rejects the app bundle because Tauri only signs the
main binary, not the embedded ripgrep and Node.js runtime binaries under
Contents/Resources/runtime/qwen-code/. Add a pre-build codesign step
that signs all native macOS executables in the bundled runtime with the
Developer ID identity, hardened runtime, and the existing entitlements.
* fix(desktop): allow Windows build without signing certificate
The Tauri release workflow threw when WINDOWS_CERTIFICATE was missing,
blocking the entire release (including macOS). Mirror the old Electron
workflow behavior: warn and continue unsigned when no cert is configured.
Also add fallback to legacy WIN_CSC_LINK/WIN_CSC_KEY_PASSWORD secrets
so existing Electron-era credentials still work if present.
* fix(desktop): allow unsigned Windows artifacts in verify step
The 'Verify Windows signature' step threw on any non-Valid status,
including NotSigned. With no Windows code signing certificate
configured, this blocked the Windows build job, which in turn
blocked the publish job (needs: [prepare, build]).
Allow NotSigned with a warning instead of throwing, matching the
fallback behavior of the 'Import Windows certificate' step. A
genuinely invalid signature (HashMismatch, etc.) still throws.
* fix(desktop): narrow find scope and deduplicate pfx import
- Scope ripgrep codesign find to *-darwin/* paths so Linux ELF
binaries (built in the same matrix) aren't targeted.
- Unify the two pfx-import branches into a single code path to
eliminate duplicated write/import/configure logic.
* fix(desktop): guard optional Windows signing config
* fix(desktop): harden vendor signing workflow
* fix(desktop): read Windows smoke log from LocalAppData
* fix(desktop): validate Windows smoke log path
* test(desktop): guard smoke log fallback branch and capture ordering (#8381)
* fix(desktop): cross-check smoke appId against tauri config and fail closed on log rotation (#8381)
* fix(desktop): reset smoke log baseline on truncation and test behavior (#8381)
The Tauri app truncates the log on every startup (main.rs:
fs::write(&log_path, b"")), so the second smoke run on any non-ephemeral
Windows machine always failed with "truncated or rotated". Reset the
baseline and keep polling instead of aborting.
Extract resolveLogRoot into a tiny module so test-release.js can verify
the platform/env resolution behaviorally rather than regex-matching
source text. Hoist the duplicated tauri.conf.json parse, add logPath to
the timeout diagnostic, and note the shared-log hermeticity constraint.
* test(desktop): pin stale-log protection wiring in smoke source guard (#8381)
* test(desktop): extract sliceNewLog helper and harden ordering assertion (#8381)
* test(desktop): pin resolveLogRoot and dual readNewLog sites in smoke guard (#8381)
* fix(desktop): log path in smoke errors; warn only on real truncation (#8381)
* fix(desktop): make smoke truncation warning reachable; relax guard regexes (#8381)
* fix(desktop): rebase smoke log baseline on truncation; embed full log on timeout (#8381)
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
* fix(desktop): drop dead truncation flags from smoke log reader (#8381)
* fix(desktop): isolate packaged smoke settings
---------
Co-authored-by: qwen-code-ci-bot <qwen-code-ci-bot@users.noreply.github.com>
Co-authored-by: Qwen Code Bot <qwen-code-bot@users.noreply.github.com>
Co-authored-by: Qwen Code <qwen-code@users.noreply.github.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
* feat(desktop): add Web Shell Tauri proof of concept
* feat(desktop): prepare Web Shell shell for release
* fix(desktop): make release dry runs portable
* fix(desktop): harden cross-platform release smoke
* fix(desktop): stabilize Windows and Linux CI
* fix(desktop): scope bootstrap env to daemon
* fix(desktop): stabilize packaged app smoke
* fix(desktop): diagnose Linux packaged startup
* fix(desktop): address release readiness review
* fix(desktop): address follow-up review findings
* fix(desktop): address runtime review blockers
* fix(desktop): gate cookie auth acceptance behind desktop bootstrap flag
- Cookie→Bearer translation middleware now only active when desktopShellBootstrap is enabled
- Use timing-safe comparison for bootstrap token validation
* fix(desktop): replace cookie handshake with URL fragment auth
- Navigate the desktop WebView to /#token=<token>; the fragment never
reaches the server, so drop the desktop cookie bootstrap middleware,
its cookie->bearer translation, and the related serve tests
- Skip the deferred-runtime auth gate for pre-auth Web Shell routes
(GET|HEAD / and /assets/*): a document navigation cannot carry an
Authorization header, so the fast-path window used to answer the
first desktop navigation with 401 Unauthorized until a manual reload
- Poll /health?deep=true before navigating: deep health stays 503
(reason: bootstrap) until the runtime app that mounts the Web Shell
is ready, so readiness can no longer race the deferred window
- Run the folder picker off the main thread and only store the runtime
after the WebView navigation succeeds
- Enable withGlobalTauri plus a bootstrap capability so the bootstrap
page can subscribe to desktop lifecycle events
- Update smoke-packaged to assert the fragment contract (unauthenticated
root navigation 200, no cookies minted, API routes still 401) and
sync the release design doc
* fix(desktop): fix Linux smoke log path, add runtime .gitkeep, correct README (#8132)
* fix(desktop): close release readiness gaps
* fix(cli): keep deferred serve auth gate closed when web shell unmounted (#8132)
* fix(desktop): address review feedback on auth gates and runtime bundle (#8132)
- Cover the method guard in isPreAuthWebShellRequest: assert unauthenticated POST to / and /assets/* is still 401 during the deferred runtime window.
- Add unit tests for is_allowed_navigation covering the unset origin, set origin, and bootstrap-after-origin cases.
- Drop DEV:'true' from the release bundle step so the esbuild metafile is no longer shipped as dead weight in the desktop runtime.
* fix(desktop): address review feedback on runtime extraction and release workflow (#8132)
- Extract .zip Node archives with unzip so Linux cross-builds for win32-x64
no longer crash on GNU tar.
- Build the Windows signing config with ConvertTo-Json instead of backslash
escapes, which PowerShell treats as a parse error.
- Fetch the runtime Web Shell without a bearer token so the smoke test
exercises the pre-auth navigation path the shell relies on.
- Make GitHub release creation idempotent so a re-run after a partial publish
uploads assets instead of failing on the existing tag.
* fix(desktop): normalize artifact filenames to prevent updater 404s (#8132)
GitHub rewrites spaces to dots when release assets are uploaded, but
the updater manifest encoded spaces as %20 via encodeURIComponent.
This caused every platform's auto-update URL to 404 on published
releases.
Replace spaces with hyphens in the Collect artifacts step for all
platforms so the local filename, the manifest URL, and the published
asset name agree by construction. Update test-release.js fixtures to
match and assert no artifact name contains a space.
* fix(desktop): address review feedback on security, lint, and code quality (#8132)
* fix(desktop): address review feedback on smoke test, error UX, and window state (#8132)
* fix(desktop): address review feedback on crate build, recovery UX, auth gate, and CI (#8132)
* fix(desktop): address review feedback on settings race, version script, and log growth (#8132)
* fix(desktop): address review feedback on retry, auth gate, and release clobber (#8132)
* fix(desktop): gate commands to bootstrap origin and show native update dialog (#8132)
* fix(desktop): use matches! instead of PartialEq on JoinError result (#8132)
* fix(desktop): wait for deferred runtime in smoke tests and sync release flags on clobber (#8132)
---------
Co-authored-by: Qwen Code Bot <qwen-code-bot@users.noreply.github.com>
Co-authored-by: qwen-code-dev-bot <qwen-code-dev@service.alibaba.com>
Co-authored-by: qwen-code-ci-bot <qwen-code-ci-bot@users.noreply.github.com>
Co-authored-by: Qwen Code Autofix <qwen-code-autofix@users.noreply.github.com>