{"id":19385784,"url":"https://github.com/doczi-dominik/tx","last_synced_at":"2026-05-04T15:40:02.491Z","repository":{"id":191863006,"uuid":"337038276","full_name":"doczi-dominik/tx","owner":"doczi-dominik","description":"Minimalistic tasks for CLI - with useful extras!","archived":false,"fork":false,"pushed_at":"2024-12-06T17:56:53.000Z","size":53,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-07T08:12:38.783Z","etag":null,"topics":["cli","golang","linux","macos","tasks","tasks-manager","terminal","todo","todolist"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/doczi-dominik.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2021-02-08T10:28:07.000Z","updated_at":"2024-12-05T14:19:43.000Z","dependencies_parsed_at":null,"dependency_job_id":"bd0d62de-464c-4010-9d3e-b15fdba9ac9f","html_url":"https://github.com/doczi-dominik/tx","commit_stats":null,"previous_names":["doczi-dominik/tx"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doczi-dominik%2Ftx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doczi-dominik%2Ftx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doczi-dominik%2Ftx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doczi-dominik%2Ftx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/doczi-dominik","download_url":"https://codeload.github.com/doczi-dominik/tx/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240527153,"owners_count":19815793,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["cli","golang","linux","macos","tasks","tasks-manager","terminal","todo","todolist"],"created_at":"2024-11-10T10:03:05.233Z","updated_at":"2026-05-04T15:39:57.457Z","avatar_url":"https://github.com/doczi-dominik.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# tx\nMinimalistic tasks for CLI - with useful extras!\n\n`tx` stands for *t extended*, and is a complete rewrite of [Steve Losh's *t*](https://stevelosh.com/projects/t/). `tx` tries to retain the original project's minimalism and its core principle:\n\n\u003e [...]the only way to make your todo list prettier is to **finish some damn tasks**.\n\n...while introducing new features that make it more pleasant *(but admittedly, more bloated)* to work with in a command line interface.\n\n# Features\n\n- ✔️ **Written in Go**: `tx` is a complete reimplementation of `t`. While the original projects was written in Python, `tx` uses the Go programming language, which makes it **faster and more portable** (since it's a single compiled binary).\n- ⏪ **Backwards Compatible**: Even though `tx` is a complete rewrite, file handling and formatting is the exact same. `tx` generates more metadata (like creation date and time), but also includes a *\"legacy\"* `id` attribute - meaning **tasklists generated by `t` can be used with `tx`** and vice versa.\n- 🧠 **Multiple Actions**: Gone are the days of invoking multiple instances of `t` when you want to remove a task, finish a task then add a new one in this sequence. **`tx` handles action flags as sequencial commands**, meaning you can accomplish the above example this way: `tx --remove 1 --finish 2 --add \"Easy!\"`. You can also specify the **same action multiple times**!\n- 📝 **Smarter Task Selection**: While you *can* specify multiple `--remove` commands to remove multiple tasks, `tx`'s \"selector\" system allows for more flexibility, allowing the selection of mulitple tasks in a variety of formats. **Convenience actions** like `--wipe` and `--complete` are also present to erase a full tasklist or mark all tasks as finished. Further information in [Selectors](#selectors).\n- 🌐 **Syncing**: `tx` offers a simple way to **move tasklists between devices and keep them in sync**. By default, the excellent [JSON Blob](https://jsonblob.com/) is used as the backbone of syncing, but you can **run your own syncing service** by mimicking the JSON Blob API and changing the Sync service using `tx sync change`. More information in [Syncing Details](#syncing-details).\n- 🤝 **Script Friendly**: `tx` was designed to be useful in a software development/CLI environment, and the use of `tx` is encouraged in shell scripts by featuring **the specification of custom output formats, the running of a callback shell command when the tasklist is modified through `tx` and many documented exit codes**. See [Scripting Help](#scripting-help) for more information.\n\n# Table of Contents\n\n1. [Setup](#setup)\n2. [General Usage](#general-usage)\n3. [Syncing Details](#syncing-details)\n4. [Scripting Help](#scripting-help)\n5. [Contributions](#contributions)\n\n# Setup\n\n1. **Download the latest binary from the [Releases Page](#https://github.com/doczi-dominik/tx/releases) or clone the repository and build it yourself with Go:**\n\n```sh\n$ git clone https://github.com/doczi-dominik/tx\n[...]\n$ cd tx\n$ go get\n$ go install  # Use this if you have GOBIN correctly configured\n$ go build    # Use this if you just want to compile a binary.\n```\n\n2. (optional) **Add aliases for tx to *\"set default options\"***. For example, if you use Bash, type this in `.bashrc`:\n\n```sh\n# Tasks mode\nalias t='tx --list=\"tasks\" tasks'\n\n# Finished tasks mode\nalias td='tx --list=\"tasks\" --delete-if-empty done'\n```\n\n# General Usage\n\n*Note: The usage section uses the aliases defined in [Setup](#setup)/2. Some of the actions are only applicable to tasks mode or done mode. Check the help page with `--help/-h` to learn more.*\n\n## Modes\n\n`tx` uses subcommands, just like Git! These are:\n- `tx tasks`: List and modify active tasks\n- `tx done`: List and modify finished tasks\n- `tx sync`: Configure syncing for the current tasklist\n\nPass `--help/-h` after passing the mode (or take a look at the [Wiki](https://github.com/doczi-dominik/tx/wiki)) to learn more.\n\n## Listing Tasks\n\nTo list tasks, just use `tx tasks` or `tx done` without any extra arguments:\n\n```sh\n$ t\n1 - these\n2 - are\n3 - active\n4 - tasks\n\n$ td\n1 - these (2021/01/14)\n2 - are (2021/01/14)\n3 - finished (2021/01/14)\n4 - tasks (2021/01/14)\n```\n\n## Adding Tasks\n\nTo add tasks in `tasks` mode, either:\n- Enter text after the last argument\n- Use the dedicated `--add/-a` action\n\n```\n$ t You do not need quotes here!\n1 - You do not need quotes here!\n\n$ t --add \"Use this when you pass other arguments after this.\" --add \"Also, you need quotes here for multiple words!\"\n1 - You do not need quotes here!\n2 - Use this when you pass other arguments after this.\n3 - Also, you need quotes here for multiple words!\n```\n\n## Selectors\n\nYou can use selectors with any of `--remove`, `--finish`, `--edit` in `tasks` mode and `--restore` and `--delete` in `done` mode.\n\nTasks can be selected using their **indexes**. A task's index is **fixed to a task**, meaning that indexes don't shift around when removing and finishing tasks. Internally, indexes are only recalculated before writing them into the taskfile and displaying them.\n\nTasks can be selected using their indexes, printed before their names (by default) or by using **placeholder letters** instead of using numbers. The letters `f` and `r` always refer to the **first task**, and `l` always refers to the **last task.**\n\nThe following formats can be used:\n- **Index**: A single task's index. Examples:\n    - 2\n    - f\n    - R\n- **CSV**: Comma-separated indexes. Examples:\n    - 3,4,5\n    - f,7,L\n- **Range:** A range of indexes. Examples:\n    - 1-6\n    - 4-2 *(Note: The range is reversed by `tx` to 2-4.)*\n    - f-l *(Note: You can also use convenience actions like `--wipe` or `--complete` for operations on every task.)*\n\nPlease note that when using `--edit`, **only Index notation can be used** as editing multiple tasks may make duplicates or cause other issues.\n\n## Editing a task\n\nYou can edit tasks in two ways, either replacing the full task text (equivalent to removing and adding a new task, but keeping its index) or by replacing all occurences of a word in it:\n\n```\n$ t\n1 - I am a task.\n2 - hello hello hello\n\n$ t --edit \"f/First Task\" --edit \"l/hello/Howdy\"\n1 - First Task\n2 - Howdy Howdy Howdy\n```\n\n## Enabling Syncing\n\nTo enable syncing for a particular tasklist, use `tx sync enable`. By default, this will request a new, unique Sync ID from the default Sync service. To connect your tasklist with an existing Sync ID, write it after the command like so: `tx sync enable \"this-is-the-sync-id\"`. Read the [Wiki](https://github.com/doczi-dominik/tx/wiki) for details on the `sync` mode.\n\n# Syncing Details\n\n`tx`'s syncing feature uses JSON and a simple HTTP server as its core. `tx` is designed to use Tristan Burch's [JSON Blob API](https://jsonblob.com/api), but any HTTP server can be provided which uses the following model:\n\n## Tasklist Format\n\nTasklists are accessed with their respective Sync ID's from the server. Taskfiles are serialized into a simple JSON object with two keys: `contents` and `doneContents`. Both keys point to a single string, which contains the respective active tasklist and finished tasklists.\n\n### Example\n\n- `tasks.txt`:\n```\none taskline\ntwo tasklines\nthree tasklines\n\n```\n\n- `.tasks.txt.done`:\n```\none finished taskline\ntwo finished tasklines\n\n```\n\n- Serialzed JSON Object:\n```json\n{\n    \"contents\": \"one taskline\\ntwo tasklines\\nthree tasklines\\n\",\n    \"doneContents\": \"one finished taskline\\ntwo finished tasklines\\n\"\n}\n```\n\n## Server API\n\nAs mentioned above, the server API should mimic the [JSON Blob API](https://jsonblob.com/api). The Sync ID of the tasklist will be appended to the provided Sync URL (e.g.: `\"https://jsonblob.com/api/jsonBlob/\" + syncID`) and `tx` will use the appropriate HTTP request depending on the operation.\n\n## Sync Information Storage\n\nThe necessary information used for syncing is stored in a *syncfile*, the filename is the taskfile's filename, but a `.` is prepended to ensure it's a hidden a file, and `.sync` is appended to signify that this is a syncfile.\n\nSyncfiles contain the following information:\n- `syncID`: The Sync ID of the tasklist as requested from the sync service\n- `syncURL`: If present, it will override the `--sync-url/-U` flag.\n- `lastNetworkUpdate`: A date signifying the time of the last successful POST/PUT request. This will be compared with a local taskfile's `mtime` to determine if the synced tasklist is up-to-date.\n\n# Scripting help\n\n## Callback\n\nYou can pass a command line to `--callback/-C` just like you would type it in a shell. The callback will only run if the tasklist was modified. The provided command's STDOUT and STDERR streams are combined into `tx`'s STDOUT stream. For more information, read [Go's 'exec' module documentation on cmd.CombinedOutput()](https://pkg.go.dev/os/exec#Cmd.CombinedOutput).\n\n## Output Formatting\n\nThe listing output can be customized using the `--output/-o` flag. The following placeholders are available:\n- `{index}`: The index of a given task\n- `{task}`: The task text\n- `{creationDate}`: The date of the task's creation in `YYYY/MM/DD` format.\n- `{creationTime}`: The time of the task's creation in `HH:MM` format.\n- `{finishedDate}`: The date the task was marked as finished in `YYYY/MM/DD` format.\n- `{finishedTime}`: The time the task was marked as finished in `HH:MM` format.\n\nIf you want to use any of these placeholders *literally*, simply double the braces: `{{index}}`. This will show up as `{index}` in the output, not as the task's index.\n\n## Exit Codes\n\n### Miscellaneous\n\nCode | Meaning\n---- | -------\n0 | Success, no errors\n1 | Command line flag parsing failed\n2 | Invalid selector notation\n3 | Invalid selector notation for `--edit/-e`\n4 | Invalid index, no task exists at that index\n5 | Task validation failed (e.g.: task contains a newline in the middle)\n6 | Non-creative operation on empty tasklist\n7 | Cannot serialize to JSON\n8 | Callback could not execute / returned a non-zero error code\n\n### Taskfile Operations\n\nCode | Meaning\n---- | -------\n9 | Could not open taskfile\n10 | Could not write taskfile\n11 | Could not read taskfile\n\n### Backup Taskfile Operations\n\nCode | Meaning\n---- | -------\n12 | Could not create backup file\n13 | Could not write backup file\n\n### Syncfile Operations\n\nCode | Meaning\n---- | -------\n14 | Could not open syncfile\n15 | Could not write syncfile\n16 | Could not read syncfile\n\n### HTTP GET Requests\n\nCode | Meaning\n---- | -------\n17 | Could not create GET Request\n\n### HTTP PUT Requests\n\nCode | Meaning\n---- | -------\n18 | Could not create PUT Request\n19 | Could not complete PUT Request\n\n### HTTP DELETE Requests\n\nCode | Meaning\n---- | -------\n20 | Could not create DELETE Request\n21 | Could not complete DELETE Request\n\n### Sync Server Errors\n\nCode | Meaning\n---- | -------\n22 | No tasklist exists with this Sync ID\n23 | Could not request new Sync ID from the Sync server\n24 | Unparseable response from Sync server\n25 | Unsupported Configuration, mainly exists to signify that deleting this blob is disabled on the Sync service, which `tx` will never configure.\n\n# Contributions\n\nIssues and PRs are always welcome, be it as small as a typo or as large as a new feature!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdoczi-dominik%2Ftx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdoczi-dominik%2Ftx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdoczi-dominik%2Ftx/lists"}