@itookit/dsht 0.2.0 → 0.2.4

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.
@@ -0,0 +1,12 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ /** Only visible semantic rows become React nodes; ANSI colors are applied after remote text sanitation. */
3
+ import { Text } from 'ink';
4
+ import { useTheme } from "./theme.js";
5
+ /** Render a viewport with role, reasoning, tool and result colors from the selected theme.
6
+ * @param rows - Already wrapped, terminal-safe visible rows.
7
+ * @returns Colored text with unchanged row geometry and plain-text role markers.
8
+ */
9
+ export function HistoryViewport({ rows }) {
10
+ const theme = useTheme();
11
+ return _jsx(Text, { children: rows.map((row, index) => _jsxs(Text, { color: theme.colors[row.kind], bold: row.bold, children: [row.text, index < rows.length - 1 ? '\n' : ''] }, index)) });
12
+ }
package/dist/history.d.ts CHANGED
@@ -1,17 +1,34 @@
1
- import type { Transcript } from './transcript.ts';
2
- /** Lay out visible conversation records and retain their first terminal row.
3
- * @param transcript - Loaded history and active assistant output.
1
+ import { type Message, type MessagePart, type Transcript } from './transcript.ts';
2
+ /** Default fold mode; individual sequence overrides are view state, never stored content. */
3
+ export type Reasoning = 'row' | 'full';
4
+ /** Color semantics are independent of the selected terminal palette. */
5
+ export type RowKind = MessagePart['kind'] | 'user' | 'assistant' | 'context' | 'muted';
6
+ /** One visible terminal row; no remote ANSI is allowed into its text. */
7
+ export interface HistoryRow {
8
+ text: string;
9
+ kind: RowKind;
10
+ bold?: boolean;
11
+ seq?: number;
12
+ }
13
+ /** Drop all terminal rows and layout metadata for an evicted or inactive transcript.
14
+ * @param transcript - Transcript whose previously returned layout is no longer used.
15
+ */
16
+ export declare function releaseHistoryLayout(transcript: Transcript): void;
17
+ /** Lay out an indexed conversation without concatenating its historical rows on every stream frame.
18
+ * @param transcript - Selected session's semantic content and unfinished assistant output.
4
19
  * @param width - Available terminal columns.
5
- * @returns Rows, messages for the history picker, and record-to-row offsets.
20
+ * @param reasoning - Global committed/completed reasoning fold mode.
21
+ * @param overrides - Sequences whose fold mode differs from the global mode; replace the set on changes.
22
+ * @param liveReasoning - Fold mode for completed blocks in the unfinished assistant attempt.
23
+ * @returns Row count, sequence offsets, and a viewport reader; `lines` materializes all rows for exports only.
6
24
  */
