Skip to content
marcsantiagoPublic

About

No description, website, or topics provided.

Resources

Stars

11 stars

Watchers

0 watching

Forks

Latest commit

 

History

16 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Trask

A simple, Git-friendly task tracker that stores tasks as Markdown files.

Installation

From Source

Trask can be built and installed using Cargo.

Clone the repository:

git clone <repository-url>
cd trask

Install Trask:

cargo install --path .

This installs the trask executable into Cargo's binary directory.

Verify the installation:

trask --help

If trask is not found after installation, make sure Cargo's binary directory is in your PATH:

export PATH="$HOME/.cargo/bin:$PATH"

Build Without Installing

To build Trask without installing it:

cargo build

The debug executable will be available at:

target/debug/trask

Run it directly with:

cargo run -- --help

Release Build

For an optimized release build:

cargo build --release

The release executable will be:

target/release/trask

You can run it directly:

./target/release/trask --help

Or install the optimized release binary:

cargo install --path .

Trask LSP

Trask includes an optional language server for editor integration.

Install the LSP binary with:

cargo install --path . --bin trask-lsp

Verify the installation:

which trask-lsp

The language server communicates over standard input/output and is intended to be started by an editor.

Helix

To use the Trask LSP with Helix, add the following to:

~/.config/helix/languages.toml
[language-server.trask-lsp]
command = "trask-lsp"

[[language]]
name = "markdown"
file-types = [
    "md",
    { glob = "TASK.md" },
]
language-servers = ["trask-lsp"]

This keeps TASK.md as Markdown while allowing the Trask LSP to provide task-specific completion and diagnostics.

Restart Helix or restart the language server after changing the configuration:

:lsp-restart

Neovim (nvim)

Trask's language server can provide task-specific completion and diagnostics for Markdown task files, and go-to-definition for task IDs referenced from source code. Install the LSP binary first (see Trask LSP).

Configure the Trask LSP

Create ~/.config/nvim/lsp/trask.lua:

return {
  cmd = { "trask-lsp" },

  filetypes = {
    "markdown",
    "go",
    "rust",
    "python",
  },

  root_dir = function(bufnr, on_dir)
    local root = vim.fs.root(bufnr, { ".trask" })
    if root then
      on_dir(root)
    end
  end,
}

This starts trask-lsp for Markdown, Go, Rust, and Python buffers in a project containing a .trask marker. The marker is used to locate the Trask project root.

Enable the configuration by adding the following line to ~/.config/nvim/init.lua:

vim.lsp.enable("trask")

LazyVim: use gd for Trask task IDs

When using LazyVim, create ~/.config/nvim/lua/plugins/trask-gd.lua:

return {
  {
    "neovim/nvim-lspconfig",
    opts = {
      servers = {
        ["*"] = {
          keys = {
            {
              "gd",
              function()
                Snacks.picker.lsp_definitions()
              end,
              desc = "Goto Definition (includes Trask tasks)",
              has = "definition",
            },
          },
        },
      },
    },
  },
}

With trask-lsp attached to the source buffer and advertising go-to-definition support, place the cursor on a task ID in a code comment and press gd to open the corresponding TASK.md. For other symbols, the Snacks picker continues to provide the normal LSP definition results.

For example, a comment containing TODO: 20260919-154500 can link to tasks/20260919-154500/TASK.md.

Restart Neovim after changing the configuration. If the LSP was already running, restart it as well.

Requirements

Trask is a Rust application and requires a current Rust toolchain with Cargo.

Check that Rust and Cargo are installed:

rustc --version
cargo --version

If you need to install Rust, use rustup.

Inspiration

This project was inspired by Tsoding's Tatr, an improvised task-tracking system designed to be more powerful than source-code TODOs without requiring a full issue tracker.

The task directory layout and TASK.md concept are directly inspired by Tatr:

tasks/
└── <task-id>/
    └── TASK.md

This project is an independent Rust implementation with its own design and implementation.

Thanks to Alexey Kutepov (Tsoding) for the original idea and inspiration.

Layout

Tasks live in a tasks/ directory at the root of your project.

Trask uses a .trask marker file to identify the project root. Commands can therefore be run from the project root or from a subdirectory within the project.

Each task gets its own directory named with its unique task ID. Every task directory contains a mandatory TASK.md file.

Task IDs are generated using the UTC timestamp at creation time:

YYYYMMDD-HHMMSS

For example:

