App-karr

 view release on metacpan or  search on metacpan

.claude/skills/kanban-issues-karr-cli/SKILL.md  view on Meta::CPAN

synced fails quietly. Mutating commands still sync the board only, so this
costs nothing outside an explicitly typed `karr sync`, and a repository
holding nothing under `refs/karr-foundation/` pushes nothing there. Deletions
in that namespace (log retention, a cleared chain) travel like board deletions
do, so a pruned run log does not come back on the next pull.

**A fresh clone fetches the board by itself.** `git clone` does not carry
`refs/karr/*`, so a new checkout holds no board while the whole board sits on
its remote. The read commands (`board`, `list`, `show`, `log`, `context`,
`metrics`, `needs`, and `config show`/`config get`) do not pull as a rule —
only mutating commands do — but where there is nothing under `refs/karr/` at
all and the remote has a board, they fetch it once and answer, with one line
on STDERR (never STDOUT) saying where it came from. Where there is no remote,
or the remote has no board, they still refuse with exit 1 rather than
rendering an empty board: that is the only place `karr init` is the answer. In
a clone whose board is on the remote, `karr init` refuses as well and points
at `karr sync`, so it can no longer start a second, empty board beside the
real one; `karr init --new-board` is the documented way through when an
independent board there really is what you want.
`KARR_NO_AUTO_FETCH=1` switches the fetch off where karr must not touch the
network.

### File view (kanban-md interop)

```bash
karr materialize                             # refs -> tasks/ + config.yml on disk
karr materialize --force                     # overwrite git-tracked cards there
karr import --yes                            # tasks/ on disk -> refs
```

The board lives in `refs/karr/*`. `materialize` writes a file view of it for
grepping or for kanban-md to read; `import` reads such a directory back in.
The `tasks/` directory is always gitignored and is never the source of truth —
losing it costs nothing, editing it costs nothing until you `import`.
`materialize` refuses to write over paths the project itself tracks in git,
which is what `--force` overrides.

### Repair an old board

```bash
karr repair                                  # report what would change
karr repair --yes                            # migrate
```

Boards written by karr 0.402 or earlier stored UTF-8 double-encoded. Such a
board is detected on read and repaired on the fly, so nothing is broken in the
meantime; this migrates the stored refs once so the workaround stops being
needed. A board created by a later version needs nothing here and says so.

The same command also raises a `started` stamp that precedes its own card's
`created` up to that `created` — karr wrote `started` as a bare date until
ticket #68, which reads as midnight and so lands before a card created later
the same day. A clamped card then asserts zero queue time and no longer
records that its stamp was ever day-granular, so the dry run tells you how
many cards that is before you apply it. It reports, but does not touch,
`completed` stamps with the same day-granular problem.

### Backup and restore

```bash
karr backup > karr-backup.yml
karr restore --yes < karr-backup.yml
```

`restore` is destructive and replaces the entire `refs/karr/*` namespace.

### Destroy

```bash
karr destroy --yes
```

Deletes the entire `refs/karr/*` namespace from the repository and prunes the
remote board state too when a remote is configured. Prefer taking a
`karr backup` first.

### Helper refs

```bash
karr set-refs superpowers/spec/1234.md draft ready
karr set-refs superpowers/spec/1234.md < design.md    # multi-line payload
karr get-refs superpowers/spec/1234.md
```

Stores and retrieves helper payloads in Git refs outside protected namespaces
such as `refs/karr/*`, branches, and tags. Use this for shared planning blobs,
agent scratch data, or similar workflow artifacts that should sync through Git
without becoming task cards.

The arguments after the ref are joined with a single space, so they are a
one-line payload. A document goes in on stdin instead — with no content
argument at all, `karr set-refs REF < file` stores the file verbatim and
`karr get-refs REF > file` gives it back unchanged.

### Activity log

```bash
karr log                                     # last 20 entries
karr log --agent swift-fox                   # filter by agent
karr log --task 5                            # filter by task
karr log --last 50 --json                    # more entries, JSON
karr log --compact                           # one line per entry, no padding
```

### Flow metrics

```bash
karr metrics                                 # throughput, lead/cycle time, efficiency, aging
karr metrics --since 2026-01-01              # only count tasks completed after this date
karr metrics --compact                       # one line plus one per aging item
karr metrics --json                          # JSON output
```

Every figure comes from the `created`/`started`/`completed` stamps on the
cards, not from the activity log. Cards whose stamps cannot carry a
measurement — an unreadable date, a `started` that precedes the card's own
`created`, or a `completed` that precedes that `started` — are left out of the
averages that need them and counted in `unusable_timestamps` (cards, not
stamps), so a low sample count is visible rather than silent.

