From e98884b200265eac6caba2c94da5254668d74394 Mon Sep 17 00:00:00 2001 From: Krzysztof kuhy Rudnicki Date: Fri, 11 Sep 2026 18:46:28 +0200 Subject: [PATCH] Re-point paths for the ~ reorganisation (home-tidy) Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01AwtowrowDXx6ccmWVPkCaF --- .pre-commit-config.yaml | 2 +- TODO-file-length-250.md | 4 ++-- TODO-finish-dart-250.md | 10 +++++----- docs/TODO-android-ui-mcp-wrapper.md | 16 +++++++-------- .../DOCS-audit-gatelock-tokens.md | 10 +++++----- .../DOCS-audit-tkinter-lock-ui.md | 2 +- docs/todo/DOCS-workstream-c-github-sync.md | 8 ++++---- .../DOCS-workstream-d-scoping-findings.md | 12 +++++------ ...DOCS-workstream-d-shared-crdt-transport.md | 14 ++++++------- install.sh | 8 ++++---- prompts/TODO-dopamine-ux-04-screen-locker.md | 20 +++++++++---------- prompts/TODO-dopamine-ux-05-workout-app.md | 16 +++++++-------- screen_locker/_compliance_predicates.py | 2 +- screen_locker/_mcp.py | 2 +- screen_locker/adjust_shutdown_schedule.sh | 2 +- scripts/add_scheduled_skip.py | 2 +- scripts/check_dependency_freshness.sh | 6 +++--- scripts/check_md_naming.sh | 6 +++--- scripts/check_no_crdt_sync_override.sh | 2 +- scripts/verify_screen_fits.py | 2 +- .../workout_app/pubspec.yaml | 2 +- web/src/index.css | 2 +- web/src/test/factories.ts | 2 +- workout-sync.service | 2 +- 24 files changed, 77 insertions(+), 77 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 57118b2..8f9981b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -277,7 +277,7 @@ repos: # Four markdown namespaces (README / CLAUDE* / DOCS* / TODO*), plus the # rule that a TODO carries "REMOVE ME AFTER FINISH" and nothing else may. - # Shared gate in ~/utils owns the namespaces and the exemption list, so + # Shared gate in ~/src/utils owns the namespaces and the exemption list, so # one repo's idea of a valid name cannot drift from every other repo's. - id: md-naming name: markdown naming convention diff --git a/TODO-file-length-250.md b/TODO-file-length-250.md index 2977abe..d744b2a 100644 --- a/TODO-file-length-250.md +++ b/TODO-file-length-250.md @@ -71,7 +71,7 @@ an exempt extension, no `# noqa`-style suppressions. A refactor without a gate silently regrows. Before this task is done: -1. Wire the shared gate `~/utils/scripts/check_file_length.sh` into this repo's +1. Wire the shared gate `~/src/utils/scripts/check_file_length.sh` into this repo's `.pre-commit-config.yaml` as a local hook. If the repo has no pre-commit config, add a minimal one. 2. The hook checks **files in the commit** (not the whole tree), so unrelated @@ -82,7 +82,7 @@ A refactor without a gate silently regrows. Before this task is done: ## Done condition -- `bash ~/utils/scripts/check_file_length.sh --all` from this repo root exits 0. +- `bash ~/src/utils/scripts/check_file_length.sh --all` from this repo root exits 0. - The repo's own test suite and coverage bar are still green. - `pre-commit run --files ` passes. - A deliberately over-250-line test file, staged, makes `git commit` **fail**. diff --git a/TODO-finish-dart-250.md b/TODO-finish-dart-250.md index 63831a9..6691e4f 100644 --- a/TODO-finish-dart-250.md +++ b/TODO-finish-dart-250.md @@ -7,7 +7,7 @@ ## Goal -`bash ~/utils/scripts/check_file_length.sh --all` from the repo root exits 0. +`bash ~/src/utils/scripts/check_file_length.sh --all` from the repo root exits 0. Everything else in `refactor_claude_todo.md` still applies (no gaming the cap, no deleting tests, no suppressions). This file only adds what the previous @@ -16,7 +16,7 @@ session learned the hard way. ## Start here (do this first, it costs one command) ```bash -cd ~/screen-locker/stronglift_replacement/workout_app +cd ~/src/screen-locker/stronglift_replacement/workout_app env -u GIT_DIR flutter test 2>&1 | tail -1 # MUST print: +402: All tests passed! ``` @@ -145,10 +145,10 @@ extension in a part still reaches `_privateField`. ## Verify (all of it, every batch) ```bash -cd ~/screen-locker/stronglift_replacement/workout_app +cd ~/src/screen-locker/stronglift_replacement/workout_app env -u GIT_DIR dart analyze lib/ # must be "No issues found!" env -u GIT_DIR flutter test 2>&1 | tail -1 # must be +402 -cd ~/screen-locker && pre-commit run # includes the 100% Flutter coverage gate +cd ~/src/screen-locker && pre-commit run # includes the 100% Flutter coverage gate ``` `dart analyze` is a **no-op on test files** — `analysis_options.yaml` excludes @@ -157,7 +157,7 @@ signal. ## Done condition -- `bash ~/utils/scripts/check_file_length.sh --all` exits 0. +- `bash ~/src/utils/scripts/check_file_length.sh --all` exits 0. - 402 Dart tests pass; `flutter` coverage still 100%. - `pre-commit run --all-files` passes. - The app still runs on the phone: use the `phone-deploy` skill diff --git a/docs/TODO-android-ui-mcp-wrapper.md b/docs/TODO-android-ui-mcp-wrapper.md index 0f450e8..5370b0b 100644 --- a/docs/TODO-android-ui-mcp-wrapper.md +++ b/docs/TODO-android-ui-mcp-wrapper.md @@ -1,12 +1,12 @@ # Task: replace blind coordinate tapping with element-targeted Android UI automation > **STATUS 2026-08-10: BUILT.** The tool now exists at -> `~/testsAndMisc/python_pkg/android_ui/` (see its README). It covers `dump` / +> `~/src/testsAndMisc/python_pkg/android_ui/` (see its README). It covers `dump` / > `find` / `tap` / `type` / `wait` / `focus` with verified typing, ambiguity as > an error, keyboard detection, and partial-tree retries — all exercised > against the physical Pixel 6a. What remains from the spec below is the -> optional MCP wrapper, `scroll_to()`, and rolling it out to `~/todo` and -> `~/dufs-cloud/app`. Everything after this line is the original brief, kept +> optional MCP wrapper, `scroll_to()`, and rolling it out to `~/src/todo` and +> `~/src/dufs-cloud/app`. Everything after this line is the original brief, kept > because it records WHY each guarantee exists. ## what @@ -51,7 +51,7 @@ nodes by class and gave exact centers, and the retry worked first time. New shared tool, not a per-repo copy. Two options, pick one: -- `~/testsAndMisc/python_pkg/android_ui/` — a CLI (`android-ui find "Connect +- `~/src/testsAndMisc/python_pkg/android_ui/` — a CLI (`android-ui find "Connect Firebase"`, `android-ui tap "Connect Firebase"`, `android-ui dump`), matching how `app_icons` is already shared across repos. - An MCP server exposing the same as tools, which is what makes it available to @@ -59,9 +59,9 @@ New shared tool, not a per-repo copy. Two options, pick one: asked for "some tool ... (mcp?) which also translates to UI". Consumers (every repo with an Android surface): -- `~/screen-locker/stronglift_replacement/workout_app` -- `~/todo` -- `~/dufs-cloud/app` +- `~/src/screen-locker/stronglift_replacement/workout_app` +- `~/src/todo` +- `~/src/dufs-cloud/app` - any future Flutter app (this should be part of the app scaffold) ## must @@ -108,7 +108,7 @@ emulator and not a debug-only Flutter driver session. - This session's working recovery: `uiautomator dump` + the bounds-parsing python in the screen-locker scratchpad (`ui.xml`, `ui2.xml`). -- `~/screen-locker/CLAUDE.md` — "You are NOT done until you install the new +- `~/src/screen-locker/CLAUDE.md` — "You are NOT done until you install the new version on the phone itself", which is why agent-driven UI is on the critical path for every task in this repo. - Note `uiautomator dump` returns an empty/partial tree while an animation is diff --git a/docs/design-audit/DOCS-audit-gatelock-tokens.md b/docs/design-audit/DOCS-audit-gatelock-tokens.md index 43741ad..72dbdfc 100644 --- a/docs/design-audit/DOCS-audit-gatelock-tokens.md +++ b/docs/design-audit/DOCS-audit-gatelock-tokens.md @@ -1,13 +1,13 @@ ## Shared gatelock library -`~/utils/gatelock` is **not** its own git repo — `git -C ~/utils/gatelock -rev-parse --show-toplevel` resolves to `/home/kuhy/utils`, so it's a -subdirectory of the `~/utils` monorepo. Per audit scope, gatelock itself was +`~/src/utils/gatelock` is **not** its own git repo — `git -C ~/src/utils/gatelock +rev-parse --show-toplevel` resolves to `/home/kuhy/src/utils`, so it's a +subdirectory of the `~/src/utils` monorepo. Per audit scope, gatelock itself was not walked against all 28 rules and no separate -`~/utils/gatelock/DESIGN_AUDIT_TODO.md` was written. +`~/src/utils/gatelock/DESIGN_AUDIT_TODO.md` was written. What's relevant here: gatelock defines exactly **one** real design token — -`LockConfig.bg: str = "#1a1a1a"` (`~/utils/gatelock/gatelock/_window.py:71`), +`LockConfig.bg: str = "#1a1a1a"` (`~/src/utils/gatelock/gatelock/_window.py:71`), applied via `self.root.configure(bg=self._config.bg, ...)` in `LockWindow.setup()` (`_window.py:143`). Both consumer repos re-hardcode this same literal instead of reading it back off their own `LockConfig` diff --git a/docs/design-audit/DOCS-audit-tkinter-lock-ui.md b/docs/design-audit/DOCS-audit-tkinter-lock-ui.md index 0b0469d..36f806f 100644 --- a/docs/design-audit/DOCS-audit-tkinter-lock-ui.md +++ b/docs/design-audit/DOCS-audit-tkinter-lock-ui.md @@ -14,7 +14,7 @@ independently, in 9 files. Evidence: `_sick_dialog.py` (18), `_temperature_status_mixin.py` (5). `#1a1a1a` alone (the background) appears **31 times** — and it is *also* already defined once, correctly, as `LockConfig.bg = "#1a1a1a"` in - `~/utils/gatelock/gatelock/_window.py:71`. None of the 31 in-repo literals + `~/src/utils/gatelock/gatelock/_window.py:71`. None of the 31 in-repo literals import or reference it; `LockWindow.setup()` in gatelock applies `config.bg` to the root window (`_window.py:143`), and then every screen-locker dialog re-hardcodes the same string as if gatelock's value diff --git a/docs/todo/DOCS-workstream-c-github-sync.md b/docs/todo/DOCS-workstream-c-github-sync.md index 940f2ee..54c06a2 100644 --- a/docs/todo/DOCS-workstream-c-github-sync.md +++ b/docs/todo/DOCS-workstream-c-github-sync.md @@ -47,7 +47,7 @@ production in this user's other repos — read both before designing this one: 1. **diet-guard's Contents-API repo sync** - (`~/diet-guard/diet_guard/_sync.py` + `_sync_github.py` + + (`~/src/diet-guard/diet_guard/_sync.py` + `_sync_github.py` + `_sync_merge.py`, ~120/190/80 lines respectively). `GitHubSyncClient` (`_sync_github.py:38`) wraps the GitHub Contents API with `get_file_text(path)`, `put_file_text(path, text, message=...)`, @@ -59,7 +59,7 @@ one: fine-grained PAT read from `~/.config/diet_guard/sync_token` (scoped to just that one repo's contents). 2. **wake-alarm's Gist-based sync** - (`~/wake-alarm/shutdown-wrapper.sh`, phone app writes to a **private + (`~/src/wake-alarm/shutdown-wrapper.sh`, phone app writes to a **private Gist**, not a repo). Config at `~/.config/wake_alarm/gist_sync.json` with `token`/`gist_id`. Much simpler (single JSON blob, no per-device paths, no merge step) — matches wake-alarm's much simpler data shape (one @@ -148,7 +148,7 @@ sync code first. - `screen_locker/_constants.py` (`WORKOUT_APP_JSON_REMOTES`, `WORKOUT_HTTP_PORT` — new `SYNC_*` constants go here too) - `stronglift_replacement/workout_app/lib/` (phone-side push, new work) -- Reference-only, do not modify: `~/diet-guard/diet_guard/_sync_github.py`, - `_sync.py`, `_sync_merge.py`; `~/wake-alarm/shutdown-wrapper.sh` +- Reference-only, do not modify: `~/src/diet-guard/diet_guard/_sync_github.py`, + `_sync.py`, `_sync_merge.py`; `~/src/wake-alarm/shutdown-wrapper.sh` - **Do not touch**: `screen_locker/_runnerup_verification.py`, `_runnerup_db.py` (hard boundary, see Context above) diff --git a/docs/todo/DOCS-workstream-d-scoping-findings.md b/docs/todo/DOCS-workstream-d-scoping-findings.md index d6e84f4..5d63d76 100644 --- a/docs/todo/DOCS-workstream-d-scoping-findings.md +++ b/docs/todo/DOCS-workstream-d-scoping-findings.md @@ -15,7 +15,7 @@ to have very different shareability: `put_file_text` / `list_directory` against a private repo) is genuinely shared already — it's independently duplicated almost line-for-line between todo's `GitHubClient` and diet-guard's `GitHubSyncClient` - (`~/diet-guard/diet_guard/_sync_github.py`, 191 lines, `requests`-only). + (`~/src/diet-guard/diet_guard/_sync_github.py`, 191 lines, `requests`-only). Extracting this into a shared Python lib (and a shared Dart lib for todo's/diet-guard's Dart-side client) is low-risk, small, and is the part Workstream C already committed to (Contents-API pattern, not Gist — @@ -70,7 +70,7 @@ library too: ## 3. Per-app migration cost (revised — the original doc's "todo = smallest lift" assumption does not hold) -Checked `~/todo/lib/data/note_repository.dart`: notes are **mutated in +Checked `~/src/todo/lib/data/note_repository.dart`: notes are **mutated in place** — `upsert()` does `INSERT ... ON CONFLICT DO UPDATE SET text = ?, priority = ?, status = ?, updated_at = ?`, relying on `sqlite_crdt`'s per-column Hybrid-Logical-Clock last-writer-wins to reconcile concurrent @@ -138,8 +138,8 @@ off the shelf. ## Critical files referenced (read-only during this pass) -- `~/todo/lib/sync/sync_service.dart`, `~/todo/lib/data/note_repository.dart` -- `~/diet-guard/diet_guard/_sync.py`, `_sync_github.py`, `_sync_merge.py` -- `~/diet-guard/app/lib/services/sync_merge.dart` -- `~/wake-alarm/shutdown-wrapper.sh` +- `~/src/todo/lib/sync/sync_service.dart`, `~/src/todo/lib/data/note_repository.dart` +- `~/src/diet-guard/diet_guard/_sync.py`, `_sync_github.py`, `_sync_merge.py` +- `~/src/diet-guard/app/lib/services/sync_merge.dart` +- `~/src/wake-alarm/shutdown-wrapper.sh` - `docs/todo/workstream-c-github-sync-workout-data.md` (this repo) diff --git a/docs/todo/DOCS-workstream-d-shared-crdt-transport.md b/docs/todo/DOCS-workstream-d-shared-crdt-transport.md index efaf290..afb859f 100644 --- a/docs/todo/DOCS-workstream-d-shared-crdt-transport.md +++ b/docs/todo/DOCS-workstream-d-shared-crdt-transport.md @@ -8,9 +8,9 @@ fell out of it (both resolved by explicit user call, 2026-07-04). **The two shared libraries are now implemented and locally verified (2026-07-05):** -- `~/crdt-sync` (Python) — 60 tests, 100% branch coverage, clean +- `~/src/utils/crdt-sync` (Python) — 60 tests, 100% branch coverage, clean ruff/mypy/pylint/bandit/pre-commit. Local git repo, one commit. -- `~/crdt_sync_dart` (pure Dart, no Flutter dep) — 59 tests, clean +- `~/src/utils/crdt_sync_dart` (pure Dart, no Flutter dep) — 59 tests, clean `dart analyze`. Local git repo, one commit. Both implement the unified LWW-map-with-sticky-remove scheme (`Hlc`, @@ -62,7 +62,7 @@ from-scratch CRDT implementation. **diet-guard and wake-alarm do NOT use CRDTs today.** Their existing "merge" mechanisms are much simpler: -- diet-guard: `_sync_merge.merge_logs` (`~/diet-guard/diet_guard/_sync_merge.py`, +- diet-guard: `_sync_merge.merge_logs` (`~/src/diet-guard/diet_guard/_sync_merge.py`, 81 lines) is a tombstone-aware, entry-key-based merge — closer to last-write-wins per entry than a general CRDT. Transport is `_sync_github.GitHubSyncClient` against a private repo's Contents API @@ -151,9 +151,9 @@ time this is scoped for real. ## Critical files (reference only — read, do not modify, during scoping) -- `~/todo/lib/sync/sync_service.dart`, `sync_settings.dart` (CRDT-via-package pattern) -- `~/diet-guard/diet_guard/_sync.py`, `_sync_github.py`, `_sync_merge.py` -- `~/diet-guard/app/lib/services/sync_service.dart`, `sync_merge.dart` -- `~/wake-alarm/shutdown-wrapper.sh` +- `~/src/todo/lib/sync/sync_service.dart`, `sync_settings.dart` (CRDT-via-package pattern) +- `~/src/diet-guard/diet_guard/_sync.py`, `_sync_github.py`, `_sync_merge.py` +- `~/src/diet-guard/app/lib/services/sync_service.dart`, `sync_merge.dart` +- `~/src/wake-alarm/shutdown-wrapper.sh` - `docs/todo/workstream-c-github-sync-workout-data.md` (this repo — resolve its open questions jointly with this one, not independently) diff --git a/install.sh b/install.sh index 0796c80..f8ad554 100755 --- a/install.sh +++ b/install.sh @@ -42,7 +42,7 @@ readonly REPO_DIR="$SCRIPT_DIR" readonly SYSTEMD_USER_DIR="$HOME/.config/systemd/user" readonly PROD_PYTHON="/usr/bin/python3" # The shared lock backend, developed in lockstep with this repo. -readonly GATELOCK_DIR="$HOME/utils/gatelock" +readonly GATELOCK_DIR="$HOME/src/utils/gatelock" echo "=== Screen Locker Installer ===" @@ -58,7 +58,7 @@ fi # 2. Install the package ------------------------------------------------------ # --break-system-packages is required on Arch (PEP 668). Editable so a later # `git pull` in THIS clone updates the running service with no reinstall. That -# is also why the clone must live somewhere durable (~/screen-locker), never a +# is also why the clone must live somewhere durable (~/src/screen-locker), never a # scratch directory: a non-editable snapshot would freeze at this commit and # silently stop tracking the repo. echo "[2/4] Installing screen_locker into user site-packages (editable)..." @@ -69,7 +69,7 @@ echo "[2/4] Installing screen_locker into user site-packages (editable)..." # pyproject.toml pins `gatelock @ git+https://.../@gatelock-v0.2.1`, so the # install above resolves that pin and overwrites any local editable gatelock # with a frozen wheel built from the tag. That silently reverts every -# unreleased change in ~/utils/gatelock and breaks the other lockers that +# unreleased change in ~/src/utils/gatelock and breaks the other lockers that # depend on them -- observed: it removed `ScrollableSurface` and took # diet_guard down with it. # @@ -122,7 +122,7 @@ if ! (cd /tmp && "$PROD_PYTHON" -c "import screen_locker" 2>/dev/null); then fi if ! (cd /tmp && "$PROD_PYTHON" -c "import gatelock" 2>/dev/null); then echo "ERROR: $PROD_PYTHON cannot import gatelock (the shared lock" >&2 - echo " backend). Install it editable from ~/utils/gatelock." >&2 + echo " backend). Install it editable from ~/src/utils/gatelock." >&2 exit 1 fi if [[ -d "$GATELOCK_DIR" ]]; then diff --git a/prompts/TODO-dopamine-ux-04-screen-locker.md b/prompts/TODO-dopamine-ux-04-screen-locker.md index 17009fb..b5f9dfc 100644 --- a/prompts/TODO-dopamine-ux-04-screen-locker.md +++ b/prompts/TODO-dopamine-ux-04-screen-locker.md @@ -2,8 +2,8 @@ > "do dopamine-ux-04-screen-locker". It is self-contained -- it needs no context from > any other session. > -> Canonical copy: `~/utils/dopamine-ux/04-screen-locker.md` (source of truth; this is a -> distributed copy). Running order and cross-prompt rules: `~/utils/dopamine-ux/00-INDEX.md`. +> Canonical copy: `~/src/utils/dopamine-ux/04-screen-locker.md` (source of truth; this is a +> distributed copy). Running order and cross-prompt rules: `~/src/utils/dopamine-ux/00-INDEX.md`. > Generated 2026-08-16 from a survey of this repo -- line numbers are accurate > as of that date; **anchor on the symbol names, not the line numbers.** @@ -19,10 +19,10 @@ Do **both**, in the same session that completes the work: Do not leave a finished prompt lying in the repo -- a stale prompt is indistinguishable from a pending one, and the next session will re-run it. -2. **Log completion in the canonical index**, in `~/utils` (a *different* repo, +2. **Log completion in the canonical index**, in `~/src/utils` (a *different* repo, so it needs its own commit): ```bash - cd ~/utils + cd ~/src/utils # append to the "Completion log" table in dopamine-ux/00-INDEX.md: # | 04-screen-locker.md | DONE | | | git add dopamine-ux/00-INDEX.md @@ -69,7 +69,7 @@ the data already exists, is already true, and needs no new state. ## where -Repo: `~/screen-locker`. +Repo: `~/src/screen-locker`. Primary: - `screen_locker/_status_sections.py` — the section renderers used by the status @@ -136,7 +136,7 @@ Primary: - optional: a daily streak alongside the weekly one. Note this **would** be new state (the existing streak is consecutive-*weeks*), so it triggers the conftest requirement above. diet-guard's consecutive-*day* streak - (`~/diet-guard/diet_guard/_daystatus.py` ~:144) is the precedent to mirror. + (`~/src/diet-guard/diet_guard/_daystatus.py` ~:144) is the precedent to mirror. ## done @@ -144,7 +144,7 @@ Primary: the current streak, bonus hours and early-bird state — with the real values from `extra_benefits_state.json`, not placeholders. 2. A week-transition milestone reaches the UI instead of only `_logger.info`. -3. `cd ~/screen-locker && python -m pytest` passes. +3. `cd ~/src/screen-locker && python -m pytest` passes. 4. `pre-commit run --files ` is clean — including the 250-line cap (`scripts/check_file_length.py`) and the silent-failure check. 5. `git diff` touches no enforcement logic: no change to lock decisions, weekly @@ -155,7 +155,7 @@ Primary: Desktop — this is a desktop Python app. ``` -cd ~/screen-locker +cd ~/src/screen-locker python -m screen_locker --status # CLI: confirm the values it prints screen-locker-status # the Tk window: confirm they render ``` @@ -176,7 +176,7 @@ Current real state for comparison: `screen_locker/extra_benefits_state.json` and (the enforcement invariant) and the reward strings ~:130-139. - `screen_locker/_unlock_view.py` — the existing celebration, for tone. - `screen_locker/status_view.py` — check its line count **before** editing. -- `~/screen-locker/CLAUDE.md` — repo rules (no silent failures, ruff `select=ALL`). +- `~/src/screen-locker/CLAUDE.md` — repo rules (no silent failures, ruff `select=ALL`). ## context you would otherwise rediscover @@ -196,7 +196,7 @@ Current real state for comparison: `screen_locker/extra_benefits_state.json` and tunable is a module-level constant. An opt-out toggle has no existing home; for a self-restriction tool, requiring a code edit to disable is arguably correct, so prefer a constant in `_constants.py` over new state. -- `~/gatelock` is **not** a repo — it is `~/utils/gatelock/gatelock/`, consumed as +- `~/gatelock` is **not** a repo — it is `~/src/utils/gatelock/gatelock/`, consumed as a pinned git dep, and it holds no workout state. - Manual workouts were **not** removed: `_manual_workout.py` implements a rate-limited, evidence-gated subsystem (budget 2 per 7 days, 10 per 30). diff --git a/prompts/TODO-dopamine-ux-05-workout-app.md b/prompts/TODO-dopamine-ux-05-workout-app.md index 0d38311..baf1112 100644 --- a/prompts/TODO-dopamine-ux-05-workout-app.md +++ b/prompts/TODO-dopamine-ux-05-workout-app.md @@ -2,8 +2,8 @@ > "do dopamine-ux-05-workout-app". It is self-contained -- it needs no context from > any other session. > -> Canonical copy: `~/utils/dopamine-ux/05-workout-app.md` (source of truth; this is a -> distributed copy). Running order and cross-prompt rules: `~/utils/dopamine-ux/00-INDEX.md`. +> Canonical copy: `~/src/utils/dopamine-ux/05-workout-app.md` (source of truth; this is a +> distributed copy). Running order and cross-prompt rules: `~/src/utils/dopamine-ux/00-INDEX.md`. > Generated 2026-08-16 from a survey of this repo -- line numbers are accurate > as of that date; **anchor on the symbol names, not the line numbers.** @@ -19,10 +19,10 @@ Do **both**, in the same session that completes the work: Do not leave a finished prompt lying in the repo -- a stale prompt is indistinguishable from a pending one, and the next session will re-run it. -2. **Log completion in the canonical index**, in `~/utils` (a *different* repo, +2. **Log completion in the canonical index**, in `~/src/utils` (a *different* repo, so it needs its own commit): ```bash - cd ~/utils + cd ~/src/utils # append to the "Completion log" table in dopamine-ux/00-INDEX.md: # | 05-workout-app.md | DONE | | | git add dopamine-ux/00-INDEX.md @@ -74,7 +74,7 @@ number with a motion token while you are in the file. ## where -Repo: `~/screen-locker`. App: `~/screen-locker/stronglift_replacement/workout_app` +Repo: `~/src/screen-locker`. App: `~/src/screen-locker/stronglift_replacement/workout_app` (a Flutter app nested inside the screen-locker repo; that directory contains **no Python** — only the app and two design docs). @@ -175,7 +175,7 @@ Theme: `lib/ui/theme.dart` — local hand-copy, **no `design_system` dependency* 2. Finishing a workout produces a haptic and a visible dialog arrival; step 2 adds a sound. 3. No inline animation duration remains in `exercise_tile_rows.dart`. -4. `cd ~/screen-locker/stronglift_replacement/workout_app && flutter analyze` clean. +4. `cd ~/src/screen-locker/stronglift_replacement/workout_app && flutter analyze` clean. 5. `flutter test` passes **and coverage stays at 100%**. 6. With OS "remove animations" on, the app works and durations are zero. 7. Step 2: the settings toggle flips, persists across restart, and silences both @@ -187,7 +187,7 @@ Theme: `lib/ui/theme.dart` — local hand-copy, **no `design_system` dependency* ``` adb devices # confirm 23181JEGR08034 -cd ~/screen-locker/stronglift_replacement/workout_app +cd ~/src/screen-locker/stronglift_replacement/workout_app flutter build apk --release adb install -r build/app/outputs/flutter-apk/app-release.apk ``` @@ -209,7 +209,7 @@ state what you felt and heard; do not infer them from the code. `setLastWorkoutType` as the public-wrapper pattern. - `lib/screens/settings_screen_sections.dart` ~:1-11 — the coverage/line-cap comments, and `_SyncSection` as the section pattern. -- `~/utils/unified-design-system/motion.md` — motion/haptic vocabulary from +- `~/src/utils/unified-design-system/motion.md` — motion/haptic vocabulary from prompt 01. **Prompt 01 must have run first.** ## context you would otherwise rediscover diff --git a/screen_locker/_compliance_predicates.py b/screen_locker/_compliance_predicates.py index deeb1c0..6a20f0e 100644 --- a/screen_locker/_compliance_predicates.py +++ b/screen_locker/_compliance_predicates.py @@ -49,7 +49,7 @@ def is_scheduled_skip_today(today: date | None = None) -> bool: """Return True if *today* is in the shared free-day pool. The source moved from this app's own ``scheduled_skips.json`` to the - fleet-wide pool (``~/utils/freedays``), so one marked day now stands down + fleet-wide pool (``~/src/utils/freedays``), so one marked day now stands down every gate app at once instead of only this one. The date is **local**, not UTC. The file-backed check this replaces diff --git a/screen_locker/_mcp.py b/screen_locker/_mcp.py index 7044ee5..4ed2532 100644 --- a/screen_locker/_mcp.py +++ b/screen_locker/_mcp.py @@ -135,7 +135,7 @@ def get_flags() -> dict[str, bool]: ``is_scheduled_skip_today`` keeps its name but no longer reads this app's ``scheduled_skips.json``: it is now the shared, fleet-wide free-day pool - (``~/utils/freedays``), so a true here also means diet-guard, wake-alarm, + (``~/src/utils/freedays``), so a true here also means diet-guard, wake-alarm, leetcode-guard and home-guard are standing down today. """ history = load_history() diff --git a/screen_locker/adjust_shutdown_schedule.sh b/screen_locker/adjust_shutdown_schedule.sh index 1489730..029fc77 100755 --- a/screen_locker/adjust_shutdown_schedule.sh +++ b/screen_locker/adjust_shutdown_schedule.sh @@ -21,7 +21,7 @@ # whole ratchet. # # Add to /etc/sudoers.d/workout-locker: -# ALL=(root) NOPASSWD: /home/kuhy/screen-locker/screen_locker/adjust_shutdown_schedule.sh +# ALL=(root) NOPASSWD: /home/kuhy/src/screen-locker/screen_locker/adjust_shutdown_schedule.sh set -euo pipefail diff --git a/scripts/add_scheduled_skip.py b/scripts/add_scheduled_skip.py index d64dc55..4e67419 100755 --- a/scripts/add_scheduled_skip.py +++ b/scripts/add_scheduled_skip.py @@ -3,7 +3,7 @@ This used to append to ``screen_locker/scheduled_skips.json``, which only screen-locker read. That file is no longer consulted by anything: the lock -chain now asks the shared pool (``~/utils/freedays``), so a day taken here +chain now asks the shared pool (``~/src/utils/freedays``), so a day taken here also stands down diet-guard, wake-alarm, leetcode-guard and home-guard. Kept as a thin wrapper rather than deleted because ``arm.sh`` calls it, and diff --git a/scripts/check_dependency_freshness.sh b/scripts/check_dependency_freshness.sh index 5cb0d78..7715d3c 100755 --- a/scripts/check_dependency_freshness.sh +++ b/scripts/check_dependency_freshness.sh @@ -3,7 +3,7 @@ # ============================================================================ # Fail if any dependency in the commit is behind its ecosystem's newest stable. # -# Thin delegate to the shared gate in ~/utils, which owns the registry +# Thin delegate to the shared gate in ~/src/utils, which owns the registry # adapters, the pre-release rules and the allowlist semantics. Copying that # logic here is what lets one repo's idea of "current" drift from every other # repo's -- so this script only locates the shared checker and forwards its @@ -18,12 +18,12 @@ set -euo pipefail -readonly SHARED_GATE="${UTILS_ROOT:-$HOME/utils}/scripts/check_dependency_freshness.sh" +readonly SHARED_GATE="${UTILS_ROOT:-$HOME/src/utils}/scripts/check_dependency_freshness.sh" main() { if [[ ! -x "$SHARED_GATE" ]]; then echo "Error: shared dependency-freshness gate not found at $SHARED_GATE" >&2 - echo " Clone github.com/kuhyx/utils to ~/utils, or set" >&2 + echo " Clone github.com/kuhyx/utils to ~/src/utils, or set" >&2 echo " UTILS_ROOT to where it lives." >&2 exit 1 fi diff --git a/scripts/check_md_naming.sh b/scripts/check_md_naming.sh index 50deaa0..7847c56 100755 --- a/scripts/check_md_naming.sh +++ b/scripts/check_md_naming.sh @@ -3,7 +3,7 @@ # ============================================================================ # Fail if any markdown file breaks the shared naming convention. # -# Thin delegate to the shared gate in ~/utils, which owns the four namespaces +# Thin delegate to the shared gate in ~/src/utils, which owns the four namespaces # (README / CLAUDE* / DOCS* / TODO*), the "REMOVE ME AFTER FINISH" marker rule # and the exemption list. Copying that logic here is what lets one repo's idea # of a valid name drift from every other repo's -- so this script only locates @@ -16,12 +16,12 @@ set -euo pipefail -readonly SHARED_GATE="${UTILS_ROOT:-$HOME/utils}/scripts/check_md_naming.sh" +readonly SHARED_GATE="${UTILS_ROOT:-$HOME/src/utils}/scripts/check_md_naming.sh" main() { if [[ ! -x "$SHARED_GATE" ]]; then echo "Error: shared markdown-naming gate not found at $SHARED_GATE" >&2 - echo " Clone github.com/kuhyx/utils to ~/utils, or set" >&2 + echo " Clone github.com/kuhyx/utils to ~/src/utils, or set" >&2 echo " UTILS_ROOT to where it lives." >&2 exit 1 fi diff --git a/scripts/check_no_crdt_sync_override.sh b/scripts/check_no_crdt_sync_override.sh index 967e6c8..e945a0d 100755 --- a/scripts/check_no_crdt_sync_override.sh +++ b/scripts/check_no_crdt_sync_override.sh @@ -5,7 +5,7 @@ # # The apps depend on crdt_sync as a *git dependency pinned to a tag*, so what # CI builds is whatever that tag points at. A `dependency_overrides:` entry -# pointing at ~/utils/crdt_sync_dart is invaluable while developing an unreleased +# pointing at ~/src/utils/crdt_sync_dart is invaluable while developing an unreleased # library change -- and catastrophic if it survives the commit: local tests go # green against code CI has never seen, and the failure is silent in both # directions. diff --git a/scripts/verify_screen_fits.py b/scripts/verify_screen_fits.py index 7944b82..08af791 100755 --- a/scripts/verify_screen_fits.py +++ b/scripts/verify_screen_fits.py @@ -18,7 +18,7 @@ whole ``tk`` module for every test so the suite can never reach a display, and widget heights can only be measured by really rendering them. Like ``verify_lock_popup_safety.py``, this re-executes itself under Xvfb: - cd ~/screen-locker && python3 -m scripts.verify_screen_fits + cd ~/src/screen-locker && python3 -m scripts.verify_screen_fits Run as a *module*, not a path: ``-m`` puts the repo root on ``sys.path`` so ``screen_locker`` resolves from the checkout. Running it as a path only works diff --git a/stronglift_replacement/workout_app/pubspec.yaml b/stronglift_replacement/workout_app/pubspec.yaml index c602ec2..47c9ad3 100644 --- a/stronglift_replacement/workout_app/pubspec.yaml +++ b/stronglift_replacement/workout_app/pubspec.yaml @@ -55,7 +55,7 @@ flutter: - assets/sounds/break_end.mp3 # Launcher icon generation. Source art is produced by the shared generator: -# PYTHONPATH=~/testsAndMisc python3 -m python_pkg.app_icons generate --app +# PYTHONPATH=~/src/testsAndMisc python3 -m python_pkg.app_icons generate --app # then run: dart run flutter_launcher_icons flutter_launcher_icons: android: true diff --git a/web/src/index.css b/web/src/index.css index 837c548..5d1a0c3 100644 --- a/web/src/index.css +++ b/web/src/index.css @@ -1,5 +1,5 @@ /* - * Tokens from ~/utils/unified-design-system (DOCS-tokens.md). Values are copied + * Tokens from ~/src/utils/unified-design-system (DOCS-tokens.md). Values are copied * rather than imported because that system ships as documentation plus * per-stack generators, not an npm package -- keep these in step with it rather * than inventing new ones. diff --git a/web/src/test/factories.ts b/web/src/test/factories.ts index 606965d..79518f4 100644 --- a/web/src/test/factories.ts +++ b/web/src/test/factories.ts @@ -61,7 +61,7 @@ export function makeHealth(over: Partial = {}): HealthPayload { armed: true, disarmed: false, disarm_marker: '/home/kuhy/.local/share/screen_locker/DISARMED', - log_file: '/home/kuhy/screen-locker/screen_locker/log.json', + log_file: '/home/kuhy/src/screen-locker/screen_locker/log.json', log_age_seconds: 3600, decision_log_file: '/home/kuhy/.local/share/screen_locker/decisions.jsonl', last_decision_age_seconds: 120, diff --git a/workout-sync.service b/workout-sync.service index bf110f4..a2b180b 100644 --- a/workout-sync.service +++ b/workout-sync.service @@ -19,4 +19,4 @@ ExecStart=/usr/bin/python3 -m screen_locker.screen_lock --sync-only # disabled early-bird-workout-check.timer and nothing noticed for 13 days). # ExecStartPost without "-" means a disarmed locker marks this unit failed, so # it surfaces in `systemctl --user --failed` instead of scrolling past. -ExecStartPost=/usr/bin/python3 %h/screen-locker/scripts/check_enforcement_armed.py --quiet +ExecStartPost=/usr/bin/python3 %h/src/screen-locker/scripts/check_enforcement_armed.py --quiet