project/
├── .trask
├── tasks/
│   ├── 20260919-154500/
│   │   └── TASK.md
│   └── 20260919-160200/
│       └── TASK.md
└── ...

Task directories can also contain attachments such as screenshots or other files.

Initialize

Run init from the root of your project:

trask init

This creates:

.trask
tasks/

The .trask file identifies the project root. Once initialized, Trask commands can also be run from subdirectories.

Running init on an already initialized project will return an error.

Create a Task

Create a task with:

trask new "Fix ad request timeout"

The new command also has the following aliases:

trask n "Fix ad request timeout"
trask add "Fix ad request timeout"
trask a "Fix ad request timeout"

Trask automatically generates a unique timestamp-based task ID. If possible the ID created is also copied to the system clipboard automatically.

For example:

tasks/
└── 20260919-154500/
    └── TASK.md

The generated TASK.md looks like:

# Fix ad request timeout

- STATUS: OPEN
- PRIORITY: 4294967295
- TAGS:

# Description

The default status is OPEN.

The default priority is u32::MAX (4294967295), which causes newly created tasks to appear first when using the default priority sort.

Edit the TASK.md file directly to add or modify the task description.

Task Format

Each task contains a TASK.md file with the following format:

# Task title

- STATUS: OPEN
- PRIORITY: 50
- TAGS: rtb, exchange, timeout

# Description

Task description goes here.

The description can contain normal Markdown.

Status

STATUS describes whether the task is open or closed.

OPEN
CLOSED

Trask represents these statuses internally using the TaskStatus enum.

A newly created task always starts with:

OPEN

To close a task, edit its TASK.md:

- STATUS: CLOSED

When using trask list, closed tasks are excluded by default.

Use --closed or -c to include closed tasks.

Priority

PRIORITY is an unsigned integer.

- PRIORITY: 50

The default priority for newly created tasks is 4294967295 (u32::MAX).

When listing tasks, priority is sorted in descending order by default, so higher-priority tasks appear first.

Tags

TAGS is a comma-separated list:

- TAGS: rust, helix, tooling

Whitespace around tags is ignored.

An empty tag list is valid:

- TAGS:

Description

The # Description heading marks the beginning of the task description:

# Description

Task description goes here.

Everything after the # Description heading is treated as the task description and may contain normal Markdown.

List Tasks

List open tasks:

trask list

You can also use the shorthand:

trask l

By default, closed tasks are excluded and tasks are sorted by priority in descending order.

Example:

20260919-160200 [OPEN] [4294967295] Add Helix integration
20260919-154500 [OPEN] [100] Fix ad request timeout

A closed task such as:

20260919-161030 [CLOSED] [10] Initial project setup

is not shown by default.

Include Closed Tasks

Use --closed or -c to include closed tasks:

trask list --closed

or:

trask l -c

Example:

20260919-160200 [OPEN] [4294967295] Add Helix integration
20260919-154500 [OPEN] [100] Fix ad request timeout
20260919-161030 [CLOSED] [10] Initial project setup

The --closed option does not mean "show only closed tasks." It means include closed tasks in the results.

Sorting

Use --sort or -s to choose the sort order:

trask list --sort priority
trask list -s priority

The available sort values are:

Sort Long form Short value
Priority priority p
ID id i
Title title t

Sort by Priority

Priority is the default sort:

trask list --sort priority
trask list --sort p
trask l -s p

Higher priorities appear first.

Sort by ID

Sort tasks by their timestamp-based ID:

trask list --sort id
trask list --sort i
trask l -s i

Example:

20260919-154500 [OPEN] [100] Fix ad request timeout
20260919-160200 [OPEN] [4294967295] Add Helix integration
20260919-161030 [CLOSED] [10] Initial project setup

Sort by Title

Sort tasks alphabetically by title:

trask list --sort title
trask list --sort t
trask l -s t

Reverse the Sort

Use --reverse or -r to reverse whichever sort is selected:

trask list --reverse
trask list -r

For example:

trask l -s p -r

reverses the default priority ordering.

You can also combine reverse with the other sort options:

trask l -s i -r
trask l -s t -r

Filter by Tag

Use --tag or -t to show only tasks containing a specific tag:

trask list --tag rust

or:

trask l -t rust

For example, given:

# Fix ad request timeout

- STATUS: OPEN
- PRIORITY: 100
- TAGS: rtb, exchange

# Description

Investigate why ad requests occasionally exceed the 100ms timeout.
# Add Rust parser

