/**
* `/kanban` — Open the project kanban panel and perform common board/task
* operations from the TUI composer.
*
* Subcommands (no subcommand → opens the kanban panel):
*
* /kanban — open the project kanban panel
* /kanban create
— create a new board, then open the panel
* /kanban add [--column X] [--desc ] — add a task to the active board (managed boards require --desc)
* /kanban use — open the kanban panel on a specific board
* /kanban boards — list every board in the project
* /kanban health — show kanban queue health summary
* /kanban audit [boardId|all] — show kanban cleaner audit (KanbanAuditSummary)
* /kanban help — show usage
*
* The slash command intentionally mirrors the WebUI `kanban` surface so
* users can perform the same operations in either surface. The TUI panel
* remains the rich interactive view (navigate, move, assign); this command
* is the text-first equivalent for when the panel is closed.
*/
import type { SlashCommand } from '@wrongstack/core/types';
import type { KanbanBoardSummary, KanbanBoundaryAccess, KanbanBoundaryPolicy, KanbanBoundarySelectorKind, KanbanQueueHealth } from '@wrongstack/kanban';
import { type KanbanAuditSummary } from './kanban-audit.js';
/**
* Result of resolving the board that an `add` operation should target.
*
* `KanbanPanel` resolves the active board from the session tag
* (`session:`) and falls back to the most-recently-updated board.
* We mirror that exact precedence so a `/kanban add` issued while the panel
* is open lands on the same board the user is looking at.
*/
export interface KanbanAddTarget {
boardId: string;
boardTitle: string;
/** Column that the task will be placed in. Defaults to the first column. */
columnId: string;
/**
* Whether the board enforces the managed Kanban Agent lifecycle. Managed
* boards require new cards to be created in the Backlog column and with a
* description, so callers route the user accordingly.
*/
managed: boolean;
}
export interface KanbanSlashDeps {
/**
* Absolute project root used by the kanban file store. Must match the
* value `KanbanPanel` reads from `agent.ctx.projectRoot` — using
* `agent.ctx.cwd` would diverge when the user launches the TUI from a
* subdirectory of the project.
*/
projectRoot: string;
/** Optional session id; when present, prefer a `session:`-tagged board. */
sessionId?: string | null | undefined;
/**
* Panel-open bridge installed by `App`. Calling `onPanelOpen.current(...)`
* with `'toggleKanbanPanel'` opens the kanban panel — same mechanism the
* other slash commands use. When absent, slash command returns text-only.
*/
onPanelOpen?: {
current: ((action: string) => boolean) | null;
} | undefined;
/**
* Optional hook that selects a specific board in the kanban panel. Used
* by `/kanban use ` and the Goal → Kanban bridge.
* The callback receives a board id and returns true on success.
*/
onBoardFocus?: {
current: ((boardId: string) => boolean) | null;
} | undefined;
/** Terminal width (cols) for help / boards table rendering. */
terminalWidth?: number | undefined;
}
export declare function createKanbanSlashCommand(deps: KanbanSlashDeps): SlashCommand;
export type ParsedKanbanArgs = {
kind: 'open';
} | {
kind: 'help';
} | {
kind: 'boards';
} | {
kind: 'create';
title: string;
} | {
kind: 'add';
title: string;
column: string | null;
description?: string | undefined;
} | {
kind: 'use';
query: string;
} | {
kind: 'health';
} | {
kind: 'audit';
boardQuery: string;
} | {
kind: 'boundary';
boardQuery: string;
action: 'show' | 'allow' | 'deny' | 'clear';
taskQuery?: string | undefined;
selectorKind?: KanbanBoundarySelectorKind | undefined;
access?: KanbanBoundaryAccess | undefined;
path?: string | undefined;
enforcement?: KanbanBoundaryPolicy['enforcement'] | undefined;
shellAccess?: KanbanBoundaryPolicy['shellAccess'] | undefined;
};
/**
* Parse the raw `args` string (everything after `/kanban`) into a tagged
* union. Exported so tests can exercise the grammar in isolation.
*
* Grammar (whitespace-separated; quoted titles supported for the `create`
* subcommand):
*
* args ::= ε | "help" | "boards" | "create" title
* | "add" title ("--" "column" columnId)?
* title ::= token+
* columnId ::= token
*/
export declare function parseKanbanArgs(raw: string): ParsedKanbanArgs;
/**
* Resolve the board that an `/kanban add` should target, matching the
* precedence used by `KanbanPanel`:
*
* 1. The board tagged with `session:` (when a session id is known).
* 2. The most-recently-updated board (sort by `updatedAt` desc).
*
* If `column` is given, prefer a column whose id or title matches. The match is
* case-insensitive and falls back to the first column when nothing matches.
*
* Exported so tests can validate the precedence rules against fixture boards.
*/
export declare function resolveAddTarget(deps: Pick, column: string | null): Promise;
/**
* Resolve a user-supplied board query to a specific board. Three match
* strategies are tried in order:
*
* 1. **Exact id match** — fastest, never ambiguous.
* 2. **Exact title match** (case-insensitive) — what `/kanban use Sprint 2`
* should hit when the user types the title verbatim.
* 3. **Tag match** — for `goal:` or `session:` tags so the
* Goal → Kanban bridge can navigate by tag without knowing the id.
*
* Returns null when no summary matches. The caller can then surface a
* helpful error pointing at `/kanban boards`.
*/
export declare function resolveBoardByQuery(deps: Pick, query: string): Promise;
/**
* Render the kanban queue health report as a compact markdown block.
* Surfaces the same Sprint-2 fields the WebUI's `KanbanView` shows
* (dependencyBlocked, staleAssignments, failedRetryable, heartbeatDue)
* plus per-status counts and the last dispatch / last recovery stamps.
*/
export declare function renderHealthReport(health: KanbanQueueHealth): string;
/**
* Render the Kanban Cleaner audit across the project. Mirrors the WebUI
* `KanbanCleanerAlert` vocabulary so a user running either surface gets
* the same findings.
*
* Two modes:
* - `boardQuery` empty → audit every board (per-board table).
* - `boardQuery` present → audit the single matching board, or report
* a clear "not found" error.
*
* Each board's row shows the issue counts (error · warning) and the
* top-3 issues, biasing toward error severity first.
*/
export declare function renderProjectAudit(deps: Pick, boardQuery: string): Promise;
/**
* Render a board-row table from a list of audited boards. The output
* is a compact markdown block suitable for the slash composer.
*
* When `multi` is true (audit-all mode) each row is prefixed with the
* board title; in single-board mode the title appears once as a header.
*/
export declare function renderAuditReport(rows: ReadonlyArray<{
title: string;
summary: KanbanAuditSummary;
error?: string;
}>, multi: boolean): string;
/**
* Render a compact boards table. Width-aware so a 60-col terminal still gets
* useful output (column titles truncated, counts abbreviated).
*/
export declare function renderBoardsList(boards: readonly KanbanBoardSummary[], width?: number): string;
//# sourceMappingURL=kanban-slash.d.ts.map