@wrongstack/tui 0.155.0 → 0.236.0

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.
package/dist/index.d.ts CHANGED
@@ -1,9 +1,121 @@
1
1
  import * as _wrongstack_core from '@wrongstack/core';
2
- import { Agent, SlashCommandRegistry, AttachmentStore, EventBus, TokenCounter, QueueStore, AutonomyStage, Director } from '@wrongstack/core';
2
+ import { Agent, SlashCommandRegistry, AttachmentStore, EventBus, TokenCounter, QueueStore, AutonomyStage, Director, Message, SessionEvent } from '@wrongstack/core';
3
3
  export { buildGoalPreamble } from '@wrongstack/core';
4
4
  import { VisionAdapters } from '@wrongstack/runtime/vision';
5
5
  import React from 'react';
6
6
 
7
+ /** A single session row from the SessionRegistry, exposed via WebSocket. */
8
+ interface LiveSessionEntry {
9
+ sessionId: string;
10
+ projectName: string;
11
+ projectSlug: string;
12
+ projectRoot?: string | undefined;
13
+ workingDir: string;
14
+ gitBranch?: string | undefined;
15
+ status: string;
16
+ pid: number;
17
+ startedAt: string;
18
+ agentCount: number;
19
+ agents: LiveAgentEntry[];
20
+ }
21
+ interface LiveAgentEntry {
22
+ id: string;
23
+ name: string;
24
+ status: string;
25
+ currentTool?: string | undefined;
26
+ iterations: number;
27
+ toolCalls: number;
28
+ lastActivityAt: string;
29
+ }
30
+
31
+ /** A single row in the project picker. Matches the CLI's PickerItem shape. */
32
+ interface ProjectPickerItem {
33
+ key: string;
34
+ label: string;
35
+ subtitle?: string | undefined;
36
+ meta?: string | undefined;
37
+ kind: 'project' | 'action';
38
+ }
39
+
40
+ type HistoryEntry = {
41
+ id: number;
42
+ kind: 'user';
43
+ text: string;
44
+ queued?: boolean | undefined;
45
+ pasteContent?: string | undefined;
46
+ } | {
47
+ id: number;
48
+ kind: 'assistant';
49
+ text: string;
50
+ } | {
51
+ id: number;
52
+ kind: 'tool';
53
+ name: string;
54
+ durationMs: number;
55
+ ok: boolean;
56
+ input?: unknown | undefined;
57
+ output?: string | undefined;
58
+ /** Full byte length of the result body the model actually received
59
+ * (post-cap, post-scrub). Carried separately because `output` is a
60
+ * ~400-char preview — `outputBytes` is what the model paid for. */
61
+ outputBytes?: number | undefined;
62
+ /** ~3.5 chars/token estimate over `outputBytes`. Cheap to render in
63
+ * the chip; the authoritative count lives in provider.response.usage. */
64
+ outputTokens?: number | undefined;
65
+ /** Real line count for tools that have a meaningful one — read counts
66
+ * numbered prefixes, shell/grep/logs count newlines. Undefined for
67
+ * tools without a line notion (json, fetch, …). */
68
+ outputLines?: number | undefined;
69
+ } | {
70
+ id: number;
71
+ kind: 'info';
72
+ text: string;
73
+ } | {
74
+ id: number;
75
+ kind: 'warn';
76
+ text: string;
77
+ } | {
78
+ id: number;
79
+ kind: 'error';
80
+ text: string;
81
+ } | {
82
+ id: number;
83
+ kind: 'turn-summary';
84
+ text: string;
85
+ } | {
86
+ id: number;
87
+ kind: 'brain';
88
+ status: 'thinking' | 'answered' | 'ask_human' | 'denied' | 'intervention';
89
+ source: string;
90
+ risk: 'low' | 'medium' | 'high' | 'critical';
91
+ question: string;
92
+ decision?: string | undefined;
93
+ rationale?: string | undefined;
94
+ } | {
95
+ id: number;
96
+ kind: 'banner';
97
+ version: string;
98
+ provider: string;
99
+ model: string;
100
+ cwd: string;
101
+ family?: string | undefined;
102
+ keyTail?: string | undefined;
103
+ } | {
104
+ id: number;
105
+ kind: 'confirm';
106
+ toolName: string;
107
+ input: unknown;
108
+ suggestedPattern: string;
109
+ } | {
110
+ id: number;
111
+ kind: 'subagent';
112
+ agentLabel: string;
113
+ agentColor: string;
114
+ icon: string;
115
+ text: string;
116
+ detail?: string | undefined;
117
+ };
118
+
7
119
  interface ProviderOption {
8
120
  id: string;
9
121
  family: string;
@@ -13,6 +125,20 @@ interface ProviderOption {
13
125
  modelsLabel?: string | undefined;
14
126
  }
15
127
 
128
+ /** Thin view over a SessionSummary for the resume picker. */
129
+ interface ResumeSessionEntry {
130
+ id: string;
131
+ title: string;
132
+ startedAt: string;
133
+ endedAt?: string | undefined;
134
+ tokenTotal: number;
135
+ iterationCount: number;
136
+ toolCallCount: number;
137
+ toolErrorCount: number;
138
+ outcome?: 'completed' | 'error' | 'timeout' | 'aborted' | undefined;
139
+ /** The current session — marked so the picker can disallow resuming into itself. */
140
+ isCurrent?: boolean | undefined;
141
+ }
16
142
  type Settings = {
17
143
  mode: 'off' | 'suggest' | 'auto';
18
144
  delayMs: number;
@@ -37,10 +163,16 @@ type Settings = {
37
163
  autoProceedMaxIterations: number;
38
164
  /** Prompt refinement preview countdown (ms). */
39
165
  enhanceDelayMs: number;
166
+ /** Enable/disable prompt refinement. */
167
+ enhanceEnabled: boolean;
168
+ /** Default language for refinement: original or english. */
169
+ enhanceLanguage: 'original' | 'english';
40
170
  /** Raw SSE stream debugging — hex-dump every byte received from providers. */
41
171
  debugStream: boolean;
42
172
  /** Where to persist settings: 'global' or 'project'. */
43
173
  configScope: 'global' | 'project';
174
+ /** Full mouse mode: in-app managed scroll + clickable UI (SGR tracking on). */
175
+ mouseMode?: boolean | undefined;
44
176
  };
45
177
 
46
178
  interface RunTuiOptions {
@@ -56,6 +188,14 @@ interface RunTuiOptions {
56
188
  banner?: boolean | undefined;
57
189
  /** Persists the input queue across crashes; if omitted, the queue is in-memory only. */
58
190
  queueStore?: QueueStore | undefined;
191
+ /**
192
+ * Called with the queue's display texts (head first) on EVERY queue change
193
+ * — enqueue, /queue delete, /queue clear, dequeue-for-delivery. The CLI
194
+ * mirrors the snapshot onto the live agent Context (core's
195
+ * setQueuedMessagesSnapshot) so a running agent learns what's waiting at
196
+ * its next iteration boundary without the queue being delivered early.
197
+ */
198
+ onQueueChange?: ((items: string[]) => void) | undefined;
59
199
  /** Surfaces the "⚠ YOLO" chip in the status bar. */
60
200
  yolo?: boolean | undefined;
61
201
  /** Query live YOLO state from the permission policy. */
@@ -117,6 +257,14 @@ interface RunTuiOptions {
117
257
  titleAnimation?: boolean | undefined;
118
258
  /** Play terminal bell (\\x07) when agent run completes. */
119
259
  chime?: boolean | undefined;
260
+ /**
261
+ * Enable terminal mouse tracking (SGR; click + wheel). Stays in the normal
262
+ * screen buffer so native scrollback survives, BUT while tracking is on the
263
+ * plain wheel reports to the app instead of scrolling history — only
264
+ * Shift+wheel reaches native scrollback. Off by default; opt in here or via
265
+ * WRONGSTACK_MOUSE=1. See mouse.ts for the trade-off rationale.
266
+ */
267
+ mouse?: boolean | undefined;
120
268
  /** Show "confirm exit" message on first Ctrl+C instead of "exit". */
121
269
  confirmExit?: boolean | undefined;
122
270
  /** Active agent mode label shown in the status bar (e.g. "teach", "brief"). */
@@ -258,7 +406,129 @@ interface RunTuiOptions {
258
406
  userRequest: string;
259
407
  assistantSummary: string;
260
408
  }) => Promise<string[]>) | undefined;
409
+ /**
410
+ * Called after each agent turn with the assistant's final output text.
411
+ * The host parses "💡 Next steps" suggestions from the text and stores
412
+ * them in the shared suggestion store so `/next 1`, `/next 1 2 3` work.
413
+ */
414
+ onSuggestionsParsed?: ((finalText: string) => void) | undefined;
415
+ /**
416
+ * Retrieve current suggestions from the shared suggestion store.
417
+ * Used by the TUI to display and auto-submit next steps in 'auto' mode.
418
+ */
419
+ getSuggestions?: (() => string[]) | undefined;
420
+ /**
421
+ * Messages restored from a previous session. When provided (non-empty),
422
+ * the TUI renders the prior conversation as history entries so a resumed
423
+ * session shows its full chat context, not just the LLM's internal state.
424
+ */
425
+ restoredMessages?: Message[] | undefined;
426
+ /**
427
+ * Tool execution records from a previous session, keyed by tool_use id.
428
+ * Used to render tool entries (name, duration, ok/error) in the TUI on
429
+ * resume. Events are `tool_call_end` records from the session JSONL.
430
+ */
431
+ restoredToolCalls?: Array<{
432
+ name: string;
433
+ id: string;
434
+ durationMs: number;
435
+ ok: boolean;
436
+ outputBytes?: number | undefined;
437
+ outputTokens?: number | undefined;
438
+ outputLines?: number | undefined;
439
+ }> | undefined;
440
+ /**
441
+ * List recent session summaries for the /resume picker. The CLI reads
442
+ * from the session store and returns ResumeSessionEntry-shaped data.
443
+ */
444
+ listSessions?: ((limit?: number) => Promise<ResumeSessionEntry[]>) | undefined;
445
+ /**
446
+ * Resume a session by id: load JSONL events, replay history entries,
447
+ * rebuild agent context, and return hydrated entries for the TUI to
448
+ * display. Returns null when resume fails.
449
+ */
450
+ onResumeSession?: ((sessionId: string) => Promise<{
451
+ entries: HistoryEntry[];
452
+ nextId: number;
453
+ sessionId: string;
454
+ } | null>) | undefined;
455
+ getProjectPickerItems?: (() => Promise<ProjectPickerItem[]>) | undefined;
456
+ onProjectSelect?: ((key: string, kind: 'project' | 'action') => void) | undefined;
457
+ /**
458
+ * Request the TUI to exit with a specific code. Used by the project picker
459
+ * to trigger a clean exit before spawning a new wstack process in a different
460
+ * project directory. The host CLI catches this exit code and performs the
461
+ * actual project switch.
462
+ */
463
+ requestExit?: (code: number) => void;
464
+ getLiveSessions?: (() => Promise<LiveSessionEntry[]>) | undefined;
465
+ onSwitchToSession?: ((sessionId: string, projectRoot: string, projectName: string) => void) | undefined;
466
+ /**
467
+ * When true, the agents monitor (F3) is open by default at TUI startup.
468
+ * Used by the `wrongstack quick` command to show agents panel immediately.
469
+ */
470
+ initialAgentsMonitorOpen?: boolean | undefined;
261
471
  }
262
472
  declare function runTui(opts: RunTuiOptions): Promise<number>;
263
473
 
264
- export { type RunTuiOptions, type Settings, runTui };
474
+ interface InlineToken {
475
+ text: string;
476
+ bold?: boolean | undefined;
477
+ italic?: boolean | undefined;
478
+ code?: boolean | undefined;
479
+ strike?: boolean | undefined;
480
+ }
481
+ /**
482
+ * Parse one line of prose into inline-emphasis tokens. Markers are stripped
483
+ * (this is display text, not length-preserving). `_..._` is intentionally NOT
484
+ * treated as italic so snake_case / file_names aren't mangled. An unterminated
485
+ * marker is emitted literally so no text is ever lost.
486
+ *
487
+ * Results are memoized: repeated calls with the same text return the identical
488
+ * cached array, eliminating redundant parsing on every TUI re-render.
489
+ */
490
+ declare function parseInline(text: string): InlineToken[];
491
+
492
+ /**
493
+ * Render a SessionEvent back into a TUI HistoryEntry so a resumed session
494
+ * displays exactly what the user saw during live interaction.
495
+ *
496
+ * ## Entry mapping
497
+ *
498
+ * | Event type | HistoryEntry kind |
499
+ * |--------------------------|-------------------|
500
+ * | `user_input` | `user` |
501
+ * | `llm_response` | `assistant` |
502
+ * | `tool_use` + `tool_result` | `tool` (paired) |
503
+ * | `tool_call_start`/`tool_call_end` | `tool` |
504
+ * | `compaction` | `info` |
505
+ * | `error` | `error` |
506
+ * | `provider_retry` | `warn` |
507
+ * | `provider_error` | `error` |
508
+ * | `checkpoint` | `info` |
509
+ * | `agent_spawned`/`agent_stopped` | `subagent` |
510
+ * | `agent_error` | `subagent` |
511
+ * | `mode_changed` | `info` |
512
+ * | `skill_activated`/`skill_deactivated` | `info` |
513
+ * | `message_truncated` | `warn` |
514
+ *
515
+ * ## Non-resumable events (subagent transcripts)
516
+ *
517
+ * Subagent events (`agent_spawned`, `agent_stopped`, `agent_error`) are
518
+ * rendered as `subagent` entries in the main TUI history but the full
519
+ * subagent tool-call details live in per-subagent JSONL files. The main
520
+ * session only holds the lifecycle markers.
521
+ *
522
+ * ## Compaction events
523
+ *
524
+ * Compaction boundaries are rendered as `info` entries showing how many
525
+ * tokens were collapsed. This keeps the display neat without pretending
526
+ * the full verbose context never existed.
527
+ *
528
+ * @param events Parsed SessionEvent[] from session JSONL
529
+ * @param startId Starting id counter for the generated entries
530
+ * @returns Ordered HistoryEntry[] ready for display
531
+ */
532
+ declare function replaySessionEvents(events: SessionEvent[], startId: number): HistoryEntry[];
533
+
534
+ export { type RunTuiOptions, type Settings, parseInline, replaySessionEvents, runTui };