@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/index.d.ts
CHANGED
|
@@ -3,10 +3,24 @@ import type { ModalController } from "./modal.js";
|
|
|
3
3
|
export { ChatViewModel } from "./view-model.js";
|
|
4
4
|
export type { Line, LineKind } from "./view-model.js";
|
|
5
5
|
export { ChatApp, suggestSlashCommands, suggestResourceMentions, type SlashSuggestion, type ResourceSuggestion, } from "./app.js";
|
|
6
|
+
export { SlashTypeahead } from "./slash-typeahead.js";
|
|
6
7
|
export { ModalController, type OpenModal } from "./modal.js";
|
|
7
8
|
export { ModelPicker, type PickableModel } from "./model-picker.js";
|
|
8
9
|
export { SessionPicker, type PickableSession } from "./session-picker.js";
|
|
9
10
|
export { ApiKeyPrompt } from "./api-key-prompt.js";
|
|
11
|
+
export { Select, type SelectOption, type SelectProps, filterOptions, moveCursor, pageCursor, visibleWindow, clampCursor, } from "./select.js";
|
|
12
|
+
export { ThemeProvider, useTheme } from "./theme-context.js";
|
|
13
|
+
export { resolveTheme, type Theme, type ThemeSetting, GLYPHS } from "./theme.js";
|
|
14
|
+
export { Markdown } from "./markdown.js";
|
|
15
|
+
export { CodeView } from "./code-view.js";
|
|
16
|
+
export { DiffView } from "./diff-view.js";
|
|
17
|
+
export { ToolMessage } from "./tool-message.js";
|
|
18
|
+
export { Progress } from "./progress.js";
|
|
19
|
+
/** (5.9) Rendering options forwarded into the chat's `ThemeProvider`. */
|
|
20
|
+
export interface ChatRenderOptions {
|
|
21
|
+
themeSetting?: import("./theme.js").ThemeSetting;
|
|
22
|
+
syntaxHighlight?: boolean;
|
|
23
|
+
}
|
|
10
24
|
export interface ChatHandle {
|
|
11
25
|
vm: ChatViewModel;
|
|
12
26
|
waitUntilExit: () => Promise<void>;
|
|
@@ -20,5 +34,5 @@ export interface ChatHandle {
|
|
|
20
34
|
* `modal` is the controller slash commands use to open pickers; pass the
|
|
21
35
|
* same instance to `dispatchSlash(name, args, { openModal: modal.open })`.
|
|
22
36
|
*/
|
|
23
|
-
export declare function renderChat(vm: ChatViewModel, onSubmit: (prompt: string) => Promise<void>, onSlash?: (line: string) => Promise<void>, modal?: ModalController, availableSlashCommands?: import("./app.js").SlashSuggestion[], availableResources?: import("./app.js").ResourceSuggestion[]): ChatHandle;
|
|
37
|
+
export declare function renderChat(vm: ChatViewModel, onSubmit: (prompt: string) => Promise<void>, onSlash?: (line: string) => Promise<void>, modal?: ModalController, availableSlashCommands?: import("./app.js").SlashSuggestion[], availableResources?: import("./app.js").ResourceSuggestion[], options?: ChatRenderOptions): ChatHandle;
|
|
24
38
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EACL,OAAO,EACP,oBAAoB,EACpB,uBAAuB,EACvB,KAAK,eAAe,EACpB,KAAK,kBAAkB,GACxB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,eAAe,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,aAAa,CAAC;IAClB,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CACxB,EAAE,EAAE,aAAa,EACjB,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,EAC3C,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,EACzC,KAAK,CAAC,EAAE,eAAe,EACvB,sBAAsB,CAAC,EAAE,OAAO,UAAU,EAAE,eAAe,EAAE,EAC7D,kBAAkB,CAAC,EAAE,OAAO,UAAU,EAAE,kBAAkB,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EACL,OAAO,EACP,oBAAoB,EACpB,uBAAuB,EACvB,KAAK,eAAe,EACpB,KAAK,kBAAkB,GACxB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,OAAO,EACL,MAAM,EACN,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,aAAa,EACb,UAAU,EACV,UAAU,EACV,aAAa,EACb,WAAW,GACZ,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,KAAK,KAAK,EAAE,KAAK,YAAY,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACjF,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,yEAAyE;AACzE,MAAM,WAAW,iBAAiB;IAChC,YAAY,CAAC,EAAE,OAAO,YAAY,EAAE,YAAY,CAAC;IACjD,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,aAAa,CAAC;IAClB,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CACxB,EAAE,EAAE,aAAa,EACjB,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,EAC3C,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,EACzC,KAAK,CAAC,EAAE,eAAe,EACvB,sBAAsB,CAAC,EAAE,OAAO,UAAU,EAAE,eAAe,EAAE,EAC7D,kBAAkB,CAAC,EAAE,OAAO,UAAU,EAAE,kBAAkB,EAAE,EAC5D,OAAO,CAAC,EAAE,iBAAiB,GAC1B,UAAU,CAqBZ"}
|
package/dist/index.js
CHANGED
|
@@ -4,10 +4,21 @@ import { ChatApp } from "./app.js";
|
|
|
4
4
|
import { ChatViewModel } from "./view-model.js";
|
|
5
5
|
export { ChatViewModel } from "./view-model.js";
|
|
6
6
|
export { ChatApp, suggestSlashCommands, suggestResourceMentions, } from "./app.js";
|
|
7
|
+
export { SlashTypeahead } from "./slash-typeahead.js";
|
|
7
8
|
export { ModalController } from "./modal.js";
|
|
8
9
|
export { ModelPicker } from "./model-picker.js";
|
|
9
10
|
export { SessionPicker } from "./session-picker.js";
|
|
10
11
|
export { ApiKeyPrompt } from "./api-key-prompt.js";
|
|
12
|
+
// (5.10 A2) The generic single-select primitive + its pure helpers.
|
|
13
|
+
export { Select, filterOptions, moveCursor, pageCursor, visibleWindow, clampCursor, } from "./select.js";
|
|
14
|
+
// (5.9) Visual-language surface — exported for reuse + focused testing.
|
|
15
|
+
export { ThemeProvider, useTheme } from "./theme-context.js";
|
|
16
|
+
export { resolveTheme, GLYPHS } from "./theme.js";
|
|
17
|
+
export { Markdown } from "./markdown.js";
|
|
18
|
+
export { CodeView } from "./code-view.js";
|
|
19
|
+
export { DiffView } from "./diff-view.js";
|
|
20
|
+
export { ToolMessage } from "./tool-message.js";
|
|
21
|
+
export { Progress } from "./progress.js";
|
|
11
22
|
/**
|
|
12
23
|
* Mounts the interactive chat. The caller owns the view-model so it can wire
|
|
13
24
|
* `vm.requestPermission` into the PermissionGate before the engine is built.
|
|
@@ -16,8 +27,8 @@ export { ApiKeyPrompt } from "./api-key-prompt.js";
|
|
|
16
27
|
* `modal` is the controller slash commands use to open pickers; pass the
|
|
17
28
|
* same instance to `dispatchSlash(name, args, { openModal: modal.open })`.
|
|
18
29
|
*/
|
|
19
|
-
export function renderChat(vm, onSubmit, onSlash, modal, availableSlashCommands, availableResources) {
|
|
20
|
-
const instance = render(_jsx(ChatApp, { vm: vm, onSubmit: onSubmit, onSlash: onSlash, modal: modal, availableSlashCommands: availableSlashCommands, availableResources: availableResources }));
|
|
30
|
+
export function renderChat(vm, onSubmit, onSlash, modal, availableSlashCommands, availableResources, options) {
|
|
31
|
+
const instance = render(_jsx(ChatApp, { vm: vm, onSubmit: onSubmit, onSlash: onSlash, modal: modal, availableSlashCommands: availableSlashCommands, availableResources: availableResources, themeSetting: options?.themeSetting, syntaxHighlight: options?.syntaxHighlight }));
|
|
21
32
|
return {
|
|
22
33
|
vm,
|
|
23
34
|
// Ink 7 widened `waitUntilExit()` to `Promise<unknown>` (Ink 5 was
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGhD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,OAAO,EACL,OAAO,EACP,oBAAoB,EACpB,uBAAuB,GAGxB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,eAAe,EAAkB,MAAM,YAAY,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAsB,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,aAAa,EAAwB,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGhD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,OAAO,EACL,OAAO,EACP,oBAAoB,EACpB,uBAAuB,GAGxB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAkB,MAAM,YAAY,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAsB,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,aAAa,EAAwB,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,oEAAoE;AACpE,OAAO,EACL,MAAM,EAGN,aAAa,EACb,UAAU,EACV,UAAU,EACV,aAAa,EACb,WAAW,GACZ,MAAM,aAAa,CAAC;AACrB,wEAAwE;AACxE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAiC,MAAM,EAAE,MAAM,YAAY,CAAC;AACjF,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAczC;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CACxB,EAAiB,EACjB,QAA2C,EAC3C,OAAyC,EACzC,KAAuB,EACvB,sBAA6D,EAC7D,kBAA4D,EAC5D,OAA2B;IAE3B,MAAM,QAAQ,GAAG,MAAM,CACrB,KAAC,OAAO,IACN,EAAE,EAAE,EAAE,EACN,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,KAAK,EACZ,sBAAsB,EAAE,sBAAsB,EAC9C,kBAAkB,EAAE,kBAAkB,EACtC,YAAY,EAAE,OAAO,EAAE,YAAY,EACnC,eAAe,EAAE,OAAO,EAAE,eAAe,GACzC,CACH,CAAC;IACF,OAAO;QACL,EAAE;QACF,mEAAmE;QACnE,yEAAyE;QACzE,sEAAsE;QACtE,aAAa,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC;QACnE,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE;KAClC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../src/markdown.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,GAAG,EAAa,MAAM,OAAO,CAAC;AAQ5C,wBAAgB,QAAQ,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,GAAG,CAAC,OAAO,CAehE"}
|
package/dist/markdown.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* (5.9 / v14) Render committed assistant text as terminal Markdown via marked's
|
|
4
|
+
* lexer → Ink nodes. NEVER throws: a bad lex falls back to the raw text, and
|
|
5
|
+
* each block is rendered under its own guard so one malformed token can't take
|
|
6
|
+
* down the turn.
|
|
7
|
+
*
|
|
8
|
+
* Streaming contract: this renders only on COMMITTED lines. The live (still
|
|
9
|
+
* streaming) assistant line is rendered as plain text by `app.tsx`, so
|
|
10
|
+
* half-finished Markdown never flickers (5.9 §4, builds on v13's committed/live
|
|
11
|
+
* split).
|
|
12
|
+
*/
|
|
13
|
+
import { Box, Text } from "ink";
|
|
14
|
+
import { lexer } from "marked";
|
|
15
|
+
import { CodeView } from "./code-view.js";
|
|
16
|
+
import {} from "./theme.js";
|
|
17
|
+
import { useTheme } from "./theme-context.js";
|
|
18
|
+
const HR_WIDTH = 40;
|
|
19
|
+
export function Markdown({ text }) {
|
|
20
|
+
const { theme, glyphs } = useTheme();
|
|
21
|
+
let tokens;
|
|
22
|
+
try {
|
|
23
|
+
tokens = lexer(text);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return _jsx(Text, { children: text });
|
|
27
|
+
}
|
|
28
|
+
return (_jsx(Box, { flexDirection: "column", children: tokens.map((t, i) => (_jsx(Block, { token: t, theme: theme, glyphs: glyphs }, i))) }));
|
|
29
|
+
}
|
|
30
|
+
function Block({ token, theme, glyphs }) {
|
|
31
|
+
try {
|
|
32
|
+
return renderBlock(token, theme, glyphs);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return _jsx(Text, { children: "raw" in token ? token.raw : "" });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function renderBlock(token, theme, glyphs) {
|
|
39
|
+
switch (token.type) {
|
|
40
|
+
case "space":
|
|
41
|
+
return _jsx(Text, { children: " " });
|
|
42
|
+
case "heading": {
|
|
43
|
+
const h = token;
|
|
44
|
+
return (_jsx(Text, { bold: true, color: h.depth === 1 ? theme.accent : undefined, children: renderInline(h.tokens, theme) }));
|
|
45
|
+
}
|
|
46
|
+
case "paragraph": {
|
|
47
|
+
const p = token;
|
|
48
|
+
return _jsx(Text, { children: renderInline(p.tokens, theme) });
|
|
49
|
+
}
|
|
50
|
+
case "text": {
|
|
51
|
+
const t = token;
|
|
52
|
+
return _jsx(Text, { children: t.tokens ? renderInline(t.tokens, theme) : t.text });
|
|
53
|
+
}
|
|
54
|
+
case "code": {
|
|
55
|
+
const c = token;
|
|
56
|
+
return _jsx(CodeView, { code: c.text, lang: c.lang });
|
|
57
|
+
}
|
|
58
|
+
case "blockquote": {
|
|
59
|
+
const bq = token;
|
|
60
|
+
const lines = bq.text.split("\n");
|
|
61
|
+
return (_jsx(Box, { flexDirection: "column", children: lines.map((line, i) => (_jsxs(Text, { dimColor: true, children: [glyphs.blockquote, " ", line] }, i))) }));
|
|
62
|
+
}
|
|
63
|
+
case "list": {
|
|
64
|
+
const list = token;
|
|
65
|
+
return (_jsx(Box, { flexDirection: "column", children: list.items.map((item, i) => {
|
|
66
|
+
const marker = list.ordered ? `${(Number(list.start) || 1) + i}.` : glyphs.bullet;
|
|
67
|
+
return (_jsxs(Text, { children: [marker, " ", renderInline(item.tokens, theme)] }, i));
|
|
68
|
+
}) }));
|
|
69
|
+
}
|
|
70
|
+
case "hr":
|
|
71
|
+
return _jsx(Text, { dimColor: true, children: glyphs.hr.repeat(HR_WIDTH) });
|
|
72
|
+
case "table": {
|
|
73
|
+
const table = token;
|
|
74
|
+
const header = table.header.map((c) => c.text).join(" ");
|
|
75
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: header }), table.rows.map((row, i) => (_jsx(Text, { children: row.map((c) => c.text).join(" ") }, i)))] }));
|
|
76
|
+
}
|
|
77
|
+
default: {
|
|
78
|
+
const raw = "raw" in token ? token.raw : "text" in token ? token.text : "";
|
|
79
|
+
return raw ? _jsx(Text, { children: raw }) : null;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/** Render inline tokens (within a paragraph/heading/list item) into Ink Text
|
|
84
|
+
* runs. Unknown inline types fall back to their raw text. */
|
|
85
|
+
function renderInline(tokens, theme) {
|
|
86
|
+
if (!tokens)
|
|
87
|
+
return [];
|
|
88
|
+
return tokens.map((t, i) => {
|
|
89
|
+
switch (t.type) {
|
|
90
|
+
case "text": {
|
|
91
|
+
const tt = t;
|
|
92
|
+
return tt.tokens ? _jsx(Text, { children: renderInline(tt.tokens, theme) }, i) : tt.text;
|
|
93
|
+
}
|
|
94
|
+
case "strong":
|
|
95
|
+
return (_jsx(Text, { bold: true, children: renderInline(t.tokens, theme) }, i));
|
|
96
|
+
case "em":
|
|
97
|
+
return (_jsx(Text, { italic: true, children: renderInline(t.tokens, theme) }, i));
|
|
98
|
+
case "del":
|
|
99
|
+
return (_jsx(Text, { strikethrough: true, children: renderInline(t.tokens, theme) }, i));
|
|
100
|
+
case "codespan":
|
|
101
|
+
return (_jsx(Text, { color: theme.synString, children: t.text }, i));
|
|
102
|
+
case "link": {
|
|
103
|
+
const link = t;
|
|
104
|
+
const label = renderInline(link.tokens, theme);
|
|
105
|
+
const showUrl = link.href && link.href !== link.text;
|
|
106
|
+
return (_jsxs(Text, { children: [_jsx(Text, { color: theme.accent, children: label }), showUrl ? _jsxs(Text, { dimColor: true, children: [" (", link.href, ")"] }) : null] }, i));
|
|
107
|
+
}
|
|
108
|
+
case "br":
|
|
109
|
+
return "\n";
|
|
110
|
+
case "escape":
|
|
111
|
+
return t.text;
|
|
112
|
+
default:
|
|
113
|
+
return "raw" in t ? t.raw : "text" in t ? t.text : "";
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=markdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.js","sourceRoot":"","sources":["../src/markdown.tsx"],"names":[],"mappings":"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"}
|
package/dist/modal.d.ts
CHANGED
|
@@ -24,8 +24,9 @@ export declare class ModalController {
|
|
|
24
24
|
*/
|
|
25
25
|
attach(setter: (node: ReactNode) => void): () => void;
|
|
26
26
|
open: <T>(render: (resolve: (value: T | null) => void) => unknown) => Promise<T | null>;
|
|
27
|
-
/** True when a modal is currently displayed.
|
|
28
|
-
*
|
|
27
|
+
/** True when a modal is currently displayed. (Since 5.10 the modal's own
|
|
28
|
+
* `Select`/`Modal` keybinding context masks chat input structurally, so this
|
|
29
|
+
* is no longer needed to gate input — it remains a small status accessor.) */
|
|
29
30
|
isActive(): boolean;
|
|
30
31
|
}
|
|
31
32
|
export type { OpenModal };
|
package/dist/modal.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modal.d.ts","sourceRoot":"","sources":["../src/modal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAExD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,OAAO,CAA4C;IAC3D,OAAO,CAAC,MAAM,CAAqD;IAEnE;;;OAGG;IACH,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,GAAG,MAAM,IAAI;IAcrD,IAAI,GAAI,CAAC,EAAG,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,KAAK,IAAI,KAAK,OAAO,KAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAmBrF;IAEF;
|
|
1
|
+
{"version":3,"file":"modal.d.ts","sourceRoot":"","sources":["../src/modal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAExD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,OAAO,CAA4C;IAC3D,OAAO,CAAC,MAAM,CAAqD;IAEnE;;;OAGG;IACH,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,GAAG,MAAM,IAAI;IAcrD,IAAI,GAAI,CAAC,EAAG,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,KAAK,IAAI,KAAK,OAAO,KAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAmBrF;IAEF;;kFAE8E;IAC9E,QAAQ,IAAI,OAAO;CAGpB;AAED,YAAY,EAAE,SAAS,EAAE,CAAC"}
|
package/dist/modal.js
CHANGED
|
@@ -54,8 +54,9 @@ export class ModalController {
|
|
|
54
54
|
this.setNode?.(node);
|
|
55
55
|
});
|
|
56
56
|
};
|
|
57
|
-
/** True when a modal is currently displayed.
|
|
58
|
-
*
|
|
57
|
+
/** True when a modal is currently displayed. (Since 5.10 the modal's own
|
|
58
|
+
* `Select`/`Modal` keybinding context masks chat input structurally, so this
|
|
59
|
+
* is no longer needed to gate input — it remains a small status accessor.) */
|
|
59
60
|
isActive() {
|
|
60
61
|
return this.active !== null;
|
|
61
62
|
}
|
package/dist/modal.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modal.js","sourceRoot":"","sources":["../src/modal.tsx"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,eAAe;IAClB,OAAO,GAAuC,IAAI,CAAC;IACnD,MAAM,GAAgD,IAAI,CAAC;IAEnE;;;OAGG;IACH,MAAM,CAAC,MAAiC;QACtC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,OAAO,GAAG,EAAE;YACV,IAAI,IAAI,CAAC,OAAO,KAAK,MAAM;gBAAE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACjD,gEAAgE;YAChE,mEAAmE;YACnE,6BAA6B;YAC7B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChB,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;gBAChC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;YACrB,CAAC;QACH,CAAC,CAAC;IACJ,CAAC;IAED,IAAI,GAAG,CAAK,MAAuD,EAAqB,EAAE;QACxF,OAAO,IAAI,OAAO,CAAW,CAAC,cAAc,EAAE,EAAE;YAC9C,uEAAuE;YACvE,IAAI,IAAI,CAAC,MAAM;gBAAE,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YAEjD,MAAM,WAAW,GAAG,CAAC,KAAe,EAAQ,EAAE;gBAC5C,iEAAiE;gBACjE,+DAA+D;gBAC/D,gDAAgD;gBAChD,IAAI,IAAI,CAAC,MAAM,EAAE,aAAa,KAAM,WAAiC,EAAE,CAAC;oBACtE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;gBACrB,CAAC;gBACD,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC;gBACrB,cAAc,CAAC,KAAK,CAAC,CAAC;YACxB,CAAC,CAAC;YACF,IAAI,CAAC,MAAM,GAAG,EAAE,aAAa,EAAE,WAAgC,EAAE,CAAC;YAClE,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAc,CAAC;YAC9C,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;IAEF;
|
|
1
|
+
{"version":3,"file":"modal.js","sourceRoot":"","sources":["../src/modal.tsx"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,eAAe;IAClB,OAAO,GAAuC,IAAI,CAAC;IACnD,MAAM,GAAgD,IAAI,CAAC;IAEnE;;;OAGG;IACH,MAAM,CAAC,MAAiC;QACtC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,OAAO,GAAG,EAAE;YACV,IAAI,IAAI,CAAC,OAAO,KAAK,MAAM;gBAAE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACjD,gEAAgE;YAChE,mEAAmE;YACnE,6BAA6B;YAC7B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChB,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;gBAChC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;YACrB,CAAC;QACH,CAAC,CAAC;IACJ,CAAC;IAED,IAAI,GAAG,CAAK,MAAuD,EAAqB,EAAE;QACxF,OAAO,IAAI,OAAO,CAAW,CAAC,cAAc,EAAE,EAAE;YAC9C,uEAAuE;YACvE,IAAI,IAAI,CAAC,MAAM;gBAAE,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YAEjD,MAAM,WAAW,GAAG,CAAC,KAAe,EAAQ,EAAE;gBAC5C,iEAAiE;gBACjE,+DAA+D;gBAC/D,gDAAgD;gBAChD,IAAI,IAAI,CAAC,MAAM,EAAE,aAAa,KAAM,WAAiC,EAAE,CAAC;oBACtE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;gBACrB,CAAC;gBACD,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC;gBACrB,cAAc,CAAC,KAAK,CAAC,CAAC;YACxB,CAAC,CAAC;YACF,IAAI,CAAC,MAAM,GAAG,EAAE,aAAa,EAAE,WAAgC,EAAE,CAAC;YAClE,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAc,CAAC;YAC9C,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;IAEF;;kFAE8E;IAC9E,QAAQ;QACN,OAAO,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC;IAC9B,CAAC;CACF"}
|
package/dist/model-picker.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { JSX } from "react";
|
|
2
2
|
export interface PickableModel {
|
|
3
3
|
/** Display id, e.g. "claude-opus-4-7". */
|
|
4
4
|
id: string;
|
|
@@ -7,45 +7,13 @@ export interface PickableModel {
|
|
|
7
7
|
/** True for the currently-active model, rendered with a marker. */
|
|
8
8
|
current?: boolean;
|
|
9
9
|
}
|
|
10
|
-
export interface ModelPickerState {
|
|
11
|
-
filter: string;
|
|
12
|
-
cursor: number;
|
|
13
|
-
}
|
|
14
|
-
/** Subset of Ink's Key shape that the reducer cares about. Defined locally so
|
|
15
|
-
* the reducer has no dependency on Ink at all — unit tests can drive it as
|
|
16
|
-
* plain data without needing a TTY. */
|
|
17
|
-
export interface PickerKey {
|
|
18
|
-
return?: boolean;
|
|
19
|
-
escape?: boolean;
|
|
20
|
-
upArrow?: boolean;
|
|
21
|
-
downArrow?: boolean;
|
|
22
|
-
backspace?: boolean;
|
|
23
|
-
delete?: boolean;
|
|
24
|
-
ctrl?: boolean;
|
|
25
|
-
meta?: boolean;
|
|
26
|
-
}
|
|
27
|
-
/** Subset of the active match list the reducer needs — kept as a generic
|
|
28
|
-
* function over PickableModel for ergonomics. */
|
|
29
|
-
export declare function filterModels(models: PickableModel[], filter: string): PickableModel[];
|
|
30
|
-
/**
|
|
31
|
-
* Pure reducer for the ModelPicker. Returns the next state plus an optional
|
|
32
|
-
* `resolved` value: a `PickableModel` when the user picked, `null` when they
|
|
33
|
-
* cancelled (Esc or Enter on empty matches), `undefined` when the keystroke
|
|
34
|
-
* was a navigation/filter edit and the picker should stay open.
|
|
35
|
-
*
|
|
36
|
-
* The component just plumbs Ink's useInput into this function — extracted so
|
|
37
|
-
* the keystroke logic is testable without ink-testing-library's stdin
|
|
38
|
-
* limitations.
|
|
39
|
-
*/
|
|
40
|
-
export declare function reduceModelPicker(state: ModelPickerState, char: string, key: PickerKey, models: PickableModel[]): {
|
|
41
|
-
state: ModelPickerState;
|
|
42
|
-
resolved?: PickableModel | null;
|
|
43
|
-
};
|
|
44
10
|
/**
|
|
45
|
-
* Fuzzy-filter model picker
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
11
|
+
* (5.10 A4) Fuzzy-filter model picker — now a thin wrapper over the generic
|
|
12
|
+
* {@link Select} (which owns all keystroke logic via the ink-ext `Select`
|
|
13
|
+
* context). The old per-component `useInput` + `reduceModelPicker` reducer are
|
|
14
|
+
* gone; their behavior (filter, ↑↓ clamp, Enter/Esc) is the Select's, covered by
|
|
15
|
+
* `select.test`. Signature is unchanged so `apps/cli/src/slash/model.ts` still
|
|
16
|
+
* renders `<ModelPicker models onChoose/>` verbatim.
|
|
49
17
|
*/
|
|
50
18
|
export declare function ModelPicker({ models, onChoose, }: {
|
|
51
19
|
models: PickableModel[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-picker.d.ts","sourceRoot":"","sources":["../src/model-picker.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"model-picker.d.ts","sourceRoot":"","sources":["../src/model-picker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAGjC,MAAM,WAAW,aAAa;IAC5B,0CAA0C;IAC1C,EAAE,EAAE,MAAM,CAAC;IACX,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,EAC1B,MAAM,EACN,QAAQ,GACT,EAAE;IACD,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,KAAK,IAAI,CAAC;CACjD,GAAG,GAAG,CAAC,OAAO,CAed"}
|
package/dist/model-picker.js
CHANGED
|
@@ -1,70 +1,19 @@
|
|
|
1
|
-
import { jsx as _jsx
|
|
2
|
-
import {
|
|
3
|
-
import { useState } from "react";
|
|
4
|
-
/** Subset of the active match list the reducer needs — kept as a generic
|
|
5
|
-
* function over PickableModel for ergonomics. */
|
|
6
|
-
export function filterModels(models, filter) {
|
|
7
|
-
const lower = filter.toLowerCase();
|
|
8
|
-
if (!lower)
|
|
9
|
-
return models;
|
|
10
|
-
return models.filter((m) => `${m.provider}/${m.id}`.toLowerCase().includes(lower));
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Pure reducer for the ModelPicker. Returns the next state plus an optional
|
|
14
|
-
* `resolved` value: a `PickableModel` when the user picked, `null` when they
|
|
15
|
-
* cancelled (Esc or Enter on empty matches), `undefined` when the keystroke
|
|
16
|
-
* was a navigation/filter edit and the picker should stay open.
|
|
17
|
-
*
|
|
18
|
-
* The component just plumbs Ink's useInput into this function — extracted so
|
|
19
|
-
* the keystroke logic is testable without ink-testing-library's stdin
|
|
20
|
-
* limitations.
|
|
21
|
-
*/
|
|
22
|
-
export function reduceModelPicker(state, char, key, models) {
|
|
23
|
-
const matches = filterModels(models, state.filter);
|
|
24
|
-
const safeCursor = Math.min(state.cursor, Math.max(0, matches.length - 1));
|
|
25
|
-
if (key.escape)
|
|
26
|
-
return { state, resolved: null };
|
|
27
|
-
if (key.return) {
|
|
28
|
-
const choice = matches[safeCursor];
|
|
29
|
-
return { state, resolved: choice ?? null };
|
|
30
|
-
}
|
|
31
|
-
if (key.upArrow) {
|
|
32
|
-
return { state: { ...state, cursor: Math.max(0, safeCursor - 1) } };
|
|
33
|
-
}
|
|
34
|
-
if (key.downArrow) {
|
|
35
|
-
return { state: { ...state, cursor: Math.min(matches.length - 1, safeCursor + 1) } };
|
|
36
|
-
}
|
|
37
|
-
if (key.backspace || key.delete) {
|
|
38
|
-
return { state: { filter: state.filter.slice(0, -1), cursor: 0 } };
|
|
39
|
-
}
|
|
40
|
-
if (char && !key.ctrl && !key.meta) {
|
|
41
|
-
return { state: { filter: state.filter + char, cursor: 0 } };
|
|
42
|
-
}
|
|
43
|
-
return { state };
|
|
44
|
-
}
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Select } from "./select.js";
|
|
45
3
|
/**
|
|
46
|
-
* Fuzzy-filter model picker
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
4
|
+
* (5.10 A4) Fuzzy-filter model picker — now a thin wrapper over the generic
|
|
5
|
+
* {@link Select} (which owns all keystroke logic via the ink-ext `Select`
|
|
6
|
+
* context). The old per-component `useInput` + `reduceModelPicker` reducer are
|
|
7
|
+
* gone; their behavior (filter, ↑↓ clamp, Enter/Esc) is the Select's, covered by
|
|
8
|
+
* `select.test`. Signature is unchanged so `apps/cli/src/slash/model.ts` still
|
|
9
|
+
* renders `<ModelPicker models onChoose/>` verbatim.
|
|
50
10
|
*/
|
|
51
11
|
export function ModelPicker({ models, onChoose, }) {
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
if (next !== state)
|
|
60
|
-
setState(next);
|
|
61
|
-
});
|
|
62
|
-
const matches = filterModels(models, state.filter);
|
|
63
|
-
const safeCursor = Math.min(state.cursor, Math.max(0, matches.length - 1));
|
|
64
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, children: [_jsx(Text, { color: "cyan", children: "Pick a model \u00B7 type to filter \u00B7 \u2191\u2193 \u00B7 Enter \u00B7 Esc" }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { children: "filter: " }), _jsx(Text, { color: "yellow", children: state.filter || "(any)" })] }), _jsxs(Box, { flexDirection: "column", marginTop: 1, children: [matches.length === 0 ? (_jsx(Text, { dimColor: true, children: "no models match" })) : (matches.slice(0, 10).map((m, i) => {
|
|
65
|
-
const selected = i === safeCursor;
|
|
66
|
-
const marker = m.current ? "●" : " ";
|
|
67
|
-
return (_jsxs(Text, { color: selected ? "cyan" : undefined, children: [selected ? "▸ " : " ", marker, " ", _jsxs(Text, { dimColor: true, children: [m.provider, "/"] }), m.id] }, `${m.provider}/${m.id}`));
|
|
68
|
-
})), matches.length > 10 ? (_jsxs(Text, { dimColor: true, children: ["\u2026 ", matches.length - 10, " more (type to narrow)"] })) : null] })] }));
|
|
12
|
+
const options = models.map((m) => ({
|
|
13
|
+
label: `${m.provider}/${m.id}`,
|
|
14
|
+
value: m,
|
|
15
|
+
current: m.current,
|
|
16
|
+
}));
|
|
17
|
+
return (_jsx(Select, { heading: "Pick a model \u00B7 type to filter \u00B7 \u2191\u2193 \u00B7 Enter \u00B7 Esc", options: options, filterable: true, onSelect: onChoose, onCancel: () => onChoose(null) }));
|
|
69
18
|
}
|
|
70
19
|
//# sourceMappingURL=model-picker.js.map
|
package/dist/model-picker.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-picker.js","sourceRoot":"","sources":["../src/model-picker.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"model-picker.js","sourceRoot":"","sources":["../src/model-picker.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,MAAM,EAAqB,MAAM,aAAa,CAAC;AAWxD;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CAAC,EAC1B,MAAM,EACN,QAAQ,GAIT;IACC,MAAM,OAAO,GAAkC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAChE,KAAK,EAAE,GAAG,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,EAAE,EAAE;QAC9B,KAAK,EAAE,CAAC;QACR,OAAO,EAAE,CAAC,CAAC,OAAO;KACnB,CAAC,CAAC,CAAC;IACJ,OAAO,CACL,KAAC,MAAM,IACL,OAAO,EAAC,gFAAkD,EAC1D,OAAO,EAAE,OAAO,EAChB,UAAU,QACV,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,GAC9B,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type JSX } from "react";
|
|
2
|
+
/** Our own small set of lively progress verbs (user decision D3 — not
|
|
3
|
+
* claude-code's whimsical brand list, not a bare static "Thinking…"). */
|
|
4
|
+
export declare const DEFAULT_VERBS: readonly ["Thinking", "Working", "Crunching", "Wrangling", "Plotting", "Cooking", "Pondering", "Tinkering", "Computing", "Noodling"];
|
|
5
|
+
/** Pick a verb by index (deterministic; callers vary the index per turn). */
|
|
6
|
+
export declare function pickVerb(index: number): string;
|
|
7
|
+
/** Human token count: `1234 → "1.2k"`, `980 → "980"`. */
|
|
8
|
+
export declare function formatTokenCount(n: number): string;
|
|
9
|
+
/** Human elapsed: `<60s → "8s"`, else `"2m 5s"`. */
|
|
10
|
+
export declare function formatElapsed(ms: number): string;
|
|
11
|
+
export interface ProgressInfo {
|
|
12
|
+
verb: string;
|
|
13
|
+
elapsedMs: number;
|
|
14
|
+
tokens: number;
|
|
15
|
+
/** Width budget for the text (excluding the leading glyph + space). */
|
|
16
|
+
width: number;
|
|
17
|
+
arrowDown: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Build the progress text after the glyph. Segments are appended in display
|
|
21
|
+
* order `esc · elapsed · tokens` but dropped from the TAIL (tokens, then
|
|
22
|
+
* elapsed, then esc) so the most useful hint — how to interrupt — survives
|
|
23
|
+
* longest. The `verb…` head is always kept (it's never dropped).
|
|
24
|
+
*/
|
|
25
|
+
export declare function formatProgress({ verb, elapsedMs, tokens, width, arrowDown }: ProgressInfo): string;
|
|
26
|
+
export interface ProgressProps {
|
|
27
|
+
active: boolean;
|
|
28
|
+
/** Verb to display. Omitted ⇒ a lively verb is picked once on mount (varies
|
|
29
|
+
* per turn because the component is mounted only while busy). */
|
|
30
|
+
verb?: string;
|
|
31
|
+
/** Estimated tokens streamed this turn (≈ chars / 4). */
|
|
32
|
+
tokens: number;
|
|
33
|
+
reducedMotion?: boolean;
|
|
34
|
+
width?: number;
|
|
35
|
+
/** Test seam: fixed elapsed ms (skips the wall clock). */
|
|
36
|
+
elapsedMsOverride?: number;
|
|
37
|
+
/** Test seam: fixed frame index (skips the interval). */
|
|
38
|
+
frameOverride?: number;
|
|
39
|
+
}
|
|
40
|
+
export declare function Progress({ active, verb, tokens, reducedMotion, width, elapsedMsOverride, frameOverride, }: ProgressProps): JSX.Element | null;
|
|
41
|
+
//# sourceMappingURL=progress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../src/progress.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAE,KAAK,GAAG,EAA+B,MAAM,OAAO,CAAC;AAQ9D;0EAC0E;AAC1E,eAAO,MAAM,aAAa,sIAWhB,CAAC;AAEX,6EAA6E;AAC7E,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,yDAAyD;AACzD,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAGlD;AAED,oDAAoD;AACpD,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAMhD;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,YAAY,GAAG,MAAM,CAYlG;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,OAAO,CAAC;IAChB;sEACkE;IAClE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yDAAyD;IACzD,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,yDAAyD;IACzD,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAOD,wBAAgB,QAAQ,CAAC,EACvB,MAAM,EACN,IAAI,EACJ,MAAM,EACN,aAAqB,EACrB,KAAK,EACL,iBAAiB,EACjB,aAAa,GACd,EAAE,aAAa,GAAG,GAAG,CAAC,OAAO,GAAG,IAAI,CAoDpC"}
|
package/dist/progress.js
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* (5.9 / v14) The progress / "thinking" line shown above the input while a turn
|
|
4
|
+
* streams: `✻ Crunching… (esc to interrupt · 8s · ↓ 1.2k tokens)`.
|
|
5
|
+
*
|
|
6
|
+
* - `formatProgress` is a pure, width-aware formatter (segments drop as the
|
|
7
|
+
* terminal narrows, keeping `esc to interrupt` longest). Tested without a clock.
|
|
8
|
+
* - The component owns a single `setInterval` for the 12-step pulse glyph,
|
|
9
|
+
* created in a `useEffect` keyed on `active` and cleared on unmount / when the
|
|
10
|
+
* turn ends (codex R1 SHOULD-2). It holds ONLY local frame state — it never
|
|
11
|
+
* touches the view-model, so it can't race the v13 FrameScheduler.
|
|
12
|
+
* - Glyph color is the accent, shifting to `stall` red after ~3s with no new
|
|
13
|
+
* tokens. Reduced-motion / NO_COLOR → a static dot.
|
|
14
|
+
*/
|
|
15
|
+
import { Box, Text } from "ink";
|
|
16
|
+
import { useEffect, useRef, useState } from "react";
|
|
17
|
+
import stringWidth from "string-width";
|
|
18
|
+
import { SPINNER_FRAMES, SPINNER_STATIC } from "./theme.js";
|
|
19
|
+
import { useTheme } from "./theme-context.js";
|
|
20
|
+
const TICK_MS = 120;
|
|
21
|
+
const STALL_MS = 3000;
|
|
22
|
+
/** Our own small set of lively progress verbs (user decision D3 — not
|
|
23
|
+
* claude-code's whimsical brand list, not a bare static "Thinking…"). */
|
|
24
|
+
export const DEFAULT_VERBS = [
|
|
25
|
+
"Thinking",
|
|
26
|
+
"Working",
|
|
27
|
+
"Crunching",
|
|
28
|
+
"Wrangling",
|
|
29
|
+
"Plotting",
|
|
30
|
+
"Cooking",
|
|
31
|
+
"Pondering",
|
|
32
|
+
"Tinkering",
|
|
33
|
+
"Computing",
|
|
34
|
+
"Noodling",
|
|
35
|
+
];
|
|
36
|
+
/** Pick a verb by index (deterministic; callers vary the index per turn). */
|
|
37
|
+
export function pickVerb(index) {
|
|
38
|
+
return DEFAULT_VERBS[Math.abs(index) % DEFAULT_VERBS.length];
|
|
39
|
+
}
|
|
40
|
+
/** Human token count: `1234 → "1.2k"`, `980 → "980"`. */
|
|
41
|
+
export function formatTokenCount(n) {
|
|
42
|
+
if (n >= 1000)
|
|
43
|
+
return `${(n / 1000).toFixed(1)}k`;
|
|
44
|
+
return String(Math.max(0, Math.round(n)));
|
|
45
|
+
}
|
|
46
|
+
/** Human elapsed: `<60s → "8s"`, else `"2m 5s"`. */
|
|
47
|
+
export function formatElapsed(ms) {
|
|
48
|
+
const s = Math.floor(ms / 1000);
|
|
49
|
+
if (s < 60)
|
|
50
|
+
return `${s}s`;
|
|
51
|
+
const m = Math.floor(s / 60);
|
|
52
|
+
const rem = s % 60;
|
|
53
|
+
return rem === 0 ? `${m}m` : `${m}m ${rem}s`;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Build the progress text after the glyph. Segments are appended in display
|
|
57
|
+
* order `esc · elapsed · tokens` but dropped from the TAIL (tokens, then
|
|
58
|
+
* elapsed, then esc) so the most useful hint — how to interrupt — survives
|
|
59
|
+
* longest. The `verb…` head is always kept (it's never dropped).
|
|
60
|
+
*/
|
|
61
|
+
export function formatProgress({ verb, elapsedMs, tokens, width, arrowDown }) {
|
|
62
|
+
const head = `${verb}…`;
|
|
63
|
+
const segs = ["esc to interrupt", formatElapsed(elapsedMs)];
|
|
64
|
+
if (tokens > 0)
|
|
65
|
+
segs.push(`${arrowDown} ${formatTokenCount(tokens)} tokens`);
|
|
66
|
+
// Drop from the tail until the whole line fits the width budget.
|
|
67
|
+
for (let keep = segs.length; keep >= 0; keep--) {
|
|
68
|
+
const kept = segs.slice(0, keep);
|
|
69
|
+
const text = kept.length > 0 ? `${head} (${kept.join(" · ")})` : head;
|
|
70
|
+
if (stringWidth(text) <= width || keep === 0)
|
|
71
|
+
return text;
|
|
72
|
+
}
|
|
73
|
+
return head;
|
|
74
|
+
}
|
|
75
|
+
function termWidth() {
|
|
76
|
+
const cols = process.stdout?.columns;
|
|
77
|
+
return typeof cols === "number" && cols > 0 ? cols : 80;
|
|
78
|
+
}
|
|
79
|
+
export function Progress({ active, verb, tokens, reducedMotion = false, width, elapsedMsOverride, frameOverride, }) {
|
|
80
|
+
const { theme, glyphs } = useTheme();
|
|
81
|
+
const [frame, setFrame] = useState(0);
|
|
82
|
+
const [autoVerb] = useState(() => pickVerb(Math.floor(Math.random() * DEFAULT_VERBS.length)));
|
|
83
|
+
const shownVerb = verb ?? autoVerb;
|
|
84
|
+
const startRef = useRef(Date.now());
|
|
85
|
+
const lastTokenRef = useRef({ tokens, at: Date.now() });
|
|
86
|
+
// Reset the turn clock on each activation. `tokens` is intentionally NOT a
|
|
87
|
+
// dependency — we seed it once when the turn begins; live movement is read
|
|
88
|
+
// through `lastTokenRef` below.
|
|
89
|
+
useEffect(() => {
|
|
90
|
+
if (active) {
|
|
91
|
+
startRef.current = Date.now();
|
|
92
|
+
lastTokenRef.current = { tokens, at: Date.now() };
|
|
93
|
+
}
|
|
94
|
+
}, [active]);
|
|
95
|
+
// Single pulse interval, cleared on unmount / when inactive (R1 SHOULD-2).
|
|
96
|
+
useEffect(() => {
|
|
97
|
+
if (!active || reducedMotion || frameOverride !== undefined)
|
|
98
|
+
return;
|
|
99
|
+
const id = setInterval(() => setFrame((f) => (f + 1) % SPINNER_FRAMES.length), TICK_MS);
|
|
100
|
+
return () => clearInterval(id);
|
|
101
|
+
}, [active, reducedMotion, frameOverride]);
|
|
102
|
+
// Track token movement for stall detection.
|
|
103
|
+
if (tokens !== lastTokenRef.current.tokens) {
|
|
104
|
+
lastTokenRef.current = { tokens, at: Date.now() };
|
|
105
|
+
}
|
|
106
|
+
if (!active)
|
|
107
|
+
return null;
|
|
108
|
+
const elapsedMs = elapsedMsOverride ?? Date.now() - startRef.current;
|
|
109
|
+
const stalled = Date.now() - lastTokenRef.current.at > STALL_MS;
|
|
110
|
+
const glyphIndex = frameOverride ?? frame;
|
|
111
|
+
const glyph = reducedMotion ? SPINNER_STATIC : (SPINNER_FRAMES[glyphIndex % SPINNER_FRAMES.length] ?? glyphs.thinking);
|
|
112
|
+
const glyphColor = stalled ? theme.stall : theme.accent;
|
|
113
|
+
const text = formatProgress({
|
|
114
|
+
verb: shownVerb,
|
|
115
|
+
elapsedMs,
|
|
116
|
+
tokens,
|
|
117
|
+
width: Math.max(8, (width ?? termWidth()) - 2),
|
|
118
|
+
arrowDown: glyphs.arrowDown,
|
|
119
|
+
});
|
|
120
|
+
return (_jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: glyphColor, children: glyph }), _jsxs(Text, { dimColor: true, children: [" ", text] })] }));
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=progress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.js","sourceRoot":"","sources":["../src/progress.tsx"],"names":[],"mappings":"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"}
|