- STATUS: OPEN
- PRIORITY: 50
- TAGS: rust, tooling

# Description

Improve the Markdown parser.
# Update dashboard

- STATUS: OPEN
- PRIORITY: 25
- TAGS: frontend, dashboard

# Description

Update the dashboard UI.

then:

trask l -t rust

returns only:

20260919-160200 [OPEN] [50] Add Rust parser

Filter by Multiple Tags

The --tag / -t option can be specified multiple times:

trask l -t rust -t tooling

When multiple tags are specified, a task must contain all of the requested tags.

For example:

trask l -t rust -t rtb

only returns tasks containing both rust and rtb.

Combine Closed Tasks, Filtering, and Sorting

All list options can be combined.

Include closed tasks and sort by priority:

trask l -c -s p

Include closed tasks and reverse the priority sort:

trask l -c -s p -r

Show only Rust tasks and sort by title:

trask l -t rust -s t

Show Rust tasks, including closed tasks, sorted by ID:

trask l -c -t rust -s i

Show Rust and tooling tasks, including closed tasks, sorted by reverse priority:

trask l -c -t rust -t tooling -s p -r

Show a Task

Display a task using its ID:

trask show 20260919-154500

The show command also has the shorthand alias:

trask s 20260919-154500

Example:

ID:       20260919-154500
Title:    Fix ad request timeout
Status:   OPEN
Priority: 100
Tags:     rtb, exchange, timeout

# Description

Investigate why ad requests occasionally exceed the 100ms timeout.

Delete a Task

Delete a task using its ID:

trask delete 20260919-154500

The delete command also has the following aliases:

trask d 20260919-154500
trask remove 20260919-154500
trask r 20260919-154500

The command removes the task associated with the specified task ID.

Git

Tasks are ordinary files, so they work naturally with Git.

git add tasks/
git commit -m "Add ad request timeout task"

Task history can be inspected using normal Git tools:

git log -- tasks/20260919-154500/TASK.md

and:

git blame tasks/20260919-154500/TASK.md

Attachments stored alongside a task are also tracked normally by Git.

Commands

trask init

trask new <title>
trask n <title>
trask add <title>
trask a <title>

trask show <id>
trask s <id>

trask list [OPTIONS]
trask l [OPTIONS]

trask gist
trask g

trask delete <id>
trask d <id>
trask remove <id>
trask r <id>

init

Initialize a Trask project:

trask init

Creates the .trask marker and tasks/ directory.

new

Create a new task:

trask new <title>

Aliases:

trask n <title>
trask add <title>
trask a <title>

A timestamp-based task ID is automatically generated.

show

Display a task:

trask show <id>
trask s <id>

list / l

List tasks:

trask list
trask l

Options:

-s, --sort <priority|p|id|i|title|t>
-r, --reverse
-t, --tag <tag>
-c, --closed

Sort aliases:

priority / p
id / i
title / t

Examples:

trask l
trask l -c

trask l -s p
trask l -s i
trask l -s t

trask l -r
trask l -c -r

trask l -t rust
trask l -t rust -t tooling

trask l -t rust -s t
trask l -t rust -s p -r

trask l -c -t rust -s i
trask l -c -t rust -t tooling -s p -r

gist / g

Group tasks by status and tags:

trask gist
trask g

delete

Delete a task:

trask delete <id>

Aliases:

trask d <id>
trask remove <id>
trask r <id>

Example:

trask d 20260919-154500

Design

The tool intentionally uses a small, predictable Markdown format instead of introducing a database or complex serialization format.

The structured fields are:

title
status
priority
tags
description

The task status is represented internally by a TaskStatus enum with two values:

Open
Closed

These are serialized to Markdown as:

OPEN
CLOSED

Everything after the # Description heading is treated as the task description and may contain normal Markdown.

The task ID belongs to the task directory rather than the TASK.md file:

tasks/<task-id>/TASK.md

Task IDs use the UTC timestamp format:

YYYYMMDD-HHMMSS

For example:

tasks/20260919-154500/TASK.md

This also allows additional files to be stored alongside the task:

tasks/
└── 20260919-154500/
    ├── TASK.md
    ├── screenshot.png
    └── notes.txt

The .trask marker allows Trask to discover the project root when commands are run from a subdirectory:

project/
├── .trask
├── tasks/
└── src/
    └── ...

About

No description, website, or topics provided.

Resources

Stars

11 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages