sara-tasks 0.3.0

Sara — folder-aware task manager (successor to tk)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
# Sara — a folder-aware task manager

`Sara` is a personal assistant with a folder-aware task manager at its core. She
knows which Git project you're standing in, ranks your work with a transparent
urgency model, tracks time, and links tasks to branches.

Task data lives in a single SQLite database in your home directory — **nothing
is ever written into your repositories.**


```bash
     ID  PRI   PROJECT      DUE           URG  DEPS             DESCRIPTION
──────────────────────────────────────────────────────────────────────────────
⛓    1  H     web-app      2026-07-01   28.0  blocks 1 task    Design the auth flow
     2  M     web-app      -             5.9                   Wire up the login form
⊘    3  M     web-app      -             0.9  blocked by 1     Write auth integration tests
```

---

## Table of contents

- [Highlights]#highlights
- [Installation]#installation
- [Quick start]#quick-start
- [Core concepts]#core-concepts
- [The task list]#the-task-list
- [The detail view (`sara info`)]#the-detail-view-sara-info
- [Working with tasks]#working-with-tasks
  - [Adding tasks]#adding-tasks
  - [Dependencies]#dependencies
  - [Time tracking]#time-tracking
  - [Recurring tasks]#recurring-tasks
  - [Checklists]#checklists
  - [Notes, comments & links]#notes-comments--links
  - [Git branch linkage]#git-branch-linkage
  - [Sharing tasks]#sharing-tasks
  - [History & undo]#history--undo
- [The urgency model]#the-urgency-model
- [Configuration]#configuration
- [Inline Taskwarrior-style tokens]#inline-taskwarrior-style-tokens
- [Due dates]#due-dates
- [Shell completions]#shell-completions
- [File locations]#file-locations
- [Command reference]#command-reference
- [Uninstall]#uninstall

---

## Highlights

- **Folder-aware**`sara` auto-detects the current project (a Git repo, or any
  folder you run `sara init` in) and scopes `sara list` to it by default.
- **Transparent urgency** — a Taskwarrior-style scoring model decides ordering; `sara info` shows the exact breakdown.
- **Interactive TUI** — a ratatui review form for adding/editing, and a rich detail view for everything else.
- **Dependencies** — block tasks on each other, with cycle detection and an at-a-glance `DEPS` column.
- **Time tracking**`sara start` / `sara stop` accumulate active time, with optional estimates.
- **Git integration** — tie a task to a branch and snapshot the files it touched.
- **Full history** — every change (field edits, deps, files, checklist, links, comments, timer) is recorded.
- **Single SQLite file** — easy to back up, and nothing is written into your repos.

---

## Installation

The fastest paths use prebuilt packages and need **no Rust toolchain**. Prefer
one of these; the from-source build further down is for development.

### Quick install (Linux & macOS)

```bash
curl -fsSL https://raw.githubusercontent.com/Abarbesgaard/Sara/main/scripts/install.sh | sh
```

