@wrongstack/tui 0.289.0 → 0.291.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/dist/app-initial-state.d.ts +5 -1
  2. package/dist/app-initial-state.d.ts.map +1 -1
  3. package/dist/app-props.d.ts +6 -0
  4. package/dist/app-props.d.ts.map +1 -1
  5. package/dist/app-reducer.d.ts.map +1 -1
  6. package/dist/app-state.d.ts +50 -0
  7. package/dist/app-state.d.ts.map +1 -1
  8. package/dist/app.d.ts +1 -1
  9. package/dist/app.d.ts.map +1 -1
  10. package/dist/components/agents-monitor.d.ts.map +1 -1
  11. package/dist/components/animation-style.d.ts +29 -0
  12. package/dist/components/animation-style.d.ts.map +1 -1
  13. package/dist/components/clear-confirm-panel.d.ts +35 -0
  14. package/dist/components/clear-confirm-panel.d.ts.map +1 -0
  15. package/dist/components/confirm-prompt.d.ts +2 -1
  16. package/dist/components/confirm-prompt.d.ts.map +1 -1
  17. package/dist/components/exit-confirm-panel.d.ts +28 -0
  18. package/dist/components/exit-confirm-panel.d.ts.map +1 -0
  19. package/dist/components/fleet-panel.d.ts +1 -0
  20. package/dist/components/fleet-panel.d.ts.map +1 -1
  21. package/dist/components/history/banner.d.ts.map +1 -1
  22. package/dist/components/history/index.d.ts.map +1 -1
  23. package/dist/components/history/types.d.ts +6 -0
  24. package/dist/components/history/types.d.ts.map +1 -1
  25. package/dist/components/kanban-panel.d.ts +72 -1
  26. package/dist/components/kanban-panel.d.ts.map +1 -1
  27. package/dist/components/phase-panel.d.ts.map +1 -1
  28. package/dist/components/plugin-picker.d.ts.map +1 -1
  29. package/dist/components/scrollable-history.d.ts.map +1 -1
  30. package/dist/components/settings-picker.d.ts +1 -1
  31. package/dist/components/settings-picker.d.ts.map +1 -1
  32. package/dist/components/slash-confirm-panel.d.ts +14 -0
  33. package/dist/components/slash-confirm-panel.d.ts.map +1 -0
  34. package/dist/components/status-bar-chips.d.ts.map +1 -1
  35. package/dist/components/status-bar.d.ts +5 -1
  36. package/dist/components/status-bar.d.ts.map +1 -1
  37. package/dist/components/statusline-picker.d.ts +6 -4
  38. package/dist/components/statusline-picker.d.ts.map +1 -1
  39. package/dist/components/tools-picker.d.ts.map +1 -1
  40. package/dist/exit-slash.d.ts +40 -0
  41. package/dist/exit-slash.d.ts.map +1 -0
  42. package/dist/f-key-panels.d.ts +3 -1
  43. package/dist/f-key-panels.d.ts.map +1 -1
  44. package/dist/heap-watchdog.d.ts.map +1 -1
  45. package/dist/height-cache.d.ts +5 -0
  46. package/dist/height-cache.d.ts.map +1 -1
  47. package/dist/history-retention.d.ts +20 -0
  48. package/dist/history-retention.d.ts.map +1 -0
  49. package/dist/hooks/use-auth-panel.d.ts +2 -0
  50. package/dist/hooks/use-auth-panel.d.ts.map +1 -1
  51. package/dist/hooks/use-director-fleet-bridge.d.ts +0 -4
  52. package/dist/hooks/use-director-fleet-bridge.d.ts.map +1 -1
  53. package/dist/hooks/use-exit-command.d.ts +55 -0
  54. package/dist/hooks/use-exit-command.d.ts.map +1 -0
  55. package/dist/hooks/use-session-interrupt-controller.d.ts +7 -0
  56. package/dist/hooks/use-session-interrupt-controller.d.ts.map +1 -1
  57. package/dist/hooks/use-subagent-events.d.ts +0 -3
  58. package/dist/hooks/use-subagent-events.d.ts.map +1 -1
  59. package/dist/hooks/use-tui-activity.d.ts +2 -0
  60. package/dist/hooks/use-tui-activity.d.ts.map +1 -1
  61. package/dist/hooks/use-tui-event-bridge.d.ts +1 -0
  62. package/dist/hooks/use-tui-event-bridge.d.ts.map +1 -1
  63. package/dist/index.js +4660 -1935
  64. package/dist/index.js.map +4 -4
  65. package/dist/input-validation.d.ts +263 -0
  66. package/dist/input-validation.d.ts.map +1 -0
  67. package/dist/kanban-audit.d.ts +116 -0
  68. package/dist/kanban-audit.d.ts.map +1 -0
  69. package/dist/kanban-slash.d.ts +178 -0
  70. package/dist/kanban-slash.d.ts.map +1 -0
  71. package/dist/run-tui.d.ts +11 -0
  72. package/dist/run-tui.d.ts.map +1 -1
  73. package/dist/submit-history.d.ts +9 -6
  74. package/dist/submit-history.d.ts.map +1 -1
  75. package/package.json +7 -7
