voku/agent-kanban
Markdown TODO Kanban parser, renderer, and verifier for coding-agent workflows.
0.3.2
26K downloads/mo
#4172 most downloaded on Packagist
voku/agent-kanban
What this package is like to depend on
Last release 7 days ago
16 Aug 2026
Ships fairly regularly
a new release about every 3 weeks
Nearly every release is documented
notes for 7 of 7 stable releases
Nothing withdrawn
no release was ever pulled
2 months old
7 releases · first in 2026
7 releases in the last 12 months
see the full history below
Release timeline
7 releases · Jun 2026 to Aug 2026Releases
latest 7-
0.3.216 Aug 2026Release notes
Open source →Fixed
- Value-taking long CLI options now accept both
--name=valueand--name value, so delegated callers such asagent-loop boarduse the same option grammar as the umbrella workflow commands. Strict validation for unknown, duplicate, boolean, empty and missing option values remains unchanged. - CLI help and validation messages now describe that two-form contract without implying that the equals form is mandatory.
- Value-taking long CLI options now accept both
-
0.3.116 Aug 2026Release notes
Open source →Added
card createaccepts--brief=<text>, so a card can be created atomically with the task brief required by its target lane.
Fixed
- Card mutations now reuse the board verifier before persistence and reject
candidate state that would immediately make the board verifier-invalid.
This closes the split-brain where a mutation could report success and the
next
verifywould reject the written card. - READY cards can therefore be created in one write when all required fields are supplied, while create/move/claim/release/restore cannot silently introduce card-local verifier errors.
-
0.3.015 Aug 2026Release notes
Open source →Changed
- Breaking: the standalone CLI default workspace moves from
<cwd>to<cwd>/.agent-loop, so the default board directory moves fromtodo/to.agent-loop/todo/. There is deliberately no hidden fallback or dual-read; callers that keep a custom/legacy location must pass--rootexplicitly. The typed PHP APIs remain explicit about their root and therefore do not inherit this CLI-only migration. SeeUPGRADING.md. - Release tags can now be requested deterministically through
.release/<version>.json, bound to an exact candidate SHA. This matches the release mechanism used by the sibling agent packages instead of relying on an unrecorded manual tag step.
Added
--fields=<a,b,c>for the commands that emit card objects (render,lane,next-pull,card show): emit only the named card fields instead of the complete card object. Cuts the dominant cost of feeding board JSON to a coding agent, which is the unboundedtaskBrief/handoffNotesprose and the 64-characterrevisiondigest repeated for every card.--compact(any command,--format=jsononly): emit JSON without pretty-print indentation and newlines.Rendering\CardFieldSelection, and optionalCardFieldSelection/compactarguments onJsonBoardRenderer::cardToArray(),cardToEnvelope(),cardsToEnvelope()andencode(), so the same reduction is available to PHP callers.Cli\OutputOptions, the typed value object carrying a command's format, compact flag and field selection.
Both options are additive.
schemaVersionis unchanged: a reduced card object is a documented subset of the existingcardshape — same envelope, same canonical key order — not a new shape. Output for callers that pass neither option is byte-for-byte unchanged.idis always emitted, whether or not it was named. Both options are rejected with exit code1when used without--format=json, as is an unknown, repeated or empty field name, rather than being silently ignored.See
docs/cli.md("Keeping JSON output small"),docs/json-format.md("Reduced card objects") anddocs/agent-loop-integration.md("Reading a board without spending the context window").Fixed
- A malformed option token (
--fields,--fields=,--limit,--bogus=1,--compact=yes, a repeated option, ...) escaped the CLI as an uncaught exception: a raw stack trace on STDERR and exit code255, instead of the documentedValidationExceptionbehavior of a clean message and exit code1.ArgvParser::parse()ran outsideCliApplication::run()'s error boundary; it now runs inside it, and--format=jsonis honored for these errors too, so a JSON-only consumer gets a JSONerrordocument rather than a stack trace. Present since 0.2.0 and not specific to the new options.
- Breaking: the standalone CLI default workspace moves from
-
0.2.113 Jul 2026 -
0.2.012 Jul 2026Release notes
Open source →Document the release of version 0.2.0 with significant architectural changes and migration guides.
Release notes
Open source →... typed engine, safe mutations, JSON output, CLI rewrite
This is a large architectural rework building toward a stable 1.0 API, including breaking changes: the pre-1.0
TodoBoardSource/TodoBoardVerifier/TodoBoardCliclasses and the CLI commands built on them are removed outright rather than kept as deprecated facades, since this project has one known consumer (voku/agent-loop) and a clean break was judged better than carrying the old generated-Markdown architecture forward. Seedocs/PLAN.mdfor the full rationale andUPGRADING.mdfor a class-by-class and command-by-command migration guide.The on-disk board format is unchanged and fully backward compatible — see "Compatibility" below.
Added
- A typed domain model (
Domain\Card,CardId,Lane,CardStatus,CardRevision,Claim,ExternalIssueRef,CardCollection) parsed directly from card files — no intermediate generated Markdown. Config\BoardConfig: project prefix, lanes, status-to-lane mapping, WIP limits, required fields per lane, transitions, format version, archive directory, external-issue system name. Nothing project-specific is hard-coded in the engine anymore.Repository\CardParser/CardSerializer: a formally specified, deterministic card format (docs/card-format.md) with stable field order, newline normalization, and documented invalid-input behavior. Unknown bullet fields (e.g. the legacyFitfield) round-trip losslessly as extension fields.Repository\MarkdownCardRepository: strict (loadAll()) and lenient (loadAllLenient()) loading, atomic writes (atomicWrite()), atomic moves (moveFile(), used by archive/restore), symlink-safe.Query\BoardQueryService: typed board queries (summary, by lane/status/ assignee/domain, search, next-pull candidates, blocked cards, WIP health) over parsed cards — never over rendered Markdown.Rendering\BoardRenderer(Markdown, generic — no hard-coded project policy prose) andRendering\JsonBoardRenderer(versioned JSON; seedocs/json-format.md).Verification\BoardVerifier: structuredVerificationReportofViolations with a stableViolationCode,Severity, and card/field/file context. Never writes to STDOUT/STDERR. Covers duplicate card IDs, invalid filenames/prefixes, unsupported lanes, invalid status-to-lane mappings, missing required fields/task briefs, invalid timestamps, malformed/ duplicate metadata, invalid WIP counts, invalid claims, invalid transition states, board-metadata inconsistencies, stale/incompatible format versions, archive conflicts, and source-directory ambiguity.Transition\TransitionPolicy/TransitionResult: configurable, validated lane-to-lane moves, decoupled from file writing.Mutation\CardMutationService/MutationResult: atomic, conflict-awarecreate/update/move/claim/release/archive/restore, all supportingdryRunand an optionalexpectedRevision(SHA-256-based optimistic concurrency). The original file is preserved on any failure.- A small, deliberately non-distributed claim model (
Domain\Claim): a current non-expired claim can't be silently replaced; expired claims can. ExternalIssue\ExternalIssueProvider/ExternalIssueComparator: a generic, credential-free, network-free contract for comparing local cards against an external tracker, replacing the Jira-specific logic previously built into the CLI. Seedocs/external-issues.md.- A rewritten CLI (
Cli\CliApplication) that delegates to the above:help,summary,render,verify,next-pull,lane,card show/create/update/move/claim/release/archive/restore,external-sync, with--format=text|markdown|json,--dry-run,--expected-revision,--root,--config, and documented, stable exit codes. Seedocs/cli.md. - Full documentation set:
docs/architecture.md,card-format.md,configuration.md,cli.md,php-api.md,json-format.md,concurrency.md,external-issues.md,agent-loop-integration.md,troubleshooting.md, plusUPGRADING.md,CONTRIBUTING.md,SECURITY.md. - PHPStan at
maxlevel and php-cs-fixer, both passing onsrc/andtests/;composer cs-check/cs-fixscripts; CI matrix across PHP 8.3/8.4/8.5 plus a clean-Composer-install verification job. - A comprehensive test suite (unit, filesystem/concurrency integration, CLI
subprocess, and compatibility tests) — see
docs/PLAN.md's VERIFY section for what was actually run and how. - Hardened concurrency and path safety in
MarkdownCardRepository: writes and moves take an exclusive per-card-file lock (flock()) and re-check the expected revision while holding it, so the file cannot change between that check and the write from another process using the repository API; lock files are removed after use without reintroducing the classicflock()-then-unlink()race (seedocs/concurrency.md). Every path the repository touches is confined to the board root and checked component-by-component for symlinks, not just at the final segment.BoardConfigrejects an absolute,..-containing, or NUL-byte-containing configured directory outright (seedocs/configuration.md). Cli\ArgvParsernow rejects unknown options, duplicate options, a missing value on a non-boolean option, a value on a boolean flag, and a non-integer value where an integer is required, instead of silently falling back to a default.CliApplicationadditionally validates options against a per-command allow-list, so e.g.summary --actor=xorverify --title=xare rejected rather than silently ignored, even though--actor/--titleare valid options for other commands. Seedocs/cli.md.
Changed
bin/agent-kanbannow runsCli\CliApplicationinstead of the removedTodoBoardCli. SeeUPGRADING.mdfor the full command mapping.
Removed (breaking)
TodoBoardSource,TodoBoardVerifier,TodoBoardCli,TodoBoardCard,TodoBoardRenderOptions, andJiraIssueProviderare deleted, not deprecated. Each has a direct typed-engine replacement documented inUPGRADING.mdwith a before/after code example. These classes generated and then re-parsed a large project-specific Markdown document — exactly the architecture pattern this release removes — and hard-coded German Jira status names, a fixed WIP limit of3, and required section headings from that one rendered template. None of that exists anywhere in the new engine; equivalent behavior is available as hostBoardConfig(docs/configuration.md) or host documentation, never as an engine invariant.- CLI commands
ticket,context,brief, andjira-sync(andjira-sync's--jqloption) are removed rather than kept as aliases. Usecard show,card show(includes the task brief), andexternal-sync --provider-class=... --query=...respectively — seeUPGRADING.md. - The generated-Markdown-as-internal-database pattern: nothing in this package parses its own rendered output anymore.
Compatibility (unchanged)
- The on-disk card format is fully backward compatible:
todo/cards/(preferred) andtodo/jira/(legacy) are both still read, existing 0.x card files (including the legacyFitfield,Next pull rankfield, anddd.mm.YYYYtimestamp format) parse unchanged, and no card file is ever silently rewritten by reading it. Only the PHP classes and CLI commands built around that format changed.
- A typed domain model (
-
0.1.022 Jun 2026Release notes
Open source →- add support for preferred card directory (
todo/cards) over legacy (todo/jira)
- add support for preferred card directory (
-
0.0.109 Jun 2026