[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-80548":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":17,"stars7d":18,"stars30d":19,"stars90d":16,"forks30d":16,"starsTrendScore":20,"compositeScore":21,"rankGlobal":10,"rankLanguage":10,"license":22,"archived":23,"fork":23,"defaultBranch":24,"hasWiki":23,"hasPages":23,"topics":25,"createdAt":10,"pushedAt":10,"updatedAt":30,"readmeContent":31,"aiSummary":32,"trendingCount":16,"starSnapshotCount":16,"syncStatus":14,"lastSyncTime":33,"discoverSource":34},80548,"tuxedo","webstonehq\u002Ftuxedo","webstonehq","A fast, keyboard-driven terminal UI for todo.txt.","",null,"Rust",496,24,2,12,0,172,229,443,516,4.19,"MIT License",false,"main",[26,27,28,29],"todo","todo-app","todotxt","tui","2026-06-12 02:04:03","# tuxedo\n\nA fast, keyboard-driven terminal UI for [todo.txt](http:\u002F\u002Ftodotxt.org\u002F).\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\u002Ftap\u002Ftuxedo\n```\n\n[![CI](https:\u002F\u002Fgithub.com\u002Fwebstonehq\u002Ftuxedo\u002Factions\u002Fworkflows\u002Fci.yml\u002Fbadge.svg)](https:\u002F\u002Fgithub.com\u002Fwebstonehq\u002Ftuxedo\u002Factions\u002Fworkflows\u002Fci.yml)\n[![Release](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Fv\u002Frelease\u002Fwebstonehq\u002Ftuxedo?logo=github)](https:\u002F\u002Fgithub.com\u002Fwebstonehq\u002Ftuxedo\u002Freleases\u002Flatest)\n[![License: MIT](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Flicense-MIT-blue.svg)](#license)\n[![Rust](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Frust-2024-orange.svg?logo=rust)](https:\u002F\u002Fwww.rust-lang.org)\n\n![tuxedo demo](docs\u002Fdemo.gif)\n\n## Highlights\n\n- **Pure todo.txt.** Reads and writes the [standard format](https:\u002F\u002Fgithub.com\u002Ftodotxt\u002Ftodo.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` \u002F `k` to move, `dd` to delete, `gg` \u002F `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 `\u002F` 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 \u002F due \u002F file order, and bulk-complete or bulk-delete in visual mode.\n- **Saved searches.** Name the active `\u002F`-search with `fs`, then recall it any time by cycling saved filters with `ff`. Stored as plain `filter.\u003Cname>` lines in the config — hand-editable like everything else.\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\u002Fscreenshots\u002Fempty.svg) |\n| **List** • list of todos, optionally grouped | ![empty](docs\u002Fscreenshots\u002Flist.svg) |\n| **Archive** • completed tasks grouped by completion date | ![archive](docs\u002Fscreenshots\u002Farchive.svg) |\n| **Filter sidebar active** • `fp` cycles projects with j\u002Fk, `fc` cycles contexts; saved searches list under a **SAVED** heading with live match counts | ![filter](docs\u002Fscreenshots\u002Ffilter.svg) |\n| **Command palette** • `:` or `Ctrl-P` opens a fuzzy palette over every action | ![command palette](docs\u002Fscreenshots\u002Fcommand-palette.svg) |\n| **Help** • `?` opens the full keybindings overlay | ![help](docs\u002Fscreenshots\u002Fhelp.svg) |\n\n\u003Cdetails>\n    \u003Csummary>How to generate the screenshots and demo\u003C\u002Fsummary>\n    \u003Cp>The screenshots in the table above are checked-in SVGs. Regenerate them with:\u003C\u002Fp>\n    \u003Cpre>mise run screenshots\u003C\u002Fpre>\n    \u003Cp>The hero GIF at the top is recorded with \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fcharmbracelet\u002Fvhs\">vhs\u003C\u002Fa> from \u003Ccode>docs\u002Fdemo.tape\u003C\u002Fcode>. Regenerate it with:\u003C\u002Fp>\n    \u003Cpre>mise run demo\u003C\u002Fpre>\n\u003C\u002Fdetails>\n\n## Themes\n\n`T` cycles through four built-in themes.\n\n| Muted Slate (default) | Dawn |\n| --- | --- |\n| ![muted slate](docs\u002Fscreenshots\u002Ftheme-muted-slate.svg) | ![dawn](docs\u002Fscreenshots\u002Ftheme-dawn.svg) |\n| **Nord** | **Matrix** |\n| ![nord](docs\u002Fscreenshots\u002Ftheme-nord.svg) | ![matrix](docs\u002Fscreenshots\u002Ftheme-matrix.svg) |\n\n## Install\n\n### Homebrew (macOS, Linux)\n\n```sh\nbrew install webstonehq\u002Ftap\u002Ftuxedo\n```\n\n### Prebuilt binaries\n\nDownload the archive for your platform from the [latest release](https:\u002F\u002Fgithub.com\u002Fwebstonehq\u002Ftuxedo\u002Freleases\u002Flatest) 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:\u002F\u002Fgithub.com\u002Fwebstonehq\u002Ftuxedo\n```\n\nOr clone and build:\n\n```sh\ngit clone https:\u002F\u002Fgithub.com\u002Fwebstonehq\u002Ftuxedo\ncd tuxedo\ncargo build --release\n.\u002Ftarget\u002Frelease\u002Ftuxedo [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 .\u002Ftodo.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> (tuxedo\nupdate)` next to the version. The check runs in the background, is cached at\n`$XDG_CACHE_HOME\u002Ftuxedo\u002Flatest_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 `.\u002Ftodo.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` \u002F `↓` | next task |\n| `k` \u002F `↑` | previous task |\n| `gg` | first task |\n| `G` | last task |\n| `Ctrl-d` \u002F `Ctrl-u` | half-page down \u002F up |\n\n### Editing\n\n| Key | Action |\n| --- | --- |\n| `n` | add task |\n| `e` \u002F `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| `\u002F` | search |\n| `fp` | filter by project (`j` \u002F `k` cycles, `Esc` clears) |\n| `fc` | filter by context (`j` \u002F `k` cycles, `Esc` clears) |\n| `ff` | pick a saved search (`j` \u002F `k` cycles, `Enter` keeps, `Esc` reverts) |\n| `fs` | save the active `\u002F`-search as a named filter |\n| `S` | cycle sort: priority → due → file order |\n| `v` | enter visual \u002F multi-select; `space` toggles a row |\n| `x` \u002F `dd` (in visual) | bulk-complete \u002F 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 & 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| `:` \u002F `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`, `ff`, `fs`) show\na `g…` \u002F `d…` \u002F `y…` \u002F `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:\u002F\u002Fgithub.com\u002Ftodotxt\u002Ftodo.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. Keys you'd rather not see can be\n  hidden from the rows via [`hide_keys`](#hiding-keyvalue-tags)\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 \u002F\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` \u002F `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 \u002F contexts** — prose form `project home` and `context bank`, or the standard `+home` \u002F `@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\" >> ~\u002Fnotes\u002Finbox.txt\necho \"Call dentist due:2026-06-01\" >> ~\u002Fnotes\u002Finbox.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>` 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\u002F.config}\u002Ftuxedo\u002Fconfig.toml`. Cycling\ntheme, density, or sort, and toggling sidebars \u002F line-numbers \u002F 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\nSaved searches (created with `fs`) are written one per line as\n`filter.\u003Cname> = \u003Cquery>`, where `\u003Cquery>` is the `\u002F`-search needle. They\nround-trip as plain text, so you can add, rename, or delete them by editing\n`config.toml` directly; a repeated `filter.\u003Cname>` keeps the last value, and\n`\u003Cname>` may not contain `=`.\n\n### Hiding `key:value` tags\n\nSome `key:value` extensions are for machines, not eyes — e.g. a `uid:` you\nsync against. Add a comma-separated `hide_keys` line to `config.toml` and\nthose keys' tokens are dropped from the task rows (list and archive views):\n\n```toml\nhide_keys = uid, sync\n```\n\nMatching is case-insensitive. Hiding is purely visual — the tags stay on\ndisk untouched, still serialize, and still show in the detail pane's **RAW**\nsection (a deliberate escape hatch). Searches still match hidden text; the\nhidden characters just aren't drawn.\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:\u002F\u002Fmise.jdx.dev\u002F).\n\n## Acknowledgments\n\n- [todo.txt](http:\u002F\u002Ftodotxt.org\u002F) by Gina Trapani — the format that makes a tool like this possible.\n- [ratatui](https:\u002F\u002Fratatui.rs\u002F) and [crossterm](https:\u002F\u002Fgithub.com\u002Fcrossterm-rs\u002Fcrossterm) — the rendering and terminal-input crates tuxedo is built on.\n\n## Roadmap\n\nPlanned and in-flight work lives in [`todo.txt`](.\u002Ftodo.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:\u002F\u002Fopensource.org\u002Flicenses\u002FMIT).\n","tuxedo 是一个快速、键盘驱动的终端用户界面，专为 todo.txt 设计。它支持 Vim 风格的快捷键、原子写入、即时外部编辑检测，并提供了四种精心调校的主题。项目使用 Rust 语言开发，保证了高性能和安全性。tuxedo 适合需要在命令行环境下高效管理待办事项的用户，特别适用于偏好键盘操作且希望保持数据格式纯净的技术人员。此外，通过生成二维码实现手机端任务输入的功能也使其成为跨设备任务管理的良好选择。","2026-06-11 04:01:10","CREATED_QUERY"]