Lead time is the deliberate exception: a `completed` that precedes its own
`created` is still averaged in, negative and all, because every value it could
be clamped to would be an invention. Such samples are counted separately in
`negative_lead_samples` and named in the closing note, so the average is
qualified instead of cleaned — they are *in* the figure, not missing from it,
which is why they are not in `unusable_timestamps`. They come from boards
written before karr 0.403, which stamped `started`/`completed` as a bare
`YYYY-MM-DD` that reads as midnight; on such a board an average printed to the
hour is finer than the data underneath it.

### Agent name

```bash
NAME=$(karr agent-name)                       # mint once, reuse everywhere
karr pick --claim "$NAME" --move in-progress

.claude/skills/kanban-issues-karr-cli/SKILL.md  view on Meta::CPAN

tags:
  - devops
  - needs:other-repo#7

Optional body with more detail.
```

Cross-board dependencies ride in `tags` (`needs:BOARD#ID`,
`escalated-from:BOARD#ID`) rather than in a frontmatter field of their own:
kanban-md marshals a card from its own struct and would drop an unmodelled key
the first time it writes, while `tags` is modelled on both sides.

Tasks are stored under `refs/karr/tasks/*/data`. During command execution `karr`
materializes the same Markdown shape into a temporary task directory, so this
format still matters when reading or generating tasks programmatically.

## Config refs

```yaml
version: 1
board:
  name: My Project
statuses:
  - backlog
  - todo
  - name: in-progress
    require_claim: true
  - name: review
    require_claim: true
  - done
  - archived
priorities: [low, medium, high, critical]
classes: [expedite, fixed-date, standard, intangible]
claim_timeout: 1h
defaults:
  status: backlog
  priority: medium
  class: standard
foundation:
  enabled: false
  reason: abandoned driver, backlog parked
```

That YAML lives in `refs/karr/config` as sparse overrides. The next numeric id
is kept separately in `refs/karr/meta/next-id`.

## Decision tree: which command?

1. **Need a board?** → `karr init`
2. **New work item?** → `karr create "Title" --priority high`
3. **What's on the board?** → `karr board` or `karr list`
4. **Starting work?** → `karr pick --claim NAME --move in-progress`
5. **Done with task, hand to review?** → `karr handoff ID --claim NAME --note "reason"`
6. **Done with task, close it?** → `karr edit ID --release && karr move ID done`
7. **Blocked?** → `karr edit ID --block "reason"`
8. **Need details?** → `karr show ID`
9. **Soft-delete?** → `karr archive ID`
10. **Board snapshot for agent context?** → `karr context --write-to AGENTS.md`
11. **Check/change config?** → `karr config` / `karr config set KEY VALUE`
12. **Install agent skills?** → `karr skill install`
13. **Need a full board snapshot?** → `karr backup` / `karr restore --yes`
14. **Need shared non-task workflow data?** → `karr set-refs` / `karr get-refs`
15. **Board should never be drained by an automation host?** → `karr disable --reason "why"`
16. **Need to remove the board completely?** → `karr destroy --yes`
17. **Overview of every board under a directory?** → `karr dashboard`

## Multi-agent workflow

```bash
# 1. Generate agent name and pick task
NAME=$(karr agent-name)
karr pick --claim $NAME --status todo --move in-progress

# 2. Work on task...

# 3. Hand off for review
karr handoff ID --claim $NAME --note "Implementation complete" --timestamp

# 4. Or: release and mark done directly
karr edit ID --release
karr move ID done
```

Claims expire after the configured timeout (default: 1h). Statuses with `require_claim: true` enforce that moves include `--claim`.

Perl remains the primary local installation path, but a Docker alias around
`raudssus/karr:latest` or `raudssus/karr:user` works with the same commands when
another repository vendors `karr` instead of installing it locally.

## Helper-ref workflow

```bash
# 1. Publish a shared planning blob
karr set-refs superpowers/spec/1234.md initial draft ready for review

# 2. Or pipe a whole document in - arguments are joined with a space and
#    would flatten it into one line
karr set-refs superpowers/spec/1234.md < design.md

# 3. Read it back elsewhere
karr get-refs superpowers/spec/1234.md
```

Use helper refs for coordination data that should travel with Git but should
not affect the board state itself.



( run in 0.684 second using v1.01-cache-2.11-cpan-4ef0a570458 )