Downloads the right binary from the latest
[GitHub Release](https://github.com/Abarbesgaard/Sara/releases) into
`~/.local/bin` (override with `SARA_INSTALL_DIR`).

### crates.io

Published as **`sara-tasks`** (`sara` and `sara-cli` were taken); the installed
binary is still `sara`.

```bash
cargo install sara-tasks          # compiles from source
cargo binstall sara-tasks         # or grabs the prebuilt binary, no compile
```

### Debian / Ubuntu (apt)

One-off `.deb` from a release:

```bash
curl -fsSLO https://github.com/Abarbesgaard/Sara/releases/latest/download/sara_amd64.deb
sudo apt install ./sara_amd64.deb
```

Or add the apt repository so `sudo apt install sara` and future upgrades work:

```bash
echo "deb [trusted=yes] https://abarbesgaard.github.io/Sara/apt stable main" \
  | sudo tee /etc/apt/sources.list.d/sara.list
sudo apt update
sudo apt install sara
```

---

### Build from source

### 1 — Prerequisites

**Rust** (if not already installed):

```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Restart your shell, or:
source "$HOME/.cargo/env"
```

### 2 — Build & install

```bash
git clone https://github.com/Abarbesgaard/Sara
cd Sara
cargo install --path .
```

This compiles the binary and places it at `~/.cargo/bin/sara`. Make sure
`~/.cargo/bin` is on your `PATH` (the Rust installer usually handles this):

```bash
echo 'export PATH="$HOME/.cargo/bin:$PATH"' >> ~/.zshrc   # or ~/.bashrc
source ~/.zshrc
sara --version
```

---

## Quick start

```bash
# Initialize the current folder as a Sara project.
# A git repo becomes its own project (named after the repo root); any other
# folder is initialized in place (named after the folder).
cd ~/web-app
sara init

# Add a task (opens the interactive review form)
sara add "add password reset flow"

# Add quickly, no form, with an inline priority token
sara add "fix logout redirect" pri:H --yes

# See what to work on (current project, ranked by urgency)
sara list

# Inspect / edit a task interactively
sara info 1

# Start the clock, do the work, stop it
sara start 1
sara stop 1

# Complete it
sara done 1
```

---

## Core concepts

**Projects.** Every task belongs to a project. Inside a Git repo, `sara` uses
the repo as the project (run `sara init` once to record its goal/stack). In any
other folder, `sara init` registers that folder as the project, named after the
directory. The configurable `default_project` (`inbox`) is only used as a
last-resort fallback when a folder has no usable name.

**IDs vs UUIDs.** Each task has a small, recycled display **ID** (the `1`, `2`,
`3` you type) and a stable **UUID** that never changes. Most commands accept
either the ID or a UUID prefix. When a task is completed, pending IDs are
repacked to stay small — so today's `4` may be tomorrow's `3`.

**Urgency.** Tasks are ordered by a computed urgency score (see
[The urgency model](#the-urgency-model)). It rewards priority, due dates,
active timers, tags, and tasks that block others — and penalizes blocked tasks.

---

## The task list

`sara list` prints the pending tasks for the current project, highest urgency
first.

```bash
sara list                      # current project
sara list -a                   # all projects
sara list -p web-app           # a specific project from anywhere (`--project` also works)
```

Each row has a small marker gutter, columns, and a dependency column:

```text
⛓    1  H     web-app      2026-07-01   28.0  blocks 1 task    Design the auth flow
```

**Gutter markers** (left edge):

| Marker | Meaning                                   |
|:------:|-------------------------------------------|
| ``    | Timer is running (task is active)         |
| ``    | Recurring task                            |
| ``    | Blocked — waiting on an unfinished task   |
| ``    | Blocking — other tasks depend on this one |

**Columns:** `ID`, `PRI` (H/M/L, color-coded), `PROJECT`, `DUE` (red overdue,
yellow soon), `URG` (urgency score), `DEPS`, and `DESCRIPTION`. A `PR` or `↗`
badge appears before the description when the task has a linked pull request or
URL.

The **`DEPS`** column spells out the relationship the gutter hints at:
`blocked by 3` (red) or `blocks 2 tasks` (gray).

> Tip: set `NO_COLOR=1` to disable colors (e.g. for piping or screenshots).

---

## The detail view (`sara info`)

`sara info <id>` opens a full-screen, interactive view of a single task: all
fields, dependencies, attached files, links, comments, a checklist, the urgency
breakdown, a git panel, a project activity heatmap, and a live history log.

It's also where you **edit** a task inline.

**Keys**

| Key            | Action                                            |
|----------------|---------------------------------------------------|
| `` / `` (or `k` / `j`) | Move between fields and items            |
| `Enter` / `e`  | Edit the selected field, or open the selected file/link |
| `` / ``      | Cycle priority (when Priority is selected)        |
| `Space`        | Toggle the selected checklist item                |
| `PgUp` / `PgDn`| Scroll                                            |
| `Esc`          | Cancel an edit                                    |
| `q` / `Esc`    | Close the view                                    |

**Editable fields:** Description, Project, Priority, Due, Tags, Estimate,
Recur, and **Depends on**.

To change dependencies, select **Depends on**, press `Enter`, and type the task
IDs it should wait on (space- or comma-separated), e.g. `7 9`. `sara` reconciles
the set — adding and removing edges — and rejects self-references and cycles
with an inline error. The change is reflected immediately in the "Blocked by"
section and the History panel.

---

## Working with tasks

### Adding tasks

```bash
sara add "write integration tests"            # opens the review form
sara add "write tests" --yes                  # skip the form, save immediately
sara add "write tests" -p web-app --priority H -t testing
```

By default `sara add` opens an interactive review form so you can confirm the
fields before saving. `--yes` saves immediately without the form. See
[inline tokens](#inline-taskwarrior-style-tokens) for the `project:` / `+tag` /
`pri:` shorthand.

```bash
sara modify 2        # edit via the review form
sara done 1          # mark complete (use --force to complete a blocked task)
sara delete 3        # soft-delete (prompts; -y to skip)
```

### Dependencies

A dependency means "this task is blocked until that task is done." Blocked tasks
sink in urgency; blocking tasks rise.

```bash
sara dep 4 on 5      # task 4 now depends on (is blocked by) task 5
sara dep 4 off 5     # remove that dependency
sara dep 4 list      # show what 4 is blocked by / blocking
```

You can also edit dependencies interactively in the **Depends on** field of
`sara info` (see above). Dependencies are shown in `sara list` via the `⊘`/`⛓`
gutter markers and the `DEPS` column. Cycles are prevented automatically.

### Time tracking

```bash
sara start 1     # begin working — marks the task active (●) and starts the clock
sara stop 1      # stop — accumulates elapsed time into "time spent"
```

Set an estimate (in the `Estimate` field of `sara info`) to see a progress
percentage against time spent. If a task is tied to a git branch, `sara stop`
snapshots the files changed on that branch.

### Recurring tasks

```bash
sara add "weekly review" --every weekly
sara add "rotate secrets" --recur 2w     # --recur is an alias for --every
```

Supported intervals: `daily`, `weekly`, `monthly`, `yearly`, or `Nd` / `Nw` /
`Nm` (e.g. `3d`, `2w`, `1m`). Recurring tasks show a `♺` marker in the list.

### Checklists

Break a task into sub-steps without creating separate tasks:

```bash
sara check 1 "draft the schema"
sara check 1 "write the migration"
```

Toggle items with `Space` in `sara info`.

### Notes, comments & links

```bash
sara annotate 1 "spoke with design, going with option B"   # alias: sara comment
sara denotate 4                                             # remove comment #4 (alias: uncomment)

sara link 1 https://github.com/org/repo/pull/123           # auto-labels GitHub PRs/issues
sara link 1 https://example.com --label "Spec"
sara unlink 2                                               # remove link #2

sara attach 1 src/auth/login.rs                             # attach a file path (alias: sara pr)
```

Linked PRs/URLs surface as a badge in `sara list` and are openable from `sara info`.

### Git branch linkage

```bash
sara addbranch 1            # tie task 1 to the *currently checked-out* branch
sara addbranch 1 --clear    # remove the tie
```

> Note: `addbranch` takes the **task ID**, not a branch name — the branch is read
> from the repo you're standing in. The task's project must have been `sara init`'d
> inside that repo. Run `sara stop` afterwards to snapshot the changed files.

### Sharing tasks

Export a task — together with its full dependency closure (the task plus every
task it transitively depends on) — to a single copy-pasteable blob, then import
it into another user's Sara on a different machine.

```bash
sara export 1                     # print a `sara-task-v1:…` blob to stdout
sara export 1 -o task.blob        # …or write it to a file
sara 1 export                     # the usual id-first shorthand

sara import task.blob             # read a blob from a file
sara import "sara-task-v1:…"      # …or pass the blob string directly
pbpaste | sara import             # …or pipe it in on stdin
sara import task.blob -p backlog  # reassign every imported task to a project
```

What travels: the description, project, status, priority, due date, tags,
estimate, recurrence, comments, checklist/steps, links and attached file paths —
plus the dependency edges between the exported tasks. On import every task gets a
**fresh** uuid and display id (so importing into a DB that already has the task
never collides), dependency edges are remapped within the bundle, the timer is
reset and urgency is recomputed. History and time-tracking do not travel.

A bundle carries each task's project **name**, not the project *profile* (its
goal, stack, conventions and setup/test/lint commands). Importing a task whose
project doesn't exist locally is fine — it's created under that name and shows up
in `sara list`/`-p` and tab-completion straight away; only the profile metadata
is absent. Run `sara init` in that project's folder to attach a profile, or use
`-p`/`--project` on import to drop everything into an existing local project
instead of the bundle's original name.

The blob tolerates being line-wrapped by email or chat clients, so a pasted
`sara-task-v1:…` token still imports even if it picked up newlines.

### History & undo

Every mutating action is recorded and shown in the History panel of `sara info`:
field edits (description, project, priority, due, tags, estimate, recur, status),
timer start/stop, dependencies, attached files, checklist items, links, comments,
and branch ties. Additions show `+`, removals show `−`, and value changes show
`old → new`.

```bash
sara undo     # revert the most recent command
```

---

## The urgency model

Urgency is a sum of weighted components, recomputed whenever a task changes.
`sara info` displays the exact breakdown, e.g.
`28.0 (pri 6.0 + due 12.0 + blocking 8.0 + age 2.0)`.

| Component   | Default | Applies when…                                  |
|-------------|--------:|------------------------------------------------|
| `priority_h`| `6.0`   | Priority is High                               |
| `priority_m`| `3.9`   | Priority is Medium                             |
| `priority_l`| `1.8`   | Priority is Low                                |
| `due`       | `12.0`  | Scaled by closeness (overdue = full, 7+ days out = 0) |
| `blocking`  | `8.0`   | The task blocks at least one other task        |
| `blocked`   | `-5.0`  | The task is blocked (penalty)                  |
| `active`    | `4.0`   | A timer is currently running                   |
| `has_tags`  | `1.0`   | The task has any tags                          |
| `project`   | `1.0`   | The task is not in the fallback project (`inbox`) |
| `age`       | `2.0`   | Scaled by age, capped at `age_max` days        |
| `age_max`   | `365.0` | Age in days at which the age bonus maxes out   |

All coefficients are configurable under `[urgency]` in the config file.

---

## Configuration

A config file is created with sensible defaults on first run.

| OS    | Path                                            |
|-------|-------------------------------------------------|
| macOS | `~/Library/Application Support/sara/config.toml`  |
| Linux | `~/.config/sara/config.toml`                      |

Full example:

```toml
default_project = "inbox"   # last-resort fallback name when a folder has no usable name
date_dialect    = "uk"      # "uk" or "us" — affects "next friday" parsing

[urgency]                   # all optional; defaults shown
priority_h = 6.0
priority_m = 3.9
priority_l = 1.8
due        = 12.0
blocking   = 8.0
blocked    = -5.0
active     = 4.0
has_tags   = 1.0
project    = 1.0
age        = 2.0
age_max    = 365.0
```

Print the resolved config and database paths:

```bash
sara paths
```

---

## Inline Taskwarrior-style tokens

Leading and trailing tokens on `sara add` are parsed as attributes:

```bash
sara add "fix login bug" project:web-app +auth pri:H
sara add project:api "redesign rate limiting" +backend
```

Tokens in the middle of a description stay as literal text. Explicit flags are
always unambiguous and win over inline tokens:

```bash
sara add "fix the project:foo reference in docs" --project web-app
```

| Token         | Meaning            |
|---------------|--------------------|
| `project:x`   | Set the project    |
| `+tag`        | Add a tag          |
| `pri:H`       | Set priority (H/M/L) |

---

## Due dates

Natural-language dates work in the `Due` field of the review form and anywhere a
date is accepted:

| Input         | Meaning            |
|---------------|--------------------|
| `2026-07-01`  | ISO date           |
| `today`       | Today              |
| `tomorrow`    | Tomorrow           |
| `friday`      | This coming Friday |
| `next friday` | Friday next week   |
| `+3d`         | 3 days from now    |
| `+2w`         | 2 weeks from now   |

The `date_dialect` config setting (`uk` vs `us`) affects ambiguous phrasing.

---

## Shell completions

Sara ships **dynamic** completions: once registered, `<TAB>` completes real
pending task ids — annotated with their descriptions — for commands like
`sara done` / `info` / `start`, and known project names for `--project` / `-p`.

Register by having your shell evaluate `COMPLETE=<shell> sara` at startup
(no `fpath`/`compinit` setup needed). Re-run on upgrade so the generated shell
glue stays in sync with the binary:

```bash
# Bash — ~/.bashrc
echo 'source <(COMPLETE=bash sara)' >> ~/.bashrc

# Zsh — ~/.zshrc
echo 'source <(COMPLETE=zsh sara)' >> ~/.zshrc

# Fish
echo 'COMPLETE=fish sara | source' >> ~/.config/fish/completions/sara.fish

# Elvish
echo 'eval (E:COMPLETE=elvish sara | slurp)' >> ~/.elvish/rc.elv
```

Restart your shell (or `source` the file) afterwards. To disable, set
`COMPLETE=` or `COMPLETE=0`.

> Prefer a **static** completion script (command/flag structure only — no
> dynamic task-id/project values)? `sara completions <shell>` still emits one,
> e.g. `sara completions zsh > ~/.zsh/completions/_sara`.

---

## File locations

| What     | macOS                                          | Linux                        |
|----------|------------------------------------------------|------------------------------|
| Database | `~/Library/Application Support/sara/tasks.db`     | `~/.local/share/sara/tasks.db` |
| Config   | `~/Library/Application Support/sara/config.toml`  | `~/.config/sara/config.toml`   |

Run `sara paths` to see the exact locations on your machine.

---

## Command reference

| Command                            | Description                                              |
|------------------------------------|----------------------------------------------------------|
| `sara init`                        | Initialize the current folder as a project (git repo or plain folder) |
| `sara add <desc> [tokens]`         | Add a task (`--yes`, `-p`, `--priority`, `-t`, `--every`) |
| `sara list`                        | List tasks (`-a` all, `-p`/`--project <name>`)           |
| `sara info <id>`                   | Open the interactive detail view                         |
| `sara modify <id>`                 | Edit via the review form                                 |
| `sara done <id>`                   | Complete a task (`--force` if blocked)                   |
| `sara delete <id>`                 | Soft-delete a task (`-y` to skip confirmation)           |
| `sara start <id>` / `sara stop <id>`| Start / stop the timer                                  |
| `sara dep <id> on\|off\|list`       | Manage dependencies                                     |
| `sara check <id> <text>`           | Add a checklist item                                     |
| `sara annotate <id> <text>`        | Add a comment (alias `comment`); `sara denotate <n>` removes |
| `sara link <id> <url>`             | Add a link; `sara unlink <n>` removes                    |
| `sara attach <id> <path>`          | Attach a file path (alias `pr`)                          |
| `sara addbranch <id>`              | Tie the current git branch to a task (`--clear`)         |
| `sara export <id>`                 | Export a task + its deps to a portable blob (`-o <file>`) |
| `sara import [src]`                | Import a task blob (file, arg, or stdin; `-p <project>`)  |
| `sara activity`                    | GitHub-style activity heatmap (`--project`, `-a`)        |
| `sara undo`                        | Revert the most recent command                           |
| `sara reset`                       | Delete a project's tasks and profile (`-p`, `-y`)        |
| `sara paths`                       | Print config and data paths                              |
| `sara completions <shell>`         | Generate shell completions                               |

Run `sara help` or `sara <command> --help` for full options.

---

## Uninstall

```bash
cargo uninstall sara
```

Remove data and config:

```bash
# macOS
rm -rf ~/Library/Application\ Support/sara/

# Linux
rm -rf ~/.config/sara/ ~/.local/share/sara/
```