/**
* Vikunja integration — low-level API-wrapper skill.
*
* WHY THIS EXISTS. `vikunja` was registered as an integration id long before
* anything implemented it: the id gated a card in the UI, and the ONLY code that
* ever talked to a board was `board-runner`'s own `lib/tracker.js`, calling REST
* inline. That works, and it stays — a scheduled runner wants deterministic,
* batched calls it can retry. But it meant the board was reachable by exactly
* one template, doing exactly the five things that template's code spelled out.
* No other agent could touch it, and nobody could say "move that card to Doing".
*
* This skill is the other half: the same board, handed to the MODEL as tools.
* The two layers are deliberate and neither replaces the other —
* tracker.js = deterministic, node-side, batch, retry-safe;
* this skill = interactive, model-driven, one action at a time.
*
* SHAPE: `linear.ts`, not `jira.ts`. Jira spawns a separate MCP server package
* (@zibby/mcp-jira); Vikunja needs no such thing — the tools live on this object
* and the generic skill server (bin/mcp-skill.mjs) exposes them. One file.
*
* API FACTS ARE INHERITED, NOT REDISCOVERED. Every endpoint below was verified
* live against a real Vikunja by the board-runner tracker (its header block
* documents the traps). The ones that bite:
* • `GET /tasks/all` is HTTP 400 even bare — list PROJECT-scoped.
* • the `labels` filter takes the NUMERIC label id, never the title (a title
* 400s with code 4019); resolve via `GET /labels?s=
`.
* • an empty label list comes back as JSON `null`, not `[]`.
* • a comment is `PUT /tasks/{id}/comments`, not POST.
* • MOVING A CARD IS NOT A FIELD WRITE. There is no task.status. A board
* column is a KANBAN BUCKET on a VIEW: resolve the project's kanban view,
* match the bucket by title, then POST the task into it. This is the single
* most surprising thing about the API and the reason `vikunja_move_task`
* exists as its own verb rather than as an argument to update.
* • `identifier` ('#1') is per-project, NOT globally unique — address tasks by
* their numeric id.
* • `description` is HTML when it was edited in the UI — strip tags on read.
*
* AUTH. `resolveIntegrationToken('vikunja')` returns BOTH halves — `{token,
* instanceUrl}` — because a credential alone cannot address a board. Same
* resolution order and the same error semantics as the tracker: a connected row
* that somehow carries no instance says exactly that, rather than letting the
* next call fail and blaming the token.
*/
/** For tests: forget the memoized credentials. */
export declare function clearVikunjaCredsCache(): void;
/**
* Vikunja stores descriptions and comments as Tiptap HTML. Both directions go
* through ONE grammar (`lib/markup.ts`): Markdown the model writes → HTML the
* board renders; HTML the board holds → Markdown the model reads. Same module
* the Jira skill uses, so a body reads the same off either tracker.
*/
export declare function vkPlainText(html: any): string;
/** Markdown → the HTML Vikunja's editor renders. */
export declare function vkRichHtml(markdown: any): string;
/** Vikunja priority is 0-5; accept the words a human (or a model) would use. */
export declare function vkPriority(p: any): number | null;
export declare const vikunjaSkill: any;