Desktop builds of todo/diet-guard/home_inventory are Flutter *web* in a Chrome --app window, so FlutterSecureStorage resolves to the web backend: AES-encrypted localStorage keyed inside the browser profile. That makes the account unsettable from outside the page -- `secret-tool` writes the wrong store (libsecret, which only the Linux build would read), and a Dart CLI cannot even import flutter_secure_storage, since it is a Flutter plugin and fails to resolve on the VM. Verified both, rather than assumed. The one process that can read the filesystem *and* reach the page is the wrapper already serving it -- the same seam diet-guard uses to keep the GitHub token out of the browser. So this adds the shared half of a wrapper route: the path constant, the opt-in env var, an opt-out marker key, and accountFromWrapper(), which fetches and hands the body to the existing FirebaseAccount.tryParse. Additive only, so consumers adopt it per-app on their own schedule; nothing forces a phone rebuild. Route handlers stay per-app because each wrapper owns its own server. Deliberately opt-in (CRDT_SYNC_SERVE_ACCOUNT): the route hands a credential with database write access to anything that can reach the wrapper's port, so it is set once to provision an install rather than left on. kSyncAccountOptOutKey exists so "Disconnect" cannot be silently undone by the next launch re-adopting the account. Every failure path returns null rather than throwing -- an absent route is the *normal* case -- so the caller degrades to "not configured", which the settings screens already handle by asking. 254 tests, analyzer clean. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0177xwzcpfpWG2qca8Mr39q9 |
||
|---|---|---|
| .github/workflows | ||
| crdt_sync_dart | ||
| crdt-sync | ||
| firebase | ||
| gatelock | ||
| guard-lib | ||
| scripts | ||
| unified-design-system | ||
| .gitignore | ||
| LICENSE | ||
| README.md | ||
utils
Shared libraries used across kuhyx's other projects. Each subdirectory is a
formerly-standalone repo, folded in here with full commit history preserved
(see each subdirectory's own git log for its pre-merge history).
crdt_sync_dart/
Dart/Flutter CRDT sync library (pub package name: crdt_sync, not published
to pub.dev — consumed via a git dependency). Mirrors crdt-sync (below)
module-for-module and test-for-test. Consumed by diet_guard's app,
screen-locker's workout_app, wake_alarm's phone_app, and todo (whose
notes are stored in the v0.2.0 LogStore).
Consume via:
dependencies:
crdt_sync:
git:
url: https://github.com/kuhyx/utils
ref: crdt_sync_dart-v0.2.0
path: crdt_sync_dart
crdt-sync/
Python CRDT sync library (package: crdt_sync, not published to PyPI). Same
design as crdt_sync_dart (HLC clocks, per-field LWW, sticky-delete
tombstones). Consumed by diet-guard and screen-locker.
Consume via:
crdt-sync @ git+https://github.com/kuhyx/utils@crdt-sync-v0.2.0#subdirectory=crdt-sync
guard-lib/
Bash tamper-resistance primitives (guardctl: chattr + bind-mount + systemd
watcher + pacman hooks). Not a package — installed by running
guard-lib/install.sh as root, which copies files onto the system
(/usr/local/bin, /usr/local/lib/guard-lib, systemd units, pacman hooks).
Consumed by steam-backlog-enforcer (expects a guard-lib/install.sh
sibling clone) and referenced by screen-locker.
gatelock/
Python lock-window + HMAC log-integrity backend (package: gatelock, not
published to PyPI). Consumed via pip by screen-locker, diet-guard, and
wake-alarm:
gatelock @ git+https://github.com/kuhyx/utils@gatelock-v0.1.0#subdirectory=gatelock
unified-design-system/
Not a package — the frozen design tokens (colors, spacing, type, radius,
shadow policy) and per-stack (Flutter/web/Tkinter) implementation patterns
that keep every one of kuhy's repos visually identical, plus annotated
component references (components.html, button.html). Read
unified-design-system/README.md and
tokens.md before touching any theme/CSS/style file in any repo. The
unified-design-system Claude Code skill is a thin pointer here, not a
duplicate.