Vikunja Kanban
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.
Global Arguments
| Argument | Type | Description |
|---|---|---|
| baseUrl | string | Base URL of the Vikunja instance, e.g. https://vikunja.example.com |
| webBaseUrl? | string | Base URL the web UI is reached at, used only to build task links in |
| apiToken | string | Vikunja personal API token (Bearer). Supply via a swamp vault |
| projectId | number | Default Vikunja project id tasks are created in and listed from (e.g. |
| viewId? | number | Optional explicit kanban view id for the default projectId. Normally |
| defaultBucketName? | string | Bucket title (case-insensitive) that new_task places tasks into by |
| bucketRoles? | object | Which bucket title (case-insensitive) plays which role on the board. |
| policy? | object | Definition-of-Ready thresholds used by audit and the sort order used |
| timeoutMs? | number | Per-request fetch timeout in milliseconds. |
| maxRetries? | number | How many times to retry a request after an HTTP 429 rate-limit response. |
| userAgent? | string | User-Agent header sent on all outbound requests. |
| Argument | Type | Description |
|---|---|---|
| apply? | boolean | false (default) only reports the moves that would be made. true |
| buckets? | array | Bucket titles (case-insensitive) to reorder. Default: every bucket |
| maxIterations? | number | Move budget PER BUCKET: reorder gives up on a bucket after |
| Argument | Type | Description |
|---|---|---|
| lookaheadDays? | number | Cards due within this many days after today are listed as upcoming. |
| now? | string | ISO 8601 instant to evaluate against instead of the clock (for tests |
| Argument | Type | Description |
|---|---|---|
| taskId | number | Vikunja task id. |
| dueDate | string | ISO 8601 instant to set as the due date (the day to look at the card |
| force? | boolean | Write even though the card was updated within |
| Argument | Type | Description |
|---|---|---|
| title | string | Task title. |
| description? | string | Optional task description/body. |
| labels? | array | Label titles to attach (case-insensitive), in addition to `label`. |
| dueDate? | string | Optional ISO 8601 due date, e.g. 2026-09-20T00:00:00Z. |
| priority? | number | Optional Vikunja numeric priority override (0=unset .. 5=DO NOW). |
| bucketName? | string | Kanban bucket title (case-insensitive) to place the task into, |
| duplicateTitle? | enum | What to do when a non-done task in the project already has this title |
| skipIfTitleExists? | boolean | Deprecated alias kept for existing callers: true (the old default) = |
| requireReady? | boolean | Apply the full Definition of Ready (as audit checks it in the ready |
| Argument | Type | Description |
|---|---|---|
| title? | string | New title. |
| description? | string | New description (HTML), replacing the old one. An empty or |
| priority? | number | New priority (0=unset .. 5=DO NOW). |
| Argument | Type | Description |
|---|---|---|
| add? | array | Label titles to attach (case-insensitive). Must already exist. |
| remove? | array | Label titles to detach (case-insensitive). Must exist on the |
| Argument | Type | Description |
|---|---|---|
| bucketName | string | Bucket title (case-insensitive) to move the card into. The done |
| Argument | Type | Description |
|---|---|---|
| humanInstructed? | boolean | Must be true. Closing a card is a person's decision, so a caller has |
| Argument | Type | Description |
|---|---|---|
| title | string | Label title. An existing label with this title (case-insensitive) is |
| hexColor? | string | Optional colour, e.g. 1973ff or #1973ff. |
| description? | string | Optional label description. |
| humanInstructed? | boolean | Must be true. Labels are the board's shared vocabulary, so a caller |
| Argument | Type | Description |
|---|---|---|
| ops | array | Operations, run in this order. Discriminated on `op`: create |
| apply? | boolean | false (default): validate every op against the live board and write |
| requireReady? | boolean | Apply the full Definition of Ready to every create, whatever its |
| maxOps? | number | Refuse a plan with more ops than this. |
| Argument | Type | Description |
|---|---|---|
| taskId | number | Vikunja task id. |
| Argument | Type | Description |
|---|---|---|
| limit? | number | Max results to return. |
| includeDone? | boolean | Include tasks already marked done. |
Resources
Global Arguments
| Argument | Type | Description |
|---|---|---|
| baseUrl | string | Base URL of the Vikunja instance (no trailing slash, no /api/v1). |
| webBaseUrl? | string | Base URL the web UI is reached at, used only for ticket links. |
| apiToken | string | Vikunja API token (Bearer), wired from a vault. Needs the tasks, |
| projectId | number | The Vikunja project this tracker files and reads tickets in. Tasks in |
| assignee? | string | Username publish assigns a ticket to when work on it starts. Leave |
| timeoutMs? | number | Per-request fetch timeout in milliseconds. |
| maxRetries? | number | How many times to retry a request after an HTTP 429 response before |
| userAgent? | string | User-Agent header sent on all outbound requests. |
| Argument | Type | Description |
|---|---|---|
| operation | enum | |
| request | union | |
| answer | string | |
| run? | string |
Resources
Modified 1 behaviors
Declare SPDX license (MIT) in manifest.
Modified 1 behaviors
Modified 1 behaviors
Modified 1 behaviors
Modified 1 behaviors
Modified 1 behaviors
- 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