@@ -0,0 +1,263 @@
1
+ /**
2
+ * Central input validation for the TUI.
3
+ *
4
+ * EVERY external data source that crosses a trust boundary passes through
5
+ * this module. Uses an **allow-list** approach: define the exact allowed
6
+ * shape, types, ranges, and formats for each input; reject everything else.
7
+ *
8
+ * ── Trust boundaries ─────────────────────────────────────────────────
9
+ *
10
+ * Boundary | Source | Validator
11
+ * ------------------|---------------------|--------------------------
12
+ * stdin | terminal emulator | validateStdinFragment()
13
+ * paste | bracketed-paste | validatePasteContent()
14
+ * AppProps | CLI host | validateAppProps()
15
+ * Reducer Action | handleKey dispatch | validateAction()
16
+ * Host callbacks | CLI/plugin return | validateCallbackReturn()
17
+ * Mouse events | SGR protocol | validateMouseEvent()
18
+ * Fleet telemetry | Director/FleetBus | validateFleetEntry()
19
+ * Restore data | session JSONL | validateRestoreEntry()
20
+ *
21
+ * ── Rejection over coercion ──────────────────────────────────────────
22
+ *
23
+ * This module **rejects** invalid input rather than coercing it, for
24
+ * three reasons:
25
+ *
26
+ * 1. **Coercion masks injection.** Trimming whitespace from a string
27
+ * that contains an ANSI escape sequence leaves the sequence intact.
28
+ * 2. **Semantic gap.** Coercing a value (e.g. clamping a PID to a valid
29
+ * range) creates a gap between what was validated and what the
30
+ * application actually uses — a future code path may use the raw
31
+ * value, not the clamped one.
32
+ * 3. **Predictable failure.** Silent data transformation makes security
33
+ * debugging harder — rejection produces a clear error at the point
34
+ * of violation; coercion produces subtly wrong behavior downstream.
35
+ *
36
+ * The single exception is **normalization before comparison**: trimming
37
+ * whitespace from an enum label before comparing it to the allow-list
38
+ * prevents trivial bypasses (e.g. `" off "` vs `"off"`). This is
39
+ * NOT the same as coercing the input — the normalized comparison only
40
+ * determines allow/deny; the caller receives the original value.
41
+ *
42
+ * ── Conventions ──────────────────────────────────────────────────────
43
+ *
44
+ * - Every `validate*` function returns `ValidationResult<T>`:
45
+ * `{ valid: true; value: T }` — the validated, ready-to-use value
46
+ * `{ valid: false; error: string }` — a specific, actionable message
47
+ * - Every error message follows the pattern:
48
+ * `"{path}": {what went wrong} ({detail}).`
49
+ * - Size limits are defined as module-level constants with doc comments.
50
+ * - Enum/union allow-lists are defined as `const` arrays and kept in
51
+ * ONE place so the allowed set is auditable.
52
+ */
53
+ export interface ValidationOk<T> {
54
+ valid: true;
55
+ value: T;
56
+ }
57
+ export interface ValidationError {
58
+ valid: false;
59
+ error: string;
60
+ }
61
+ export type ValidationResult<T> = ValidationOk<T> | ValidationError;
62
+ /** Maximum length of a single input line from stdin (before Enter). */
63
+ export declare const MAX_INPUT_BUFFER_CHARS = 100000;
64
+ /** Maximum size of a single paste operation (prevents OOM from 10MB paste). */
65
+ export declare const MAX_PASTE_CHARS = 50000;
66
+ /** Maximum length of a single history entry text payload. */
67
+ export declare const MAX_ENTRY_TEXT_CHARS = 500000;
68
+ /** Maximum entries in the history array (matches history-retention.ts). */
69
+ export declare const MAX_HISTORY_ENTRIES = 400;
70
+ /** Maximum actions in a fleetBatch dispatch (prevents render-thrashing). */
71
+ export declare const MAX_BATCHED_ACTIONS = 500;
72
+ /** Maximum length of a single action payload string field. */
73
+ export declare const MAX_ACTION_STRING_FIELD = 10000;
74
+ /** Maximum subagents tracked in fleet state. */
75
+ export declare const MAX_FLEET_ENTRIES = 200;
76
+ /** Maximum tools tracked per-subagent. */
77
+ export declare const MAX_RECENT_TOOLS = 100;
78
+ /** Maximum messages tracked per-subagent. */
79
+ export declare const MAX_RECENT_MESSAGES = 50;
80
+ /** Maximum depth of nested action payload objects. */
81
+ export declare const MAX_ACTION_DEPTH = 8;
82
+ /** Maximum characters in a paste fragment (single stdin chunk). */
83
+ export declare const MAX_PASTE_FRAGMENT_CHARS = 100000;
84
+ /** Maximum length for any host-provided string (model, provider, etc). */
85
+ export declare const MAX_HOST_STRING_FIELD = 500;
86
+ /** Maximum entries in a picker matches list. */
87
+ export declare const MAX_PICKER_MATCHES = 500;
88
+ /** Known reducer action types — the authoritative allow-list. */
89
+ export declare const ALLOWED_ACTION_TYPES: readonly ['addEntry', 'compactHistory', 'setBuffer', 'clearInput', 'clearHistory', 'replaceHistory', 'replaceEntry', 'historyRoll', 'setHistoryIndex', 'setHistoryDraft', 'scrollBy', 'scrollTo', 'scrollPage', 'scrollToBottom', 'scrollToTop', 'setMeasuredLines', 'setViewportRows', 'pickerOpen', 'pickerMove', 'pickerClose', 'pickerQuery', 'pickerSetMatches', 'slashPickerOpen', 'slashPickerMove', 'slashPickerClose', 'slashPickerQuery', 'slashPickerSetMatches', 'modelPickerOpen', 'modelPickerMove', 'modelPickerClose', 'modelPickerSelect', 'modelPickerSetProviders', 'autonomyPickerOpen', 'autonomyPickerMove', 'autonomyPickerClose', 'autonomyPickerSelect', 'cancelSend', 'submit', 'afterSubmit', 'streamStart', 'streamToken', 'streamToolUse', 'streamToolResult', 'streamEnd', 'setMode', 'toggleHelp', 'toggleMonitor', 'toggleAgentsMonitor', 'toggleTodosMonitor', 'toggleQueuePanel', 'toggleProcessList', 'toggleCronMonitor', 'toggleAuditPanel', 'togglePlanPanel', 'closeAllPanels', 'toggleKanbanPanel', 'toggleGoalPanel', 'toggleGoalKanbanPanel', 'toggleContextPanel', 'toggleSessionsPanel', 'sessionsPanelSet', 'sessionsPanelMove', 'sessionsPanelBusy', 'sessionResumeConfirmSet', 'sessionResumeConfirmClear', 'settingsPickerOpen', 'settingsPickerMove', 'settingsPickerClose', 'settingsPick', 'statuslinePickerOpen', 'statuslinePickerMove', 'statuslinePickerClose', 'pluginPickerOpen', 'pluginPickerMove', 'pluginPickerClose', 'mcpPickerOpen', 'mcpPickerMove', 'mcpPickerClose', 'toolsPickerOpen', 'toolsPickerMove', 'toolsPickerClose', 'projectPickerOpen', 'projectPickerMove', 'projectPickerClose', 'projectPickerSelect', 'projectPickerSetItems', 'fKeyPickerOpen', 'fKeyPickerMove', 'fKeyPickerClose', 'confirmPromptOpen', 'confirmPromptClose', 'clearConfirmOpen', 'clearConfirmClose', 'clearConfirmSetValue', 'exitConfirmOpen', 'exitConfirmClose', 'slashConfirmOpen', 'slashConfirmClose', 'escConfirmOpen', 'escConfirmClose', 'sendModePickerOpen', 'sendModePickerMove', 'sendModePickerClose', 'resetContextChip', 'fleetSeed', 'fleetSpawn', 'fleetToolStart', 'fleetToolEnd', 'fleetStart', 'fleetDelta', 'fleetMessage', 'fleetTool', 'fleetUsage', 'fleetDone', 'fleetRemove', 'fleetBudgetWarning', 'fleetBudgetExtended', 'fleetCtxPct', 'fleetCost', 'fleetConcurrency', 'fleetBatch', 'leaderIterStart', 'leaderIterEnd', 'leaderToolStart', 'leaderToolEnd', 'leaderCtxPct', 'setFleetChat', 'enhanceOpen', 'enhanceClose', 'enhanceBusy', 'enhanceBusyDone', 'enhanceResult', 'enhanceCancel', 'enhanceDismiss', 'refineFailureOpen', 'refineFailureClose', 'continueConfirmOpen', 'continueConfirmClose', 'checkpointReceived', 'rewindOverlayOpen', 'rewindOverlayClose', 'rewindOverlayMove', 'setDeadline', 'setLiveProvider', 'setLiveModel', 'setCapability', 'setDesignKit', 'setAnimationStyle', 'setEffectiveMaxContext', 'setStreamingText', 'setToolStream', 'toolStreamClear', 'setThinkingWord', 'setFleetVerbosity', 'setAutonomyMode', 'setSendMode', 'setSteering', 'setSteeringPending', 'clearSteering', 'setGoalText', 'setGoalPanelGoal', 'showGoal', 'goalSummary', 'goalRunInit', 'goalRunPhaseUpdate', 'goalRunRunningPhases', 'goalRunElapsed', 'goalRunTaskActive', 'goalRunMonitorToggle', 'goalRunReset', 'sddBoardSnapshot', 'toggleSddBoardMonitor', 'sddBoardFocusNext', 'sddBoardFocusPrev', 'worktreeUpsert', 'worktreeRemove', 'toggleWorktreeMonitor', 'collabBugFound', 'collabPlanEmitted', 'collabEvalComplete', 'collabSessionDone', 'collabSubagentSpawned', 'debugStreamStats', 'debugStreamStatsClear', 'countdownTick', 'countdownEnded', 'coordinatorEvent', 'toggleCoordinatorMonitor', 'setEnhancedPrompt', 'enhanceConfirmOpen', 'enhanceConfirmClose', 'setShowModelReasoning'];
90
+ export type AllowedActionType = (typeof ALLOWED_ACTION_TYPES)[number];
91
+ /** History entry kinds that carry text (must be non-empty to be stored). */
92
+ export declare const TEXT_BEARING_ENTRY_KINDS: Set<string>;
93
+ /** All valid history entry kinds. */
94
+ export declare const ALLOWED_ENTRY_KINDS: Set<string>;
95
+ /** Fleet subagent status values. */
96
+ export declare const ALLOWED_FLEET_STATUSES: Set<string>;
97
+ /** Mouse event kinds */
98
+ export declare const ALLOWED_MOUSE_KINDS: Set<string>;
99
+ /** Mouse buttons */
100
+ export declare const ALLOWED_MOUSE_BUTTONS: Set<string>;
101
+ /** Keyboard modifier keys. */
102
+ export declare const ALLOWED_KEY_EVENT_FIELDS: Set<string>;
103
+ /** Scroll direction for scrollPage. */
104
+ export declare const ALLOWED_SCROLL_DIRS: Set<string>;
105
+ /** Autonomy mode values. */
106
+ export declare const ALLOWED_AUTONOMY_MODES: Set<string>;
107
+ /** Known send modes. */
108
+ export declare const ALLOWED_SEND_MODES: Set<string>;
109
+ /** FleetChat verbosity modes. */
110
+ export declare const ALLOWED_FLEET_CHAT_MODES: Set<string>;
111
+ /** SDD lifecycle ops. */
112
+ export declare const ALLOWED_SDD_OPS: Set<string>;
113
+ /** Project picker item kinds. */
114
+ export declare const ALLOWED_PICKER_KINDS: Set<string>;
115
+ /** Collaboration verdicts. */
116
+ export declare const ALLOWED_COLLAB_VERDICTS: Set<string>;
117
+ /** Known terminal capability keys. */
118
+ export declare const ALLOWED_CAPABILITY_FIELDS: Set<string>;
119
+ /**
120
+ * Validate a keyboard input fragment from stdin.
121
+ *
122
+ * This catches raw bytes from the terminal BEFORE they enter the input
123
+ * buffer. The allow-list is: known control sequences, printable ASCII,
124
+ * and common Unicode (which terminals emit as normal keystrokes).
125
+ *
126
+ * Rejects:
127
+ * - Raw escape sequences that don't match known patterns
128
+ * - Fragments containing C0 control chars other than tab/newline (0x09, 0x0a)
129
+ * - Fragments longer than MAX_PASTE_FRAGMENT_CHARS (likely a flood)
130
+ */
131
+ export declare function validateStdinFragment(data: Buffer | string): ValidationResult<string>;
132
+ /**
133
+ * Validate a fully-assembled paste payload AFTER the terminal markers
134
+ * have been stripped by paste-accumulator.ts.
135
+ *
136
+ * Rejects:
137
+ * - Paste > MAX_PASTE_CHARS
138
+ * - Paste containing C0 control chars (except \n, \t)
139
+ * - Paste that looks binary (>30% non-printable)
140
+ * - Paste with unbalanced surrogate pairs
141
+ */
142
+ export declare function validatePasteContent(content: string): ValidationResult<string>;
143
+ /**
144
+ * Validate a parsed mouse event from the SGR protocol.
145
+ *
146
+ * Rejects:
147
+ * - Unknown mouse event kinds
148
+ * - Unknown button values
149
+ * - Coordinates outside reasonable terminal bounds (0 < x < 5000, 0 < y < 5000)
150
+ * - Wheel values other than -1, 0, 1
151
+ */
152
+ export declare function validateMouseEvent(event: {
153
+ kind: string;
154
+ button: string;
155
+ x: number;
156
+ y: number;
157
+ wheel: number;
158
+ shift?: boolean;
159
+ meta?: boolean;
160
+ ctrl?: boolean;
161
+ motion?: boolean;
162
+ }): ValidationResult<{
163
+ kind: string;
164
+ button: string;
165
+ x: number;
166
+ y: number;
167
+ wheel: number;
168
+ shift: boolean;
169
+ meta: boolean;
170
+ ctrl: boolean;
171
+ motion: boolean;
172
+ }>;
173
+ /**
174
+ * Validate a KeyEvent from stdin against the known allow-list.
175
+ *
176
+ * Every boolean field in a KeyEvent must be exactly `true` or `false`.
177
+ * `fn` must be 1–12 when present. `wheelDeltaY` must be an integer.
178
+ *
179
+ * Rejects:
180
+ * - Unknown fields on the key event object
181
+ * - Non-boolean values for boolean fields
182
+ * - fn outside 1–12
183
+ * - wheelDeltaY that is not an integer
184
+ */
185
+ export declare function validateKeyEventFields(key: Record<string, unknown>): ValidationResult<Record<string, unknown>>;
186
+ /**
187
+ * Validate a reducer Action before dispatch.
188
+ *
189
+ * This is the central gate for all state mutations. EVERY dispatch from
190
+ * external sources (keyboard, host callbacks, fleet events, restore data)
191
+ * should run through this before reaching the reducer.
192
+ *
193
+ * Rejects:
194
+ * - Unknown action types
195
+ * - Malformed payload types
196
+ * - Oversized strings/arrays
197
+ * - Out-of-range numeric values
198
+ * - Deeply nested payloads (prototype poison / DoS)
199
+ */
200
+ export declare function validateAction(action: {
201
+ type: string;
202
+ [key: string]: any;
203
+ }): ValidationResult<Record<string, unknown>>;
204
+ /**
205
+ * Validate a fleet subagent entry from telemetry.
206
+ *
207
+ * Rejects:
208
+ * - Unknown status
209
+ * - Oversized streamingText
210
+ * - Malformed recent tools/messages arrays
211
+ * - Non-finite cost
212
+ */
213
+ export declare function validateFleetEntry(entry: {
214
+ id: string;
215
+ name: string;
216
+ status: string;
217
+ streamingText?: string;
218
+ iterations?: number;
219
+ toolCalls?: number;
220
+ recentTools?: unknown[];
221
+ recentMessages?: unknown[];
222
+ cost?: number;
223
+ }): ValidationResult<Record<string, unknown>>;
224
+ /**
225
+ * Validate a restored session entry (from JSONL).
226
+ *
227
+ * Rejects:
228
+ * - Non-object entries
229
+ * - Unknown entry kinds
230
+ * - Oversized payloads
231
+ */
232
+ export declare function validateRestoreEntry(entry: unknown, index: number): ValidationResult<Record<string, unknown>>;
233
+ /**
234
+ * Validate that an action dispatch is safe for the reducer.
235
+ * This is a convenience wrapper used at the dispatch boundary.
236
+ * Returns the original action untouched if valid, or throws with the
237
+ * specific error message if invalid.
238
+ *
239
+ * In production, the caller can log the error and drop the action
240
+ * instead of crashing — but for security boundaries, throwing is the
241
+ * safe default because it prevents any partially-valid state from
242
+ * reaching the reducer.
243
+ */
244
+ export declare function ensureValidAction(action: {
245
+ type: string;
246
+ [key: string]: any;
247
+ }): Record<string, unknown>;
248
+ /**
249
+ * Safe dispatch wrapper: validates the action, then calls dispatch
250
+ * only if validation passes. Returns true if dispatched, false if rejected
251
+ * (with the error logged).
252
+ */
253
+ export declare function safeDispatch(action: {
254
+ type: string;
255
+ [key: string]: any;
256
+ }, dispatch: (action: Record<string, unknown>) => void): boolean;
257
+ /**
258
+ * Normalize a string by trimming whitespace.
259
+ * This is the ONLY normalization we do — and it's only used for
260
+ * allow-list comparison, never for the returned value.
261
+ */
262
+ export declare function normalizedEquals(a: string, b: string): boolean;
263
+ //# sourceMappingURL=input-validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input-validation.d.ts","sourceRoot":"","sources":["../src/input-validation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,116 @@
1
+ /**
2
+ * `kanban-audit.ts` — Pure, dependency-free Kanban Cleaner audit for the TUI.
3
+ *
4
+ * Mirrors the WebUI's `packages/webui/src/lib/kanban-cleaner.ts` but
5
+ * lives in the TUI package so we don't have to thread `@wrongstack/webui`
6
+ * (which depends on React) into a server-side TUI pipeline. The two
7
+ * implementations intentionally share the same audit-code vocabulary
8
+ * (10 codes) and severity levels (`error`, `warning`) so a board audited
9
+ * from either surface produces the same findings.
10
+ *
11
+ * The output of `auditKanbanBoard()` feeds the TUI panel header badge so
12
+ * users see Cleaner warnings inline — mirroring the WebUI's
13
+ * `KanbanCleanerAlert` component, but inline-pinned to the project root.
14
+ */
15
+ import type { KanbanBoard } from '@wrongstack/kanban';
16
+ export type KanbanAuditSeverity = 'error' | 'warning';
17
+ export type KanbanAuditIssueCode = 'missing-description' | 'missing-assignee' | 'missing-due-date' | 'missing-labels' | 'missing-subtasks' | 'missing-success-criteria' | 'skipped-lifecycle-state' | 'abandoned-running-task' | 'stale-running-task' | 'stale-review';
18
+ export interface KanbanAuditIssue {
19
+ id: string;
20
+ taskId: string;
21
+ taskTitle: string;
22
+ code: KanbanAuditIssueCode;
23
+ severity: KanbanAuditSeverity;
24
+ message: string;
25
+ }
26
+ export interface KanbanAuditSummary {
27
+ /** Wall-clock time the audit ran (ISO-8601). Used by the renderer to
28
+ * label the report and by tests to pin the audit's age. */
29
+ generatedAt: string;
30
+ /** IDs of every board this summary aggregated across. */
31
+ boardIds: readonly string[];
32
+ /** Aggregate severity counters. */
33
+ counts: Readonly<Record<KanbanAuditSeverity, number>>;
34
+ /** Detail buckets surfaced by the WebUI Cleaner `KanbanCleanerAlert`.
35
+ * Each entry lists the tasks that triggered the signal. */
36
+ dependencyBlocked: {
37
+ count: number;
38
+ tasks: ReadonlyArray<{
39
+ board: {
40
+ title: string;
41
+ };
42
+ task: {
43
+ title: string;
44
+ };
45
+ }>;
46
+ };
47
+ staleAssignments: {
48
+ count: number;
49
+ tasks: ReadonlyArray<{
50
+ board: {
51
+ title: string;
52
+ };
53
+ task: {
54
+ title: string;
55
+ };
56
+ }>;
57
+ };
58
+ failedRetryable: {
59
+ count: number;
60
+ tasks: ReadonlyArray<{
61
+ board: {
62
+ title: string;
63
+ };
64
+ task: {
65
+ title: string;
66
+ };
67
+ }>;
68
+ };
69
+ heartbeatDue: {
70
+ count: number;
71
+ tasks: ReadonlyArray<{
72
+ board: {
73
+ title: string;
74
+ };
75
+ task: {
76
+ title: string;
77
+ };
78
+ }>;
79
+ };
80
+ /** Activity stamps for last dispatch / last recovery. */
81
+ lastDispatchedAt: string | undefined;
82
+ lastStaleRecoveredAt: string | undefined;
83
+ /** All issues raised by the audit, sorted error-first. */
84
+ issues: readonly KanbanAuditIssue[];
85
+ /** Distinct task IDs across `issues`. */
86
+ affectedTaskCount: number;
87
+ }
88
+ export interface KanbanAuditOptions {
89
+ /** Explicit time input keeps the audit pure, deterministic, and unit-testable. */
90
+ now: number | Date;
91
+ /** IDs or names of agents currently reported as running by the WebUI fleet roster. */
92
+ liveAgentIdentities?: ReadonlySet<string> | readonly string[] | undefined;
93
+ /** Enable only when the shared Kanban task contract exposes a due date. */
94
+ requireDueDate?: boolean | undefined;
95
+ /** Used when the board has no review-age policy. */
96
+ defaultReviewStaleAfterMs?: number | undefined;
97
+ }
98
+ export declare function auditKanbanBoard(board: KanbanBoard, options: KanbanAuditOptions): KanbanAuditSummary;
99
+ /**
100
+ * Short headline string used by the panel header badge. Returns null when
101
+ * the summary is empty so callers can hide the badge entirely instead of
102
+ * rendering a noisy "0 warnings" chip.
103
+ */
104
+ export declare function summarizeAuditHeadline(summary: KanbanAuditSummary): string | null;
105
+ /**
106
+ * Top-N issues, biased toward `error` severity first. The TUI panel
107
+ * surfaces these inline; the full list is still available via
108
+ * `summary.issues` for tooling.
109
+ *
110
+ * We sort defensively (rather than rely on `auditKanbanBoard`'s in-place
111
+ * order) so callers that hand us a manually-built summary — for example
112
+ * a test fixture, or a future caller that aggregates issues from
113
+ * multiple boards — still get the error-first ordering.
114
+ */
115
+ export declare function topAuditIssues(summary: KanbanAuditSummary, limit?: number): readonly KanbanAuditIssue[];
116
+ //# sourceMappingURL=kanban-audit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kanban-audit.d.ts","sourceRoot":"","sources":["../src/kanban-audit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,178 @@
1
+ /**
2
+ * `/kanban` — Open the project kanban panel and perform common board/task
3
+ * operations from the TUI composer.
4
+ *
5
+ * Subcommands (no subcommand → opens the kanban panel):
6
+ *
7
+ * /kanban — open the project kanban panel
8
+ * /kanban create <title> — create a new board, then open the panel
9
+ * /kanban add <title> [--column X] — add a task to the active board
10
+ * /kanban use <boardId|title|tag> — open the kanban panel on a specific board
11
+ * /kanban boards — list every board in the project
12
+ * /kanban health — show kanban queue health summary
13
+ * /kanban audit [boardId|all] — show kanban cleaner audit (KanbanAuditSummary)
14
+ * /kanban help — show usage
15
+ *
16
+ * The slash command intentionally mirrors the WebUI `kanban` surface so
17
+ * users can perform the same operations in either surface. The TUI panel
18
+ * remains the rich interactive view (navigate, move, assign); this command
19
+ * is the text-first equivalent for when the panel is closed.
20
+ */
21
+ import type { SlashCommand } from '@wrongstack/core';
22
+ import type { KanbanBoundaryAccess, KanbanBoundaryPolicy, KanbanBoundarySelectorKind, KanbanBoardSummary, KanbanQueueHealth } from '@wrongstack/kanban';
23
+ import { type KanbanAuditSummary } from './kanban-audit.js';
24
+ /**
25
+ * Result of resolving the board that an `add` operation should target.
26
+ *
27
+ * `KanbanPanel` resolves the active board from the session tag
28
+ * (`session:<sessionId>`) and falls back to the most-recently-updated board.
29
+ * We mirror that exact precedence so a `/kanban add` issued while the panel
30
+ * is open lands on the same board the user is looking at.
31
+ */
32
+ export interface KanbanAddTarget {
33
+ boardId: string;
34
+ boardTitle: string;
35
+ /** Column that the task will be placed in. Defaults to the first column. */
36
+ columnId: string;
37
+ }
38
+ export interface KanbanSlashDeps {
39
+ /**
40
+ * Absolute project root used by the kanban file store. Must match the
41
+ * value `KanbanPanel` reads from `agent.ctx.projectRoot` — using
42
+ * `agent.ctx.cwd` would diverge when the user launches the TUI from a
43
+ * subdirectory of the project.
44
+ */
45
+ projectRoot: string;
46
+ /** Optional session id; when present, prefer a `session:<id>`-tagged board. */
47
+ sessionId?: string | null | undefined;
48
+ /**
49
+ * Panel-open bridge installed by `App`. Calling `onPanelOpen.current(...)`
50
+ * with `'toggleKanbanPanel'` opens the kanban panel — same mechanism the
51
+ * other slash commands use. When absent, slash command returns text-only.
52
+ */
53
+ onPanelOpen?: {
54
+ current: ((action: string) => boolean) | null;
55
+ } | undefined;
56
+ /**
57
+ * Optional hook that selects a specific board in the kanban panel. Used
58
+ * by `/kanban use <boardId|title|tag>` and the Goal → Kanban bridge.
59
+ * The callback receives a board id and returns true on success.
60
+ */
61
+ onBoardFocus?: {
62
+ current: ((boardId: string) => boolean) | null;
63
+ } | undefined;
64
+ /** Terminal width (cols) for help / boards table rendering. */
65
+ terminalWidth?: number | undefined;
66
+ }
67
+ export declare function createKanbanSlashCommand(deps: KanbanSlashDeps): SlashCommand;
68
+ export type ParsedKanbanArgs = {
69
+ kind: 'open';
70
+ } | {
71
+ kind: 'help';
72
+ } | {
73
+ kind: 'boards';
74
+ } | {
75
+ kind: 'create';
76
+ title: string;
77
+ } | {
78
+ kind: 'add';
79
+ title: string;
80
+ column: string | null;
81
+ } | {
82
+ kind: 'use';
83
+ query: string;
84
+ } | {
85
+ kind: 'health';
86
+ } | {
87
+ kind: 'audit';
88
+ boardQuery: string;
89
+ } | {
90
+ kind: 'boundary';
91
+ boardQuery: string;
92
+ action: 'show' | 'allow' | 'deny' | 'clear';
93
+ taskQuery?: string | undefined;
94
+ selectorKind?: KanbanBoundarySelectorKind | undefined;
95
+ access?: KanbanBoundaryAccess | undefined;
96
+ path?: string | undefined;
97
+ enforcement?: KanbanBoundaryPolicy['enforcement'] | undefined;
98
+ shellAccess?: KanbanBoundaryPolicy['shellAccess'] | undefined;
99
+ };
100
+ /**
101
+ * Parse the raw `args` string (everything after `/kanban`) into a tagged
102
+ * union. Exported so tests can exercise the grammar in isolation.
103
+ *
104
+ * Grammar (whitespace-separated; quoted titles supported for the `create`
105
+ * subcommand):
106
+ *
107
+ * args ::= ε | "help" | "boards" | "create" title
108
+ * | "add" title ("--" "column" columnId)?
109
+ * title ::= token+
110
+ * columnId ::= token
111
+ */
112
+ export declare function parseKanbanArgs(raw: string): ParsedKanbanArgs;
113
+ /**
114
+ * Resolve the board that an `/kanban add` should target, matching the
115
+ * precedence used by `KanbanPanel`:
116
+ *
117
+ * 1. The board tagged with `session:<sessionId>` (when a session id is known).
118
+ * 2. The most-recently-updated board (sort by `updatedAt` desc).
119
+ *
120
+ * If `column` is given, prefer a column whose id or title matches. The match is
121
+ * case-insensitive and falls back to the first column when nothing matches.
122
+ *
123
+ * Exported so tests can validate the precedence rules against fixture boards.
124
+ */
125
+ export declare function resolveAddTarget(deps: Pick<KanbanSlashDeps, 'projectRoot' | 'sessionId'>, column: string | null): Promise<KanbanAddTarget | null>;
126
+ /**
127
+ * Resolve a user-supplied board query to a specific board. Three match
128
+ * strategies are tried in order:
129
+ *
130
+ * 1. **Exact id match** — fastest, never ambiguous.
131
+ * 2. **Exact title match** (case-insensitive) — what `/kanban use Sprint 2`
132
+ * should hit when the user types the title verbatim.
133
+ * 3. **Tag match** — for `goal:<text>` or `session:<id>` tags so the
134
+ * Goal → Kanban bridge can navigate by tag without knowing the id.
135
+ *
136
+ * Returns null when no summary matches. The caller can then surface a
137
+ * helpful error pointing at `/kanban boards`.
138
+ */
139
+ export declare function resolveBoardByQuery(deps: Pick<KanbanSlashDeps, 'projectRoot'>, query: string): Promise<KanbanBoardSummary | null>;
140
+ /**
141
+ * Render the kanban queue health report as a compact markdown block.
142
+ * Surfaces the same Sprint-2 fields the WebUI's `KanbanView` shows
143
+ * (dependencyBlocked, staleAssignments, failedRetryable, heartbeatDue)
144
+ * plus per-status counts and the last dispatch / last recovery stamps.
145
+ */
146
+ export declare function renderHealthReport(health: KanbanQueueHealth): string;
147
+ /**
148
+ * Render the Kanban Cleaner audit across the project. Mirrors the WebUI
149
+ * `KanbanCleanerAlert` vocabulary so a user running either surface gets
150
+ * the same findings.
151
+ *
152
+ * Two modes:
153
+ * - `boardQuery` empty → audit every board (per-board table).
154
+ * - `boardQuery` present → audit the single matching board, or report
155
+ * a clear "not found" error.
156
+ *
157
+ * Each board's row shows the issue counts (error · warning) and the
158
+ * top-3 issues, biasing toward error severity first.
159
+ */
160
+ export declare function renderProjectAudit(deps: Pick<KanbanSlashDeps, 'projectRoot'>, boardQuery: string): Promise<string>;
161
+ /**
162
+ * Render a board-row table from a list of audited boards. The output
163
+ * is a compact markdown block suitable for the slash composer.
164
+ *
165
+ * When `multi` is true (audit-all mode) each row is prefixed with the
166
+ * board title; in single-board mode the title appears once as a header.
167
+ */
168
+ export declare function renderAuditReport(rows: ReadonlyArray<{
169
+ title: string;
170
+ summary: KanbanAuditSummary;
171
+ error?: string;
172
+ }>, multi: boolean): string;
173
+ /**
174
+ * Render a compact boards table. Width-aware so a 60-col terminal still gets
175
+ * useful output (column titles truncated, counts abbreviated).
176
+ */
177
+ export declare function renderBoardsList(boards: readonly KanbanBoardSummary[], width?: number): string;
178
+ //# sourceMappingURL=kanban-slash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kanban-slash.d.ts","sourceRoot":"","sources":["../src/kanban-slash.ts"],"names":[],"mappings":"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"}
package/dist/run-tui.d.ts CHANGED
@@ -15,6 +15,7 @@ export interface RunTuiOptions {
15
15
  /** Host-owned mutable bridge for slash commands that need masked input. */
16
16
  secretInputController?: {
17
17
  readSecret(prompt: string): Promise<string>;
18
+ readText?(prompt: string): Promise<string>;
18
19
  } | undefined;
19
20
  attachments: AttachmentStore;
20
21
  events: EventBus;
@@ -85,6 +86,8 @@ export interface RunTuiOptions {
85
86
  family?: string | undefined;
86
87
  /** Last 3 chars of the active API key — shown in the banner for visual key-pick verification. */
87
88
  keyTail?: string | undefined;
89
+ /** Active fallback profile name, shown in the banner (e.g. "default"). */
90
+ profile?: string | undefined;
88
91
  /** Background autonomy agents to display in the banner (Brain, Shadow,
89
92
  * Kanban, Mailbox, Memory, etc.). Read from the mailbox at boot. */
90
93
  autonomyAgents?: import('./components/history/types.js').AutonomyAgentStatus[] | undefined;
@@ -166,6 +169,7 @@ export interface RunTuiOptions {
166
169
  onClearHistory?: ((dispatch: React.Dispatch<{
167
170
  type: 'clearHistory';
168
171
  model?: string | undefined;
172
+ provider?: string | undefined;
169
173
  } | {
170
174
  type: 'resetContextChip';
171
175
  } | {
@@ -224,6 +228,11 @@ export interface RunTuiOptions {
224
228
  interruptController?: {
225
229
  abortLeader: () => boolean;
226
230
  isRunning?: (() => boolean) | undefined;
231
+ confirmClear?: ((info: {
232
+ leaderActive: boolean;
233
+ subagentCount: number;
234
+ }) => Promise<boolean>) | undefined;
235
+ confirmSlash?: ((question: string, defaultYes: boolean) => Promise<boolean | null>) | undefined;
227
236
  resetSession?: (() => void) | undefined;
228
237
  waitForIdle?: (() => Promise<void>) | undefined;
229
238
  } | undefined;
@@ -243,6 +252,8 @@ export interface RunTuiOptions {
243
252
  buildEnhancerProvider?: ((providerId: string, modelId: string) => Promise<import('@wrongstack/core').Provider | undefined>) | undefined;
244
253
  /** Resolve the one-key "retry with another model" fallback ref on a refine failure. */
245
254
  getEnhanceFallbackRef?: (() => string | undefined) | undefined;
255
+ /** Resolve the dedicated refiner target for the initial refinement attempt. */
256
+ getConfiguredRefinerRef?: (() => string | undefined) | undefined;
246
257
  /**
247
258
  * Controller for status bar hidden items. App installs a dispatch-backed
248
259
  * setter on mount so the /statusline slash command can update the TUI's