tix — a terminal issue tracker
tix is a kanban-style issue tracker that lives entirely in your repository: issues are plain Markdown + YAML frontmatter files. There is no database, no server, and no proprietary format — you get a terminal UI (TUI), a full CLI, and optional GitLab/Linear sync in one Rust binary.

Heavily AI assisted. This project was designed, specified, and built end-to-end with AI agents under a spec-kitty-SPEC style governed workflow (spec → plan → tasks → implement → review → merge): all 6 work packages, 27 functional requirements, and 33 subtasks, each passing real gate checks (
cargo test,clippy -D warnings,cargo fmt) before merge. The mission trail lives inkitty-specs/issue-tracker-tui-01M27PTN/; the integration surfaces are documented indocs/spec-kitty-integration.md,docs/openspec-integration.mdanddocs/mcp.md.tix init-agentswrites an AI-agent usage section intoAGENTS.md, so other agents can operate this tracker autonomously.
Install
The crate is published to crates.io as tix-tracker (the binary is still
called tix). See docs/packaging.md for the full
maintainer workflow (crates.io account, publishing, binary releases).
# or, with prebuilt binaries (fast, no Rust toolchain needed):
Local development installs (same binary) work too:
Requires a Rust toolchain (edition 2024, MSRV 1.85). The only runtime
dependency is your favorite editor for tix edit.
Quickstart
CLI
| Command | What it does |
|---|---|
tix init |
Create a default tix.toml (and add *.tixbak / *.md.bak to .gitignore) |
tix create |
New issue (title/body/status/priority/assignee/labels/estimate/files) |
tix new |
The same, in the TUI: opens the board with the create-issue form already open |
tix list |
Table of issues, optional --status filter, --columns selection and --with-archived scope |
tix view <issue> |
Full issue (frontmatter + body) |
tix status |
Board summary: count per column + total |
tix search <query> |
Substring-search issue titles and bodies (case-insensitive; --with-archived includes archived issues) |
tix lint |
Validate issue frontmatter and report diagnostics |
tix render |
Render the current board once without entering the TUI |
tix clean |
Remove the backup files tix writes beside an issue before it rewrites one — *.tixbak and *.md.bak; confirms each file unless -f/--force |
tix edit <issue> |
Edit fields via flags, or full file via $EDITOR (--files) |
tix move <issue> <column> |
Move between columns; done records a commit hash (auto-captured from HEAD, or --commit auto/<hash>) |
tix link <a> <b> --type <kind> |
Add a typed relationship — blocks, blocked_by, duplicates, or related (required) |
tix link list / tix link edit <id> / tix link remove <id> |
Inspect, retarget/re-kind, and remove relationships by their stable id |
tix unlink <a> <b> --type <kind> |
Remove a relationship of that kind |
tix chain <issue> |
Print the transitive blocks chain an issue holds up |
tix archive <issue> / tix restore <issue> |
Hide an issue from the default views, or bring it back — by dot-prefixing its filename (details) |
tix bulk edit|link|unlink |
Batch over a selection; preview is the default, --apply writes (details) |
tix cycle ... / tix milestone ... |
Create, list, edit, rename, and delete planning items; creating a cycle warns when its dates overlap another |
tix workflow categories | show | transitions |
Print the status-category vocabulary, how this board resolves each column, and which transitions are permitted |
tix delete <issue> --yes |
Remove an issue file |
tix export --target gitlab|linear |
Push local issues to a remote tracker (details) |
tix import --target gitlab|linear |
Pull open issues from a remote tracker |
tix import --target speckit |
Mirror a local GitHub Spec Kit project as labeled issues and subissues; idempotent |
tix init-agents |
Write/refresh the AI usage section in AGENTS.md |
An issue can be referenced by number, filename fragment, or title fragment.
tix init-agents detects .kittify/, openspec/ and .specify/ independently
and writes the corresponding tracking blocks into AGENTS.md. When it sees them,
it also prints the matching detection lines to stdout so scripts can tell which
blocks were emitted.
TUI
Launch with tix (no arguments) from the repository root; tix new starts the
same session with the create-issue form already open. The complete, configurable
key reference is docs/key-bindings.md; the list here is
only a default overview.
Six top-level modes share one shell with a vertical navigation tree on the left
(clickable limbs per board, cycle, milestone and template). A mode's function
key switches to it only when the active mode does not bind that key itself, so
F2 inside a form is still the picker.
| Mode | Key | What it shows | Guide |
|---|---|---|---|
| New Issue | F1 |
the create-issue form, with an explicit Triage/Todo target | new issue |
| Triage | F2 |
the triage inbox | triage |
| Board | F3 |
the kanban board | board keys |
| Cycles | F4 |
cycles grouped current / future / archived, with statistics | cycles |
| Milestones | F5 |
the milestone registry with per-milestone progress | config |
| Config | F12 |
dashboards, cycles, milestones, types, and attributes in one surface | config |
Board highlights: arrows and h/j/k navigate, PgUp/PgDn page a column,
Enter opens an issue, n/F1 creates, Shift+C clones, u toggles the
sub-issue tree, e edits in $EDITOR, v views read-only, d deletes, m
manages cycles and milestones, / searches the live board, ? opens searchable
help, q/Esc quits. In the issue detail view, n/E/d add, re-kind and
remove typed relationships, and Shift+P sets, changes or clears the parent —
all through the same service the CLI and MCP use, so a relationship created in
the TUI is byte-identical to one created with tix link.
The TUI is mouse-aware (click, double-click, drag, right-click, scroll, hover) and never sacrifices keyboard operation. Editor round trips are conflict-safe: a file changed by another writer is never clobbered by a stray keypress — see the edit-conflict and edit-repair modals.
Storage format
Issues are files under docs/issues/… with YAML frontmatter and a Markdown
body. tix re-renders the frontmatter in its own style on write (custom keys are
preserved, ## History verbatim), and the layout, related_issues, and custom
frontmatter keys are all configurable. See
storage format.
Relationships and parents
Four typed relationship kinds (blocks, blocked_by, duplicates, related)
replace the retired links: key; only blocks drives the blocked-move guard. An
issue has at most one parent — a decomposition tree, not an ordering edge. See
relationships and
parent issues.
Batch editing
tix bulk edit|link|unlink over a selection: preview is the default, --apply
writes, and each item reports its own outcome with no rollback. See
batch editing.
Archiving
tix archive/tix restore dot-prefix an issue's filename to hide it from the
default views without deleting it; the number is never recycled. See
archiving.
Workflow status categories
Map board columns onto the global six-word vocabulary (backlog … canceled).
Declaring a category_map opts the board into the transition policy; an unmapped
column falls back to unstarted. See
workflow status categories.
Triage inbox
An opt-in inbox, declared by a [triage] section in tix.toml, holds unreviewed
work before it joins the normal workflow. Every decision is one History event,
and the CLI, the TUI (F2) and MCP read one snapshot through the same service.
See triage and the design reference
docs/triage.md.
External sync
tix export/import targets GitLab (through glab) and Linear (through
linear-cli), plus a local tix import --target speckit. Repeated runs are
idempotent. See external sync.
Configuration
tix.toml holds the issues directory, [export] targets, keybindings and legacy
tables; boards live in docs/boards/<name>.md. The full key reference is in
configuration, the TUI editing surface in
config mode, and the metadata stores in
navigation.
Documentation
Beyond the guides linked above, docs/for-users/ also holds
navigation (mode shell and metadata stores),
new issue, cycles
and config mode, plus
key bindings and MCP.
Version
Current version: 0.7.0. See CHANGELOG.md.
License
MIT OR Apache-2.0.