Commit Graph

5 Commits

Author SHA1 Message Date
8957d51432 Desktop: launch Chrome --app with --disable-extensions (no stray extension windows)
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
file-length / file length <= 250 lines (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (mypy, mypy, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (pylint, pylint, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (rest, , mypy,pylint) (push) Waiting to run
Tests / test (push) Waiting to run
release-apk / release (APK) (push) Waiting to run
repo-contract / repo contract (push) Waiting to run
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 13:04:10 +01:00
688bd7b1de Finish the three sync bugs: gate, SIGKILL flag, and silent catches
Some checks are pending
pre-commit / pre-commit (push) Waiting to run
Tests / test (3.10) (push) Waiting to run
Tests / test (3.11) (push) Waiting to run
Tests / test (3.12) (push) Waiting to run
release-apk / release (APK) (push) Waiting to run
Auditing the whole fleet for the bugs found on the desktop turned up three
that were still live here.

1. `--virtual-time-budget=45000` was still in the provisioning args. The
   previous commit added the comment explaining why it must not be there but
   left the flag itself, so headless Chrome kept SIGKILLing itself (exit -9)
   and could still truncate a sync. Actually removed now; a provisioning run
   exits 0.

2. `backgroundSyncPush` gated on `settings.isConfigured` -- "has a GitHub
   token" -- so the WorkManager background push was skipped entirely on a
   device connected only to Firebase. Same defect as _autoSync's, one layer
   down. Either backend now counts.

3. Three swallowed exceptions, all in the sync path: the in-isolate config
   read, the background push itself, and `loadAccount()`. The last one is the
   worst -- it hid *why* provisioning failed, which is indistinguishable from
   "no account set" until it says so, and cost real debugging time this
   session. All log at warning/error with the stack trace and stay non-fatal,
   per the repo's no-silent-failures rule.

Verified after the change, not just compiled: provisioning exits 0 and the
desktop (c891b813) still holds 359 food_log records, identical to the PC
daemon's, 0 missing.

522 tests, analyzer and pre-commit clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0177xwzcpfpWG2qca8Mr39q9
2026-08-09 22:28:18 +02:00
d388f90ed4 Stop SIGKILLing the provisioning browser, and say why auto-sync failed
Some checks are pending
pre-commit / pre-commit (push) Waiting to run
Tests / test (3.10) (push) Waiting to run
Tests / test (3.11) (push) Waiting to run
Tests / test (3.12) (push) Waiting to run
release-apk / release (APK) (push) Waiting to run
Two fixes found while verifying the desktop actually reaches Firebase rather
than trusting an exit code.

`--virtual-time-budget` makes headless Chrome SIGKILL itself when the budget
expires: the run reported exit -9 and could cut a sync short mid-flight. It
now gets a real wall-clock window and is closed cleanly, so the exit code
means what it says.

`_autoSync` caught `on Exception` and ignored it entirely — the exact
silent-failure shape screen-locker's CLAUDE.md bans ("an invisible log is a
silent failure with extra steps"). It now catches broadly and logs at error
level with the stack trace, so the next failure is diagnosable instead of
looking identical to "nothing to sync". `--enable-logging=stderr` on the
provisioning run surfaces that in the terminal that started it.

Verified end to end, which is what settled it: the desktop appears in the
RTDB as c891b813 with all four documents and a revs entry, and its food_log
holds 359 records — identical to the PC daemon's, 0 missing either way. An
earlier check read as "not pushing" because it ran before the push landed.

522 tests, analyzer and pre-commit clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0177xwzcpfpWG2qca8Mr39q9
2026-08-09 22:15:34 +02:00
c093c22ae0 Auto-sync on a Firebase-only device, and provision with no window
Some checks are pending
pre-commit / pre-commit (push) Waiting to run
Tests / test (3.10) (push) Waiting to run
Tests / test (3.11) (push) Waiting to run
Tests / test (3.12) (push) Waiting to run
release-apk / release (APK) (push) Waiting to run
Two bugs, found because headless provisioning silently did nothing here while
it worked in todo.

`_autoSync` returned early unless `settings.isConfigured`, which means "has a
GitHub token". A desktop connected only to Firebase therefore never synced at
all -- not on this run, not ever -- and since the provisioning fallback is
reached through openFirebase(), it could never provision either. This is the
same defect workout_app's push() already documents ("Gating on the GitHub
token alone silently dropped every push from a device connected only to
Firebase -- and once the mirror is retired that would be every device").
Either backend now counts.

--provision-sync-account then does the setup with no window: the account
lives in origin-keyed localStorage so the page must run, but --headless=new
runs it without ever mapping a window. Startup auto-sync calls loadAccount(),
the wrapper fallback provisions, the process exits.

Verified after the fix, having watched it fail twice before it:
FlutterSecureStorage.firebase.account now holds a real AES payload in the
desktop profile's localStorage. The time budget is 45s rather than todo's
15s -- this log is an order of magnitude larger.

Usage:  CRDT_SYNC_SERVE_ACCOUNT=1 diet-guard-app --provision-sync-account

522 tests, analyzer and pre-commit clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0177xwzcpfpWG2qca8Mr39q9
2026-08-09 22:00:53 +02:00
aeb9376391 app: add the desktop wrapper that serves the web build and fronts GitHub
A browser cannot touch the filesystem, so the desktop app needs a second
half. This local process serves the built web assets, owns an on-disk copy of
every document and photo blob the app stores, and performs the GitHub I/O the
page cannot.

Both GitHub responsibilities are load-bearing, not convenience:

- the device-flow endpoints (github.com/login/device/*) send no CORS headers,
  so a page cannot call them at all;
- proxying api.github.com server-side is what keeps the token out of the
  browser -- the page is told `{"status":"ok"}`, never the token itself.

The wrapper falls back to the PC gate's existing
`~/.config/diet_guard/sync_token`, so this machine needs no second setup.

Details learned the hard way in the two apps migrated before this one, kept
here deliberately: loopback-only binding (the endpoints overwrite files in
$HOME with no auth), `application/wasm` for .wasm or CanvasKit renders
nothing at all, a fixed port and Chrome profile because IndexedDB is keyed by
origin, and treating a browser exit inside ~5s as a handoff to an existing
window rather than a reason to stop serving. Mirror names are rejected unless
they are plain filenames -- a `..` segment would turn a mirror write into an
arbitrary-file overwrite.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 16:31:47 +02:00