Skip to main content

Vikunja Kanban

@sntxrr/vikunja-kanbanv2026.10.23.1· MIT· 12d agoBEHAVIORS
01README

Vikunja kanban orchestrator — creates tasks in a Vikunja project directly via the Vikunja REST API and records each as a swamp data resource with its ID, title, labels, and status. Built as a homelab-native replacement for @webframp/hermes-kanban-orchestrator: no hermes binary, no shell-out — just an authenticated HTTP client talking to a self-hosted Vikunja instance.

New tasks are placed into a named kanban bucket (default "Backlog") of the target project — the kanban view is discovered automatically — so automation-created tasks land in a backlog column rather than the view's default working column. The bucket is resolved before the task is created, so an unknown bucket name fails with nothing created. Any project can be targeted per call via a projectId argument.

Methods

  • new_task — Create a task in a Vikunja project (default or per-call projectId), placing it in a named bucket (bucketName) and optionally attaching existing labels by title (label / labels), all resolved before anything is created. Refuses a card that does not meet its target bucket's readiness rules (ready: full Definition of Ready; waiting: a due date; doing/review/done: never) or requireReady; duplicateTitle refuse/skip/allow (default skip); every field is read back.
  • apply_plan — Batch writes in one run: validate every create / update / labels / move / due / close op against one read of the board and report all problems (dry run by default); with apply: true, write nothing unless every op is valid, then run them in order with read-backs, stopping at the first failure. Records a planResult.
  • board — Read-only: every open card (full description, bucket and role, labels, priority, due date) as one boardSnapshot resource, with truncated: true if the read hit the page cap.
  • get_task — Read-only: one card and the bucket it sits in.
  • list_recent — List the most recently created tasks in a project.
  • audit — Read-only Definition-of-Ready audit of the whole board: empty/short descriptions, missing labels or label groups, unset priority, missing verdict/acceptance/source-link markers, stale cards per bucket role (waiting cards: by due date, which they must carry), WIP over the limit, buckets out of order.
  • reorder — Sort every non-done bucket by priority then age. Dry run by default; apply moves one card at a time and re-reads until the board converges. A gap too small to halve, or a Vikunja 4028, makes it respace the view first (position below 0.01 triggers Vikunja's full recalculation). Each bucket has its own move budget; a run that gives up names that bucket and still writes its reorderPlan.
  • due_report — Read-only: split the board's dated, not-done cards into overdue / due today / upcoming (lookaheadDays) with a link per card and a ready-to-send Markdown message, so a scheduled workflow can nudge on a card's due date.
  • set_due_date — Set or clear one card's due date via a full-task read-modify-write, refusing done cards, asserting on read-back that the date took, and moving the card back (verified) if the write dropped it out of its bucket.
  • update_task — Change one card's title, description and/or priority via a full-task read-modify-write, asserting each field on read-back and moving the card back if the write dropped it out of its bucket.
  • set_labels — Attach and detach existing labels on one card by title through the label endpoints, with read-back.
  • move_task — Move one card into a named bucket (never the done bucket) and read the placement back; the ready bucket needs the full Definition of Ready and waiting a due date, unless force: true.
  • close_task — Mark one card done and move it into the done bucket; runs only with humanInstructed: true.
  • create_label — Create one label (title, optional hexColor and description), idempotently: an existing title (case-insensitive, every page read) is returned instead of a duplicate, and a new one is read back. Runs only with humanInstructed: true; no other method creates labels.

The edit methods (update_task, set_labels, move_task, set_due_date) refuse done cards and cards someone else updated within policy.recentEditMinutes unless force: true.

Tracker for @swamp/stagecraft

A second model, @sntxrr/vikunja-kanban/tracker, is a stagecraft tracker (contract 1): put a @swamp/stagecraft/publisher in front of it and stagecraft's publish / claim / create / fetch-issue / mark-duplicate workflows file, comment on, move, relate and assign cards in one Vikunja project. Statuses are kanban bucket titles, types are labels, relations map onto Vikunja's relation kinds, and tasks outside the configured project are not_found.

02Behaviors2
@sntxrr/vikunja-kanbanv2026.10.22.1extensions/models/vikunja_kanban.ts

Global Arguments

ArgumentTypeDescription
baseUrlstringBase URL of the Vikunja instance, e.g. https://vikunja.example.com
webBaseUrl?stringBase URL the web UI is reached at, used only to build task links in
apiTokenstringVikunja personal API token (Bearer). Supply via a swamp vault
projectIdnumberDefault Vikunja project id tasks are created in and listed from (e.g.
viewId?numberOptional explicit kanban view id for the default projectId. Normally
defaultBucketName?stringBucket title (case-insensitive) that new_task places tasks into by
bucketRoles?objectWhich bucket title (case-insensitive) plays which role on the board.
policy?objectDefinition-of-Ready thresholds used by audit and the sort order used
timeoutMs?numberPer-request fetch timeout in milliseconds.
maxRetries?numberHow many times to retry a request after an HTTP 429 rate-limit response.
userAgent?stringUser-Agent header sent on all outbound requests.
fn audit()
Read-only Definition-of-Ready audit of a project's kanban board:
fn reorder(apply?: boolean, buckets?: array, maxIterations?: number)
Sort each non-done bucket by priority (desc) then age. Dry run by
ArgumentTypeDescription
apply?booleanfalse (default) only reports the moves that would be made. true
buckets?arrayBucket titles (case-insensitive) to reorder. Default: every bucket
maxIterations?numberMove budget PER BUCKET: reorder gives up on a bucket after
fn due_report(lookaheadDays?: number, now?: string)
Read-only: list the not-done cards on a project's board that are
ArgumentTypeDescription
lookaheadDays?numberCards due within this many days after today are listed as upcoming.
now?stringISO 8601 instant to evaluate against instead of the clock (for tests
fn set_due_date(taskId: number, dueDate: string, force?: boolean)
Set or clear one card's due date — the day to look at it again.
ArgumentTypeDescription
taskIdnumberVikunja task id.
dueDatestringISO 8601 instant to set as the due date (the day to look at the card
force?booleanWrite even though the card was updated within
fn new_task(title: string, description?: string, labels?: array, dueDate?: string, priority?: number, bucketName?: string, duplicateTitle?: enum, skipIfTitleExists?: boolean, requireReady?: boolean)
Create a task in a Vikunja project (the configured default, or a
ArgumentTypeDescription
titlestringTask title.
description?stringOptional task description/body.
labels?arrayLabel titles to attach (case-insensitive), in addition to `label`.
dueDate?stringOptional ISO 8601 due date, e.g. 2026-09-20T00:00:00Z.
priority?numberOptional Vikunja numeric priority override (0=unset .. 5=DO NOW).
bucketName?stringKanban bucket title (case-insensitive) to place the task into,
duplicateTitle?enumWhat to do when a non-done task in the project already has this title
skipIfTitleExists?booleanDeprecated alias kept for existing callers: true (the old default) =
requireReady?booleanApply the full Definition of Ready (as audit checks it in the ready
fn update_task(title?: string, description?: string, priority?: number)
Change one card's title, description and/or priority. Reads the
ArgumentTypeDescription
title?stringNew title.
description?stringNew description (HTML), replacing the old one. An empty or
priority?numberNew priority (0=unset .. 5=DO NOW).
fn set_labels(add?: array, remove?: array)
Attach (add) and detach (remove) existing labels on one card by
ArgumentTypeDescription
add?arrayLabel titles to attach (case-insensitive). Must already exist.
remove?arrayLabel titles to detach (case-insensitive). Must exist on the
fn move_task(bucketName: string)
Move one card into a named bucket and read its placement back
ArgumentTypeDescription
bucketNamestringBucket title (case-insensitive) to move the card into. The done
fn close_task(humanInstructed?: boolean)
Close one card: set done=true, move it into the done bucket, and
ArgumentTypeDescription
humanInstructed?booleanMust be true. Closing a card is a person's decision, so a caller has
fn create_label(title: string, hexColor?: string, description?: string, humanInstructed?: boolean)
Create one label (title, optional hexColor and description).
ArgumentTypeDescription
titlestringLabel title. An existing label with this title (case-insensitive) is
hexColor?stringOptional colour, e.g. 1973ff or #1973ff.
description?stringOptional label description.
humanInstructed?booleanMust be true. Labels are the board's shared vocabulary, so a caller
fn apply_plan(ops: array, apply?: boolean, requireReady?: boolean, maxOps?: number)
Batch card writes in one run. Validates EVERY op (create, update,
ArgumentTypeDescription
opsarrayOperations, run in this order. Discriminated on `op`: create
apply?booleanfalse (default): validate every op against the live board and write
requireReady?booleanApply the full Definition of Ready to every create, whatever its
maxOps?numberRefuse a plan with more ops than this.
fn board()
Read-only: write every not-done card on the project's kanban
fn get_task(taskId: number)
Read-only: one card plus the bucket (and role) it sits in,
ArgumentTypeDescription
taskIdnumberVikunja task id.
fn list_recent(limit?: number, includeDone?: boolean)
List the most recently created tasks in a Vikunja project (the
ArgumentTypeDescription
limit?numberMax results to return.
includeDone?booleanInclude tasks already marked done.

Resources

vikunjaTask(infinite)— A Vikunja task with id, title, labels, priority, bucket, and status.
summary(infinite)— Per-listing summary: scope, endpoint, count, and item ids.
boardAudit(infinite)— One audit run of a kanban board: per-card and per-bucket
reorderPlan(infinite)— One reorder run: the moves planned (dry run) or performed
label(infinite)— One create_label run: the label's id, title, colour and
dueReport(infinite)— One due-date pass over a board: overdue, due-today and upcoming
planResult(infinite)— One apply_plan run: the outcome (dry-run / refused / applied /
boardSnapshot(infinite)— Every not-done card on a board with its bucket, role, labels,
@sntxrr/vikunja-kanban/trackerv2026.10.23.1extensions/models/vikunja_tracker.ts

Global Arguments

ArgumentTypeDescription
baseUrlstringBase URL of the Vikunja instance (no trailing slash, no /api/v1).
webBaseUrl?stringBase URL the web UI is reached at, used only for ticket links.
apiTokenstringVikunja API token (Bearer), wired from a vault. Needs the tasks,
projectIdnumberThe Vikunja project this tracker files and reads tickets in. Tasks in
assignee?stringUsername publish assigns a ticket to when work on it starts. Leave
timeoutMs?numberPer-request fetch timeout in milliseconds.
maxRetries?numberHow many times to retry a request after an HTTP 429 response before
userAgent?stringUser-Agent header sent on all outbound requests.
fn describe()
Record what this tracker is, for stagecraft to bind to
fn operate(operation: enum, request: union, answer: string, run?: string)
Make one tracker operation and write its answer under the given
ArgumentTypeDescription
operationenum
requestunion
answerstring
run?string

Resources

answer(infinite)— operate's answers, under the names stagecraft gave them
description(infinite)— What this tracker says of itself, for stagecraft to bind
relation(infinite)— Which side a related_to was written from (Vikunja's related is
03Previous Versions16
2026.10.22.1MIT

Modified 1 behaviors

2026.10.15.1MIT
2026.10.14.1MIT(was none)

Declare SPDX license (MIT) in manifest.

2026.09.27.4
2026.09.27.3
2026.09.27.2

Modified 1 behaviors

2026.09.27.1
2026.09.26.1

Modified 1 behaviors

2026.09.21.2
2026.09.21.1
2026.09.19.2

Modified 1 behaviors

2026.09.19.1

Modified 1 behaviors

2026.09.15.1

Modified 1 behaviors

2026.09.14.1
2026.09.13.2
2026.09.13.1
04Stats
A
100 / 100
Downloads
60
Archive size
90.4 KB
  • Has README or module doc2/2earned
  • README has a code example1/1earned
  • README is substantive1/1earned
  • Most symbols documented1/1earned
  • No slow types (deprecated)1/1earned
  • Dependencies pass trust audit2/2earned
  • Docs keep secrets in a vault1/1earned
  • Has description1/1earned
  • Platform support declared (or universal)2/2earned
  • License2/2earned
  • Verified public repository2/2earned
05Platforms
06Labels