@chances-ai/tui 13.0.0 → 15.0.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/api-key-prompt.d.ts +8 -15
- package/dist/api-key-prompt.d.ts.map +1 -1
- package/dist/api-key-prompt.js +21 -31
- package/dist/api-key-prompt.js.map +1 -1
- package/dist/app.d.ts +15 -21
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +180 -151
- package/dist/app.js.map +1 -1
- package/dist/code-view.d.ts +9 -0
- package/dist/code-view.d.ts.map +1 -0
- package/dist/code-view.js +28 -0
- package/dist/code-view.js.map +1 -0
- package/dist/diff-model.d.ts +64 -0
- package/dist/diff-model.d.ts.map +1 -0
- package/dist/diff-model.js +156 -0
- package/dist/diff-model.js.map +1 -0
- package/dist/diff-view.d.ts +13 -0
- package/dist/diff-view.d.ts.map +1 -0
- package/dist/diff-view.js +60 -0
- package/dist/diff-view.js.map +1 -0
- package/dist/highlight-to-segments.d.ts +18 -0
- package/dist/highlight-to-segments.d.ts.map +1 -0
- package/dist/highlight-to-segments.js +224 -0
- package/dist/highlight-to-segments.js.map +1 -0
- package/dist/index.d.ts +15 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -2
- package/dist/index.js.map +1 -1
- package/dist/markdown.d.ts +5 -0
- package/dist/markdown.d.ts.map +1 -0
- package/dist/markdown.js +117 -0
- package/dist/markdown.js.map +1 -0
- package/dist/modal.d.ts +3 -2
- package/dist/modal.d.ts.map +1 -1
- package/dist/modal.js +3 -2
- package/dist/modal.js.map +1 -1
- package/dist/model-picker.d.ts +7 -39
- package/dist/model-picker.d.ts.map +1 -1
- package/dist/model-picker.js +14 -65
- package/dist/model-picker.js.map +1 -1
- package/dist/progress.d.ts +41 -0
- package/dist/progress.d.ts.map +1 -0
- package/dist/progress.js +122 -0
- package/dist/progress.js.map +1 -0
- package/dist/select.d.ts +59 -0
- package/dist/select.d.ts.map +1 -0
- package/dist/select.js +114 -0
- package/dist/select.js.map +1 -0
- package/dist/session-picker.d.ts +7 -15
- package/dist/session-picker.d.ts.map +1 -1
- package/dist/session-picker.js +14 -40
- package/dist/session-picker.js.map +1 -1
- package/dist/slash-typeahead.d.ts +34 -0
- package/dist/slash-typeahead.d.ts.map +1 -0
- package/dist/slash-typeahead.js +78 -0
- package/dist/slash-typeahead.js.map +1 -0
- package/dist/theme-context.d.ts +25 -0
- package/dist/theme-context.d.ts.map +1 -0
- package/dist/theme-context.js +24 -0
- package/dist/theme-context.js.map +1 -0
- package/dist/theme.d.ts +106 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +116 -0
- package/dist/theme.js.map +1 -0
- package/dist/tool-line.d.ts +33 -0
- package/dist/tool-line.d.ts.map +1 -0
- package/dist/tool-line.js +168 -0
- package/dist/tool-line.js.map +1 -0
- package/dist/tool-message.d.ts +18 -0
- package/dist/tool-message.d.ts.map +1 -0
- package/dist/tool-message.js +37 -0
- package/dist/tool-message.js.map +1 -0
- package/dist/view-model.d.ts +46 -1
- package/dist/view-model.d.ts.map +1 -1
- package/dist/view-model.js +109 -16
- package/dist/view-model.js.map +1 -1
- package/package.json +9 -4
package/dist/select.d.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { type JSX, type ReactNode } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* (5.10 A2) The ONE generic single-select primitive. Generalizes the
|
|
4
|
+
* `reduceModelPicker` pure-reducer pattern so `/model`, `/resume`, and (v16)
|
|
5
|
+
* `AskUserQuestion` all drive the same list UI with identical keys/marks — the
|
|
6
|
+
* mistake pi and oh-my-pi both made was letting each call site re-roll its own
|
|
7
|
+
* list loop. Navigation comes entirely from the `Select` keybinding context
|
|
8
|
+
* (ink-ext A1); this component owns no `useInput`.
|
|
9
|
+
*
|
|
10
|
+
* `SelectMulti` (checkbox multi-select) lands in v16 alongside its only consumer,
|
|
11
|
+
* `AskUserQuestion` — building it now would be speculative.
|
|
12
|
+
*/
|
|
13
|
+
export interface SelectOption<T> {
|
|
14
|
+
/** Row text. */
|
|
15
|
+
label: string;
|
|
16
|
+
/** The value handed to `onSelect`. */
|
|
17
|
+
value: T;
|
|
18
|
+
/** Optional dim trailing description. */
|
|
19
|
+
description?: string;
|
|
20
|
+
/** Non-selectable row (skipped by cursor movement, dimmed). */
|
|
21
|
+
disabled?: boolean;
|
|
22
|
+
/** Marks the currently-active choice (rendered with a `●`). */
|
|
23
|
+
current?: boolean;
|
|
24
|
+
}
|
|
25
|
+
/** Case-insensitive substring filter over `label`+`description`. Empty filter
|
|
26
|
+
* returns the list unchanged. */
|
|
27
|
+
export declare function filterOptions<T>(options: SelectOption<T>[], filter: string): SelectOption<T>[];
|
|
28
|
+
/** Move the cursor by `delta`, clamped to `[0, count-1]` (no wrap — matches
|
|
29
|
+
* claude-code's Select + our model-picker), skipping `disabled` rows in the
|
|
30
|
+
* direction of travel. Returns the original cursor when there's nowhere to go. */
|
|
31
|
+
export declare function moveCursor<T>(options: SelectOption<T>[], cursor: number, delta: number): number;
|
|
32
|
+
/** Page the cursor by a window, clamped to range, then settle onto the nearest
|
|
33
|
+
* enabled row (search in the travel direction first, else the other way). */
|
|
34
|
+
export declare function pageCursor<T>(options: SelectOption<T>[], cursor: number, dir: -1 | 1, visibleRows: number): number;
|
|
35
|
+
/** The slice of options visible given the cursor + window, centered like the
|
|
36
|
+
* model picker. Returns `{ slice, offset }` so the renderer can mark the cursor
|
|
37
|
+
* and show "N more" affordances. */
|
|
38
|
+
export declare function visibleWindow<T>(options: SelectOption<T>[], cursor: number, visibleRows: number): {
|
|
39
|
+
slice: SelectOption<T>[];
|
|
40
|
+
offset: number;
|
|
41
|
+
};
|
|
42
|
+
/** Clamp a cursor into range against a (possibly re-filtered) list. */
|
|
43
|
+
export declare function clampCursor<T>(options: SelectOption<T>[], cursor: number): number;
|
|
44
|
+
export interface SelectProps<T> {
|
|
45
|
+
options: SelectOption<T>[];
|
|
46
|
+
onSelect: (value: T) => void;
|
|
47
|
+
onCancel: () => void;
|
|
48
|
+
/** Header line above the list. */
|
|
49
|
+
heading?: ReactNode;
|
|
50
|
+
/** Max rows shown at once (default 10). */
|
|
51
|
+
visibleRows?: number;
|
|
52
|
+
/** When true, typing narrows the list (model picker); otherwise typed chars
|
|
53
|
+
* are ignored (session picker). Default false. */
|
|
54
|
+
filterable?: boolean;
|
|
55
|
+
/** Whether this select owns input right now (pushes the `Select` context). */
|
|
56
|
+
active?: boolean;
|
|
57
|
+
}
|
|
58
|
+
export declare function Select<T>({ options, onSelect, onCancel, heading, visibleRows, filterable, active, }: SelectProps<T>): JSX.Element;
|
|
59
|
+
//# sourceMappingURL=select.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../src/select.tsx"],"names":[],"mappings":"AACA,OAAO,EAAY,KAAK,GAAG,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAI3D;;;;;;;;;;GAUG;AACH,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,gBAAgB;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,sCAAsC;IACtC,KAAK,EAAE,CAAC,CAAC;IACT,yCAAyC;IACzC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,+DAA+D;IAC/D,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAID;kCACkC;AAClC,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,YAAY,CAAC,CAAC,CAAC,EAAE,CAI9F;AAED;;mFAEmF;AACnF,wBAAgB,UAAU,CAAC,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAU/F;AAED;8EAC8E;AAC9E,wBAAgB,UAAU,CAAC,CAAC,EAC1B,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,EAC1B,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,EACX,WAAW,EAAE,MAAM,GAClB,MAAM,CAOR;AAED;;qCAEqC;AACrC,wBAAgB,aAAa,CAAC,CAAC,EAC7B,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,EAC1B,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAClB;IAAE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAM9C;AAED,uEAAuE;AACvE,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEjF;AAID,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAC7B,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,kCAAkC;IAClC,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,2CAA2C;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;uDACmD;IACnD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,8EAA8E;IAC9E,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,MAAM,CAAC,CAAC,EAAE,EACxB,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,WAAgB,EAChB,UAAkB,EAClB,MAAa,GACd,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,OAAO,CA6F9B"}
|
package/dist/select.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { useKeybinding, useKeybindingContext, useTextInput } from "@chances-ai/ink-ext";
|
|
5
|
+
import { useTheme } from "./theme-context.js";
|
|
6
|
+
// -- pure helpers (unit-tested without a TTY, the reduceModelPicker convention) --
|
|
7
|
+
/** Case-insensitive substring filter over `label`+`description`. Empty filter
|
|
8
|
+
* returns the list unchanged. */
|
|
9
|
+
export function filterOptions(options, filter) {
|
|
10
|
+
const lower = filter.trim().toLowerCase();
|
|
11
|
+
if (!lower)
|
|
12
|
+
return options;
|
|
13
|
+
return options.filter((o) => `${o.label} ${o.description ?? ""}`.toLowerCase().includes(lower));
|
|
14
|
+
}
|
|
15
|
+
/** Move the cursor by `delta`, clamped to `[0, count-1]` (no wrap — matches
|
|
16
|
+
* claude-code's Select + our model-picker), skipping `disabled` rows in the
|
|
17
|
+
* direction of travel. Returns the original cursor when there's nowhere to go. */
|
|
18
|
+
export function moveCursor(options, cursor, delta) {
|
|
19
|
+
if (options.length === 0)
|
|
20
|
+
return 0;
|
|
21
|
+
const step = delta < 0 ? -1 : 1;
|
|
22
|
+
let next = cursor;
|
|
23
|
+
for (let i = 0; i < options.length; i++) {
|
|
24
|
+
next += step;
|
|
25
|
+
if (next < 0 || next > options.length - 1)
|
|
26
|
+
return cursor; // hit an edge → stay
|
|
27
|
+
if (!options[next]?.disabled)
|
|
28
|
+
return next;
|
|
29
|
+
}
|
|
30
|
+
return cursor;
|
|
31
|
+
}
|
|
32
|
+
/** Page the cursor by a window, clamped to range, then settle onto the nearest
|
|
33
|
+
* enabled row (search in the travel direction first, else the other way). */
|
|
34
|
+
export function pageCursor(options, cursor, dir, visibleRows) {
|
|
35
|
+
if (options.length === 0)
|
|
36
|
+
return 0;
|
|
37
|
+
const target = Math.min(options.length - 1, Math.max(0, cursor + dir * visibleRows));
|
|
38
|
+
if (!options[target]?.disabled)
|
|
39
|
+
return target;
|
|
40
|
+
const towards = moveCursor(options, target, dir);
|
|
41
|
+
if (towards !== target)
|
|
42
|
+
return towards;
|
|
43
|
+
return moveCursor(options, target, dir === 1 ? -1 : 1);
|
|
44
|
+
}
|
|
45
|
+
/** The slice of options visible given the cursor + window, centered like the
|
|
46
|
+
* model picker. Returns `{ slice, offset }` so the renderer can mark the cursor
|
|
47
|
+
* and show "N more" affordances. */
|
|
48
|
+
export function visibleWindow(options, cursor, visibleRows) {
|
|
49
|
+
if (options.length <= visibleRows)
|
|
50
|
+
return { slice: options, offset: 0 };
|
|
51
|
+
const half = Math.floor(visibleRows / 2);
|
|
52
|
+
let offset = cursor - half;
|
|
53
|
+
offset = Math.max(0, Math.min(offset, options.length - visibleRows));
|
|
54
|
+
return { slice: options.slice(offset, offset + visibleRows), offset };
|
|
55
|
+
}
|
|
56
|
+
/** Clamp a cursor into range against a (possibly re-filtered) list. */
|
|
57
|
+
export function clampCursor(options, cursor) {
|
|
58
|
+
return Math.min(Math.max(0, cursor), Math.max(0, options.length - 1));
|
|
59
|
+
}
|
|
60
|
+
export function Select({ options, onSelect, onCancel, heading, visibleRows = 10, filterable = false, active = true, }) {
|
|
61
|
+
const { theme } = useTheme();
|
|
62
|
+
const [filter, setFilter] = useState("");
|
|
63
|
+
const [cursor, setCursor] = useState(0);
|
|
64
|
+
// Select is a MODAL context: while it's up, the chat below receives nothing.
|
|
65
|
+
useKeybindingContext("Select", active);
|
|
66
|
+
const matches = filterOptions(options, filter);
|
|
67
|
+
const safeCursor = clampCursor(matches, cursor);
|
|
68
|
+
useKeybinding("select:previous", () => setCursor(moveCursor(matches, safeCursor, -1)), {
|
|
69
|
+
context: "Select",
|
|
70
|
+
active,
|
|
71
|
+
});
|
|
72
|
+
useKeybinding("select:next", () => setCursor(moveCursor(matches, safeCursor, 1)), {
|
|
73
|
+
context: "Select",
|
|
74
|
+
active,
|
|
75
|
+
});
|
|
76
|
+
useKeybinding("select:pageUp", () => setCursor(pageCursor(matches, safeCursor, -1, visibleRows)), {
|
|
77
|
+
context: "Select",
|
|
78
|
+
active,
|
|
79
|
+
});
|
|
80
|
+
useKeybinding("select:pageDown", () => setCursor(pageCursor(matches, safeCursor, 1, visibleRows)), {
|
|
81
|
+
context: "Select",
|
|
82
|
+
active,
|
|
83
|
+
});
|
|
84
|
+
useKeybinding("select:accept", () => {
|
|
85
|
+
const choice = matches[safeCursor];
|
|
86
|
+
if (choice && !choice.disabled)
|
|
87
|
+
onSelect(choice.value);
|
|
88
|
+
else
|
|
89
|
+
onCancel(); // accept on empty/disabled = cancel, matching reduceModelPicker
|
|
90
|
+
}, { context: "Select", active });
|
|
91
|
+
useKeybinding("select:cancel", onCancel, { context: "Select", active });
|
|
92
|
+
// Free-text: narrows the filter when filterable; backspace edits it. Typed
|
|
93
|
+
// chars are otherwise ignored (no Other row in v15 — that's v16/AskUserQuestion).
|
|
94
|
+
useTextInput("Select", (input, key) => {
|
|
95
|
+
if (!filterable)
|
|
96
|
+
return;
|
|
97
|
+
if (key.backspace || key.delete) {
|
|
98
|
+
setFilter((f) => f.slice(0, -1));
|
|
99
|
+
setCursor(0);
|
|
100
|
+
}
|
|
101
|
+
else if (input && !key.ctrl && !key.meta) {
|
|
102
|
+
setFilter((f) => f + input);
|
|
103
|
+
setCursor(0);
|
|
104
|
+
}
|
|
105
|
+
}, { active });
|
|
106
|
+
const { slice, offset } = visibleWindow(matches, safeCursor, visibleRows);
|
|
107
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: theme.permission, paddingX: 1, children: [heading ? _jsx(Text, { color: theme.permission, children: heading }) : null, filterable ? (_jsxs(Box, { marginTop: heading ? 1 : 0, children: [_jsx(Text, { children: "filter: " }), _jsx(Text, { color: theme.warning, children: filter || "(any)" })] })) : null, _jsxs(Box, { flexDirection: "column", marginTop: 1, children: [matches.length === 0 ? (_jsx(Text, { dimColor: true, children: "no matches" })) : (slice.map((o, i) => {
|
|
108
|
+
const idx = offset + i;
|
|
109
|
+
const selected = idx === safeCursor;
|
|
110
|
+
const marker = o.current ? "●" : " ";
|
|
111
|
+
return (_jsxs(Text, { color: selected ? theme.permission : undefined, dimColor: o.disabled, children: [selected ? "❯ " : " ", marker, " ", o.label, o.description ? _jsxs(Text, { dimColor: true, children: [" \u2014 ", o.description] }) : null] }, `${idx}-${o.label}`));
|
|
112
|
+
})), matches.length > slice.length ? (_jsxs(Text, { dimColor: true, children: ["\u2026 ", matches.length - slice.length, " more"] })) : null] })] }));
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=select.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select.js","sourceRoot":"","sources":["../src/select.tsx"],"names":[],"mappings":"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"}
|
package/dist/session-picker.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { PickerKey } from "./model-picker.js";
|
|
1
|
+
import type { JSX } from "react";
|
|
3
2
|
export interface PickableSession {
|
|
4
3
|
id: string;
|
|
5
4
|
title: string;
|
|
@@ -10,19 +9,12 @@ export interface PickableSession {
|
|
|
10
9
|
preview?: string;
|
|
11
10
|
}
|
|
12
11
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
resolved?: PickableSession | null;
|
|
20
|
-
};
|
|
21
|
-
/**
|
|
22
|
-
* Vertical list of recent sessions with arrow-key cursor + Enter to resume.
|
|
23
|
-
* Modeled on oh-my-pi's `session-selector.ts`; simplified — no fuzzy filter
|
|
24
|
-
* yet (defer until lists exceed ~20 entries in practice). All keystroke
|
|
25
|
-
* logic in {@link reduceSessionPicker} for testability.
|
|
12
|
+
* (5.10 A4) Recent-session picker — a thin wrapper over the generic
|
|
13
|
+
* {@link Select}. The old `useInput` + `reduceSessionPicker` reducer are gone;
|
|
14
|
+
* the ↑↓/Enter/Esc behavior is the Select's (see `select.test`). Not filterable
|
|
15
|
+
* (lists are short — last ~10 by updatedAt). Signature unchanged so
|
|
16
|
+
* `apps/cli/src/slash/resume.ts` renders `<SessionPicker sessions onChoose/>`
|
|
17
|
+
* verbatim.
|
|
26
18
|
*/
|
|
27
19
|
export declare function SessionPicker({ sessions, onChoose, }: {
|
|
28
20
|
sessions: PickableSession[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-picker.d.ts","sourceRoot":"","sources":["../src/session-picker.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"session-picker.d.ts","sourceRoot":"","sources":["../src/session-picker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAGjC,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,SAAS,EAAE,MAAM,CAAC;IAClB;qEACiE;IACjE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,QAAQ,GACT,EAAE;IACD,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,QAAQ,EAAE,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI,KAAK,IAAI,CAAC;CACrD,GAAG,GAAG,CAAC,OAAO,CAcd"}
|
package/dist/session-picker.js
CHANGED
|
@@ -1,45 +1,19 @@
|
|
|
1
|
-
import { jsx as _jsx
|
|
2
|
-
import {
|
|
3
|
-
import { useState } from "react";
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Select } from "./select.js";
|
|
4
3
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
if (key.escape)
|
|
12
|
-
return { cursor: safe, resolved: null };
|
|
13
|
-
if (key.return)
|
|
14
|
-
return { cursor: safe, resolved: sessions[safe] ?? null };
|
|
15
|
-
if (key.upArrow)
|
|
16
|
-
return { cursor: Math.max(0, safe - 1) };
|
|
17
|
-
if (key.downArrow)
|
|
18
|
-
return { cursor: Math.min(sessions.length - 1, safe + 1) };
|
|
19
|
-
return { cursor: safe };
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Vertical list of recent sessions with arrow-key cursor + Enter to resume.
|
|
23
|
-
* Modeled on oh-my-pi's `session-selector.ts`; simplified — no fuzzy filter
|
|
24
|
-
* yet (defer until lists exceed ~20 entries in practice). All keystroke
|
|
25
|
-
* logic in {@link reduceSessionPicker} for testability.
|
|
4
|
+
* (5.10 A4) Recent-session picker — a thin wrapper over the generic
|
|
5
|
+
* {@link Select}. The old `useInput` + `reduceSessionPicker` reducer are gone;
|
|
6
|
+
* the ↑↓/Enter/Esc behavior is the Select's (see `select.test`). Not filterable
|
|
7
|
+
* (lists are short — last ~10 by updatedAt). Signature unchanged so
|
|
8
|
+
* `apps/cli/src/slash/resume.ts` renders `<SessionPicker sessions onChoose/>`
|
|
9
|
+
* verbatim.
|
|
26
10
|
*/
|
|
27
11
|
export function SessionPicker({ sessions, onChoose, }) {
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
if (next !== cursor)
|
|
37
|
-
setCursor(next);
|
|
38
|
-
});
|
|
39
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, children: [_jsx(Text, { color: "cyan", children: "Resume a session \u00B7 \u2191\u2193 \u00B7 Enter \u00B7 Esc" }), _jsx(Box, { flexDirection: "column", marginTop: 1, children: sessions.length === 0 ? (_jsx(Text, { dimColor: true, children: "no saved sessions in this workspace" })) : (sessions.slice(0, 10).map((s, i) => {
|
|
40
|
-
const selected = i === safeCursor;
|
|
41
|
-
const date = s.updatedAt.slice(0, 10);
|
|
42
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: selected ? "cyan" : undefined, children: [selected ? "▸ " : " ", _jsx(Text, { dimColor: true, children: date }), " ", s.title] }), s.preview ? (_jsxs(Text, { dimColor: true, children: [" ", s.preview.slice(0, 60)] })) : null] }, s.id));
|
|
43
|
-
})) })] }));
|
|
12
|
+
const options = sessions.map((s) => ({
|
|
13
|
+
label: `${s.updatedAt.slice(0, 10)} ${s.title}`,
|
|
14
|
+
value: s,
|
|
15
|
+
description: s.preview ? s.preview.slice(0, 60) : undefined,
|
|
16
|
+
}));
|
|
17
|
+
return (_jsx(Select, { heading: "Resume a session \u00B7 \u2191\u2193 \u00B7 Enter \u00B7 Esc", options: options, onSelect: onChoose, onCancel: () => onChoose(null) }));
|
|
44
18
|
}
|
|
45
19
|
//# sourceMappingURL=session-picker.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-picker.js","sourceRoot":"","sources":["../src/session-picker.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"session-picker.js","sourceRoot":"","sources":["../src/session-picker.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,MAAM,EAAqB,MAAM,aAAa,CAAC;AAYxD;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,EAC5B,QAAQ,EACR,QAAQ,GAIT;IACC,MAAM,OAAO,GAAoC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACpE,KAAK,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE;QAC/C,KAAK,EAAE,CAAC;QACR,WAAW,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS;KAC5D,CAAC,CAAC,CAAC;IACJ,OAAO,CACL,KAAC,MAAM,IACL,OAAO,EAAC,8DAAqC,EAC7C,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,GAC9B,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type JSX } from "react";
|
|
2
|
+
export interface SlashSuggestion {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
/** (5.10 A3) Ghost-text shown after the name, e.g. `<provider> <url>`. */
|
|
6
|
+
argumentHint?: string;
|
|
7
|
+
}
|
|
8
|
+
/** Pure helper for picking the suggestions to show for a partial input. The
|
|
9
|
+
* typeahead is only meaningful before the first space (while typing the command
|
|
10
|
+
* NAME); once args begin, the menu hides and Enter submits normally. */
|
|
11
|
+
export declare function suggestSlashCommands(input: string, available: SlashSuggestion[]): SlashSuggestion[];
|
|
12
|
+
/**
|
|
13
|
+
* (5.10 A3) Stateful slash-command typeahead — replaces the old passive
|
|
14
|
+
* ghost-text list. While visible it owns the **non-modal** `Autocomplete`
|
|
15
|
+
* context (ink-ext A1), so the user keeps typing into chat to filter, but
|
|
16
|
+
* `↑/↓` select, `Tab` completes the name, `Enter` executes the SELECTED command
|
|
17
|
+
* (not the raw text), and `Esc` dismisses. The Enter interception is real
|
|
18
|
+
* submit-gating: `Autocomplete.return → autocomplete:execute` resolves before
|
|
19
|
+
* `Chat.chat:submit` on the bus, so the menu must be acted on or dismissed.
|
|
20
|
+
*
|
|
21
|
+
* Visible only while typing the command name (input starts with `/`, no space
|
|
22
|
+
* yet, ≥1 match, not dismissed). Tab inserts a trailing space → the menu closes
|
|
23
|
+
* and the user types args, which Enter then submits via the normal chat path.
|
|
24
|
+
*/
|
|
25
|
+
export declare function SlashTypeahead({ input, available, busy, onComplete, onExecute, }: {
|
|
26
|
+
input: string;
|
|
27
|
+
available: SlashSuggestion[];
|
|
28
|
+
busy: boolean;
|
|
29
|
+
/** Tab: replace the draft with the completed `"/name "` (trailing space). */
|
|
30
|
+
onComplete: (newInput: string) => void;
|
|
31
|
+
/** Enter: run the selected command line `"/name"`. */
|
|
32
|
+
onExecute: (line: string) => void;
|
|
33
|
+
}): JSX.Element | null;
|
|
34
|
+
//# sourceMappingURL=slash-typeahead.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slash-typeahead.d.ts","sourceRoot":"","sources":["../src/slash-typeahead.tsx"],"names":[],"mappings":"AACA,OAAO,EAAuB,KAAK,GAAG,EAAE,MAAM,OAAO,CAAC;AAItD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,0EAA0E;IAC1E,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;yEAEyE;AACzE,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,eAAe,EAAE,GAC3B,eAAe,EAAE,CAKnB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,SAAS,EACT,IAAI,EACJ,UAAU,EACV,SAAS,GACV,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,IAAI,EAAE,OAAO,CAAC;IACd,6EAA6E;IAC7E,UAAU,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,sDAAsD;IACtD,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC,GAAG,GAAG,CAAC,OAAO,GAAG,IAAI,CAgErB"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import { useKeybinding, useKeybindingContext } from "@chances-ai/ink-ext";
|
|
5
|
+
import { useTheme } from "./theme-context.js";
|
|
6
|
+
/** Pure helper for picking the suggestions to show for a partial input. The
|
|
7
|
+
* typeahead is only meaningful before the first space (while typing the command
|
|
8
|
+
* NAME); once args begin, the menu hides and Enter submits normally. */
|
|
9
|
+
export function suggestSlashCommands(input, available) {
|
|
10
|
+
if (!input.startsWith("/"))
|
|
11
|
+
return [];
|
|
12
|
+
const partial = input.slice(1).toLowerCase();
|
|
13
|
+
if (partial === "")
|
|
14
|
+
return available.slice(0, 5);
|
|
15
|
+
return available.filter((c) => c.name.toLowerCase().startsWith(partial)).slice(0, 5);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* (5.10 A3) Stateful slash-command typeahead — replaces the old passive
|
|
19
|
+
* ghost-text list. While visible it owns the **non-modal** `Autocomplete`
|
|
20
|
+
* context (ink-ext A1), so the user keeps typing into chat to filter, but
|
|
21
|
+
* `↑/↓` select, `Tab` completes the name, `Enter` executes the SELECTED command
|
|
22
|
+
* (not the raw text), and `Esc` dismisses. The Enter interception is real
|
|
23
|
+
* submit-gating: `Autocomplete.return → autocomplete:execute` resolves before
|
|
24
|
+
* `Chat.chat:submit` on the bus, so the menu must be acted on or dismissed.
|
|
25
|
+
*
|
|
26
|
+
* Visible only while typing the command name (input starts with `/`, no space
|
|
27
|
+
* yet, ≥1 match, not dismissed). Tab inserts a trailing space → the menu closes
|
|
28
|
+
* and the user types args, which Enter then submits via the normal chat path.
|
|
29
|
+
*/
|
|
30
|
+
export function SlashTypeahead({ input, available, busy, onComplete, onExecute, }) {
|
|
31
|
+
const { theme } = useTheme();
|
|
32
|
+
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
33
|
+
const [dismissed, setDismissed] = useState(false);
|
|
34
|
+
const matches = suggestSlashCommands(input, available);
|
|
35
|
+
const isCommandName = input.startsWith("/") && !input.includes(" ");
|
|
36
|
+
const visible = isCommandName && matches.length > 0 && !dismissed;
|
|
37
|
+
// Any edit to the draft re-opens the menu and resets the selection — the
|
|
38
|
+
// filter changed, so a stale index/dismiss must not stick.
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
setDismissed(false);
|
|
41
|
+
setSelectedIndex(0);
|
|
42
|
+
}, [input]);
|
|
43
|
+
const safeIndex = Math.min(selectedIndex, Math.max(0, matches.length - 1));
|
|
44
|
+
useKeybindingContext("Autocomplete", visible);
|
|
45
|
+
useKeybinding("autocomplete:previous", () => setSelectedIndex(Math.max(0, safeIndex - 1)), {
|
|
46
|
+
context: "Autocomplete",
|
|
47
|
+
active: visible,
|
|
48
|
+
});
|
|
49
|
+
useKeybinding("autocomplete:next", () => setSelectedIndex(Math.min(matches.length - 1, safeIndex + 1)), {
|
|
50
|
+
context: "Autocomplete",
|
|
51
|
+
active: visible,
|
|
52
|
+
});
|
|
53
|
+
useKeybinding("autocomplete:accept", // Tab — complete the name, leave args to the user
|
|
54
|
+
() => {
|
|
55
|
+
const m = matches[safeIndex];
|
|
56
|
+
if (m)
|
|
57
|
+
onComplete(`/${m.name} `);
|
|
58
|
+
}, { context: "Autocomplete", active: visible });
|
|
59
|
+
useKeybinding("autocomplete:execute", // Enter — run the selected command
|
|
60
|
+
() => {
|
|
61
|
+
if (busy)
|
|
62
|
+
return; // mirror chat:submit's streaming guard
|
|
63
|
+
const m = matches[safeIndex];
|
|
64
|
+
if (m)
|
|
65
|
+
onExecute(`/${m.name}`);
|
|
66
|
+
}, { context: "Autocomplete", active: visible });
|
|
67
|
+
useKeybinding("autocomplete:dismiss", () => setDismissed(true), {
|
|
68
|
+
context: "Autocomplete",
|
|
69
|
+
active: visible,
|
|
70
|
+
});
|
|
71
|
+
if (!visible)
|
|
72
|
+
return null;
|
|
73
|
+
return (_jsx(Box, { flexDirection: "column", marginLeft: 2, children: matches.map((m, i) => {
|
|
74
|
+
const selected = i === safeIndex;
|
|
75
|
+
return (_jsxs(Text, { color: selected ? theme.permission : undefined, dimColor: !selected, children: [selected ? "❯ " : " ", "/", m.name, m.argumentHint ? _jsxs(Text, { dimColor: true, children: [" ", m.argumentHint] }) : null, _jsxs(Text, { dimColor: true, children: [" \u2014 ", m.description] })] }, m.name));
|
|
76
|
+
}) }));
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=slash-typeahead.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slash-typeahead.js","sourceRoot":"","sources":["../src/slash-typeahead.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* (5.9 / v14) Minimal React seam over the pure `theme.ts` literals. Components
|
|
3
|
+
* read the resolved palette + glyphs via `useTheme()`; the host wraps the tree
|
|
4
|
+
* once in `<ThemeProvider>`. Defaults to the dark palette + platform glyphs so
|
|
5
|
+
* components rendered without a provider (e.g. focused component tests) still
|
|
6
|
+
* work unchanged.
|
|
7
|
+
*/
|
|
8
|
+
import { type JSX, type ReactNode } from "react";
|
|
9
|
+
import { type Glyphs, type Theme, type ThemeSetting } from "./theme.js";
|
|
10
|
+
export interface ThemeContextValue {
|
|
11
|
+
theme: Theme;
|
|
12
|
+
glyphs: Glyphs;
|
|
13
|
+
/** Whether code blocks + diff context get syntax colors (`config.tui.
|
|
14
|
+
* syntaxHighlight`). Under `NO_COLOR` the syntax theme roles are already
|
|
15
|
+
* undefined, so plain output falls out regardless. */
|
|
16
|
+
syntaxHighlight: boolean;
|
|
17
|
+
}
|
|
18
|
+
export declare function ThemeProvider({ setting, glyphs, syntaxHighlight, children, }: {
|
|
19
|
+
setting?: ThemeSetting;
|
|
20
|
+
glyphs?: Glyphs;
|
|
21
|
+
syntaxHighlight?: boolean;
|
|
22
|
+
children: ReactNode;
|
|
23
|
+
}): JSX.Element;
|
|
24
|
+
export declare function useTheme(): ThemeContextValue;
|
|
25
|
+
//# sourceMappingURL=theme-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-context.d.ts","sourceRoot":"","sources":["../src/theme-context.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAA6B,KAAK,GAAG,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC5E,OAAO,EAAU,KAAK,MAAM,EAAgB,KAAK,KAAK,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAE9F,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,KAAK,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf;;2DAEuD;IACvD,eAAe,EAAE,OAAO,CAAC;CAC1B;AAUD,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EACP,MAAe,EACf,eAAsB,EACtB,QAAQ,GACT,EAAE;IACD,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,EAAE,SAAS,CAAC;CACrB,GAAG,GAAG,CAAC,OAAO,CAGd;AAED,wBAAgB,QAAQ,IAAI,iBAAiB,CAE5C"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* (5.9 / v14) Minimal React seam over the pure `theme.ts` literals. Components
|
|
4
|
+
* read the resolved palette + glyphs via `useTheme()`; the host wraps the tree
|
|
5
|
+
* once in `<ThemeProvider>`. Defaults to the dark palette + platform glyphs so
|
|
6
|
+
* components rendered without a provider (e.g. focused component tests) still
|
|
7
|
+
* work unchanged.
|
|
8
|
+
*/
|
|
9
|
+
import { createContext, useContext } from "react";
|
|
10
|
+
import { GLYPHS, resolveTheme } from "./theme.js";
|
|
11
|
+
const defaultValue = {
|
|
12
|
+
theme: resolveTheme("dark"),
|
|
13
|
+
glyphs: GLYPHS,
|
|
14
|
+
syntaxHighlight: true,
|
|
15
|
+
};
|
|
16
|
+
const ThemeContext = createContext(defaultValue);
|
|
17
|
+
export function ThemeProvider({ setting, glyphs = GLYPHS, syntaxHighlight = true, children, }) {
|
|
18
|
+
const value = { theme: resolveTheme(setting), glyphs, syntaxHighlight };
|
|
19
|
+
return _jsx(ThemeContext.Provider, { value: value, children: children });
|
|
20
|
+
}
|
|
21
|
+
export function useTheme() {
|
|
22
|
+
return useContext(ThemeContext);
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=theme-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-context.js","sourceRoot":"","sources":["../src/theme-context.tsx"],"names":[],"mappings":";AAAA;;;;;;GAMG;AACH,OAAO,EAAE,aAAa,EAAE,UAAU,EAA4B,MAAM,OAAO,CAAC;AAC5E,OAAO,EAAE,MAAM,EAAe,YAAY,EAAiC,MAAM,YAAY,CAAC;AAW9F,MAAM,YAAY,GAAsB;IACtC,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC;IAC3B,MAAM,EAAE,MAAM;IACd,eAAe,EAAE,IAAI;CACtB,CAAC;AAEF,MAAM,YAAY,GAAG,aAAa,CAAoB,YAAY,CAAC,CAAC;AAEpE,MAAM,UAAU,aAAa,CAAC,EAC5B,OAAO,EACP,MAAM,GAAG,MAAM,EACf,eAAe,GAAG,IAAI,EACtB,QAAQ,GAMT;IACC,MAAM,KAAK,GAAsB,EAAE,KAAK,EAAE,YAAY,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;IAC3F,OAAO,KAAC,YAAY,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YAAG,QAAQ,GAAyB,CAAC;AACjF,CAAC;AAED,MAAM,UAAU,QAAQ;IACtB,OAAO,UAAU,CAAC,YAAY,CAAC,CAAC;AAClC,CAAC"}
|
package/dist/theme.d.ts
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* (5.9 / v14) The single home for the TUI's visual-language literals: glyphs +
|
|
3
|
+
* color palettes. Pure module — NO React, NO Ink — so every consumer (the
|
|
4
|
+
* pure diff/highlight/markdown cores AND the components) reads one source and
|
|
5
|
+
* the constants are unit-testable in isolation. The React seam lives in
|
|
6
|
+
* `theme-context.tsx`.
|
|
7
|
+
*
|
|
8
|
+
* Colors are emitted as Ink-compatible `rgb(r,g,b)` strings; Ink renders them
|
|
9
|
+
* through chalk, which downsamples truecolor → 256/16 by the terminal's
|
|
10
|
+
* detected level. We therefore keep ONE truecolor palette per mode and let
|
|
11
|
+
* chalk degrade — there is no hand-rolled 16-ANSI fallback table (5.9 §0).
|
|
12
|
+
*
|
|
13
|
+
* `NO_COLOR` (https://no-color.org) is honored explicitly here because chalk
|
|
14
|
+
* 5 / Ink 7 only read the `--no-color` *flag*, not the env var (codex R1
|
|
15
|
+
* MUST-2): when set, `resolveTheme` returns a palette whose every color is
|
|
16
|
+
* `undefined`, so components emit no `color`/`backgroundColor` and meaning is
|
|
17
|
+
* carried by glyphs + sigils alone (the diff `+`/`-`, the `⏺`/`⎿` shapes).
|
|
18
|
+
*
|
|
19
|
+
* Dark RGB values are the facts of claude-code's `darkTheme` visual language
|
|
20
|
+
* (verified `~/Projects/github/claude-code/src/utils/theme.ts`); light values
|
|
21
|
+
* track its `lightTheme`. Syntax colors are an OneDark-ish set legible on the
|
|
22
|
+
* respective background.
|
|
23
|
+
*/
|
|
24
|
+
/** A resolved palette. Every field optional: `undefined` ⇒ emit no color for
|
|
25
|
+
* that role (terminal default fg / no bg). The NO_COLOR palette is all-undefined. */
|
|
26
|
+
export interface Theme {
|
|
27
|
+
/** Claude accent (orange). Running tool dot, top-level headings, links, spinner glyph. */
|
|
28
|
+
accent?: string;
|
|
29
|
+
/** Successful tool / ok states. */
|
|
30
|
+
success?: string;
|
|
31
|
+
/** Errors (dot, message body). */
|
|
32
|
+
error?: string;
|
|
33
|
+
/** Amber warnings. */
|
|
34
|
+
warning?: string;
|
|
35
|
+
/** Permission dialog rule + title. */
|
|
36
|
+
permission?: string;
|
|
37
|
+
/** Plan-mode badge. */
|
|
38
|
+
planMode?: string;
|
|
39
|
+
/** auto-edit / yolo badge (violet). */
|
|
40
|
+
autoAccept?: string;
|
|
41
|
+
/** Bash tool accent (pink). */
|
|
42
|
+
bashPink?: string;
|
|
43
|
+
/** Full-line diff backgrounds. */
|
|
44
|
+
diffAddedBg?: string;
|
|
45
|
+
diffRemovedBg?: string;
|
|
46
|
+
/** Word-level (intra-line) diff backgrounds — brighter than the line bg. */
|
|
47
|
+
diffAddedWordBg?: string;
|
|
48
|
+
diffRemovedWordBg?: string;
|
|
49
|
+
/** User-message bubble background. */
|
|
50
|
+
userMessageBg?: string;
|
|
51
|
+
/** Stalled-spinner red (interpolation target when no token for ~3s). */
|
|
52
|
+
stall?: string;
|
|
53
|
+
synKeyword?: string;
|
|
54
|
+
synString?: string;
|
|
55
|
+
synComment?: string;
|
|
56
|
+
synNumber?: string;
|
|
57
|
+
synFunction?: string;
|
|
58
|
+
synType?: string;
|
|
59
|
+
synLiteral?: string;
|
|
60
|
+
synTitle?: string;
|
|
61
|
+
synAttr?: string;
|
|
62
|
+
}
|
|
63
|
+
/** Theme selection as it arrives from config. `'auto'` resolves to `'dark'` in
|
|
64
|
+
* v14 (terminal-background detection is a later lever). */
|
|
65
|
+
export type ThemeSetting = "dark" | "light" | "auto";
|
|
66
|
+
/** `NO_COLOR` (https://no-color.org): present and NON-EMPTY ⇒ disable color,
|
|
67
|
+
* regardless of value. An empty string does NOT disable (per the spec). */
|
|
68
|
+
export declare function isNoColor(env?: NodeJS.ProcessEnv): boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Resolve a palette. `NO_COLOR` wins over any setting; otherwise `'light'` →
|
|
71
|
+
* the light palette and `'dark'`/`'auto'`/undefined → dark.
|
|
72
|
+
*/
|
|
73
|
+
export declare function resolveTheme(setting: ThemeSetting | undefined, env?: NodeJS.ProcessEnv): Theme;
|
|
74
|
+
export interface Glyphs {
|
|
75
|
+
/** Tool/turn status dot. `⏺` aligns well only on macOS terminals; `●`
|
|
76
|
+
* elsewhere (matches claude-code `figures.ts` BLACK_CIRCLE). */
|
|
77
|
+
dot: string;
|
|
78
|
+
/** Result continuation L-branch. */
|
|
79
|
+
branch: string;
|
|
80
|
+
/** Input + selection prompt caret. */
|
|
81
|
+
prompt: string;
|
|
82
|
+
/** Blockquote bar. */
|
|
83
|
+
blockquote: string;
|
|
84
|
+
/** Plan-mode badge symbol. */
|
|
85
|
+
plan: string;
|
|
86
|
+
/** Accept-edits / auto badge symbol. */
|
|
87
|
+
accept: string;
|
|
88
|
+
/** Success tick. */
|
|
89
|
+
tick: string;
|
|
90
|
+
/** Horizontal rule fill. */
|
|
91
|
+
hr: string;
|
|
92
|
+
/** Unordered-list bullet. */
|
|
93
|
+
bullet: string;
|
|
94
|
+
/** Progress "thinking" glyph (also the brightest spinner frame). */
|
|
95
|
+
thinking: string;
|
|
96
|
+
arrowDown: string;
|
|
97
|
+
arrowUp: string;
|
|
98
|
+
}
|
|
99
|
+
/** Build the glyph set for a platform. Exported as a function so tests can pin
|
|
100
|
+
* both the darwin (`⏺`) and non-darwin (`●`) dot without monkey-patching. */
|
|
101
|
+
export declare function makeGlyphs(platform?: NodeJS.Platform): Glyphs;
|
|
102
|
+
export declare const GLYPHS: Glyphs;
|
|
103
|
+
export declare const SPINNER_FRAMES: readonly string[];
|
|
104
|
+
/** Static glyph shown instead of the animation under reduced-motion / NO_COLOR. */
|
|
105
|
+
export declare const SPINNER_STATIC = "\u25CF";
|
|
106
|
+
//# sourceMappingURL=theme.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH;sFACsF;AACtF,MAAM,WAAW,KAAK;IACpB,0FAA0F;IAC1F,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mCAAmC;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kCAAkC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sBAAsB;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sCAAsC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uBAAuB;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kCAAkC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,4EAA4E;IAC5E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,sCAAsC;IACtC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;4DAC4D;AAC5D,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAyDrD;4EAC4E;AAC5E,wBAAgB,SAAS,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAGvE;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,YAAY,GAAG,SAAS,EACjC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,KAAK,CAGP;AAED,MAAM,WAAW,MAAM;IACrB;qEACiE;IACjE,GAAG,EAAE,MAAM,CAAC;IACZ,oCAAoC;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,sBAAsB;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,6BAA6B;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,oEAAoE;IACpE,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;8EAC8E;AAC9E,wBAAgB,UAAU,CAAC,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAAG,MAAM,CAe/E;AAED,eAAO,MAAM,MAAM,EAAE,MAAqB,CAAC;AAK3C,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EAAsD,CAAC;AAEnG,mFAAmF;AACnF,eAAO,MAAM,cAAc,WAAM,CAAC"}
|