Kanban CLI is a terminal-native task manager written in Rust that stores board state in a local file. No web server, no database, no API layer. The tool is explicitly labeled “agent-first” in its Show HN post, which signals a design priority: agents can manipulate task state through the same CLI commands that humans use, without needing to parse HTML, handle rate limits, or authenticate against a remote service.
The architecture reveals patterns for building tools that bridge autonomous workflows and human oversight. The state file lives in the Git repository, so task history becomes part of version control. Agents running in CI pipelines, pre-commit hooks, or local automation scripts can read and write the same board state that a developer sees in their terminal.
Architecture: File-Based State in the Repository
The tool stores the entire board in a single local file. The Rust implementation (visible in the 209-commit history and Cargo.toml manifest on Codeberg) reads this file, mutates state in memory, and writes it back.
Key components:
- State file: Single source of truth on disk, versioned with the project.
- Command parser: CLI that accepts both human-typed commands and agent-generated strings.
- Git integration: The state file lives in the repo, so
git logbecomes the audit trail.
This design eliminates the coordination overhead of a centralized service. Agents and humans operate on the same file. The trade-off is that you need a strategy for concurrent writes.
Concurrent Writes: Common Patterns for File-Based Tools
When both a human and an agent try to update the board simultaneously, file-based tools typically use one of three coordination primitives:
- Advisory file locking (flock on Unix): The process grabs an exclusive lock, reads, mutates, writes, and releases. Other processes wait.
- Atomic rename: Write to a temp file, then rename over the original. The filesystem guarantees atomicity, but concurrent edits cannot be merged.
- Optimistic locking with retries: Read the file, compute a checksum, mutate, and write only if the checksum matches. Retry on conflict.
The available source material (README, commit messages, directory structure) does not document which strategy Kanban CLI implements. The .agents/skills/kanban directory structure suggests agent-specific command wrappers, but the internal locking mechanism is not specified in the visible documentation.
Trade-off table for file-based coordination:
| Strategy | Concurrency | Complexity | Conflict Merge Support |
|---|---|---|---|
| Advisory lock | Serialized | Low | No |
| Atomic rename | Serialized | Low | No |
| Optimistic lock | Parallel reads | Medium | Requires conflict detection |
For a file-based tool where agents and humans rarely collide on the same machine, advisory locking is typically sufficient. A brief wait is acceptable when conflicts occur.
Command Syntax: Deterministic Parsing for Agents
Agents need commands that are unambiguous and composable. The design pattern for agent-first tools avoids natural language parsing, which introduces non-determinism. Instead, the CLI exposes a set of verbs with positional or flag-based arguments.
The README does not include command syntax examples, so the actual interface is not documented in the available source material. However, the pattern for agent-first tools typically looks like this:
# Both human and agent use identical syntax
kanban add "Implement auth" --column todo --priority high
# Agent can add metadata programmatically
kanban add --title "Implement auth" --column todo --priority high --assignee bot
The parser does not distinguish between human and agent invocations. Both get the same result for the same input. This determinism is critical when agents generate commands programmatically.
Agent integration pattern:
An agent running in a CI pipeline might:
- Parse test failures from stdout.
- Generate a
kanban addcommand for each failure. - Execute the command, which updates the local state file.
- Commit the updated file back to the repo.
The agent does not need API credentials, webhooks, or a network connection. It runs a binary and writes to a file.
Terminal Output: Structured Data vs. Human-Readable Formatting
Traditional CLI tools format output for human eyes: colors, tables, progress bars. Agents need structured data. The design pattern for agent-first tools typically supports both modes through a format flag.
Human mode: ANSI colors, Unicode box-drawing characters, interactive prompts.
Agent mode: JSON or line-delimited output that agents can parse without regex.
The available source material does not document whether Kanban CLI supports a structured output mode. This is a common pattern in agent-first tools, but verification would require inspecting the actual command-line options or source code.
State Persistence: Git as the Sync Layer
Because the state file lives in the repo, Git becomes the synchronization mechanism. When a developer pushes changes, the board state travels with the code. When an agent commits a task update in CI, that change propagates to every checkout.
Conflict resolution:
Git merge conflicts on the state file are inevitable when multiple branches modify the board independently. The commit log shows a recalibrate command (commit 943f672739: “feat(recalibrate): generic schema self-healing upgrades”) which suggests the tool may include schema migration or conflict resolution logic. This pattern could indicate:
- Schema versioning in the state file format.
- Migration logic that upgrades older schemas on read.
- Conflict detection that resolves common merge scenarios.
The actual implementation is not documented in the available source material. Verification would require inspecting the recalibrate command source code.
This approach differs from centralized task managers, where the server is the source of truth. Here, the repo is the source of truth, and the tool adapts to whatever state it finds.
Agent Handoff: Boundaries Between Autonomous and Human Tasks
The .agents/ directory structure (visible in the Codeberg file listing) suggests a deliberate boundary between agent-managed and human-managed workflows. This is a common pattern in agent-first tools, where certain operations are restricted to prevent agents from overriding human decisions.
Typical agent capabilities in file-based task tools:
- Create tasks automatically (e.g., from linter warnings).
- Move tasks between columns based on CI results.
- Archive completed tasks after deployment.
Operations typically restricted to humans:
- Reassigning tasks without approval.
- Deleting tasks (archive instead).
- Overriding priority set by a human.
The CLI can enforce these boundaries through command restrictions. Agents use a subset of commands, and certain operations require interactive confirmation (which agents cannot provide). The actual implementation in Kanban CLI is not documented in the available source material.
Observability: Audit Log from Git History
Every state change is a Git commit. This provides:
- Full audit trail:
git logshows who changed what and when. - Rollback:
git revertundoes a bad task update. - Blame:
git blameon the state file shows which commit introduced a task.
No separate audit log or event stream is needed. The version control system is the observability layer.
Failure Modes
Repository-native design introduces specific challenges:
Corrupted state file:
If the file is malformed (e.g., a process crashes mid-write), the tool may fail to start. The recalibrate command (inferred from commit message 943f672739) may attempt to fix it, but you may need to restore from Git history. This is the trade-off for file-based design: no central authority to enforce schema validity.
Lock contention:
If an agent holds the file lock for too long (e.g., waiting on network I/O), human commands block. The solution is to keep agent operations fast and avoid blocking I/O inside the critical section. This constraint shapes how agents interact with the tool.
Merge conflicts:
When two branches modify the board independently, Git will create conflict markers. The tool needs logic to parse these and present a resolution UI. Without it, you are manually editing the state file. Complex three-way merges may still require human intervention.
Technical Verdict
Use this approach when:
- You want task state versioned with your code.
- Agents need to manipulate tasks without API overhead.
- Your team works in the terminal and values file-based tools.
- You are building automation that creates, moves, or archives tasks programmatically within a single repository context.
Example scenario: An agent that parses linter warnings, creates a task for each warning, and commits the updated board state back to the repo in a pre-commit hook.
Avoid it when:
- You need real-time collaboration across distributed teams (Git sync is asynchronous).
- Your agents run on separate machines without shared filesystem access.
- You require fine-grained permissions (the file is all-or-nothing).
- Your workflow depends on webhooks or push notifications (no server means no push).
The design trades centralized coordination for simplicity and determinism. For agent-first workflows where the repo is the coordination point, this is a viable pattern.