mirror of
https://github.com/kuhyx/utils.git
synced 2026-11-11 14:07:46 +01:00
Some checks are pending
code-runner pre-commit / pre-commit (push) Waiting to run
code-runner tests / test (push) Waiting to run
dependency freshness / dependencies on newest stable (push) Waiting to run
file length / file-length (push) Waiting to run
focus-project pre-commit / pre-commit (push) Waiting to run
focus-project tests / test (push) Waiting to run
leetcode-coach pre-commit / pre-commit (push) Waiting to run
leetcode-coach tests / test (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
palette drift / palette (push) Waiting to run
repo-contract / repo contract (push) Waiting to run
shared gate tests / gate unit tests (push) Waiting to run
sql-drills pre-commit / pre-commit (push) Waiting to run
sql-drills tests / test (push) Waiting to run
Minutes past a day's target bank (max 60) and pay on the next project day; status shows real minutes (121/120) plus carried_in/carry_out; carry ledger rows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WzxdWYGW5NZL5uVpnqmNKo
29 lines
1.6 KiB
Markdown
29 lines
1.6 KiB
Markdown
# focus_project
|
|
|
|
Time-boxed focus projects ("until Thursday I prepare for X"). The active
|
|
project switches chosen gates off and defines a daily-minutes gate.
|
|
|
|
```python
|
|
import focus_project as fp
|
|
|
|
fp.stands_down("leetcode", today) # gate in leetcode|book|reading|tutor; never raises
|
|
fp.active(today) # Project | None
|
|
fp.status(today) # dict for i3bar / GUIs
|
|
fp.record_activity("timer", "start")
|
|
```
|
|
|
|
Data: `$FOCUS_PROJECT_DATA` or `~/.local/share/focus_project/` (`projects.json`,
|
|
`activity.jsonl`). `minutes.py` is owned by the minutes/harvester agent.
|
|
Time rules: `minutes_for` clips every interval at "now" (an event stamped ahead of
|
|
the clock earns only once the clock reaches it); `record_activity` rejects a `ts`
|
|
more than 120 s ahead (ValueError). `end_project(id, day)` rejects a past `day`
|
|
(ValueError); today or later is fine. The harvester pays every project day of the
|
|
last 31 days, so late-synced events for older days are credited (idempotent).
|
|
Overtime carries over: own minutes past a day's target bank (max 60) and pay on the
|
|
next project day; the bank never crosses the project's end. `minutes_for(day)` is the
|
|
capped pay figure, `status(day)["minutes"]` the real count (121/120) with `carried_in`,
|
|
`carry_out`, `own_minutes`, `counted_minutes`. Carry ledger rows: `<project>-<YYYYMMDD>-carry`
|
|
(`detail.carry`), never over `daily_minutes` together with own rows.
|
|
Open the work: `python3 -m focus_project.open [--no-site]` (tutor focus screen, `work_url`).
|
|
Install: `./install.sh` (stdlib only, editable user install for `/usr/bin/python3`).
|