7
- export declare function historyLayout(transcript: Transcript, width: number): {
8
- messages: import("./transcript.ts").Message[];
9
- lines: string[];
25
+ export declare function historyLayout(transcript: Transcript, width: number, reasoning?: Reasoning, overrides?: ReadonlySet<number>, liveReasoning?: Reasoning): {
26
+ messages: Message[];
10
27
  offsets: Map<number, number>;
11
28
  first: number | undefined;
29
+ length: number;
30
+ liveOffset: number;
31
+ viewport: (start: number, end: number) => HistoryRow[];
32
+ readonly cachedRowCount: number;
33
+ readonly lines: string[];
12
34
  };
13
- /** Parse an exact visible-record sequence or an endpoint alias.
14
- * @param value - Text after /jump.
15
- * @returns A non-negative sequence, first, or last.
16
- */
17
- export declare function jumpTarget(value: string): number | 'first' | 'last';
package/dist/history.js CHANGED
@@ -1,32 +1,177 @@
1
- /** Width-aware history layout shared by scrolling and explicit message jumps. */
1
+ /** Indexed semantic history with bounded terminal-row caching and viewport-only materialization. */
2
2
  import wrapAnsi from 'wrap-ansi';
3
- /** Lay out visible conversation records and retain their first terminal row.
4
- * @param transcript - Loaded history and active assistant output.
5
- * @param width - Available terminal columns.
6
- * @returns Rows, messages for the history picker, and record-to-row offsets.
7
- */
8
- export function historyLayout(transcript, width) {
9
- const wrap = (value) => wrapAnsi(value, width, { hard: true }).split('\n');
10
- const messages = transcript.messagesForWidth(width);
11
- const lines = [];
12
- const offsets = new Map();
13
- for (const message of messages) {
14
- offsets.set(message.seq, lines.length);
15
- lines.push(...(message.compact ? [] : [message.role]), ...wrap(message.text), '');
3
+ import { toolLine } from "./transcript.js";
4
+ /** A session owns one layout cache; dropped sessions release their entire cache. */
5
+ class LayoutIndex {
6
+ width;
7
+ reasoning;
8
+ overrides;
9
+ messages = [];
10
+ segments = [];
11
+ offsets = new Map();
12
+ length = 0;
13
+ cache = new Map();
14
+ cacheSize = 0;
15
+ // Bound both row objects and long rows. Full semantic content remains available for search.
16
+ maxRows = 2048;
17
+ heights = new WeakMap();
18
+ constructor(width, reasoning, overrides) {
19
+ this.width = width;
20
+ this.reasoning = reasoning;
21
+ this.overrides = overrides;
22
+ }
23
+ rows(message, reasoning, heading) {
24
+ const cached = this.cache.get(message);
25
+ if (cached?.width === this.width && cached.reasoning === reasoning && cached.heading === heading) {
26
+ this.cache.delete(message);
27
+ this.cache.set(message, cached);
28
+ return cached.rows;
29
+ }
30
+ const rows = messageRows(message, this.width, reasoning, heading);
31
+ if (cached) {
32
+ this.cache.delete(message);
33
+ this.cacheSize -= cached.rows.length;
34
+ }
35
+ if (rows.length <= this.maxRows && rows.reduce((sum, row) => sum + row.text.length, 0) <= 256 * 1024) {
36
+ while (this.cacheSize + rows.length > this.maxRows) {
37
+ const key = this.cache.keys().next().value;
38
+ this.cacheSize -= this.cache.get(key).rows.length;
39
+ this.cache.delete(key);
40
+ }
41
+ this.cache.set(message, { width: this.width, reasoning, heading, rows });
42
+ this.cacheSize += rows.length;
43
+ }
44
+ return rows;
45
+ }
46
+ dispose() {
47
+ this.messages = [];
48
+ this.segments = [];
49
+ this.offsets.clear();
50
+ this.cache.clear();
51
+ this.cacheSize = 0;
52
+ this.length = 0;
53
+ this.heights = new WeakMap();
54
+ }
55
+ get cachedRowCount() { return this.cacheSize; }
56
+ get assistantSeen() { return this.segments.at(-1)?.assistantSeen ?? false; }
57
+ update(messages) {
58
+ if (messages === this.messages)
59
+ return;
60
+ // Appended durable messages extend the row index; replacements and older pages rebuild offsets.
61
+ let prefix = 0;
62
+ while (prefix < this.messages.length && prefix < messages.length && this.messages[prefix] === messages[prefix])
63
+ prefix++;
64
+ if (prefix < this.messages.length) {
65
+ const retained = new Set(messages);
66
+ for (const [message, cached] of this.cache)
67
+ if (!retained.has(message)) {
68
+ this.cacheSize -= cached.rows.length;
69
+ this.cache.delete(message);
70
+ }
71
+ this.segments.length = prefix;
72
+ this.offsets = new Map(this.segments.map(segment => [segment.message.seq, segment.start]));
73
+ this.length = this.segments.at(-1) ? this.segments.at(-1).start + this.segments.at(-1).count : 0;
74
+ }
75
+ let assistantSeen = this.assistantSeen;
76
+ for (let i = prefix; i < messages.length; i++) {
77
+ const message = messages[i];
78
+ if (message.role === 'You')
79
+ assistantSeen = false;
80
+ const heading = !message.compact && (message.role !== 'Assistant' || !assistantSeen);
81
+ if (message.role === 'Assistant' && heading)
82
+ assistantSeen = true;
83
+ const reasoning = this.overrides.has(message.seq) ? this.reasoning === 'row' ? 'full' : 'row' : this.reasoning;
84
+ const cached = this.heights.get(message);
85
+ const count = cached?.width === this.width && cached.reasoning === reasoning && cached.heading === heading ? cached.count : this.rows(message, reasoning, heading).length;
86
+ this.heights.set(message, { width: this.width, reasoning, heading, count });
87
+ this.offsets.set(message.seq, this.length);
88
+ this.segments.push({ message, start: this.length, count, reasoning, heading, assistantSeen });
89
+ this.length += count;
90
+ }
91
+ this.messages = messages;
92
+ }
93
+ viewport(start, end) {
94
+ let lo = 0, hi = this.segments.length;
95
+ while (lo < hi) {
96
+ const middle = (lo + hi) >>> 1;
97
+ const segment = this.segments[middle];
98
+ if (segment.start + segment.count <= start)
99
+ lo = middle + 1;
100
+ else
101
+ hi = middle;
102
+ }
103
+ const rows = [];
104
+ for (let i = lo; i < this.segments.length; i++) {
105
+ const segment = this.segments[i];
106
+ if (segment.start >= end)
107
+ break;
108
+ rows.push(...this.rows(segment.message, segment.reasoning, segment.heading).slice(Math.max(0, start - segment.start), end - segment.start));
109
+ }
110
+ return rows;
16
111
  }
17
- const live = transcript.liveTextForWidth(width);
18
- if (live)
19
- lines.push(...(transcript.liveToolOnly ? [] : ['Assistant · streaming']), ...wrap(live));
20
- return { messages, lines, offsets, first: transcript.beforeSeq };
21
112
  }
22
- /** Parse an exact visible-record sequence or an endpoint alias.
23
- * @param value - Text after /jump.
24
- * @returns A non-negative sequence, first, or last.
113
+ const liveRows = new WeakMap();
114
+ function partRows(parts, width, reasoning, seq) {
115
+ return parts.flatMap(part => {
116
+ const cached = seq === undefined ? liveRows.get(part) : undefined;
117
+ if (cached?.width === width && cached.reasoning === reasoning)
118
+ return cached.rows;
119
+ const fold = part.kind === 'reasoning' && reasoning === 'row' && (seq !== undefined || part.closed);
120
+ const text = fold ? toolLine(`◇ /think${seq === undefined ? ' live' : ` ${seq}`} · ${part.text.slice(2)}`, width) : part.text;
121
+ const rows = wrapAnsi(text, width, { hard: true, trim: !['tool', 'success', 'error'].includes(part.kind) }).split('\n').map(text => ({ text, kind: part.kind, seq }));
122
+ if (seq === undefined)
123
+ liveRows.set(part, { width, reasoning, rows });
124
+ return rows;
125
+ });
126
+ }
127
+ function messageRows(message, width, reasoning, heading) {
128
+ const kind = message.role === 'You' ? 'user' : message.role === 'Context' ? 'context' : 'assistant';
129
+ const label = kind === 'user' ? '❯ User' : kind === 'context' ? '◆ Context' : '✦ Assistant';
130
+ return [
131
+ ...(!heading ? [] : [{ text: label, kind, bold: true, seq: message.seq }]),
132
+ ...partRows(message.parts, width, reasoning, message.seq),
133
+ { text: '', kind: 'muted', seq: message.seq },
134
+ ];
135
+ }
136
+ const indexes = new WeakMap();
137
+ const noOverrides = new Set();
138
+ /** Drop all terminal rows and layout metadata for an evicted or inactive transcript.
139
+ * @param transcript - Transcript whose previously returned layout is no longer used.
140
+ */
141
+ export function releaseHistoryLayout(transcript) {
142
+ indexes.get(transcript)?.dispose();
143
+ indexes.delete(transcript);
144
+ }
145
+ /** Lay out an indexed conversation without concatenating its historical rows on every stream frame.
146
+ * @param transcript - Selected session's semantic content and unfinished assistant output.
147
+ * @param width - Available terminal columns.
148
+ * @param reasoning - Global committed/completed reasoning fold mode.
149
+ * @param overrides - Sequences whose fold mode differs from the global mode; replace the set on changes.
150
+ * @param liveReasoning - Fold mode for completed blocks in the unfinished assistant attempt.
151
+ * @returns Row count, sequence offsets, and a viewport reader; `lines` materializes all rows for exports only.
25
152
  */
26
- export function jumpTarget(value) {
27
- if (value === 'first' || value === 'last')
28
- return value;
29
- if (/^\d+$/.test(value) && Number.isSafeInteger(Number(value)))
30
- return Number(value);
31
- throw new Error('Use /jump <record sequence|first|last>; /history lists record sequences');
153
+ export function historyLayout(transcript, width, reasoning = 'row', overrides = noOverrides, liveReasoning = reasoning) {
154
+ let index = indexes.get(transcript);
155
+ if (!index || index.width !== width || index.reasoning !== reasoning || index.overrides !== overrides) {
156
+ index = new LayoutIndex(width, reasoning, overrides);
157
+ indexes.set(transcript, index);
158
+ }
159
+ index.update(transcript.messagesForWidth(width));
160
+ const live = transcript.liveParts(width);
161
+ const streamed = live.length ? [
162
+ ...(transcript.liveToolOnly || index.assistantSeen ? [] : [{ text: '✦ Assistant · streaming', kind: 'assistant', bold: true }]),
163
+ ...partRows(live, width, liveReasoning),
164
+ ] : [];
165
+ const committed = index;
166
+ const length = committed.length + streamed.length;
167
+ const viewport = (start, end) => {
168
+ start = Math.max(0, start);
169
+ end = Math.min(length, end);
170
+ if (end <= start)
171
+ return [];
172
+ return [...committed.viewport(start, end), ...streamed.slice(Math.max(0, start - committed.length), Math.max(0, end - committed.length))];
173
+ };
174
+ return { messages: index.messages, offsets: index.offsets, first: transcript.beforeSeq, length, liveOffset: committed.length, viewport,
175
+ get cachedRowCount() { return committed.cachedRowCount; },
176
+ get lines() { return viewport(0, length).map(row => row.text); } };
32
177
  }
@@ -0,0 +1,19 @@
1
+ /** Bounded, process-local recall history; never stores transcripts or writes prompt text to disk. */
2
+ export declare class InputHistory {
3
+ private entries;
4
+ private bytes;
5
+ private position;
6
+ private draft;
7
+ /** Remember submitted input, coalescing consecutive duplicates and enforcing both budgets.
8
+ * @param value - Submitted command or prompt, excluding interaction answers.
9
+ */
10
+ record(value: string): void;
11
+ /** Leave recall navigation when the composer is edited or otherwise replaced. */
12
+ reset(): void;
13
+ /** Recall older/newer input, restoring the original unsent draft at the end.
14
+ * @param direction - Negative for older input, positive for newer input.
15
+ * @param current - Current composer content before beginning recall.
16
+ * @returns Recalled input, or the original draft when returning to the newest position.
17
+ */
18
+ move(direction: -1 | 1, current: string): string;
19
+ }
@@ -0,0 +1,43 @@
1
+ /** Bounded, process-local recall history; never stores transcripts or writes prompt text to disk. */
2
+ export class InputHistory {
3
+ entries = [];
4
+ bytes = 0;
5
+ position;
6
+ draft = '';
7
+ /** Remember submitted input, coalescing consecutive duplicates and enforcing both budgets.
8
+ * @param value - Submitted command or prompt, excluding interaction answers.
9
+ */
10
+ record(value) {
11
+ this.reset();
12
+ if (!value || this.entries.at(-1) === value || value.length * 2 > 256 * 1024)
13
+ return;
14
+ this.entries.push(value);
15
+ this.bytes += value.length * 2;
16
+ while (this.entries.length > 200 || this.bytes > 256 * 1024)
17
+ this.bytes -= this.entries.shift().length * 2;
18
+ }
19
+ /** Leave recall navigation when the composer is edited or otherwise replaced. */
20
+ reset() { this.position = undefined; this.draft = ''; }
21
+ /** Recall older/newer input, restoring the original unsent draft at the end.
22
+ * @param direction - Negative for older input, positive for newer input.
23
+ * @param current - Current composer content before beginning recall.
24
+ * @returns Recalled input, or the original draft when returning to the newest position.
25
+ */
26
+ move(direction, current) {
27
+ if (!this.entries.length)
28
+ return current;
29
+ if (this.position === undefined) {
30
+ if (direction > 0)
31
+ return current;
32
+ this.position = this.entries.length;
33
+ this.draft = current;
34
+ }
35
+ this.position = Math.max(0, Math.min(this.entries.length, this.position + direction));
36
+ if (this.position === this.entries.length) {
37
+ const draft = this.draft;
38
+ this.reset();
39
+ return draft;
40
+ }
41
+ return this.entries[this.position];
42
+ }
43
+ }
package/dist/input.d.ts CHANGED
@@ -13,11 +13,13 @@ export interface EditState {
13
13
  */
14
14
  export declare function editInput(state: EditState, input: string, key: Partial<Key>): EditState;
15
15
  /** Controlled composer with local cursor and kill buffer; Enter submission belongs to the caller. */
16
- export declare function TextInput({ value, onChange, onCursorChange, onSubmit, focus, placeholder }: {
16
+ export declare function TextInput({ value, onChange, onCursorChange, onSubmit, focus, placeholder, reservedKeys }: {
17
17
  value: string;
18
18
  onChange(value: string): void;
19
19
  onCursorChange(cursor: number): void;
20
20
  onSubmit(): void;
21
21
  focus: boolean;
22
22
  placeholder: string;
23
+ /** Keys owned by the surrounding picker while the composer is empty. */
24
+ reservedKeys?: readonly string[];
23
25
  }): import("react").JSX.Element;
package/dist/input.js CHANGED
@@ -60,7 +60,7 @@ export function editInput(state, input, key) {
60
60
  return { ...state, text: text.slice(0, cursor) + inserted + text.slice(cursor), cursor: cursor + inserted.length };
61
61
  }
62
62
  /** Controlled composer with local cursor and kill buffer; Enter submission belongs to the caller. */
63
- export function TextInput({ value, onChange, onCursorChange, onSubmit, focus, placeholder }) {
63
+ export function TextInput({ value, onChange, onCursorChange, onSubmit, focus, placeholder, reservedKeys }) {
64
64
  const { internal_eventEmitter } = useStdin();
65
65
  const rawKey = useRef('');
66
66
  useEffect(() => {
@@ -77,6 +77,8 @@ export function TextInput({ value, onChange, onCursorChange, onSubmit, focus, pl
77
77
  useInput((input, key) => {
78
78
  if (key.eventType === 'release' || isMouseReport(rawKey.current))
79
79
  return;
80
+ if (!current.current.text && !key.ctrl && !key.meta && reservedKeys?.includes(input))
81
+ return;
80
82
  if (key.return) {
81
83
  onSubmit();
82
84
  return;
@@ -0,0 +1,13 @@
1
+ /** Soft budgets for reloadable semantic history, excluding active output and protected reading. */
2
+ export interface HistoryLimits {
3
+ maxRecords: number;
4
+ maxBytes: number;
5
+ }
6
+ /** Default balance: keep recent history in memory, reload older records through the host. */
7
+ export declare const DEFAULT_HISTORY_LIMITS: HistoryLimits;
8
+ /** Parse optional CLI limits before opening a connection or writing application state.
9
+ * @param records - Maximum retained semantic records, as a positive integer.
10
+ * @param megabytes - Estimated semantic payload budget in MiB, as a positive integer.
11
+ * @returns Validated history budgets, using defaults for omitted options.
12
+ */
13
+ export declare function historyLimits(records?: string, megabytes?: string): HistoryLimits;
package/dist/memory.js ADDED
@@ -0,0 +1,22 @@
1
+ /** Default balance: keep recent history in memory, reload older records through the host. */
2
+ export const DEFAULT_HISTORY_LIMITS = { maxRecords: 2000, maxBytes: 16 * 1024 * 1024 };
3
+ /** Parse optional CLI limits before opening a connection or writing application state.
4
+ * @param records - Maximum retained semantic records, as a positive integer.
5
+ * @param megabytes - Estimated semantic payload budget in MiB, as a positive integer.
6
+ * @returns Validated history budgets, using defaults for omitted options.
7
+ */
8
+ export function historyLimits(records, megabytes) {
9
+ const positive = (value, fallback, name) => {
10
+ if (value === undefined)
11
+ return fallback;
12
+ const parsed = Number(value);
13
+ if (!/^\d+$/.test(value) || !Number.isSafeInteger(parsed) || parsed < 1)
14
+ throw new Error(`${name} must be a positive integer`);
15
+ return parsed;
16
+ };
17
+ const maxRecords = positive(records, DEFAULT_HISTORY_LIMITS.maxRecords, '--history-records');
18
+ const maxBytes = positive(megabytes, DEFAULT_HISTORY_LIMITS.maxBytes / 1048576, '--history-mb') * 1048576;
19
+ if (!Number.isSafeInteger(maxBytes))
20
+ throw new Error('--history-mb is too large');
21
+ return { maxRecords, maxBytes };
22
+ }
package/dist/mouse.d.ts CHANGED
@@ -10,5 +10,7 @@ export declare function isMouseReport(raw: string): boolean;
10
10
  export declare function wheelDirection(raw: string): number;
11
11
  /** Enable cell-based mouse reports for this mount and restore normal terminal behavior on exit.
12
12
  * @param scroll - Current transcript scrolling callback.
13
+ * @param enabled - False restores native terminal selection while display updates are paused.
14
+ * @param select - Left press callback that can freeze the display and release mouse capture.
13
15
  */
14
- export declare function useMouseWheel(scroll: (direction: number) => void): void;
16
+ export declare function useMouseWheel(scroll: (direction: number) => void, enabled?: boolean, select?: () => void): void;
package/dist/mouse.js CHANGED
@@ -20,15 +20,26 @@ export function wheelDirection(raw) {
20
20
  }
21
21
  /** Enable cell-based mouse reports for this mount and restore normal terminal behavior on exit.
22
22
  * @param scroll - Current transcript scrolling callback.
23
+ * @param enabled - False restores native terminal selection while display updates are paused.
24
+ * @param select - Left press callback that can freeze the display and release mouse capture.
23
25
  */
24
- export function useMouseWheel(scroll) {
26
+ export function useMouseWheel(scroll, enabled = true, select) {
25
27
  const { internal_eventEmitter } = useStdin();
26
28
  const { stdout } = useStdout();
27
29
  const callback = useRef(scroll);
28
30
  callback.current = scroll;
31
+ const selection = useRef(select);
32
+ selection.current = select;
29
33
  useEffect(() => {
30
- const onInput = (raw) => { const direction = wheelDirection(raw); if (direction)
31
- callback.current(direction); };
34
+ if (!enabled)
35
+ return;
36
+ const onInput = (raw) => {
37
+ const direction = wheelDirection(raw);
38
+ if (direction)
39
+ callback.current(direction);
40
+ else if (/^\x1b\[<0;\d+;\d+M$/.test(raw))
41
+ selection.current?.();
42
+ };
32
43
  internal_eventEmitter.on('input', onInput);
33
44
  if (stdout.isTTY)
34
45
  stdout.write('\x1b[?1006h\x1b[?1000h');
@@ -37,5 +48,5 @@ export function useMouseWheel(scroll) {
37
48
  if (stdout.isTTY)
38
49
  stdout.write('\x1b[?1000l\x1b[?1006l');
39
50
  };
40
- }, [internal_eventEmitter, stdout]);
51
+ }, [internal_eventEmitter, stdout, enabled]);
41
52
  }
@@ -1,6 +1,6 @@
1
1
  /** Shared display names and unambiguous slash-command target resolution. */
2
2
  import { type ObjectValue } from './wire.ts';
3
- /** Parse the short navigation commands and their equivalent long aliases. */
3
+ /** Parse workspace and resume navigation, including their long aliases. */
4
4
  export declare function navigationCommand(value: string): {
5
5
  kind: 'workspace' | 'session';
6
6
  query?: string;
@@ -1,8 +1,8 @@
1
1
  /** Shared display names and unambiguous slash-command target resolution. */
2
2
  import { safeText, string } from "./wire.js";
3
- /** Parse the short navigation commands and their equivalent long aliases. */
3
+ /** Parse workspace and resume navigation, including their long aliases. */
4
4
  export function navigationCommand(value) {
5
- const match = /^\/(ws|workspace|workspaces|s|session|sessions)(?:\s+(.+))?$/.exec(value);
5
+ const match = /^\/(ws|workspace|workspaces|resume|session|sessions)(?:\s+(.+))?$/.exec(value);
6
6
  if (!match)
7
7
  return undefined;
8
8
  return { kind: match[1] === 'ws' || match[1].startsWith('workspace') ? 'workspace' : 'session', query: match[2] };
package/dist/status.d.ts CHANGED
@@ -13,7 +13,7 @@ export declare function elapsedTime(milliseconds: number): string;
13
13
  */
14
14
  export declare function metricLines(values: ObjectValue, defaultModel: ObjectValue | undefined, running: boolean): string[];
15
15
  /** Fit the status summary to one terminal row; details remain available through /status.
16
- * @param fields - Priority-ordered status fields, followed by optional details.
16
+ * @param fields - Activity, model, cost, context, and cumulative usage groups in display order.
17
17
  * @param width - Available terminal columns.
18
18
  * @returns A terminal-safe single line, shortened by display width.
19
19
  */
@@ -22,5 +22,7 @@ export declare function compactStatus(fields: string[], width: number): string;
22
22
  export declare const StatusBar: import("react").NamedExoticComponent<{
23
23
  controller: Controller;
24
24
  expanded?: boolean;
25
+ width?: number;
25
26
  revision?: number;
27
+ paused?: boolean;
26
28
  }>;