@getorrery/cells 0.0.0-stage → 0.2.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.
@@ -0,0 +1,204 @@
1
+ /**
2
+ * The terminal design, as cells — a port of the `orrery-cells` crate
3
+ * (`harness/clients/cells/src/lib.rs`), line for line.
4
+ *
5
+ * Every element is a pure function from a view model and a width to
6
+ * {@link Item}s — rows of {@link Seg}ments, each a run of text and the classes
7
+ * that say how it is meant. Widths are counted in code points, as the Rust
8
+ * counts `chars()`.
9
+ *
10
+ * Soft and hard fitting: an element is drawn in *soft* mode, where {@link fit}
11
+ * keeps an overflowing line whole for {@link flow} to wrap. Outside an element
12
+ * {@link fit} cuts with an ellipsis. {@link hfit} always cuts.
13
+ */
14
+ /** One run of cells. */
15
+ export type Seg =
16
+ /** Text, and the classes on it (space separated, possibly empty). */
17
+ {
18
+ k: "t";
19
+ text: string;
20
+ cls: string;
21
+ }
22
+ /**
23
+ * The 2-cell mark: an animation in one of its states (decision 0043). How it
24
+ * is drawn (an image, pixels, a glyph) is the client's choice by what the
25
+ * terminal can show.
26
+ */
27
+ | {
28
+ k: "px";
29
+ anim: string;
30
+ state: string;
31
+ }
32
+ /** The 1-cell spinner, with its class. */
33
+ | {
34
+ k: "spin";
35
+ cls: string;
36
+ }
37
+ /** `w` cells the renderer fills itself (the theme preview). */
38
+ | {
39
+ k: "blank";
40
+ w: number;
41
+ };
42
+ /** A row of runs. */
43
+ export type Line = Seg[];
44
+ /** What fills a {@link Blk}. */
45
+ export type Fill =
46
+ /** The mark, large (15 × 8 cells): an animation and a state. */
47
+ {
48
+ k: "pixel";
49
+ anim: string;
50
+ state: string;
51
+ } | {
52
+ k: "preview";
53
+ lines: Item[];
54
+ theme: string;
55
+ };
56
+ /** A fixed-width block, and the rows beside it. */
57
+ export interface Blk {
58
+ w: number;
59
+ h: number | null;
60
+ fill: Fill;
61
+ lines: Line[];
62
+ }
63
+ /** What an element draws on one row. */
64
+ export type Item = {
65
+ k: "line";
66
+ line: Line;
67
+ } | {
68
+ k: "blk";
69
+ blk: Blk;
70
+ } | {
71
+ k: "skip";
72
+ };
73
+ /** Code points of a string. */
74
+ export declare function cps(s: string): string[];
75
+ /** Cells in a string: its code points. */
76
+ export declare function chars(s: string): number;
77
+ /** How many cells a run takes. */
78
+ export declare function segWidth(s: Seg): number;
79
+ /** A line as an item. */
80
+ export declare function lineItem(line: Line): Item;
81
+ /** A run of text with classes. */
82
+ export declare function t(text: string, cls: string): Seg;
83
+ /** `n` spaces, unstyled. */
84
+ export declare function sp(n: number): Seg;
85
+ /** The Orrery mark in `state`: the one animation the host sends today (decision 0043). */
86
+ export declare function px(state: string, anim?: string): Seg;
87
+ /** The spinner, in a class (`ac` when none). */
88
+ export declare function spin(cls: string): Seg;
89
+ /** The glyph in colour, the `[word]` in mono (bold when an error or a warning). */
90
+ export declare function g(m: boolean, glyph: string, word: string, cls: string): Seg;
91
+ /** The agent-state mark: the pixel mark in colour, `[state]` in mono. */
92
+ export declare function mark(m: boolean, state: string): Seg;
93
+ /** Cells in a line. */
94
+ export declare function len(l: Line): number;
95
+ /** Run `f` in soft mode, where {@link fit} keeps a line whole for {@link flow}. */
96
+ export declare function soft<R>(f: () => R): R;
97
+ /** Cut a line to `w` cells, ending in `…`. */
98
+ export declare function hfit(l: Line, w: number): Line;
99
+ /** {@link hfit}, except in soft mode, where the line is kept for {@link flow}. */
100
+ export declare function fit(l: Line, w: number): Line;
101
+ /** Pad a line to `w` cells, or fit it. */
102
+ export declare function pad(l: Line, w: number): Line;
103
+ /** `a` on the left, `b` on the right. With `keep`, `a` is cut before `b` is dropped. */
104
+ export declare function lr(a: Line, b: Line, w: number, keep: boolean): Line;
105
+ /** A line centred in `w` cells. */
106
+ export declare function center(l: Line, w: number): Line;
107
+ /** Cut text to `n` cells from the right, ending in `…`. */
108
+ export declare function tr(s: string, n: number): string;
109
+ /** Cut text to `n` cells from the left, starting with `…`. */
110
+ export declare function trL(s: string, n: number): string;
111
+ /** Text cut and padded to exactly `n` cells, left-aligned. */
112
+ export declare function ps(s: string, n: number): string;
113
+ /** Text cut and padded to exactly `n` cells, right-aligned. */
114
+ export declare function pr(s: string, n: number): string;
115
+ /** Word-wrap text to `n` cells (at least 4), hard-breaking long words. */
116
+ export declare function wrap(text: string, n0: number): string[];
117
+ /** Which box-drawing set. */
118
+ export type BoxKind = "round" | "square" | "heavy" | "double" | "dashed";
119
+ /** How a box is drawn: its set, its colour class, and what its borders say. */
120
+ export interface BoxOpts {
121
+ /** The set; round when absent. */
122
+ k?: BoxKind;
123
+ /** The border's class; `dd` when empty. */
124
+ c?: string;
125
+ /** Top-left label. */
126
+ t?: Line | null;
127
+ /** Top-right label. */
128
+ r?: Line | null;
129
+ /** Bottom-left label. */
130
+ bl?: Line | null;
131
+ /** Bottom-right label. */
132
+ b?: Line | null;
133
+ }
134
+ /** Rows in a box `w` wide; the rows are flowed to `w - 4` first. */
135
+ export declare function boxed(inner: Line[], w: number, o?: BoxOpts): Line[];
136
+ /** A rule `w` wide, carrying a label on the left and one on the right. */
137
+ export declare function rule(w: number, l: Line | null | undefined, r: Line | null | undefined, c: string, ch: string): Line;
138
+ /** {@link rule} with `─`. */
139
+ export declare function ruleD(w: number, l: Line, r: Line | null | undefined, c: string): Line;
140
+ /** Mark a line selected: every text run gains `sel`. */
141
+ export declare function sel(l: Line): Line;
142
+ /** Dim a line: every text run becomes `dd`. */
143
+ export declare function dim(l: Line): Line;
144
+ /** Every text run of a line in one class. */
145
+ export declare function cls(l: Line, c: string): Line;
146
+ /** Key hints — `enter send|esc stop` — dropping whatever does not fit in `w`. */
147
+ export declare function keys(spec: string, w: number, lead: number): Line;
148
+ /** Text wrapped after a lead-in; continuation rows are indented by its width, or start with `cont`. */
149
+ export declare function para(first: Line, text: string, w: number, c: string, cont?: Seg | null): Line[];
150
+ /** The user's prompt echoed: `> …` on a tinted band. */
151
+ export declare function user(text: string, w: number): Line[];
152
+ /** Model prose under a `●` gutter; with `caret`, the caret after the last character. */
153
+ export declare function prose(text: string, w: number, dimmed: boolean, caret: boolean): Line[];
154
+ /** A tool call's state. */
155
+ export type ToolState = "ok" | "run" | "err" | "wait" | "deny" | "dim";
156
+ /** A tool call's head row: `● Name args dur`. */
157
+ export declare function tool(name: string, args: string, w: number, m: boolean, st: ToolState, dur: string | null | undefined, selected: boolean): Line[];
158
+ /** A tool result under `⎿` (or aligned under one, when not `first`). */
159
+ export declare function res(text: string, w: number, c: string, first: boolean): Line[];
160
+ /** How a turn ended. */
161
+ export type Outcome = "done" | "interrupted" | "error";
162
+ /** The line that closes a turn. */
163
+ export declare function outcome(k: Outcome, detail: string, w: number, m: boolean): Line;
164
+ /** A table column. */
165
+ export interface Col {
166
+ /** Header. */
167
+ h: string;
168
+ /** Width in cells. */
169
+ w: number;
170
+ /** Right-aligned. */
171
+ right?: boolean;
172
+ /** Drop priority: the highest goes first; `0` never drops. */
173
+ p?: number;
174
+ /** Takes the slack. */
175
+ flex?: boolean;
176
+ /** Cuts from the left. */
177
+ trl?: boolean;
178
+ }
179
+ /** A table row: cells, each with an optional class. */
180
+ export interface TRow {
181
+ c: [string, string | null][];
182
+ dis?: boolean;
183
+ cls?: string | null;
184
+ }
185
+ /** How a table is drawn. */
186
+ export interface TableOpts {
187
+ /** Cells before the first column; `2` when absent. */
188
+ lead?: number | null;
189
+ noHead?: boolean;
190
+ /** The sorted column, and whether descending. */
191
+ sort?: [number, boolean] | null;
192
+ hfocus?: number | null;
193
+ sel?: number | null;
194
+ }
195
+ /** A table that drops columns by priority rather than wrap. */
196
+ export declare function table(cols: Col[], rows: TRow[], w: number, o?: TableOpts): Line[];
197
+ /** Wrap a line that overflows `w` at word boundaries; the continuation is indented under the text. */
198
+ export declare function flow(l: Line, w: number): Line[];
199
+ /** Flow every line of an element's rows to `w`; blocks pass through. */
200
+ export declare function flowItems(items: Item[], w: number): Item[];
201
+ /** Lines as items. */
202
+ export declare function items(lines: Line[]): Item[];
203
+ /** The text runs of a line, joined — for tests and plain output. */
204
+ export declare function plain(l: Line): string;
@@ -0,0 +1,153 @@
1
+ /**
2
+ * List 2 · Agent work & control: permission mode, the plan card, pinned todos,
3
+ * edit approval, tool call cards, background tasks (`/tasks`), background processes, steering —
4
+ * port of `el/agent.rs`.
5
+ */
6
+ import { type Item, type Line } from "../cells";
7
+ import { type Block, type ToolSt } from "./block";
8
+ import { type FooterView, type InputView } from "./chrome";
9
+ import { type OutLine, type TaskItemV } from "./content";
10
+ /** The mode notice over the footer, or every mode. */
11
+ export interface ModeView {
12
+ /** `default` when absent. */
13
+ mode?: string;
14
+ next?: string | null;
15
+ /** `changed`, `all`, `error`, `locked`; `changed` when absent. */
16
+ state?: string;
17
+ note?: string | null;
18
+ footer: FooterView;
19
+ }
20
+ /** shift+tab: a one-row notice naming the mode and the next one. */
21
+ export declare function mode(p: ModeView, w: number, m: boolean): Item[];
22
+ /** The plan the agent proposes in plan mode. */
23
+ export interface PlanView {
24
+ steps?: string[];
25
+ selected?: number;
26
+ /** `proposed`, `approving`, `stale`, `rejected`; `proposed` when absent. */
27
+ state?: string;
28
+ note?: string | null;
29
+ }
30
+ /** Numbered steps and a/e/r in a box titled with the step count. */
31
+ export declare function plan(p: PlanView, w: number, m: boolean): Item[];
32
+ /** The agent's task list, pinned in the dock slot. */
33
+ export interface TodosView {
34
+ items?: TaskItemV[];
35
+ open?: boolean;
36
+ focused?: boolean;
37
+ working?: string | null;
38
+ }
39
+ /** A rule with the count; expanded, the items (two per row at ≥64 columns). */
40
+ export declare function todos(p: TodosView, w: number, m: boolean): Item[];
41
+ /** A proposed hunk. */
42
+ export interface ReviewHunk {
43
+ header: string;
44
+ /** `[sign, text]` pairs. */
45
+ lines: [string, string][];
46
+ /** `pending`, `accept`, `reject`; `pending` when absent. */
47
+ decision?: string;
48
+ }
49
+ /** Proposed edits to one file, per hunk. */
50
+ export interface EditApprovalView {
51
+ path: string;
52
+ stat?: string;
53
+ hunks?: ReviewHunk[];
54
+ /** `0` the file header, `n` the n-th hunk. */
55
+ focus?: number;
56
+ /** `review`, `applying`, `error`, `readonly`, `empty`; `review` when absent. */
57
+ state?: string;
58
+ note?: string | null;
59
+ }
60
+ /** A diff with accept/reject per file and per hunk. */
61
+ export declare function editApproval(p: EditApprovalView, w: number, m: boolean): Item[];
62
+ /** A tool call as the thread shows it. */
63
+ export interface ToolCardView {
64
+ name: string;
65
+ args?: string;
66
+ state?: ToolSt;
67
+ dur?: string | null;
68
+ output?: OutLine[];
69
+ more?: string | null;
70
+ selected?: boolean;
71
+ }
72
+ /** The tool card: the head row, `⎿` preview, `+N lines`. */
73
+ export declare function toolcard(p: ToolCardView, w: number, m: boolean): Item[];
74
+ /** The class a row's `✕` carries, naming the task it stops: a zero-width run just before the `✕`. */
75
+ export declare const STOP_MARK = "stop:";
76
+ /** Where a row's `✕` is and the task it stops: its column and the id. */
77
+ export declare function stopMark(l: Line): [number, string] | null;
78
+ /** A background task: a sub-agent or a process. */
79
+ export interface TaskRow {
80
+ id: string;
81
+ /** `agent` or `process`. */
82
+ kind?: string;
83
+ label?: string;
84
+ /** `running`, `done`, `stopped`, `killed`, `failed`, `exited`, `lost`. */
85
+ state?: string;
86
+ age?: string;
87
+ port?: number | null;
88
+ }
89
+ /** `/tasks`: the session's background tasks, in the dock. */
90
+ export interface TasksView {
91
+ items?: TaskRow[];
92
+ /** The row under the cursor (the client's). */
93
+ cursor?: number | null;
94
+ selected?: number | null;
95
+ }
96
+ /** State, kind, label, `:port`, age and `✕` on a running row; the cursor's row selected. Empty, it says so. */
97
+ export declare function tasks(p: TasksView, w: number, m: boolean): Item[];
98
+ /**
99
+ * One item of an agent's thread in its view: its brief, a message that reached
100
+ * it, what it said, a tool call (one folded line, decision 0024), a message
101
+ * typed into the view and not yet in its thread, a note — or a line of a
102
+ * process's log.
103
+ */
104
+ export interface ViewItem {
105
+ /** `brief`, `user`, `text`, `tool`, `sent`, `note`, `log`. */
106
+ t: string;
107
+ text?: string;
108
+ name?: string;
109
+ arg?: string;
110
+ /** A tool's state: `running`, `ok`, `failed`, `denied`, `cancelled`. */
111
+ state?: string;
112
+ }
113
+ /** An agent's view (decision 0031 §4), as the host declares it: whose thread, how it stands, and the thread itself. A process's is its log. */
114
+ export interface AgentViewV {
115
+ /** `agent` or `process`. */
116
+ kind?: string;
117
+ name?: string;
118
+ state?: string;
119
+ age?: string;
120
+ turns?: number | null;
121
+ port?: number | null;
122
+ items?: ViewItem[];
123
+ }
124
+ /** The view's header, pinned over its thread: `dir-finder-1 · running · 3m · 8 turns`, the state in the switcher's colour (`done ✓`, `failed ✗`, `stopped ■` in mono; decision 0033 §2), then a rule. */
125
+ export declare function agentViewHead(p: AgentViewV, w: number, m: boolean): Line[];
126
+ /** The view's thread: each item as the main thread draws its kind, a blank row between kinds. A log is its lines as written. Empty, it says what it waits for. */
127
+ export declare function agentViewBody(p: AgentViewV, w: number, m: boolean): Line[];
128
+ /** The whole view: its header over its thread. Clients that pin the header draw `agentViewHead` and `agentViewBody` apart. */
129
+ export declare function agentView(p: AgentViewV, w: number, m: boolean): Item[];
130
+ /** A background process. */
131
+ export interface ProcRow {
132
+ cmd: string;
133
+ port?: string;
134
+ uptime: string;
135
+ last?: string;
136
+ /** `running`, `exited`, `killed`. */
137
+ state: string;
138
+ }
139
+ /** Background shells and servers, pinned in the dock slot. */
140
+ export interface ProcsView {
141
+ items?: ProcRow[];
142
+ selected?: number | null;
143
+ busy?: string | null;
144
+ }
145
+ /** Command, port, last line, uptime. */
146
+ export declare function background(p: ProcsView, w: number, m: boolean): Item[];
147
+ /** A steer, where it landed, and the input when it has focus. */
148
+ export interface SteerView {
149
+ blocks?: Block[];
150
+ input?: InputView | null;
151
+ }
152
+ /** `↳ steer: …` inside the turn it changed. */
153
+ export declare function steer(p: SteerView, w: number, m: boolean): Item[];
@@ -0,0 +1,66 @@
1
+ /** Transcript blocks: the pieces a turn is made of — port of `el/block.rs`. */
2
+ import { type Line, type ToolState } from "../cells";
3
+ import { type FoldView } from "./chrome";
4
+ /** How a turn ended, as the fixtures spell it (`int` and `err` are aliases). */
5
+ export type OutcomeKind = "done" | "interrupted" | "int" | "error" | "err";
6
+ /** A tool call's state, as the fixtures spell it. */
7
+ export type ToolSt = ToolState;
8
+ /** One piece of a turn, tagged by `b`. */
9
+ export type Block = {
10
+ b: "user";
11
+ text: string;
12
+ } | {
13
+ b: "prose";
14
+ text: string;
15
+ caret?: boolean;
16
+ dim?: boolean;
17
+ } | {
18
+ b: "tool";
19
+ name: string;
20
+ args?: string;
21
+ st?: ToolSt;
22
+ dur?: string | null;
23
+ sel?: boolean;
24
+ } | {
25
+ b: "res";
26
+ text: string;
27
+ c?: string;
28
+ first?: boolean;
29
+ } | {
30
+ b: "outcome";
31
+ k: OutcomeKind;
32
+ detail: string;
33
+ } | {
34
+ b: "note";
35
+ text: string;
36
+ c?: string;
37
+ } | {
38
+ b: "empty";
39
+ } | {
40
+ b: "blank";
41
+ } | {
42
+ b: "keys";
43
+ spec: string;
44
+ lead?: number;
45
+ } | ({
46
+ b: "fold";
47
+ } & FoldView) | {
48
+ b: "steer";
49
+ text: string;
50
+ pending?: boolean;
51
+ } | {
52
+ b: "done";
53
+ text: string;
54
+ } | {
55
+ b: "queued";
56
+ text: string;
57
+ } | {
58
+ b: "alert";
59
+ kind: string;
60
+ text: string;
61
+ } | {
62
+ b: "raw";
63
+ runs: [string, string][];
64
+ };
65
+ /** Draw blocks at `w` columns. */
66
+ export declare function blocks(bs: Block[], w: number, m: boolean): Line[];
@@ -0,0 +1,240 @@
1
+ /**
2
+ * List 1 · Chrome, Tier 1: banner, thread, turn, status pin, reasoning fold,
3
+ * dock, consent bar, input, slash completion, queued messages, footer — port
4
+ * of `el/chrome.rs`.
5
+ */
6
+ import { type Item, type Line } from "../cells";
7
+ import { type Block } from "./block";
8
+ import { type FormView } from "./content";
9
+ /** The input's own box: `› typed▏`, accent (heavy in mono). */
10
+ export declare function inputBox(row: Line, w: number, m: boolean): Line[];
11
+ /** What the banner shows. */
12
+ export interface BannerView {
13
+ harness: string;
14
+ version: string;
15
+ path: string;
16
+ branch?: string | null;
17
+ trusted?: unknown;
18
+ model?: string | null;
19
+ provider?: string | null;
20
+ /** `idle`, `loading` or `error`; `idle` when absent. */
21
+ state?: string;
22
+ error?: string | null;
23
+ /** The client drawing it (`ratatui`, `ink`), shown beside the version. */
24
+ client?: string | null;
25
+ }
26
+ /** The banner: the pixel logo beside the facts at ≥64 columns in colour, a box below that. */
27
+ export declare function banner(p: BannerView, w: number, m: boolean): Item[];
28
+ /** How the thread's viewport stands. */
29
+ export type ThreadMode = "follow" | "scrolled" | "loading" | "empty" | "error" | "dim";
30
+ /** The thread's viewport. */
31
+ export interface ThreadView {
32
+ mode?: ThreadMode;
33
+ blocks?: Block[];
34
+ /** Rows in view; 10 when absent. */
35
+ height?: number;
36
+ top?: number;
37
+ track?: [number, number] | null;
38
+ new_count?: number;
39
+ error?: string | null;
40
+ }
41
+ /** The `── ↓ N new · end ──` row. */
42
+ export declare function newPill(n: number, w: number): Line;
43
+ /** The thread: a window on its rows, the last column kept for the scroll track. */
44
+ export declare function thread(p: ThreadView, w: number, m: boolean): Item[];
45
+ /** One turn. */
46
+ export interface MessageView {
47
+ blocks: Block[];
48
+ selected?: boolean;
49
+ rewound?: boolean;
50
+ }
51
+ /** A turn: the prompt, what came back, the outcome. */
52
+ export declare function message(p: MessageView, w: number, m: boolean): Item[];
53
+ /** The agent's state, pinned to the newest turn. */
54
+ export interface StatusView {
55
+ state: string;
56
+ title: string;
57
+ elapsed: string;
58
+ detail?: string;
59
+ tokens?: string | null;
60
+ spinner?: boolean;
61
+ }
62
+ /** The class of an agent state. */
63
+ export declare function stateClass(st: string): string;
64
+ /** Two rows: mark, title and time (tokens on the right); the detail under. */
65
+ export declare function status(p: StatusView, w: number, m: boolean): Item[];
66
+ /** A turn's reasoning. */
67
+ export interface FoldView {
68
+ /** `streaming`, `done`, `hidden`, `redacted`, `cut`; `done` when absent. */
69
+ state?: string;
70
+ seconds?: number;
71
+ open?: unknown;
72
+ selected?: boolean;
73
+ text?: string;
74
+ rows?: number | null;
75
+ }
76
+ /** `✻ Thought for Ns ▸`, and the text under a `│` when open. */
77
+ export declare function fold(p: FoldView, w: number, m: boolean): Item[];
78
+ /** An option in the dock's list. */
79
+ export interface DockItem {
80
+ label: string;
81
+ detail?: string;
82
+ }
83
+ /** What a flow is asking, above the input. */
84
+ export interface DockView {
85
+ title: string;
86
+ step?: string | null;
87
+ /** `asking`, `busy`, `empty`, `error`, `locked`, `answered`; `asking` when absent. */
88
+ state?: string;
89
+ prompt?: string;
90
+ items?: DockItem[];
91
+ selected?: number;
92
+ busy?: string | null;
93
+ note?: string | null;
94
+ error?: string | null;
95
+ summary?: string | null;
96
+ form?: FormView | null;
97
+ }
98
+ /** The dock: a rule with title and step, the question, its body. */
99
+ export declare function dock(p: DockView, w: number, m: boolean): Item[];
100
+ /** A choice on the consent bar. */
101
+ export interface ConsentChoice {
102
+ key: string;
103
+ label: string;
104
+ }
105
+ /** A permission request, minted by the host. */
106
+ export interface ConsentView {
107
+ tool: string;
108
+ command: string;
109
+ detail: string;
110
+ choices: ConsentChoice[];
111
+ /** `asking`, `busy`, `blocked`, `no-allow`; `asking` when absent. */
112
+ state?: string;
113
+ selected?: number;
114
+ queued?: number;
115
+ /** Seconds left to answer, when the request has a deadline (plan 37). */
116
+ seconds?: number | null;
117
+ }
118
+ /** The consent bar: a box, the command, why, and the choices. */
119
+ export declare function consent(p: ConsentView, w: number, m: boolean): Item[];
120
+ /** The input box. */
121
+ export interface InputView {
122
+ focus?: unknown;
123
+ disabled?: boolean;
124
+ label?: string | null;
125
+ text?: string | null;
126
+ secret?: boolean;
127
+ lines?: string[] | null;
128
+ placeholder?: string;
129
+ hint?: string;
130
+ error?: string | null;
131
+ chip?: string | null;
132
+ vim?: string | null;
133
+ }
134
+ /** The input: a box with its prefix, the text or placeholder, the caret, and the hint row (or the error). */
135
+ export declare function input(p: InputView, w: number, m: boolean): Item[];
136
+ /** {@link input} as lines. */
137
+ export declare function inputLines(p: InputView, w: number, m: boolean): Line[];
138
+ /** A command in the completion list. */
139
+ export interface CmdItem {
140
+ name: string;
141
+ usage?: string;
142
+ desc?: string;
143
+ disabled?: boolean;
144
+ when?: string;
145
+ when_short?: string;
146
+ }
147
+ /** The completion popup above the input. */
148
+ export interface SlashView {
149
+ query: string;
150
+ items?: CmdItem[];
151
+ selected?: number;
152
+ /** `ready`, `loading`, `error`, `shell`; `ready` when absent. */
153
+ state?: string;
154
+ error?: string | null;
155
+ loading?: string | null;
156
+ shell?: string | null;
157
+ }
158
+ /** The completion popup and the input under it. */
159
+ /** How many commands the popup shows at once; the rest scroll. */
160
+ export declare const SLASH_ROWS = 6;
161
+ export declare function slash(p: SlashView, w: number, m: boolean): Item[];
162
+ /** A message typed while a turn runs. */
163
+ export interface QueueItem {
164
+ text: string;
165
+ /** `queued`, `held`, `sending`, `dropped`; `queued` when absent. */
166
+ state?: string;
167
+ }
168
+ /** The queue under the thread. */
169
+ export interface QueueView {
170
+ items: QueueItem[];
171
+ selected?: number | null;
172
+ note?: string | null;
173
+ }
174
+ /** `⎿ queued: …`, one row each. */
175
+ export declare function queue(p: QueueView, w: number, m: boolean): Item[];
176
+ /** The bottom row. */
177
+ export interface FooterView {
178
+ /** `default`, `accept`, `plan`, `bypass`; `default` when absent. */
179
+ mode?: string;
180
+ hints?: string;
181
+ tokens?: string | null;
182
+ cost?: string;
183
+ model?: string | null;
184
+ model_error?: unknown;
185
+ ctx?: number | null;
186
+ armed?: unknown;
187
+ /** Background tasks running — processes (decisions 0027, 0031). */
188
+ tasks?: number | null;
189
+ /** Agents running, attached ones included (decision 0031). */
190
+ agents?: number | null;
191
+ /** The indicator has focus (the client's): drawn inverse, or `›` in mono. */
192
+ indicator?: unknown;
193
+ /** The views the switcher offers (decisions 0031 §4, 0033 §1), from the host: `main`, the agents that run, the view on screen; empty (or main's alone) hides it. */
194
+ views?: string[];
195
+ /** The view on screen, from the host; absent is main's. */
196
+ view?: string | null;
197
+ /** How each view is doing, by name (decision 0033 §2), from the host: `running`, `done`, `failed`, `stopped`; missing is running. */
198
+ view_states?: Record<string, string> | null;
199
+ /** The switcher has focus, with its cursor on this view (the client's). */
200
+ switcher?: number | null;
201
+ }
202
+ /**
203
+ * How a view's state is drawn (decision 0033 §2), for the switcher and the
204
+ * view's header: its class and its no-colour glyph. Running is plain, done
205
+ * green `✓`, failed — a budget stop, a kill, a lost process — red `✗`,
206
+ * stopped by a person dim `■`.
207
+ */
208
+ export declare function viewState(state: string): [string, string];
209
+ /** How many characters of a view's name the switcher keeps under 64 columns (plan 34 part C). */
210
+ export declare const SWITCHER_NARROW = 8;
211
+ /**
212
+ * The view switcher (decisions 0031 §4, 0033 §2): every view in its state's
213
+ * colour — running plain, done green, failed red, stopped dim; in mono
214
+ * `name ✓`, `name ✗`, `name ■` — the one on screen selected: inverse, `›name`
215
+ * in mono. While it has focus the cursor is underlined, `[name]` in mono.
216
+ * Under 64 columns each name keeps its first 8 characters; when even that does
217
+ * not fit, only the cursor's (or the screen's) view is drawn, between `‹ ›`,
218
+ * with where it is in the list. `null` while there is one view.
219
+ */
220
+ export declare function switcher(views: string[], view: string | null | undefined, states: Record<string, string> | null | undefined, cursor: number | null | undefined, w: number, m: boolean): Line | null;
221
+ /** The zero-width run in front of the task indicator, so a client finds it for a click (decision 0031 §3). */
222
+ export declare const INDICATOR_MARK = "open:tasks";
223
+ /** Where the task indicator is on a row: its column and its width. */
224
+ export declare function indicatorMark(l: Line): [number, number] | null;
225
+ /**
226
+ * The task indicator (decision 0031 §1): what runs, by kind —
227
+ * `2 agents · 1 background task`, `2a · 1bg` under 64 columns — hidden when
228
+ * nothing does. Focused, it is inverse, or `›` in mono.
229
+ */
230
+ export declare function indicator(agents: number | null | undefined, tasks: number | null | undefined, w: number, focused: boolean, m: boolean): Line | null;
231
+ /** A permission mode's badge: glyph and label, class, and its mono word. */
232
+ export declare function modeBadge(mode: string): [string, string, string];
233
+ /** A 10-cell meter: `━` in colour, `[####......]` in mono. */
234
+ export declare function ctxMeter(pct: number, m: boolean): Line;
235
+ /** Rust's `f64::round`: half away from zero. */
236
+ export declare function roundHalfAway(x: number): number;
237
+ /** The footer rows: one at ≥64 columns, two below. */
238
+ export declare function footerLines(p: FooterView, w: number, m: boolean): Line[];
239
+ /** The footer. */
240
+ export declare function footer(p: FooterView, w: number, m: boolean): Item[];