██████╗██╗ ████████╗
██╔════╝██║ ╚══██╔══╝
██║ ██║ ██║
██║ ██║ ██║
╚██████╗███████╗██║
╚═════╝╚══════╝╚═╝
▸ command line tasks
▸ file-backed · rust · tui · agents
A file-system-backed task manager written in Rust. clt stores work in Markdown files or task folders, gives humans a fast CLI and TUI Kanban board, and can coordinate Codex agent runs across multiple registered projects.
- File-based Persistence: Tasks are stored in
tasks/todo.md,tasks/doing.md, andtasks/done.md, or in status folders such astasks/todo/. - Long Task Files: In a status folder, each direct file is a task.
cltdisplays the first sentence and preserves the full file content. - Nested Boards: A task subfolder can contain its own
todo,doing, anddonefiles or folders. The TUI can open those as subtask boards. - Kanban TUI: A visual board view powered by
ratatui, with nested board navigation and a full-screen registered-projects pane. - Simple CLI: Easy commands to add, move, and list tasks.
- Smart Root Detection: Automatically finds the git repository root to keep tasks centralized, or uses the current directory.
- Agent Registry: Register many projects, toggle them on or off, inspect
todo/doingcounts, toggle per-project git commits, and open any registered task board from the TUI. - Codex Automation: Run one Codex task at a time per enabled project, either in the foreground or through a background service.
- Agent Support Files: Includes
skill-clt.mdfor task-board workflows andskill-git-commit.mdfor safe commit workflows.
Ensure you have Rust and Cargo installed.
cargo install clt-rsInitialize the task directory structure:
clt initCreate folder-backed statuses from the start:
clt init --foldersNote: By default, clt looks for the root of your git repository to store the tasks/ folder. To force use of the current directory instead, use the --local flag:
clt --local initOpen the interactive TUI Kanban board:
cltPress Enter to open a folder task with subtasks, e to edit the selected task, Space to create a task, Backspace to return to the parent board, and q to quit.
Press Tab to switch to the full-screen agent projects pane. There, Up/Down selects a registered project, Enter opens that project's task board, Space toggles the project ON or OFF, and g toggles the GIT column, which controls whether that project's agent prompt asks Codex to use the git-commit skill after a completed task. The currently open project is marked with *, and the terminal title updates to the active project.
clt agent can run Codex against enabled registered projects that have pending todo tasks. Each project keeps its own repo-local tasks/ board, while the agent stores cross-project runtime state in one central state directory.
Before registering a project, initialize its task board and make sure the codex CLI is installed and authenticated. With no path, register uses the same project root that normal clt commands use:
clt init --folders
clt agent registerRegister more projects by passing their paths:
clt agent register ~/code/project-a
clt agent register ~/code/project-b
clt agent projectsTurn projects off and on without removing them from the registry:
clt agent pause ~/code/project-a
clt agent resume ~/code/project-aIn the TUI agent pane, the same state appears as OFF or ON.
Enable or disable the optional git-commit skill instruction per project:
clt agent git-commit enable ~/code/project-a
clt agent git-commit disable ~/code/project-aWhen enabled, the scheduler appends a prompt section that tells Codex to use the $git-commit skill after completing and verifying a task. The instruction is skipped for projects where the setting is disabled. In the TUI, this setting appears in the GIT column.
Agent-facing workflow files are included at the repo root:
skill-clt.md: task-board workflow guidance for usingclt.skill-git-commit.md: git commit and optional push workflow guidance.
Run one foreground scheduler pass:
clt agent run --onceThe scheduler scans enabled projects, picks projects with pending todo tasks, takes an agent lease, and starts one Codex run at a time. Each Codex run is prompted to inspect the board, move one available task to doing, complete it, run relevant checks, update the task through clt, and stop after that single task.
Run the scheduler continuously in the foreground:
clt agent daemonStart or stop the background service:
clt agent start
clt agent stopOn macOS, start installs a user launchd service named com.alpinevibrations.clt.agent. On Linux, it installs a user systemd service named clt-agent.service. Other platforms can still use clt agent run --once or clt agent daemon, but start and stop are unsupported.
Run clt agent start and clt agent stop as your normal user, not with sudo; these commands manage per-user services.
Inspect agent state and recent output:
clt agent status
clt agent logs
clt agent clean
clt agent pause .
clt agent resume .
clt agent unregister .clt agent clean resets stored failure state, deletes recorded run history, removes agent run logs, and truncates background service logs. It keeps registered projects and task boards intact, and refuses to run while active Codex leases exist.
By default, agent state is stored at ~/Library/Application Support/clt on macOS, $XDG_STATE_HOME/clt on Linux when XDG_STATE_HOME is set, or ~/.local/state/clt otherwise. The state directory contains agent.db, scheduler run logs, and background service logs such as agent-service.out and agent-service.err. Override it with:
CLT_AGENT_STATE_DIR=/path/to/state clt agent daemonUseful runtime tuning variables are:
CLT_AGENT_MAX_GLOBAL_JOBS: maximum Codex runs active globally, default12.CLT_AGENT_POLL_INTERVAL_SECONDS: daemon delay between scheduler passes, default15.CLT_AGENT_RUN_TIMEOUT_SECONDS: Codex process timeout, default2700.CLT_AGENT_LEASE_TIMEOUT_SECONDS: active lease expiry, default3600.CLT_AGENT_FAILURE_BACKOFF_SECONDS: delay after a failed project run, default300.CLT_AGENT_SUCCESS_COOLDOWN_SECONDS: delay after a successful project run, default5.CLT_AGENT_CODEX_PATH: Codex executable path.clt agent startresolves and stores this for the background service so launchd/systemd does not depend on an interactive shellPATH.CLT_AGENT_HEARTBEAT_TAIL: print a short stderr tail on still-running heartbeats when set to1,true,yes, oron; defaultfalse.
Add a new task to the To Do list:
clt add My first taskMetadata: You can optionally add metadata (tags, priority, or IDs) which will be stored in parentheses:
clt add "Fix login bug" "BUG, HIGH"Change the status of a task:
clt status todo 1 doing
clt status doing 1 doneAlternatively, mark a task as done quickly:
clt done doing 1Remove a task from a specific list:
clt delete todo 1Get an overview of all tasks, or filter by status:
clt list
clt list todoYou can create folder-backed statuses during init or expand an existing markdown list:
clt init --folders
clt expand todo
clt expandclt expand todo migrates only todo.md. clt expand migrates todo.md, doing.md, and done.md. The original Markdown files are preserved as .bak files.
A folder-backed status looks like this:
tasks/
todo/
0001-write-release-plan.md
doing.md
done.md
Each file in tasks/todo/ is one task. The CLI and TUI show the first sentence, while the file can hold longer notes, checklists, and links. If a folder-backed task moves into a Markdown-backed status, clt expands that destination status to a folder and preserves the old Markdown file as status.md.bak.
Task folders become navigable subtask boards when they contain status stores:
tasks/
doing/
0001-ship-dashboard/
task.md
todo.md
doing.md
done.md
The folder's task.md provides the parent task text. Inside the TUI, selecting that task and pressing Enter opens its nested board.
If you want to contribute or build from source:
git clone <repository-url>
cd cli-task
cargo build --releaseRelease notes are tracked in CHANGELOG.md. New user-facing features, behavior changes, and bug fixes should be added under Unreleased first, then moved into a versioned section when publishing a release.