The git-backed issue tracker for AI agents. tk is inspired by Joe Armstrong's Minimal Viable Program with additional quality of life features for managing and querying against complex issue dependency graphs.
Tickets are markdown files with YAML frontmatter in .tickets/. tk will search upward from the current directory to find the nearest .tickets/ (or respect TICKETS_DIR when set), so commands work from any subdirectory. This allows AI agents to easily search them for relevant content without dumping ten thousand character JSONL lines into their context window.
Using ticket IDs as file names also allows IDEs to quickly navigate to the ticket for you. For example, you might run git log in your terminal and see something like:
nw-5c46: add SSE connection management
VS Code allows you to Ctrl+Click or Cmd+Click the ID and jump directly to the file to read the details.
From source:
git clone https://github.com/xymist/tkrs.git
cd tkrs && cargo install --path .From prebuilt binaries:
Download the binary for your system from the latest release; unpack it, make it executable, and put it somewhere on your PATH
Run tk update; if there is a new version it will download and unpack it over itself.
tk is a Rust binary with no system dependencies.
Add this line to your CLAUDE.md or AGENTS.md:
This project uses a CLI ticket system for task management. Run `tk help` when you need to use it.
Claude Opus picks it up naturally from there. Other models may need additional guidance.
tk create— create a ticket, with optional fieldstk start|close|reopen|status— set ticket status (all accept--note; close recordsclosed_atautomatically; reopen clearsclosed_atand can log a note)tk dep|undep|link|unlink— manage dependencies and links (usetk dep cycle --include-closedto scan closed tickets too;tk dep --check-cycle <bool>toggles the cycle guard, defaulttrue;unlinksupports--warn-missing;linksupports--dry-run;undepis idempotent and normalizes deps;dep treesupports--statusand--only-open)tk ls|list— list tickets with filters (supports--columns,--json, and--parent <id>to scope to direct children of a parent; the--jsonshape always includes aparentsarray derived from reverse dependencies)tk ready|blocked— show tickets with dependency readiness (readysupports--statusand--show-deps;blockedsupports--only-open)tk closed— list recently closed tickets (supports--limit,--since <RFC3339>,--assignee,--tags)tk show|edit|add-note— inspect and edit tickets (showsupports--jsonand lists derivedparents;add-noteis idempotent on headers and supports--tag <label>)tk query [FILTER]— output tickets as JSON; supports--format ndjson|prettyand built-in filters (field==valueexact match,field~substrcontains)tk update— self-updatetkto the latest release published on GitHub, installing it over the running binary; printsNo new version availablewhen already currenttk tui— EXPERIMENTAL - Start a TUI for browsing tickets with a little more context than just a bucket of IDs.
Pushing a tag matching vX.Y.Z triggers the GitHub Actions workflow .github/workflows/release.yml. It first ensures a GitHub release exists for the tag, then builds the Rust binary in release mode for each supported target and publishes a versioned, per-target tarball as a release asset. The workflow can also be run manually (workflow_dispatch) by providing the tag to build.
Built targets and asset names:
tk-vX.Y.Z-x86_64-unknown-linux-musl.tar.gz(Linux, x86_64; a fully static musl binary with no glibc dependency, so it runs on any x86_64 Linux distribution regardless of GLIBC version)tk-vX.Y.Z-aarch64-apple-darwin.tar.gz(macOS, Apple Silicon)
tk update self-installs by matching the running binary's target triple against these asset names, so each platform pulls its own build automatically.
MIT