{"id":49735878,"url":"https://github.com/webstonehq/tuxedo","last_synced_at":"2026-05-18T02:13:39.641Z","repository":{"id":356619173,"uuid":"1232392591","full_name":"webstonehq/tuxedo","owner":"webstonehq","description":"A fast, keyboard-driven terminal UI for todo.txt.","archived":false,"fork":false,"pushed_at":"2026-05-09T07:09:53.000Z","size":304,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-09T08:43:04.492Z","etag":null,"topics":["todo","todo-app","todotxt","tui"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/webstonehq.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-07T22:16:21.000Z","updated_at":"2026-05-09T08:01:53.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/webstonehq/tuxedo","commit_stats":null,"previous_names":["webstonehq/tuxedo"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/webstonehq/tuxedo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webstonehq%2Ftuxedo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webstonehq%2Ftuxedo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webstonehq%2Ftuxedo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webstonehq%2Ftuxedo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/webstonehq","download_url":"https://codeload.github.com/webstonehq/tuxedo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webstonehq%2Ftuxedo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33162451,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-17T22:39:12.733Z","status":"online","status_checked_at":"2026-05-18T02:00:06.436Z","response_time":71,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["todo","todo-app","todotxt","tui"],"created_at":"2026-05-09T08:12:39.722Z","updated_at":"2026-05-18T02:13:39.633Z","avatar_url":"https://github.com/webstonehq.png","language":"Rust","funding_links":[],"categories":["Rust","💻 Apps"],"sub_categories":["🚀 Productivity and Utilities"],"readme":"# tuxedo\n\nA fast, keyboard-driven terminal UI for [todo.txt](http://todotxt.org/).\nVim-style bindings, atomic writes, instant external-edit detection, and four\nhand-tuned themes — all in a single static binary.\n\n```sh\nbrew install webstonehq/tap/tuxedo\n```\n\n[![CI](https://github.com/webstonehq/tuxedo/actions/workflows/ci.yml/badge.svg)](https://github.com/webstonehq/tuxedo/actions/workflows/ci.yml)\n[![Release](https://img.shields.io/github/v/release/webstonehq/tuxedo?logo=github)](https://github.com/webstonehq/tuxedo/releases/latest)\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](#license)\n[![Rust](https://img.shields.io/badge/rust-2024-orange.svg?logo=rust)](https://www.rust-lang.org)\n\n![tuxedo demo](docs/demo.gif)\n\n## Highlights\n\n- **Pure todo.txt.** Reads and writes the [standard format](https://github.com/todotxt/todo.txt) — every line is plain text you can edit with anything else.\n- **Natural-language add.** Type prose into the add prompt — `Pay rent monthly on the first, show 3 days before due, project home` — and tuxedo rewrites it to canonical todo.txt for you to review and save. Local, offline, no AI service.\n- **Phone capture.** Press `s` for a QR pointing at a tiny PWA on your machine's LAN — type tasks from your phone and they appear in the list. Captures land in a sibling `inbox.txt` first, so any tool that can append a line (shell, iOS Shortcuts, cron) is also a capture source.\n- **Vim keys, no surprises.** `j` / `k` to move, `dd` to delete, `gg` / `G` to jump, `u` to undo (50 levels), chord prompts (`gg`, `dd`, `fp`, `fc`) with a 600 ms window.\n- **Command palette.** `:` or `Ctrl-P` opens a fuzzy palette over every action — type a few letters, hit Enter. Same matcher as `/` search, ranked so start-of-label hits beat word-boundary hits beat mid-word hits.\n- **Atomic, sync-friendly writes.** Every change goes through write-temp-then-rename. If another process — Dropbox, an editor, a script — modifies the file, tuxedo reloads on the next keypress (or within ~250 ms while idle) and flashes a notice.\n- **Sibling-file archive.** `A` moves completed tasks to `done.txt` next to your file, atomically.\n- **Filter, sort, multi-select.** Cycle by `+project` or `@context`, sort by priority / due / file order, and bulk-complete or bulk-delete in visual mode.\n- **Four themes, three densities.** Cycle with `T` and `D`. Choices persist across runs.\n- **No daemon, no database, no cloud.** One file in, one file out.\n\n## Screens\n\n| | |\n| --- | --- |\n| **Empty state** • cell-bowtie mark and quick-start when the file has no tasks | ![empty](docs/screenshots/empty.svg) |\n| **List** • list of todos, optionally grouped | ![empty](docs/screenshots/list.svg) |\n| **Archive** • completed tasks grouped by completion date | ![archive](docs/screenshots/archive.svg) |\n| **Filter sidebar active** • `fp` cycles projects with j/k, `fc` cycles contexts | ![filter](docs/screenshots/filter.svg) |\n| **Command palette** • `:` or `Ctrl-P` opens a fuzzy palette over every action | ![command palette](docs/screenshots/command-palette.svg) |\n| **Help** • `?` opens the full keybindings overlay | ![help](docs/screenshots/help.svg) |\n\n\u003cdetails\u003e\n    \u003csummary\u003eHow to generate the screenshots and demo\u003c/summary\u003e\n    \u003cp\u003eThe screenshots in the table above are checked-in SVGs. Regenerate them with:\u003c/p\u003e\n    \u003cpre\u003emise run screenshots\u003c/pre\u003e\n    \u003cp\u003eThe hero GIF at the top is recorded with \u003ca href=\"https://github.com/charmbracelet/vhs\"\u003evhs\u003c/a\u003e from \u003ccode\u003edocs/demo.tape\u003c/code\u003e. Regenerate it with:\u003c/p\u003e\n    \u003cpre\u003emise run demo\u003c/pre\u003e\n\u003c/details\u003e\n\n## Themes\n\n`T` cycles through four built-in themes.\n\n| Muted Slate (default) | Dawn |\n| --- | --- |\n| ![muted slate](docs/screenshots/theme-muted-slate.svg) | ![dawn](docs/screenshots/theme-dawn.svg) |\n| **Nord** | **Matrix** |\n| ![nord](docs/screenshots/theme-nord.svg) | ![matrix](docs/screenshots/theme-matrix.svg) |\n\n## Install\n\n### Homebrew (macOS, Linux)\n\n```sh\nbrew install webstonehq/tap/tuxedo\n```\n\n### Prebuilt binaries\n\nDownload the archive for your platform from the [latest release](https://github.com/webstonehq/tuxedo/releases/latest) and put `tuxedo` on your `PATH`.\n\nTargets: `x86_64-unknown-linux-gnu`, `aarch64-unknown-linux-gnu`, `x86_64-apple-darwin`, `aarch64-apple-darwin`, `x86_64-pc-windows-msvc`. Each archive ships with a `.sha256` checksum.\n\n### From source\n\n```sh\ncargo install --git https://github.com/webstonehq/tuxedo\n```\n\nOr clone and build:\n\n```sh\ngit clone https://github.com/webstonehq/tuxedo\ncd tuxedo\ncargo build --release\n./target/release/tuxedo [FILE]\n```\n\nRequires the Rust 2024 edition (recent stable toolchain).\n\n## Usage\n\n```sh\ntuxedo [FILE]      # open FILE (created if missing)\ntuxedo             # open ./todo.txt, or a sample file if none\ntuxedo --sample    # open the bundled sample file in the temp dir\ntuxedo update      # print upgrade instructions for your install\ntuxedo --help\ntuxedo --version\n```\n\nWhen a newer release is available, the status bar shows `↑ \u003cversion\u003e (tuxedo\nupdate)` next to the version. The check runs in the background, is cached at\n`$XDG_CACHE_HOME/tuxedo/latest_version.json` for 24 h, and fails silently\nwhen offline. Set `TUXEDO_NO_UPDATE_CHECK=1` to disable.\n\nIf `FILE` is omitted, tuxedo opens `./todo.txt` from the current working\ndirectory if it exists. Otherwise it falls back to a sample todo.txt in the\nsystem temp directory so you can poke around without committing to a path.\n\nEdits are persisted on every change via atomic write (write `.tmp`, rename).\n\nIf the file changes on disk (another editor, a sync client, a script),\ntuxedo notices on the next keypress, or within ~250 ms while idle, and\nreloads. The keystroke that triggered the reload is consumed — press it\nagain to act on the fresh state — and the status bar flashes a notice.\n\nPressing `A` appends every completed task to a sibling `done.txt` and\nremoves them from the working file (atomically: `done.txt` is written\nbefore the originals are dropped). `a` toggles the archive view so you\ncan browse, un-archive, or permanently delete past tasks.\n\n## Keybindings\n\n### Navigation\n\n| Key | Action |\n| --- | --- |\n| `j` / `↓` | next task |\n| `k` / `↑` | previous task |\n| `gg` | first task |\n| `G` | last task |\n| `Ctrl-d` / `Ctrl-u` | half-page down / up |\n\n### Editing\n\n| Key | Action |\n| --- | --- |\n| `n` | add task |\n| `e` / `i` | edit current task |\n| `x` | toggle complete |\n| `dd` | delete task |\n| `p` | cycle priority A → B → C → · |\n| `c` | add or remove a context |\n| `+` | add a project |\n| `yy` | copy current line to clipboard |\n| `yb` | copy current body only (no priority, dates, projects, contexts, `key:value`) |\n| `u` | undo (50 levels) |\n\n### Filtering, sort, view\n\n| Key | Action |\n| --- | --- |\n| `/` | search |\n| `fp` | filter by project (`j` / `k` cycles, `Esc` clears) |\n| `fc` | filter by context (`j` / `k` cycles, `Esc` clears) |\n| `S` | cycle sort: priority → due → file order |\n| `v` | enter visual / multi-select; `space` toggles a row |\n| `x` / `dd` (in visual) | bulk-complete / bulk-delete the selection |\n| `l` | list (default) view |\n| `a` | toggle archive view |\n| `A` | archive completed tasks → `done.txt` |\n| `H` | toggle showing done tasks in the main list |\n\n### Layout \u0026 theme\n\n| Key | Action |\n| --- | --- |\n| `[` | toggle filter sidebar |\n| `]` | toggle detail sidebar |\n| `T` | cycle theme |\n| `D` | cycle density: compact → comfortable → cozy |\n| `L` | toggle line numbers |\n\n### System\n\n| Key | Action |\n| --- | --- |\n| `:` / `Ctrl-P` | command palette |\n| `s` | share capture QR (phone PWA) |\n| `?` | help overlay |\n| `,` | settings overlay |\n| `q` | quit |\n\nTwo-key chord prompts (`gg`, `dd`, `yy`, `yb`, `fp`, `fc`) show a `g…` /\n`d…` / `y…` / `f…` indicator in the status-bar mode chip while the\nleader is armed; the window is 600 ms.\n\nCopy uses the OSC 52 terminal escape, so it works locally and over SSH on\nany terminal that supports it (kitty, alacritty, wezterm, iTerm2, foot,\nmodern xterm; tmux when `set -g set-clipboard on`). Older terminals will\nsilently ignore the keystroke.\n\n## todo.txt format\n\nStandard [todo.txt](https://github.com/todotxt/todo.txt) lines:\n\n```\n(A) 2026-04-28 Call dentist @phone +health due:2026-05-08\n```\n\n- `(A)` — priority, A through Z (omit for none)\n- `2026-04-28` — creation date in ISO 8601\n- `+project` — project tag\n- `@context` — context tag\n- `key:value` — extension; `due:YYYY-MM-DD` is recognized for sort and\n  due-bucket grouping in the list view\n- `rec:[+]N{d,b,w,m,y}` — recurrence; on completion (`x`), tuxedo inserts\n  a fresh copy of the task with `due:` advanced by `N` days, business\n  days (Mon–Fri), weeks, months, or years. The `+` prefix means\n  *strict* recurrence anchored to the previous due date (e.g.\n  `rec:+1m` for monthly rent on the 15th); without it, the new due is\n  computed from the completion date (e.g. `rec:1w` for \"water plants\n  one week after I last did\").\n\nCompleted tasks are prefixed with `x ` and a completion date:\n\n```\nx 2026-05-05 2026-05-01 Submit expense report +work\n```\n\nRecurring example:\n\n```\n2026-05-09 Pay rent due:2026-05-15 rec:+1m\n```\n\nPressing `x` on the line above marks the original complete *and* inserts\n`2026-05-09 Pay rent due:2026-06-15 rec:+1m`. `u` undoes both at once.\n\n## Natural-language add\n\nPress `n` to open the add prompt. Type the task in plain English. When the\nbuffer contains recognized phrases (dates, weekdays, recurrence, project /\ncontext names, priority), pressing Enter rewrites the draft into canonical\ntodo.txt — review or tweak it, then Enter again to save.\n\n| What you type | What lands in the draft |\n| --- | --- |\n| `Pay rent monthly on the first of the month, show the todo 3 days before the due date. It's part of project home and context bank` | `Pay rent +home @bank due:2026-06-01 rec:+1m t:-3d` |\n| `Buy milk tomorrow` | `Buy milk due:2026-05-12` |\n| `Call mom every week starting Friday for project family` | `Call mom +family due:2026-05-15 rec:+1w` |\n| `Submit timesheet every other friday show 1 day before` | `Submit timesheet due:2026-05-15 rec:+2w t:-1d` |\n| `Daily standup high priority` | `(A) standup rec:+1d` |\n| `Annual review April 15 +work @office` | `Annual review +work @office due:2027-04-15` |\n\nRecognized vocabulary:\n\n- **Dates** — `today`, `tonight`, `tomorrow`, `yesterday`, weekdays (`monday` / `mon` …), months (`april 15`, `15th of april`), `in 3 days`, `the first of the month`, ISO `2026-05-15`.\n- **Recurrence** — `daily`, `weekly`, `biweekly`, `monthly`, `yearly`, `annually`, `every monday`, `every 2 weeks`, `every other friday`, `every business day`.\n- **Threshold** — `show 3 days before due`, `2 weeks before due`.\n- **Projects / contexts** — prose form `project home` and `context bank`, or the standard `+home` / `@bank` sigils.\n- **Priority** — `high priority` → A, `medium priority` → B, `low priority` → C, or `priority A`.\n\nParsing is rule-based and runs locally — no network calls, no API key. If\nthe buffer already contains a `due:`, `rec:`, or `t:` token, tuxedo assumes\nyou've typed canonical form and saves it directly on the first Enter.\n\n## Phone capture\n\nPress `s` to start a tiny capture server on your machine's LAN address and\ndisplay a QR code for it. Scan it from your phone — any modern browser — to\nget a minimal PWA you can install to your home screen. Type a task, tap\nAdd, and within a tick it shows up in your task list.\n\nCaptures never touch `todo.txt` directly. They land in a sibling\n`inbox.txt`, which tuxedo drains on every external-change poll: each line\nis run through the same natural-language pipeline as the `n` add prompt,\ngiven a creation date if missing, and merged into `todo.txt` as a single\nundoable batch (`u` rolls back the whole drain at once).\n\nThat makes `inbox.txt` a general capture endpoint, not just a PWA backend.\nAnything that can append a line works as a producer:\n\n```sh\necho \"Refill prescription tomorrow\" \u003e\u003e ~/notes/inbox.txt\necho \"Call dentist due:2026-06-01\" \u003e\u003e ~/notes/inbox.txt\n```\n\nShell aliases, iOS Shortcuts writing to a synced folder, cron jobs,\nemail-to-file gateways — pick your producer. As long as it appends a line\nto the sibling `inbox.txt`, tuxedo picks it up.\n\nThe server:\n\n- Binds on first `s` press and stays up for the rest of the session.\n  Subsequent `s` presses just re-show the QR; any key dismisses the\n  overlay.\n- Listens on `0.0.0.0:\u003cport\u003e` so phones on the same WiFi can reach it.\n  The port is OS-assigned on first use and persisted to `config.toml` so\n  phone bookmarks survive across sessions.\n- Gates every protected route on a 64-character hex token baked into the\n  URL path. The token is generated once, persisted to `config.toml`, and\n  compared in constant time.\n- Speaks plain HTTP — **trusted networks only.** On a shared or public\n  WiFi anyone passive-sniffing can recover the token. To rotate, delete\n  `share_token` from `config.toml` and press `s` again.\n\nDrains from tuxedo-managed producers are crash-safe: the capture server\nholds the same advisory lock as the TUI's rename-and-merge, and any\nstaging file left over from an interrupted drain is replayed on the\nnext session. Plain shell appends are useful for lightweight capture,\nbut they do not take that lock; use the capture server or the same lock\nif a producer must be serialized with the TUI drain.\n\n## Configuration\n\nPersisted to `${XDG_CONFIG_HOME:-$HOME/.config}/tuxedo/config.toml`. Cycling\ntheme, density, or sort, and toggling sidebars / line-numbers / done-visibility\nall update the file. Unknown keys are ignored, so older binaries don't break\non newer files.\n\nTwo additional keys, `share_token` and `share_port`, are written by the\n[phone capture](#phone-capture) server on first use. Treat `share_token`\nas a secret — anyone who has the value and LAN reach can append to your\ninbox. Delete the key from `config.toml` to rotate it on the next `s`\npress.\n\n## Development\n\n```sh\nmise run fmt      # cargo fmt --all\nmise run clippy   # cargo clippy --all-targets --locked -- -D warnings\nmise run test     # cargo test --locked\n```\n\nCI runs all three on every push and pull request. Tasks are also runnable as\nplain `cargo` commands if you don't use [mise](https://mise.jdx.dev/).\n\n## Acknowledgments\n\n- [todo.txt](http://todotxt.org/) by Gina Trapani — the format that makes a tool like this possible.\n- [ratatui](https://ratatui.rs/) and [crossterm](https://github.com/crossterm-rs/crossterm) — the rendering and terminal-input crates tuxedo is built on.\n\n## Roadmap\n\nPlanned and in-flight work lives in [`todo.txt`](./todo.txt) — eat your own dog food.\n\n## Contributing\n\nIssues and pull requests are welcome. For larger changes, please open an\nissue first to discuss the approach. Run `mise run fmt clippy test` (or the\nplain cargo equivalents) before submitting.\n\n## License\n\nReleased under the [MIT License](https://opensource.org/licenses/MIT).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwebstonehq%2Ftuxedo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwebstonehq%2Ftuxedo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwebstonehq%2Ftuxedo/lists"}