Skip to content

feat(update): integrate shared studio update dialog behind flag - #70

Merged
ElbertePlinio merged 5 commits into
mainfrom
feat/36-update-dialog
Jul 23, 2026
Merged

feat(update): integrate shared studio update dialog behind flag#70
ElbertePlinio merged 5 commits into
mainfrom
feat/36-update-dialog

Conversation

@ElbertePlinio

Copy link
Copy Markdown
Member

Summary

  • Mounts @pickforge/tauri-updater's shared controller + <pickforge-update-dialog> element on PickGauge's main window when the studioUpdateDialog flag is on. Default off (@pickforge/flags, src/lib/flags.ts) — no PickGauge-local flag registry existed before this PR, so a thin per-app wrapper was added matching the pattern already used in pickforge/src/stores/flags.ts (own definitions per app repo, not a monorepo-shared registry).
  • While the flag is off, the legacy window.confirm updater in src/lib/updater.ts is untouched (removal is a later PR per the issue's rollout plan).
  • src/lib/updateDialog.ts enforces the hard rules from the issue:
    • Capsule exclusion: createMainWindowEligibility checks the real Tauri window label (win.label !== "main") — the floating capsule (Float.svelte, label "float") never imports this module at all, and even if it did, the label check independently blocks it.
    • Hidden-window exclusion: a main window that isn't visible yet defers via onFocusChanged, resolving eligible only on first focus — this mirrors the pre-existing checkForUpdatesWhenVisible deferral in updater.ts so behavior doesn't regress.
    • Single check per process: one memoized controller promise plus the package's createProcessCheckGate().
    • Packaged builds only: no-ops in dev and outside Tauri (browser preview), matching the legacy flow.
    • Silent, non-blocking startup failures: wiring errors are caught and logged; nothing blocks app startup.
  • main.ts skips the legacy checkForUpdatesWhenVisible call on the main window only when the flag is on, so the two flows can never double-prompt.
  • Added a dev-only ?updateDialogFixture=available|downloading route (src/lib/updateDialogFixture.ts) with injected deterministic state for manual visual inspection at PickGauge's normal (1000×700) and minimum (820×580) sizes. PickGauge has no VRT/screenshot-baseline harness (confirmed — no such workflow or fixture infra exists in this repo), so per the issue's fallback this fixture is kept/polished instead of building one; import.meta.env.DEV elimination confirmed by build (fixture code appears only in the sourcemap, not the executable bundle).
  • docs/releases/UNRELEASED.md updated (internal/release change entry + validation).

Fixed from the inherited work

  • @pickforge/flags and @pickforge/tauri-updater were pinned exact (0.4.0, 0.12.0) in package.json/bun.lock. Every other @pickforge/* dependency across PickForge/PickScribe/PickGauge uses a caret range except @pickforge/brand (deliberately exact-pinned for asset consistency). Changed both to ^0.4.0 / ^0.12.0 to match the workspace convention and re-synced the lockfile.

Validation

  • bun run lint — clean
  • bun run check (svelte-check) — 0 errors, 0 warnings
  • bun run test — 85 vitest tests (incl. new flags.test.ts, updateDialog.test.ts) + 18 Node tests, all passing
  • bun run test:coverage — ratchet holds (existing thresholds: 16/23/26/17)
  • bun run build — succeeds; confirmed the dev-only fixture module is tree-shaken from the production bundle
  • No Rust files touched; cargo check/cargo test not run

Owner-gated packaged-update smoke (old build → staged newer build) and floating/hidden-window smoke on a real packaged app are deferred, per the issue's PR plan, to the flag-enable PR later in the rollout.

Refs pickforge/pickforge-platform#36

🤖 Generated with Claude Code

Mount @pickforge/tauri-updater's shared controller and dialog element on
PickGauge's main window when studioUpdateDialog is on (default off via
@pickforge/flags); the legacy window.confirm flow in updater.ts is
untouched while the flag is off. Eligibility excludes the floating
capsule by Tauri window label and defers a hidden main window until its
first focus event, preserving the existing checkForUpdatesWhenVisible
deferral. Adds a dev-only ?updateDialogFixture= route for the available
and downloading states, tree-shaken from production builds, since
PickGauge has no visual-regression baseline harness.

Refs pickforge/pickforge-platform#36
createMainWindowEligibility resolved eligible on visibility alone and
trusted a focus-changed event's payload without re-checking visibility,
so a hidden main window receiving an early focus event could pass, and a
window that became visible+focused during listener registration could
hang until a later focus event that might not come. Now eligibility
requires both isVisible() and isFocused(), re-queries both on every
focus-changed event instead of trusting the payload, and re-checks once
right after the listener registers to close that gap.

Also extracts the flag-on/flag-off startup routing decision (legacy
window.confirm vs. the shared dialog) out of main.ts/App.svelte into
src/lib/updateRouting.ts so the no-double-prompt guarantee between them
is directly unit tested.

Refs pickforge/pickforge-platform#36
# Conflicts:
#	bun.lock
#	docs/releases/UNRELEASED.md
@ElbertePlinio
ElbertePlinio merged commit a31b503 into main Jul 23, 2026
4 checks passed
@ElbertePlinio
ElbertePlinio deleted the feat/36-update-dialog branch July 23, 2026 23:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant