/** * Pure tree formatter — presentation-agnostic dependency tree rendering. * * Exports {@link formatTree} which renders a flat tree node array into one of * four output modes (rich, json, markdown, quiet) without importing any CLI * or platform-specific module. ANSI colors are injected by the caller via * the optional `colorize` callback so that this module remains dependency-free * of terminal utilities. * * @module */ /** * Output mode for {@link formatTree}. * * - `'rich'` — Terminal-friendly output with ASCII/Unicode connectors, * status symbols, priority color (via {@link FormatOpts.colorize}), * and blocker indicators. * - `'json'` — Returns `JSON.stringify({ tree: nodes })` for machine * consumers that already have the data payload. * - `'markdown'` — GitHub-flavored Markdown: indented list with `[status]` * prefix and no ANSI sequences. * - `'quiet'` — ASCII connector hierarchy with ID as the last token on each * line, safe for `awk '{print $NF}'` extraction. */ export type FormatMode = 'rich' | 'json' | 'markdown' | 'quiet'; /** * Color style tokens passed to {@link FormatOpts.colorize}. * * The core formatter never applies ANSI directly — it hands style tokens to * the caller-supplied `colorize` function. CLI renderers inject ANSI; Studio * or API callers can inject HTML classes or return the text verbatim. */ export type ColorStyle = 'bold' | 'dim' | 'red' | 'green' | 'yellow' | 'blue' | 'magenta' | 'cyan' | 'reset'; /** * Connector characters used when drawing the ASCII/Unicode tree. * * Override to use plain ASCII on terminals that do not support Unicode * box-drawing, or to use a different visual style. */ export interface TreeConnectors { /** Branch connector — not the last child: `├── ` */ branch: string; /** Last child connector: `└── ` */ last: string; /** Vertical pipe continuation: `│ ` */ vertical: string; /** Empty continuation (after last child): ` ` */ space: string; } /** * Options for {@link formatTree}. */ export interface FormatOpts { /** * Output mode. * * @defaultValue `'rich'` */ mode?: FormatMode; /** * Color injection callback. * * Called as `colorize(text, style)`. The default implementation is the * identity function (returns `text` unchanged) so core output is plain when * no colorize is provided. * * CLI renderers inject ANSI via the `colors.ts` helper; Studio callers may * inject CSS class names or simply omit this option. * * @example * // CLI usage — inject ANSI via colors helper * const output = formatTree(nodes, { * colorize: (text, style) => applyAnsi(text, style), * }); */ colorize?: (text: string, style: ColorStyle) => string; /** * Connector overrides for the ASCII/Unicode tree skeleton. * * Only the `connectors` subkey is supported; future subkeys may be added * here without breaking the interface. */ symbols?: { connectors?: Partial; }; /** * When `true`, each task in the tree output has its direct dependency chain * inlined below it (all four modes). * * - `rich` — indented dim line `← depends on: T1195 (done), T1198 (pending)` * - `markdown` — nested ` - depends on: [T1195](#T1195), [T1198](#T1198)` list item * - `json` — `depends` array already present on each node (no change needed) * - `quiet` — skipped (quiet mode is for scripts that want IDs only) * * Only tasks that have at least one entry in their `depends` array emit a * dep line. Tasks with an empty `depends` array emit nothing extra. * * @defaultValue `false` */ withDeps?: boolean; /** * When `true`, each blocked task in the tree output has its transitive * blocker chain rendered below it. * * The `blockerChain` and `leafBlockers` fields must already be populated on * the nodes (via `coreTaskTree(..., true)` at the data layer). * * Per-mode behaviour: * - `rich` — indented dim lines with `↳ chain:` arrow notation and a * distinct color for leaf blockers (cyan). * - `markdown` — nested list items ` - blocker chain: T200 → T198 → T199 (leaf)`. * - `json` — `blockerChain` and `leafBlockers` arrays are already embedded * on each node; no extra rendering needed. * - `quiet` — skipped (scripts should use `--format json` for chain data). * * Only nodes whose `blockerChain` is non-empty emit chain lines. * * Compatible with `withDeps`: when both flags are set, the dep line is * rendered first, followed by the blocker chain lines. * * @defaultValue `false` * * @example * ```typescript * const out = formatTree(nodes, { mode: 'rich', withBlockers: true }); * // ↳ chain: T1200 → T1198 → T1199 (leaf) * ``` */ withBlockers?: boolean; } /** * A single node in the flat tree array produced by `tasks.tree`. * * Children are embedded directly in the node rather than being a separate * lookup table so that recursive rendering is straightforward. */ export interface FlatTreeNode { /** Task identifier, e.g. `"T001"`. */ id: string; /** Human-readable task title. */ title: string; /** Task status string, e.g. `"pending"`, `"active"`, `"done"`. */ status: string; /** Task priority string, e.g. `"critical"`, `"high"`, `"medium"`, `"low"`. */ priority?: string; /** * Raw direct dependency IDs from the task record. * * All dep IDs are listed here regardless of the referenced task's status. * Use {@link blockedBy} for the subset that are still open. * Populated by Wave 2 (T1199) enrichment in `buildTreeNode`. */ depends?: string[]; /** Open dependency IDs blocking this task. Present after T1199 enrichment. */ blockedBy?: string[]; /** * Whether the task is immediately actionable (no open deps, not yet done). * Present after T1199 enrichment. */ ready?: boolean; /** * Full transitive blocker chain for this task. * * Every open dependency reachable by walking the `depends` graph upstream * (deduplicated, cycle-safe). Only present when `withBlockers` was * requested at tree-build time (T1206). */ blockerChain?: string[]; /** * Leaf-level blockers — root-cause tasks that must be resolved first. * * A subset of `blockerChain` whose own dependencies are all resolved (or * that have no dependencies). Only present when `withBlockers` was * requested at tree-build time (T1206). */ leafBlockers?: string[]; /** Nested child nodes. */ children?: FlatTreeNode[]; } /** * Format a flat tree node array as a string in the requested mode. * * The function is pure — it has no side-effects and does not read from * `process.env` or the filesystem. All terminal concerns are delegated to * the caller through {@link FormatOpts.colorize}. * * @param nodes - Array of {@link FlatTreeNode} objects (top-level children of * the tree root). May be empty — returns `''` in quiet mode * and `'No tree data.'` in other modes. * @param opts - Rendering options. All fields are optional. * @returns A formatted string in the requested mode. * * @example * // Rich mode — plain text (no colorize), Unicode connectors * const plain = formatTree(nodes, { mode: 'rich' }); * * @example * // Rich mode — with ANSI color injection * const colored = formatTree(nodes, { * mode: 'rich', * colorize: (text, style) => applyAnsi(text, style), * }); * * @example * // JSON mode — machine-readable passthrough * const json = formatTree(nodes, { mode: 'json' }); * const parsed = JSON.parse(json); // { tree: [...] } * * @example * // Markdown mode — for GitHub issue comments * const md = formatTree(nodes, { mode: 'markdown' }); * * @example * // Quiet mode — IDs only, hierarchy preserved, safe for awk * const quiet = formatTree(nodes, { mode: 'quiet' }); */ export declare function formatTree(nodes: FlatTreeNode[], opts?: FormatOpts): string; //# sourceMappingURL=tree.d.ts.map