@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,136 @@
1
+ /**
2
+ * List 2 · Input & navigation: @-mentions, attachments, the palette, search,
3
+ * help, message actions, rewind — port of `el/input.rs`.
4
+ */
5
+ import { type Item } from "../cells";
6
+ import { type Runs } from "./content";
7
+ /** A match. */
8
+ export interface MentionItem {
9
+ path: string;
10
+ meta: string;
11
+ }
12
+ /** The `@` picker above the input. */
13
+ export interface MentionView {
14
+ query: string;
15
+ typed?: string;
16
+ items?: MentionItem[];
17
+ selected?: number;
18
+ /** `ready`, `indexing`, `error`, `outside`, `chip`; `ready` when absent. */
19
+ state?: string;
20
+ note?: string | null;
21
+ error?: string | null;
22
+ chip?: string | null;
23
+ }
24
+ /** Fuzzy file and symbol search over the workspace; a pick becomes a chip. */
25
+ export declare function mention(p: MentionView, w: number, m: boolean): Item[];
26
+ /** An attachment. */
27
+ export interface AttachChip {
28
+ text: string;
29
+ /** `ready`, `uploading`, `rejected`, `unsupported`; `ready` when absent. */
30
+ state?: string;
31
+ }
32
+ /** The input with its attachments on the first row. */
33
+ export interface AttachView {
34
+ chips: AttachChip[];
35
+ selected?: number | null;
36
+ typed?: string;
37
+ /** `[kind, text]`: `error` or `warn`. */
38
+ message?: [string, string] | null;
39
+ hint?: string;
40
+ }
41
+ /** Chips on their own row inside the input. */
42
+ export declare function attach(p: AttachView, w: number, m: boolean): Item[];
43
+ /** A palette entry. */
44
+ export interface PaletteItem {
45
+ label: string;
46
+ detail?: string;
47
+ disabled?: boolean;
48
+ }
49
+ /** A group of entries. */
50
+ export interface PaletteGroup {
51
+ label: string;
52
+ items?: PaletteItem[];
53
+ loading?: string | null;
54
+ error?: string | null;
55
+ }
56
+ /** ctrl+k. */
57
+ export interface PaletteView {
58
+ query?: string;
59
+ groups?: PaletteGroup[];
60
+ /** The entry under the cursor, by label. */
61
+ selected?: string | null;
62
+ }
63
+ /** Every command, setting and recent session in one fuzzy list. */
64
+ export declare function palette(p: PaletteView, w: number, m: boolean): Item[];
65
+ /** ctrl+r in the input, or `/` in the thread. */
66
+ export interface SearchView {
67
+ /** `history` or `transcript`. */
68
+ scope: string;
69
+ query: string;
70
+ count?: string;
71
+ /** `ready`, `searching`, `empty`, `error`; `ready` when absent. */
72
+ state?: string;
73
+ entry?: string;
74
+ rows?: Runs[];
75
+ note?: string | null;
76
+ error?: string | null;
77
+ }
78
+ /** The search row, or the history label in the input. */
79
+ export declare function search(p: SearchView, w: number, m: boolean): Item[];
80
+ /** A key. */
81
+ export interface KeyV {
82
+ key: string;
83
+ action: string;
84
+ disabled?: boolean;
85
+ }
86
+ /** `?` on an empty input. */
87
+ export interface HelpView {
88
+ keys: KeyV[];
89
+ filter?: string | null;
90
+ note?: string | null;
91
+ visible?: number | null;
92
+ }
93
+ /** Every key in two columns at ≥64 columns, one below; typing filters. */
94
+ export declare function help(p: HelpView, w: number, m: boolean): Item[];
95
+ /** An action on a message. */
96
+ export interface ActionV {
97
+ key: string;
98
+ label: string;
99
+ disabled?: boolean;
100
+ }
101
+ /** The row under a selected message. */
102
+ export interface ActionsView {
103
+ message: string;
104
+ actions: ActionV[];
105
+ /** The action with focus, by key. */
106
+ focused?: string | null;
107
+ busy?: string | null;
108
+ error?: string | null;
109
+ note?: string | null;
110
+ }
111
+ /** Copy, retry, edit & resend, fork — one row, single-letter keys. */
112
+ export declare function actions(p: ActionsView, w: number, m: boolean): Item[];
113
+ /** A file a turn changed. */
114
+ export interface FileStat {
115
+ path: string;
116
+ stat: string;
117
+ }
118
+ /** A turn to rewind to. */
119
+ export interface RewindTurn {
120
+ n: string;
121
+ prompt: string;
122
+ at: string;
123
+ files?: FileStat[];
124
+ /** `true` when absent. */
125
+ checkpoint?: boolean;
126
+ }
127
+ /** esc esc on an empty input. */
128
+ export interface RewindView {
129
+ turns?: RewindTurn[];
130
+ selected?: number;
131
+ busy?: string | null;
132
+ error?: string | null;
133
+ hint?: string | null;
134
+ }
135
+ /** Turns with the files each changed; enter restores code and chat. */
136
+ export declare function rewind(p: RewindView, w: number, m: boolean): Item[];
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Streaming markdown as rows — port of `el/markdown.rs`.
3
+ *
4
+ * A line is final once its newline arrives: nothing drawn above the last line
5
+ * ever changes. A half-open fence is code at once. The markup is formatted,
6
+ * not shown: headings lose their `#`, emphasis is styled, lists nest.
7
+ */
8
+ import { type Line } from "../cells";
9
+ /** Markdown source as rows at `w` columns. */
10
+ export declare function render(src: string, w: number, m: boolean, streaming: boolean, link: number | null): Line[];
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Every element of the design, as a view model and a function drawing it —
3
+ * port of `el/mod.rs`.
4
+ *
5
+ * A view model is plain JSON (snake_case, the same fields and defaults as the
6
+ * crate's serde structs), so the same props drive the Rust crate, this port
7
+ * and the fixtures under `harness/clients/conformance/design/props/`.
8
+ */
9
+ import { type Item } from "../cells";
10
+ import * as agent from "./agent";
11
+ import * as chrome from "./chrome";
12
+ import * as content from "./content";
13
+ import * as extensions from "./extensions";
14
+ import * as context from "./context";
15
+ import * as feedback from "./feedback";
16
+ import * as input from "./input";
17
+ import * as sessions from "./sessions";
18
+ /** Every element id, in the design's order. */
19
+ export declare const ELEMENTS: readonly string[];
20
+ /** An element's props did not match its view model, or the id is unknown. */
21
+ export declare class BadProps extends Error {
22
+ readonly id: string;
23
+ readonly reason: string;
24
+ constructor(id: string, reason: string);
25
+ }
26
+ /**
27
+ * Draw element `id` from its props at `w` columns, in mono when `m`.
28
+ *
29
+ * @throws {BadProps} when the id is unknown or the props are not an object.
30
+ */
31
+ export declare function render(id: string, props: unknown, w: number, m: boolean): Item[];
32
+ export { agent, chrome, content, context, extensions, feedback, input, sessions };
33
+ export { type Block, blocks } from "./block";
34
+ export * as markdown from "./markdown";
35
+ export { arrow, errLines, flag, hl, ov, panelHead, warnLines } from "./helpers";
@@ -0,0 +1,131 @@
1
+ /**
2
+ * List 2 · Sessions & setup: resume, the session tree, OAuth, MCP, skills,
3
+ * workspace trust, the first run, the theme picker — port of `el/sessions.rs`.
4
+ */
5
+ import { type Item, type Line } from "../cells";
6
+ import { type Runs } from "./content";
7
+ /** A past session. */
8
+ export interface SessionRow {
9
+ title: string;
10
+ branch: string;
11
+ at: string;
12
+ cost: string;
13
+ turns: string;
14
+ locked?: string | null;
15
+ }
16
+ /** `orrery --resume`, `/resume`. */
17
+ export interface ResumeView {
18
+ items?: SessionRow[];
19
+ selected?: number;
20
+ preview?: Runs[];
21
+ last?: string;
22
+ loading?: string | null;
23
+ error?: string | null;
24
+ }
25
+ /** Title, branch, cost; a preview pane on the right at ≥64 columns. */
26
+ export declare function resume(p: ResumeView, w: number, m: boolean): Item[];
27
+ /** A turn in the tree. */
28
+ export interface TreeTurn {
29
+ lane?: string;
30
+ n: string;
31
+ prompt: string;
32
+ branch?: string | null;
33
+ current?: boolean;
34
+ }
35
+ /** Forks, with box-drawing lanes. */
36
+ export interface SessionTreeView {
37
+ turns?: TreeTurn[];
38
+ selected?: number;
39
+ busy?: string | null;
40
+ error?: string | null;
41
+ }
42
+ /** `●` a turn, `◉` where you are. */
43
+ export declare function sessionTree(p: SessionTreeView, w: number, m: boolean): Item[];
44
+ /** Device-code sign-in. */
45
+ export interface OAuthView {
46
+ title: string;
47
+ step?: string | null;
48
+ url: string;
49
+ code: string;
50
+ /** `waiting`, `approved`, `error`, `expired`; `waiting` when absent. */
51
+ state?: string;
52
+ note?: string;
53
+ }
54
+ /** The URL, the code large in a heavy box, a spinner with the expiry. */
55
+ export declare function oauth(p: OAuthView, w: number, m: boolean): Item[];
56
+ /** A server. */
57
+ export interface Server {
58
+ name: string;
59
+ transport: string;
60
+ /** `ok`, `auth`, `failed`, `off`, `connecting`. */
61
+ state: string;
62
+ detail: string;
63
+ }
64
+ /** `/mcp`. */
65
+ export interface McpView {
66
+ servers?: Server[];
67
+ selected?: number;
68
+ tools?: string[] | null;
69
+ note?: string | null;
70
+ }
71
+ /** One row per server; its error and fix on the row. */
72
+ export declare function mcp(p: McpView, w: number, m: boolean): Item[];
73
+ /** A skill. */
74
+ export interface SkillRow {
75
+ name: string;
76
+ version: string;
77
+ /** `on`, `off`, `update`, `installing`. */
78
+ state: string;
79
+ latest?: string | null;
80
+ progress?: number | null;
81
+ }
82
+ /** `/skills`. */
83
+ export interface SkillsView {
84
+ /** `installed` or `available`; `installed` when absent. */
85
+ tab?: string;
86
+ items?: SkillRow[];
87
+ selected?: number;
88
+ error?: string | null;
89
+ }
90
+ /** Tabs, then name, version and state per row; install progress inline. */
91
+ export declare function skills(p: SkillsView, w: number, m: boolean): Item[];
92
+ /** The first run in a folder. */
93
+ export interface TrustView {
94
+ path: string;
95
+ hooks?: string[];
96
+ mcp?: string[];
97
+ /** Other files found that trust would load (configuration, extensions). */
98
+ files?: string[];
99
+ /** The answers, in order; the design's three when empty. */
100
+ options?: string[];
101
+ selected?: number;
102
+ error?: string | null;
103
+ }
104
+ /** What trust enables, the hooks and servers by name, three choices. */
105
+ export declare function trust(p: TrustView, w: number, m: boolean): Item[];
106
+ /** Under the banner on an empty thread. */
107
+ export interface WelcomeView {
108
+ suggestions?: string[];
109
+ tips?: string[];
110
+ /** `ready`, `scanning`, `empty`; `ready` when absent. */
111
+ state?: string;
112
+ selected?: number | null;
113
+ warn?: string | null;
114
+ }
115
+ /** Three suggestions, tips, and what is missing. */
116
+ export declare function welcome(p: WelcomeView, w: number, m: boolean): Item[];
117
+ /** A theme. */
118
+ export interface ThemeRow {
119
+ id: string;
120
+ label: string;
121
+ }
122
+ /** `/theme`. */
123
+ export interface ThemeView {
124
+ themes: ThemeRow[];
125
+ selected?: number;
126
+ error?: string | null;
127
+ }
128
+ /** The fixed sample every theme is previewed with. */
129
+ export declare function themeSample(w: number, m: boolean): Line[];
130
+ /** The list; under it, a fixed sample redrawn in the highlighted theme. */
131
+ export declare function theme(p: ThemeView, w: number, m: boolean): Item[];
package/dist/from.d.ts ADDED
@@ -0,0 +1,131 @@
1
+ /**
2
+ * From what the host sent to what the design draws — port of
3
+ * `harness/clients/cells/src/from.rs`.
4
+ *
5
+ * The protocol carries surfaces, turns and UI nodes; the design draws
6
+ * elements. This is the one place a TypeScript client turns the first into
7
+ * the second, so two clients cannot map a diff or a tool call differently.
8
+ * Only types are imported from `@getorrery/client` and `@getorrery/protocol`: this
9
+ * package stays pure drawing.
10
+ */
11
+ import type { TurnView } from "@getorrery/client";
12
+ import type { Field, Status, Surface, TurnMeta, UiDoc } from "@getorrery/protocol";
13
+ import { type Line } from "./cells";
14
+ import * as content from "./el/content";
15
+ /**
16
+ * What the client knows about a surface that the host does not: the cursor
17
+ * in a question, the focused field, whether a tool call is expanded.
18
+ */
19
+ export interface Local {
20
+ /** The choice under the cursor in a question. */
21
+ choice?: number | null;
22
+ /** The field with focus in a form, and what is typed in it. */
23
+ field?: [number, string] | null;
24
+ /** A tool call's whole result, not its preview. */
25
+ expanded?: boolean;
26
+ /** The row under the cursor in a list or table. */
27
+ row?: number | null;
28
+ /** How long a tool call took, or has run: `0.4s`. */
29
+ dur?: string | null;
30
+ }
31
+ /** Model prose, markdown, under a `●` gutter; the caret after it while it streams. */
32
+ export declare function proseMd(src: string, streaming: boolean, w: number, m: boolean): Line[];
33
+ /**
34
+ * A tool call's argument summary: the first string argument (a path, a
35
+ * command), else the arguments compacted.
36
+ */
37
+ export declare function argsSummary(raw0: string): string;
38
+ /** How many result rows a folded tool call previews. Decision 0024 folds a call to its head row alone. */
39
+ export declare const PREVIEW_ROWS = 3;
40
+ /** The class of the zero-width mark a foldable surface's first row carries: `fold:<surface id>`. */
41
+ export declare const FOLD_MARK = "fold:";
42
+ /** The surface id a row's fold mark names, when it has one. */
43
+ export declare function foldMark(l: Line): string | null;
44
+ /** A tool's short name for its line: `builtin.bash` is `bash`. */
45
+ export declare function toolName(name: string): string;
46
+ /**
47
+ * A call's main argument, for its one line (decision 0024): `bash` → the
48
+ * command, `read` / `write` / `edit` → the path, `glob` / `grep` → the
49
+ * pattern, anything else → its first string argument. First line only.
50
+ */
51
+ export declare function mainArg(name: string, raw: string): string;
52
+ /** A tool call: its head row, then its result under `⎿`. */
53
+ export declare function toolCall(name: string, status: Status | null | undefined, children: Surface[], local: Local, w: number, m: boolean): Line[];
54
+ /** The custom surface kind the host uses for input that joined a run. */
55
+ export declare const STEER_KIND = "orrery.steer";
56
+ /**
57
+ * The custom surface kind an attached agent's result is (decision 0021):
58
+ * `{ name, state, ms, text }`, drawn folded — `▸ code-reviewer · done · 12s` —
59
+ * over the first line of what it said; unfolded, all of it.
60
+ */
61
+ export declare const AGENT_RESULT_KIND = "orrery.agent-result";
62
+ /** A surface as the element that draws its kind. */
63
+ export { propsEntries, propsText, textForm } from "./open";
64
+ export declare function surfaceLines(s: Surface, local: Local, w: number, m: boolean): Line[];
65
+ /**
66
+ * How a client draws its own `custom` kinds (decision 0093): the rows for a
67
+ * kind's props at a width, null for a kind it does not know. The port of the
68
+ * crate's `catalog::CustomDraw`.
69
+ */
70
+ export type CustomDraw = (kind: string, props: Record<string, unknown>, w: number) => Line[] | null | undefined;
71
+ /**
72
+ * Install the client's own components: every `custom` surface of a kind it
73
+ * draws is drawn by it, at the width it is given (a stack's child at the
74
+ * child's), with its own classes. One per process; null removes it.
75
+ */
76
+ export declare function setCustomDraw(f: CustomDraw | null): void;
77
+ /** The installed hook's rows for `kind`, each cut to `w`; null when it does not draw `kind`. */
78
+ export declare function customLines(kind: string, props: unknown, w: number): Line[] | null;
79
+ /** A form surface's view model, with the client's focus and typing. */
80
+ export declare function formView(fields: Field[], submit: string, local: Local): content.FormView;
81
+ /** A turn's rows: the prompt, the reasoning fold, what came back, the outcome. */
82
+ export interface TurnOpts {
83
+ /** The line that started it. */
84
+ echo?: string | null;
85
+ /** Its reasoning is open. */
86
+ foldOpen?: boolean;
87
+ /** The clock now, for a fold still thinking. */
88
+ nowMs?: number;
89
+ /** The host's facts about it. */
90
+ meta?: TurnMeta | null;
91
+ /** A surface not drawn here (the dock has it). */
92
+ hidden?: string | null;
93
+ /** Per-surface client state, by surface id. */
94
+ local?: ((id: string) => Local) | null;
95
+ /** The prompt is selected: banded, the actions under it. */
96
+ selected?: boolean;
97
+ /**
98
+ * Close a turn that ended well with its outcome line. A prompt's turn
99
+ * does; a command's says how it ended itself.
100
+ */
101
+ outcome?: boolean;
102
+ }
103
+ /** Micro-USD as a person reads it (decision 0019): two decimals, or four under a cent, so a real cost never reads `$0.00`. */
104
+ export declare function usd(micro: number): string;
105
+ /** `1.2k`, `41.2k`, `340`. */
106
+ export declare function kilo(n: number): string;
107
+ /** A tool call's duration: `0.4s`, `12s`, `1m 5s`. */
108
+ export declare function dur(ms: number): string;
109
+ /** `4s`, `1m 52s`, `1h 12m`. */
110
+ export declare function took(ms: number): string;
111
+ /** The outcome line's detail: time, tools, tokens, cost. */
112
+ export declare function outcomeDetail(meta: TurnMeta | null | undefined, tools: number): string;
113
+ /** Whether a stack is a tool call: its first child is the arguments, as code. */
114
+ export declare function isToolCall(children: Surface[] | undefined): boolean;
115
+ /** A turn as rows at `w` columns. */
116
+ export declare function turn(tv: TurnView, o: TurnOpts, w: number, m: boolean): Line[];
117
+ /**
118
+ * How many options an element offers to choose from, when it is one a person
119
+ * chooses in (decision 0007): the trust answers, the models, the sessions to
120
+ * resume, the servers, the skills, the turns to rewind to, the themes, the
121
+ * forks, the suggestions.
122
+ */
123
+ export declare function options(el: string, props: unknown): number | null;
124
+ /** An element's props with this client's cursor put in them. */
125
+ export declare function withCursor(el: string, props: unknown, cursor: string | null | undefined): unknown;
126
+ /** An overlay's child as rows: as {@link node}, and an element that windows its rows (`/extensions`) is told the `rows` the overlay has. */
127
+ export declare function overlayNode(doc: UiDoc, id: string, cursor: string | null | undefined, rows: number, w: number, m: boolean): Line[];
128
+ /** A UI node (Tier 2, or an element) as rows. `cursor` is where this client moved a list's cursor. */
129
+ export declare function node(doc: UiDoc, id: string, cursor: string | null | undefined, w: number, m: boolean): Line[];
130
+ /** Whether a node's children are drawn by the node itself. */
131
+ export declare function childrenDrawnInline(type: string): boolean;
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Rows as the design's goldens write them, and a comparison that says where
3
+ * two renderings part — a port of `harness/clients/cells/src/golden.rs`.
4
+ *
5
+ * A row is `{ t: text, c: [[cells, classes], …] }`. The 2-cell pixel mark is
6
+ * `` with class `px:<state>`, the spinner `` with
7
+ * `spin <cls>`. A block beside rows is `{ blk: {…}, lines: [row, …] }`.
8
+ */
9
+ import { type Item, type Line } from "./cells";
10
+ /** A golden row, as JSON. */
11
+ export type Row = {
12
+ t: string;
13
+ c: [number, string][];
14
+ } | {
15
+ blk: unknown;
16
+ lines: Row[];
17
+ };
18
+ /** One line as a golden row, cut to `w` the way the design's page does. */
19
+ export declare function row(l: Line, w: number): Row;
20
+ /** An element's rows as golden rows. */
21
+ export declare function rows(items: Item[], w: number): Row[];
22
+ /** Normalise a golden row: classes sorted and runs merged, so order is not a difference. */
23
+ export declare function normalise(v: any): any;
24
+ /** What a set of classes paints in mono, where hue is gone. */
25
+ export declare function monoPaint(c: string): string;
26
+ /** Deep JSON equality, as `serde_json::Value` compares: key order ignored, a missing key is not `null`. */
27
+ export declare function jsonEq(a: unknown, b: unknown): boolean;
28
+ /** {@link diff}, comparing what mono paints rather than class names. */
29
+ export declare function diffMono(want: unknown[], got: unknown[]): string | null;
30
+ /** Where two renderings first differ, as a sentence and both renderings in plain text; `null` when the same. */
31
+ export declare function diff(want0: unknown[], got0: unknown[]): string | null;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * `@getorrery/cells` — the terminal design as cells, a TypeScript port of the
3
+ * `orrery-cells` crate (`harness/clients/cells`). Same view models, same
4
+ * rows, checked against the same goldens.
5
+ */
6
+ export * from "./cells";
7
+ export * as golden from "./golden";
8
+ export { compose, thumb, threadRows, type Part, type ScreenView } from "./screen";
9
+ export { BadProps, ELEMENTS, render } from "./el/mod";
10
+ export * as el from "./el/mod";
11
+ export * as from from "./from";
12
+ export * as open from "./open";
13
+ export * as pixelFrames from "./pixel_frames";
14
+ export * as session from "./session";