app.rs holds everything and runs the loop: keys become commands, the
screen turns them into actions, and App::apply is the only place data
changes. Journal edits happen on a copy, are undoable, saved atomically
and rolled back if saving fails. It also runs the reminders and picks
up outside edits of shifts.toml every second.
main.rs loads the settings, takes the lock, makes the daily backup and
starts the UI; --config, --paths, --help and --version.
The tests drive the whole app with fake key presses and draw every
screen and popup at several sizes in an in-memory terminal.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
- Tracker: big running timer, pomodoro line, clickable buttons, today's
progress and timeline, this week.
- Days: work days grouped by week, the selected day's details, timeline
and segments to edit, add, delete and copy.
- Insights: overview cards and charts, calendar heatmap, weekday x hour
rhythm, session lengths and breaks.
- Settings: generated from the settings table; expert settings are
folded away (za).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
- segment_editor: type start/end times; the exact moments they mean are
shown live, and invalid edits keep the popup open.
- time_prompt: "I started / paused / ended the day at...".
- copy_menu: every copy preset with a preview of what will be pasted.
- export_dialog, still_working (for sessions left running very long),
help (generated from the key tables) and the `:` command line.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
- keymap: every key sequence in vim notation (gg, yy, <C-a>,
<Space>s), with counts (5j), per-screen overrides and which-key hints,
all from the same tables.
- Component: the one trait for screens and popups. They only look at
the data through a Context and answer with Actions.
- Action: everything a screen can ask the app to do.
- widgets: big digits, buttons, a day timeline, a heatmap, a text field.
- ui/mod.rs: tabs, status line and the which-key popup; terminal.rs sets
the terminal up (and restores it after a crash).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
- config.toml is written from the settings table, with each help text as
a comment; mistakes in it become warnings, never a crash.
- shifts.toml is plain, hand-editable TOML. Reading checks every journal
rule and reports mistakes with the day and segment. Edits made while
skyshift runs are reloaded; a broken file is never overwritten.
- Saves are atomic (temp file + rename), a copy is kept once a day, and
a file lock stops two copies of skyshift from using the same data.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Every setting is described once in FIELDS: its config.toml section and
key, label, help text, whether it's an expert setting, and how to read
and write it as text. The config file and the Settings screen are both
generated from this table, so adding a setting is one field, one
default and one table entry.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Advice only: it reads your real Start/Pause presses and says when a
break (or getting back) fits the rhythm. Interruptions shorter than a
short break don't reset a focus stretch; every Nth completed stretch
earns a long break.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
- timesheet: copy presets (total H:MM, decimal hours, segments,
in/out/break as tab-separated cells, custom template) with optional
rounding to a step.
- clipboard: system clipboard (Windows, X11, Wayland), falling back to
the terminal's OSC 52, or a custom command like wl-copy.
- csv, json, markdown: report files for a range of dates. CSV uses ';'
when the decimal separator is ','; the Markdown report has a summary
and one padded table per week.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Plain data computed from the work days, nothing about drawing:
- overview: week/month totals, balance against the daily target, weekly
totals, and when days start and end (past 24h for night shifts).
- calendar: time worked per date, as weeks x weekdays.
- rhythm: time worked per weekday and hour, split at hour boundaries.
- focus: session lengths, long sessions (hyperfocus), breaks, days that
went past midnight.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The rules, with no files and no UI:
- Segment: one stretch of work; it can only be built with end > start.
- WorkDay: segments filed under one date, even past midnight.
- Journal: every work day plus what's happening now (Idle, OnBreak,
Working). Start opens a work day that stays open until End day; a
break longer than a setting opens a new day (the safety net for a
forgotten End day). Segments never overlap, even across days.
- snapshot(): the days with the running session included, so analysis
and export never special-case it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
- clock: the system clock, with a time zone override (name or fixed
offset) and a manual adjustment; Start/Pause record whole minutes so
displayed times and totals always add up.
- format: every time, date and duration shown in the app goes through
Formatter (12h/24h, 7h 45m / 7:45 / 7.75); parse_time reads both 12h
and 24h input (22:30, 2230, 22h30, 10:30pm, 10p).
- resolve: turns a typed "01:30" into the moment meant, so an end time
before the start is the next day (night shifts).
- range: date ranges (week, month, last N days).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A terminal app (ratatui) to track work shifts, built on stable Rust,
edition 2024.
- Cargo.toml: eight well-known crates, each with a comment saying why:
ratatui (UI), jiff (dates and time zones), serde + toml + serde_json
(files), directories (per-OS folders), arboard (clipboard), anyhow.
- .cargo/config.toml: static C runtime on Windows, so the .exe runs
without the Visual C++ Redistributable; `cargo lint` alias.
- rustfmt.toml: one formatting style for `cargo fmt`.
Co-Authored-By: Claude Opus 5.5 <[email protected]>