Adding work to a day you forgot to track meant typing its full date. The Work day field now also takes 09-14 (this year), today, yesterday, -3 (three days ago) and weekday names like mon or friday (the most recent one). The editor shows the date it understood next to the field. The parsing lives in time::format::parse_date, next to parse_time. Co-Authored-By: Claude Opus 5.5 <[email protected]>
122 lines
5.5 KiB
Markdown
122 lines
5.5 KiB
Markdown
# skyshift
|
|
|
|
Track your work shifts from the terminal: start, pause, end the day
|
|
(even when the day runs past midnight), copy totals into your timesheet,
|
|
export reports, and see your work patterns.
|
|
|
|
Runs on Windows, Linux and macOS. Keyboard first, with vim-style keys, and
|
|
the mouse works too.
|
|
|
|
## Build and run
|
|
|
|
You need Rust 1.89 or newer ([rustup.rs](https://rustup.rs), or your
|
|
distribution's `rust` and `cargo` packages).
|
|
|
|
```sh
|
|
cargo build --release
|
|
```
|
|
|
|
The program is `target/release/skyshift` (`skyshift.exe` on Windows): copy
|
|
it to a folder on your `PATH`.
|
|
|
|
- **Windows**: nothing else to install. The `.exe` carries its own C runtime
|
|
and runs on any Windows 10 or 11.
|
|
- **Void Linux**: `sudo xbps-install -S rust cargo`, then build as above.
|
|
- **Fedora**: `sudo dnf install rust cargo`, then build as above.
|
|
|
|
On Linux no system library is needed: the clipboard works on both X11 and
|
|
Wayland. If copying doesn't work in your setup, set `clipboard = "command"`
|
|
and `clipboard_command = "wl-copy"` (or `"xclip -selection clipboard"`)
|
|
in the settings.
|
|
|
|
## Everyday keys
|
|
|
|
| Keys | What they do |
|
|
|------------------|----------------------------------------------------------|
|
|
| `s` `p` `e` | start, pause, end the work day |
|
|
| `<Space><Space>` | start / pause |
|
|
| `<Space>p` | "I actually paused at 17:30" (also `<Space>s`, `<Space>e`) |
|
|
| `Ctrl-x` `Ctrl-a`| the running session started 5 minutes earlier / later |
|
|
| `yy` `yw` | copy the day / the week for your timesheet |
|
|
| `<Space>c` | copy in another format, with a preview |
|
|
| `gh` `gd` `gi` `gs` | Tracker, Days, Insights, Settings (also `gt`, `Tab`) |
|
|
| `u` `Ctrl-r` | undo, redo: mistakes cost nothing |
|
|
| `zz` | snooze the break suggestion |
|
|
| `:` | command line: `:pause 17:30`, `:export csv lastmonth`, `:set time_format=12h` |
|
|
| `?` | every key, for the screen you're on |
|
|
| `q` | quit (a running shift keeps running) |
|
|
|
|
After the first key of a sequence (`g`, `y`, `<Space>`...), a popup lists
|
|
what can follow (like which-key in Neovim). It can be turned off in the
|
|
settings, or with `<Space>w`.
|
|
|
|
## How work days work
|
|
|
|
- **Start** opens a work day if none is open. The day keeps its date until
|
|
you press **End day**, so a shift from 22:00 to 04:00 counts for the day
|
|
it started.
|
|
- Forgot **End day**? If a break lasts longer than 8 hours (a setting), the
|
|
next Start opens a new work day by itself.
|
|
- Times you type (`22:30`, `2230`, `22h30`, `10:30pm`, `10p`) are read in
|
|
both 12h and 24h styles. An end time before the start time means the next
|
|
day.
|
|
- To add work to a day you didn't track, press `o` and change the **Work
|
|
day** field: `2026-09-14`, `09-14`, `yesterday`, `-3` (3 days ago) or a
|
|
weekday like `mon` all work.
|
|
- Times are recorded to the minute, so what you see always adds up.
|
|
|
|
## Your files
|
|
|
|
Run `skyshift --paths` to see where they are.
|
|
|
|
- **`config.toml`**: every setting, each with a comment explaining it.
|
|
Change settings in the app (Settings tab, `za` shows the expert ones) or
|
|
in the file.
|
|
- **`shifts.toml`**: your work, in plain text. You can edit it by hand;
|
|
skyshift reloads it when it changes, and won't overwrite it while it has
|
|
a mistake in it. A copy is saved once a day in `backups/`.
|
|
- **Exports** (CSV, JSON, Markdown) go to your Documents folder, or the
|
|
folder set in the settings.
|
|
|
|
To keep everything together, for example on a USB stick or in a synced
|
|
folder: `skyshift --config D:\skyshift\config.toml` with
|
|
`data_file = "shifts.toml"` in that config.
|
|
|
|
## How the code is organized
|
|
|
|
Every file starts with a comment explaining what it's for.
|
|
|
|
| Folder / file | What's in it |
|
|
|----------------|--------------------------------------------------------------|
|
|
| `domain/` | the rules: segments, work days, the journal (no files, no UI) |
|
|
| `time/` | the clock, 12h/24h text, typed times, date ranges |
|
|
| `analysis/` | the numbers behind the Insights screen |
|
|
| `export/` | timesheet text, the clipboard, CSV/JSON/Markdown reports |
|
|
| `storage/` | config.toml, shifts.toml, backups, the lock |
|
|
| `ui/` | keys (`keymap.rs`), screens, popups, widgets, colors |
|
|
| `settings.rs` | every setting, described once in one table |
|
|
| `reminders.rs` | the pomodoro rhythm |
|
|
| `action.rs` | everything the screens can ask the app to do |
|
|
| `app.rs` | the core: the loop, and the one place where data changes |
|
|
|
|
The flow is always the same: a key becomes a `Command` (`ui/keymap.rs`),
|
|
the screen turns the command into an `Action`, and `App::apply` changes the
|
|
data, saves it, and shows a message.
|
|
|
|
Common changes:
|
|
|
|
- **Change a key**: edit the tables in `src/ui/keymap.rs`. The help screen
|
|
and the which-key popup follow automatically.
|
|
- **Add a setting**: add a field to `Settings`, its default, and one entry
|
|
in `FIELDS` (all in `src/settings.rs`). The Settings screen and
|
|
config.toml follow automatically.
|
|
|
|
## Development
|
|
|
|
```sh
|
|
cargo test # run the tests
|
|
cargo lint # clippy, treating warnings as errors
|
|
cargo fmt # format the code
|
|
cargo test show_screens -- --ignored --nocapture # print every screen as text
|
|
```
|