Commit Graph

9 Commits

Author SHA1 Message Date
2ed9267e06 warm-tint the unified-design-system palette, fix design audit violations
Replaces the inline ColorScheme.fromSeed(Colors.deepPurple) theme with a new
lib/ui/theme.dart built from explicit light/dark ColorSchemes on the frozen
unified-design-system tokens (same shared spacing/radius/type-scale constants
as diet-guard/habit_stack's theme.dart), and adds darkTheme (previously
absent).

Fixes 2 of 3 violations in DESIGN_AUDIT_TODO.md:
- settings_screen.dart's one hardcoded Colors.red -> colorScheme.error,
  matching every other error-state text in the app
- markdown_view.dart and note_editor.dart's raw-mode TextField now cap their
  reading/editing column at kProseMaxWidth (640) via Center+ConstrainedBox --
  the desktop build is an arbitrarily wide Chrome --app window, so text was
  running the full viewport. Deliberately no extra Column introduced around
  the raw-mode TextField, per its own documented expands:true/nested-Column
  regression history.

The 3rd violation (a few off-scale SizedBox/EdgeInsets values, e.g. 6px vs
the file's dominant 4px scale) was attempted but reverted: bumping the
_EnumChips/_MultiChips/_DateRangeField 6px gaps to 8px broke 3 real tests --
the filter bottom sheet's "Apply" button is tight enough against its edge
that even a 2px shift pushes it out of the hit-testable area. Not worth
trading a working control for a cosmetic 2px scale nitpick; left at 6px.

Verified: flutter analyze clean, dart format clean on all touched files,
188/188 tests passing (added test/theme_test.dart for the new file, which
had 0% coverage on its own), 100% total line coverage maintained, re-verified
identical in an isolated worktree at HEAD (narrowly staged around this
repo's own pre-existing uncommitted CLAUDE.md edit, left untouched). A
Flutter-web headless-Chrome screenshot check for the desktop target was
attempted but blocked by a CanvasKit/WebGL rendering issue in this sandbox,
unrelated to the app itself; the widget test suite (which does catch real
RenderFlex overflow, as confirmed during this same rollout) passed clean for
both touched screens instead. Mobile on-device verification (phone-deploy)
is pending -- the phone isn't connected via ADB right now.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 18:56:45 +02:00
66143bdfe3 Make the app compile and run for web, behind platform seams
First step of moving the desktop app off Flutter's Linux embedder, which tops
out at ~20fps at 4K (see docs/desktop-performance-findings.md). Android is
unaffected and keeps every existing code path.

The blocker was that `dart:io` was imported by note_repository, capture_screen
and settings_screen. On web it compiles to a stub and then throws at runtime --
the first web build rendered a blank white window. So each `dart:io` use now
sits behind a conditional export, with the shared logic hoisted into pure Dart:

- note_repository loses `dart:io`/sqlite entirely. Platform wiring moves to
  repository_factory{,_io,_web}, and the legacy sqlite import moves to its own
  io-only library. The HLC-from-updated_at seeding is preserved verbatim, so
  independently-migrating devices still resolve pre-cutover edits by real edit
  time.
- Notes persist to IndexedDB on web, not localStorage: the log is the primary
  copy of the backlog and localStorage caps at ~5-10MB and is evicted eagerly.
- BACKLOG.md and the explicit Export keep working through a local wrapper
  (added next). A browser cannot write `~/todo/BACKLOG.md`, and the user's
  tooling plus the todo MCP server read that path, so leaving it to rot was not
  an option. Writes are best-effort so the app still works with no wrapper.
- Notes are also mirrored to the wrapper's on-disk copy, so a wiped Chrome
  profile is not a total-loss event for notes that have not reached GitHub yet.

`openRepository` is split so `openRepositoryIn` keeps the migration tests; the
suite stays at 174 green and 100% coverage.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 13:14:03 +02:00
f463e50d67 Switch to very_good_analysis, matching the rest of the Flutter ecosystem
Standardizes on the same stricter lint set + shared analysis_options.yaml
used by diet-guard/app and the new habit_stack app. Fixes all 127 issues
surfaced: dart fix --apply for imports/cascades/sorting, unawaited() on
fire-and-forget Futures, bare catch(e) narrowed to on Exception catch(e)
(matching diet_guard's existing pattern), one documented ignore for a
deliberate TypeError catch around untrusted peer JSON, and missing
public-member doc comments throughout. No behavior change: 174/174 tests
pass, 100% line coverage maintained.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-20 11:05:13 +02:00
253088c4ed Use crdt_sync's shared GitHubClient; drop todo's local copy
crdt_sync v0.3.0 now provides canAccessRepo() + deleteFile(), so todo syncs
through the one shared client like the other apps instead of its own copy.
SyncService loses its SHA-tracking (crdt_sync's putFileText self-resolves the
sha); lib/sync/github_client.dart + its test are deleted; capture/settings/
sync_smoke repoint to the shared client. flutter analyze clean, 169 tests at
100% coverage, device-verified (27-note backlog intact, no crash).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019KwUCPESvE5CjCtmUFz8xQ
2026-07-11 23:53:47 +02:00
9edf603a24 Point notes sync at the consolidated syncs monorepo
todo-sync, diet-guard-sync, and screen-locker-sync were folded into
one private github.com/kuhyx/syncs monorepo, each keeping its own
subdirectory as the Contents-API path prefix. Update the default
owner/repo, the changeset path prefix, and add a persisted-value
migration so an already-installed device that saved the old
'todo-sync' repo name picks up 'syncs' on next load.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-10 14:04:05 +02:00
0ce35ded4f Fix device-flow connect: sync immediately and reload settings
Connecting via the device flow saved the token to prefs but had no effect:
the capture screen cached its settings from launch and only re-adopted them
when Settings was popped *with a result*, which the connect flow never did.
So auto-sync kept using stale (token-less) settings (notes never downloaded)
and reopening Settings re-seeded the fields from the stale settings (empty
token → Test connection failed, Connect restarted every time).

- settings: on a successful connect, save then run a sync right away and
  report the result ("Connected and synced …") so notes download and the
  user gets real confirmation, instead of the inert "Token saved on Save".
- capture: always reload settings from storage after returning from Settings,
  so a device-flow connect (which saves without popping a result) is picked up.
- tool/device_flow_check.dart: standalone end-to-end device-flow probe used to
  confirm the OAuth App + token + repo-access chain is healthy (it is); the bug
  was purely app-side token application.

152 tests, 100% line coverage.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 22:38:30 +02:00
f5d79a6a57 One-tap GitHub connect via a baked-in OAuth App client id
Previously "Connect GitHub" (OAuth device flow) still required entering an
OAuth App client id and owner/repo — friction that returned on every
reinstall once shared_prefs were wiped.

- Bake the app's own device-flow OAuth App client id in as
  SyncSettings.defaultClientId and default to it in load() (alongside the
  existing kuhyx/todo-sync repo default). A device-flow client id is a
  public identifier, not a secret, so it is safe to commit.
- Settings now leads with a single "Connect GitHub" button; the manual
  client-id / token fields and Test connection move under an "Advanced"
  expander. Result: fresh install (or post-reinstall) is one tap →
  authorize the code in the browser → synced. No tokens, no setup.

Note: an OAuth App authorizes with the classic `repo` scope (all repos),
broader than the prior fine-grained PAT — the trade-off for one-tap
device-flow convenience. 151 tests, 100% line coverage.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 22:21:34 +02:00
7f84414c87 Add list filters/sort, status, priority rework, export/import, structured template
Notes list & filtering:
- Text-search filter plus independent date-range filters for both created
  and last-updated (AND-combined), a priority filter, and a new status
  filter. Default view hides Done/Abandoned and renders as "unfiltered"
  (no badge for the default state); fixed badge clipping.
- NoteSort options wired into the list UI; watchCount() for the "N saved".

Status & priority:
- New Status enum (toDo/inProgress/Done/Abandoned) as a settable + filterable
  attribute on every note, with capture-screen dropdown.
- Removed "None" priority: every note is Low/Medium/High, default Medium.
  Schema migration v2->v3 rewrites legacy priority 0 -> Medium.

Export / import:
- NotesMarkdown round-trippable single-file format with HTML-comment markers.
- Settings "Export notes" (mobile share sheet / desktop writes ~/todo/BACKLOG.md)
  and "Import notes" (file picker + safe newer-wins merge by id).

Structured template:
- Every new note pre-fills the richer what/where/must/nice/out/done/depends/
  estimate/refs scaffold.

Tests:
- New fast (~5s), deterministic suite via FakeNoteRepository (no DB timers) and
  injected http/file-selector/url-launcher fakes. 86 tests, 96.2% line coverage
  (note.dart & sync_service.dart at 100%, settings 98.7%). Mobile-only share
  branch excluded via coverage:ignore (unreachable on the Linux test host).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 16:52:59 +02:00
d48bcd24f7 Initial commit: offline-first CRDT notes app (capture + GitHub sync)
Flutter app for Android + Linux desktop. Captures ideas with per-keystroke local autosave to a CRDT-backed SQLite store (sqlite_crdt), and syncs through a private GitHub repo using per-device changeset files (conflict-free last-writer-wins merge). Includes GitHub OAuth device-flow sign-in with PAT fallback, a barebones notes list, and sync settings.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 14:20:19 +02:00