openhorse 0.2.2 → 0.2.3

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.
Files changed (215) hide show
  1. package/README.md +23 -0
  2. package/dist/cli.js +163 -22
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/index.d.ts.map +1 -1
  5. package/dist/commands/index.js +82 -2
  6. package/dist/commands/index.js.map +1 -1
  7. package/dist/framework/prompt.d.ts +4 -0
  8. package/dist/framework/prompt.d.ts.map +1 -1
  9. package/dist/framework/prompt.js +18 -0
  10. package/dist/framework/prompt.js.map +1 -1
  11. package/dist/framework/query.d.ts +7 -0
  12. package/dist/framework/query.d.ts.map +1 -1
  13. package/dist/framework/query.js +14 -0
  14. package/dist/framework/query.js.map +1 -1
  15. package/dist/framework/store.d.ts +3 -1
  16. package/dist/framework/store.d.ts.map +1 -1
  17. package/dist/framework/store.js +1 -0
  18. package/dist/framework/store.js.map +1 -1
  19. package/dist/ink-ui/App.d.ts +4 -1
  20. package/dist/ink-ui/App.d.ts.map +1 -1
  21. package/dist/ink-ui/App.js +2 -2
  22. package/dist/ink-ui/App.js.map +1 -1
  23. package/dist/ink-ui/components/NativeCursor.d.ts +12 -0
  24. package/dist/ink-ui/components/NativeCursor.d.ts.map +1 -0
  25. package/dist/ink-ui/components/NativeCursor.js +35 -0
  26. package/dist/ink-ui/components/NativeCursor.js.map +1 -0
  27. package/dist/ink-ui/components/PromptInput.d.ts +5 -1
  28. package/dist/ink-ui/components/PromptInput.d.ts.map +1 -1
  29. package/dist/ink-ui/components/PromptInput.js +10 -6
  30. package/dist/ink-ui/components/PromptInput.js.map +1 -1
  31. package/dist/ink-ui/components/RunningHorseIndicator.d.ts +1 -1
  32. package/dist/ink-ui/components/RunningHorseIndicator.d.ts.map +1 -1
  33. package/dist/ink-ui/components/RunningHorseIndicator.js +3 -41
  34. package/dist/ink-ui/components/RunningHorseIndicator.js.map +1 -1
  35. package/dist/ink-ui/components/SelectList.d.ts +2 -1
  36. package/dist/ink-ui/components/SelectList.d.ts.map +1 -1
  37. package/dist/ink-ui/components/SelectList.js +26 -11
  38. package/dist/ink-ui/components/SelectList.js.map +1 -1
  39. package/dist/ink-ui/components/StatusLine.d.ts.map +1 -1
  40. package/dist/ink-ui/components/StatusLine.js +22 -31
  41. package/dist/ink-ui/components/StatusLine.js.map +1 -1
  42. package/dist/ink-ui/components/TerminalCursor.d.ts +4 -2
  43. package/dist/ink-ui/components/TerminalCursor.d.ts.map +1 -1
  44. package/dist/ink-ui/components/TerminalCursor.js +18 -43
  45. package/dist/ink-ui/components/TerminalCursor.js.map +1 -1
  46. package/dist/ink-ui/components/ToolActivity.d.ts +17 -0
  47. package/dist/ink-ui/components/ToolActivity.d.ts.map +1 -0
  48. package/dist/ink-ui/components/ToolActivity.js +107 -0
  49. package/dist/ink-ui/components/ToolActivity.js.map +1 -0
  50. package/dist/ink-ui/components/Transcript.d.ts +7 -1
  51. package/dist/ink-ui/components/Transcript.d.ts.map +1 -1
  52. package/dist/ink-ui/components/Transcript.js +40 -3
  53. package/dist/ink-ui/components/Transcript.js.map +1 -1
  54. package/dist/ink-ui/controllers/chat-controller.d.ts +1 -33
  55. package/dist/ink-ui/controllers/chat-controller.d.ts.map +1 -1
  56. package/dist/ink-ui/controllers/chat-controller.js +15 -437
  57. package/dist/ink-ui/controllers/chat-controller.js.map +1 -1
  58. package/dist/ink-ui/hooks/use-raw-input-bridge.d.ts +6 -0
  59. package/dist/ink-ui/hooks/use-raw-input-bridge.d.ts.map +1 -0
  60. package/dist/ink-ui/hooks/use-raw-input-bridge.js +27 -0
  61. package/dist/ink-ui/hooks/use-raw-input-bridge.js.map +1 -0
  62. package/dist/ink-ui/hooks/use-terminal-size.d.ts +7 -0
  63. package/dist/ink-ui/hooks/use-terminal-size.d.ts.map +1 -0
  64. package/dist/ink-ui/hooks/use-terminal-size.js +34 -0
  65. package/dist/ink-ui/hooks/use-terminal-size.js.map +1 -0
  66. package/dist/ink-ui/launch.d.ts +6 -0
  67. package/dist/ink-ui/launch.d.ts.map +1 -1
  68. package/dist/ink-ui/launch.js +60 -2
  69. package/dist/ink-ui/launch.js.map +1 -1
  70. package/dist/ink-ui/runtime/grapheme.d.ts +9 -0
  71. package/dist/ink-ui/runtime/grapheme.d.ts.map +1 -0
  72. package/dist/ink-ui/runtime/grapheme.js +63 -0
  73. package/dist/ink-ui/runtime/grapheme.js.map +1 -0
  74. package/dist/ink-ui/runtime/input-buffer.d.ts +32 -0
  75. package/dist/ink-ui/runtime/input-buffer.d.ts.map +1 -0
  76. package/dist/ink-ui/runtime/input-buffer.js +165 -0
  77. package/dist/ink-ui/runtime/input-buffer.js.map +1 -0
  78. package/dist/ink-ui/runtime/layout-budget.d.ts +13 -0
  79. package/dist/ink-ui/runtime/layout-budget.d.ts.map +1 -0
  80. package/dist/ink-ui/runtime/layout-budget.js +25 -0
  81. package/dist/ink-ui/runtime/layout-budget.js.map +1 -0
  82. package/dist/ink-ui/runtime/native-cursor.d.ts +62 -0
  83. package/dist/ink-ui/runtime/native-cursor.d.ts.map +1 -0
  84. package/dist/ink-ui/runtime/native-cursor.js +423 -0
  85. package/dist/ink-ui/runtime/native-cursor.js.map +1 -0
  86. package/dist/ink-ui/runtime/prompt-layout.d.ts +20 -1
  87. package/dist/ink-ui/runtime/prompt-layout.d.ts.map +1 -1
  88. package/dist/ink-ui/runtime/prompt-layout.js +129 -11
  89. package/dist/ink-ui/runtime/prompt-layout.js.map +1 -1
  90. package/dist/ink-ui/runtime/raw-input.d.ts +4 -0
  91. package/dist/ink-ui/runtime/raw-input.d.ts.map +1 -0
  92. package/dist/ink-ui/runtime/raw-input.js +15 -0
  93. package/dist/ink-ui/runtime/raw-input.js.map +1 -0
  94. package/dist/ink-ui/runtime/stdout.d.ts +11 -0
  95. package/dist/ink-ui/runtime/stdout.d.ts.map +1 -0
  96. package/dist/ink-ui/runtime/stdout.js +82 -0
  97. package/dist/ink-ui/runtime/stdout.js.map +1 -0
  98. package/dist/ink-ui/runtime/transcript-state.d.ts +37 -0
  99. package/dist/ink-ui/runtime/transcript-state.d.ts.map +1 -0
  100. package/dist/ink-ui/runtime/transcript-state.js +89 -0
  101. package/dist/ink-ui/runtime/transcript-state.js.map +1 -0
  102. package/dist/ink-ui/screens/ReplScreen.d.ts +8 -2
  103. package/dist/ink-ui/screens/ReplScreen.d.ts.map +1 -1
  104. package/dist/ink-ui/screens/ReplScreen.js +247 -151
  105. package/dist/ink-ui/screens/ReplScreen.js.map +1 -1
  106. package/dist/ink-ui/types.d.ts +1 -42
  107. package/dist/ink-ui/types.d.ts.map +1 -1
  108. package/dist/ink-ui/types.js +15 -0
  109. package/dist/ink-ui/types.js.map +1 -1
  110. package/dist/print-ui/launch.d.ts +8 -0
  111. package/dist/print-ui/launch.d.ts.map +1 -0
  112. package/dist/print-ui/launch.js +205 -0
  113. package/dist/print-ui/launch.js.map +1 -0
  114. package/dist/runtime/agent-runtime-controller.d.ts +69 -0
  115. package/dist/runtime/agent-runtime-controller.d.ts.map +1 -0
  116. package/dist/runtime/agent-runtime-controller.js +225 -0
  117. package/dist/runtime/agent-runtime-controller.js.map +1 -0
  118. package/dist/runtime/agent-runtime-protocol.d.ts +90 -0
  119. package/dist/runtime/agent-runtime-protocol.d.ts.map +1 -0
  120. package/dist/runtime/agent-runtime-protocol.js +80 -0
  121. package/dist/runtime/agent-runtime-protocol.js.map +1 -0
  122. package/dist/runtime/chat-controller.d.ts +41 -0
  123. package/dist/runtime/chat-controller.d.ts.map +1 -0
  124. package/dist/runtime/chat-controller.js +577 -0
  125. package/dist/runtime/chat-controller.js.map +1 -0
  126. package/dist/runtime/ui-events.d.ts +59 -0
  127. package/dist/runtime/ui-events.d.ts.map +1 -0
  128. package/dist/runtime/ui-events.js +3 -0
  129. package/dist/runtime/ui-events.js.map +1 -0
  130. package/dist/services/commit-plan.d.ts +17 -0
  131. package/dist/services/commit-plan.d.ts.map +1 -0
  132. package/dist/services/commit-plan.js +161 -0
  133. package/dist/services/commit-plan.js.map +1 -0
  134. package/dist/services/config.d.ts +3 -2
  135. package/dist/services/config.d.ts.map +1 -1
  136. package/dist/services/config.js +7 -6
  137. package/dist/services/config.js.map +1 -1
  138. package/dist/services/doctor.d.ts +33 -0
  139. package/dist/services/doctor.d.ts.map +1 -0
  140. package/dist/services/doctor.js +211 -0
  141. package/dist/services/doctor.js.map +1 -0
  142. package/dist/services/file-context.d.ts +21 -0
  143. package/dist/services/file-context.d.ts.map +1 -0
  144. package/dist/services/file-context.js +194 -0
  145. package/dist/services/file-context.js.map +1 -0
  146. package/dist/services/global-config.d.ts +1 -1
  147. package/dist/services/global-config.d.ts.map +1 -1
  148. package/dist/services/project-instructions.d.ts +16 -0
  149. package/dist/services/project-instructions.d.ts.map +1 -0
  150. package/dist/services/project-instructions.js +135 -0
  151. package/dist/services/project-instructions.js.map +1 -0
  152. package/dist/services/prompt-context.d.ts +3 -0
  153. package/dist/services/prompt-context.d.ts.map +1 -0
  154. package/dist/services/prompt-context.js +13 -0
  155. package/dist/services/prompt-context.js.map +1 -0
  156. package/dist/services/session-storage.d.ts +3 -0
  157. package/dist/services/session-storage.d.ts.map +1 -1
  158. package/dist/services/session-storage.js +11 -0
  159. package/dist/services/session-storage.js.map +1 -1
  160. package/dist/services/workspace-diff.d.ts +27 -0
  161. package/dist/services/workspace-diff.d.ts.map +1 -0
  162. package/dist/services/workspace-diff.js +129 -0
  163. package/dist/services/workspace-diff.js.map +1 -0
  164. package/dist/terminal-ui/completion.d.ts +6 -0
  165. package/dist/terminal-ui/completion.d.ts.map +1 -0
  166. package/dist/terminal-ui/completion.js +80 -0
  167. package/dist/terminal-ui/completion.js.map +1 -0
  168. package/dist/terminal-ui/editor.d.ts +17 -0
  169. package/dist/terminal-ui/editor.d.ts.map +1 -0
  170. package/dist/terminal-ui/editor.js +42 -0
  171. package/dist/terminal-ui/editor.js.map +1 -0
  172. package/dist/terminal-ui/launch.d.ts +23 -0
  173. package/dist/terminal-ui/launch.d.ts.map +1 -0
  174. package/dist/terminal-ui/launch.js +567 -0
  175. package/dist/terminal-ui/launch.js.map +1 -0
  176. package/dist/terminal-ui/raw-editor.d.ts +57 -0
  177. package/dist/terminal-ui/raw-editor.d.ts.map +1 -0
  178. package/dist/terminal-ui/raw-editor.js +339 -0
  179. package/dist/terminal-ui/raw-editor.js.map +1 -0
  180. package/dist/tools/index.d.ts.map +1 -1
  181. package/dist/tools/index.js +61 -19
  182. package/dist/tools/index.js.map +1 -1
  183. package/dist/tui-core/frame.d.ts +25 -0
  184. package/dist/tui-core/frame.d.ts.map +1 -0
  185. package/dist/tui-core/frame.js +104 -0
  186. package/dist/tui-core/frame.js.map +1 -0
  187. package/dist/tui-core/input-parser.d.ts +25 -0
  188. package/dist/tui-core/input-parser.d.ts.map +1 -0
  189. package/dist/tui-core/input-parser.js +207 -0
  190. package/dist/tui-core/input-parser.js.map +1 -0
  191. package/dist/tui-core/terminal-writer.d.ts +34 -0
  192. package/dist/tui-core/terminal-writer.d.ts.map +1 -0
  193. package/dist/tui-core/terminal-writer.js +92 -0
  194. package/dist/tui-core/terminal-writer.js.map +1 -0
  195. package/dist/tui-ui/launch.d.ts +7 -0
  196. package/dist/tui-ui/launch.d.ts.map +1 -0
  197. package/dist/tui-ui/launch.js +194 -0
  198. package/dist/tui-ui/launch.js.map +1 -0
  199. package/dist/tui-ui/layout.d.ts +9 -0
  200. package/dist/tui-ui/layout.d.ts.map +1 -0
  201. package/dist/tui-ui/layout.js +239 -0
  202. package/dist/tui-ui/layout.js.map +1 -0
  203. package/dist/tui-ui/pickers.d.ts +13 -0
  204. package/dist/tui-ui/pickers.d.ts.map +1 -0
  205. package/dist/tui-ui/pickers.js +79 -0
  206. package/dist/tui-ui/pickers.js.map +1 -0
  207. package/dist/tui-ui/runner.d.ts +43 -0
  208. package/dist/tui-ui/runner.d.ts.map +1 -0
  209. package/dist/tui-ui/runner.js +387 -0
  210. package/dist/tui-ui/runner.js.map +1 -0
  211. package/dist/tui-ui/state.d.ts +106 -0
  212. package/dist/tui-ui/state.d.ts.map +1 -0
  213. package/dist/tui-ui/state.js +202 -0
  214. package/dist/tui-ui/state.js.map +1 -0
  215. package/package.json +1 -1
@@ -0,0 +1,25 @@
1
+ export interface TuiCursor {
2
+ row: number;
3
+ column: number;
4
+ visible: boolean;
5
+ }
6
+ export interface TuiCell {
7
+ char: string;
8
+ width: 0 | 1 | 2;
9
+ }
10
+ export interface TuiFrame {
11
+ width: number;
12
+ height: number;
13
+ rows: TuiCell[][];
14
+ cursor: TuiCursor;
15
+ }
16
+ export interface TuiFrameDiff {
17
+ changedRows: number[];
18
+ cursorChanged: boolean;
19
+ }
20
+ export declare function createTuiFrame(width: number, height: number): TuiFrame;
21
+ export declare function writeFrameText(frame: TuiFrame, row: number, column: number, text: string): void;
22
+ export declare function setFrameCursor(frame: TuiFrame, row: number, column: number, visible?: boolean): void;
23
+ export declare function renderFrameRows(frame: TuiFrame): string[];
24
+ export declare function diffTuiFrames(previous: TuiFrame | null, next: TuiFrame): TuiFrameDiff;
25
+ //# sourceMappingURL=frame.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frame.d.ts","sourceRoot":"","sources":["../../src/tui-core/frame.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC;IAClB,MAAM,EAAE,SAAS,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,QAAQ,CAStE;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CA0B/F;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,UAAO,GAAG,IAAI,CAMjG;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,EAAE,CAIzD;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,EAAE,IAAI,EAAE,QAAQ,GAAG,YAAY,CAyBrF"}
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createTuiFrame = createTuiFrame;
7
+ exports.writeFrameText = writeFrameText;
8
+ exports.setFrameCursor = setFrameCursor;
9
+ exports.renderFrameRows = renderFrameRows;
10
+ exports.diffTuiFrames = diffTuiFrames;
11
+ const string_width_1 = __importDefault(require("string-width"));
12
+ function createTuiFrame(width, height) {
13
+ const safeWidth = Math.max(1, Math.floor(width));
14
+ const safeHeight = Math.max(1, Math.floor(height));
15
+ return {
16
+ width: safeWidth,
17
+ height: safeHeight,
18
+ rows: Array.from({ length: safeHeight }, () => createEmptyRow(safeWidth)),
19
+ cursor: { row: 0, column: 0, visible: true },
20
+ };
21
+ }
22
+ function writeFrameText(frame, row, column, text) {
23
+ let y = clamp(row, 0, frame.height - 1);
24
+ let x = clamp(column, 0, frame.width - 1);
25
+ for (const char of segmentText(text)) {
26
+ if (char === '\n') {
27
+ y += 1;
28
+ x = clamp(column, 0, frame.width - 1);
29
+ if (y >= frame.height)
30
+ break;
31
+ continue;
32
+ }
33
+ const width = charWidth(char);
34
+ if (width === 0)
35
+ continue;
36
+ if (x + width > frame.width) {
37
+ y += 1;
38
+ x = 0;
39
+ if (y >= frame.height)
40
+ break;
41
+ }
42
+ frame.rows[y][x] = { char, width };
43
+ if (width === 2 && x + 1 < frame.width) {
44
+ frame.rows[y][x + 1] = { char: '', width: 0 };
45
+ }
46
+ x += width;
47
+ }
48
+ }
49
+ function setFrameCursor(frame, row, column, visible = true) {
50
+ frame.cursor = {
51
+ row: clamp(row, 0, frame.height - 1),
52
+ column: clamp(column, 0, frame.width - 1),
53
+ visible,
54
+ };
55
+ }
56
+ function renderFrameRows(frame) {
57
+ return frame.rows.map(row => row
58
+ .map(cell => cell.width === 0 ? '' : cell.char)
59
+ .join(''));
60
+ }
61
+ function diffTuiFrames(previous, next) {
62
+ if (!previous || previous.width !== next.width || previous.height !== next.height) {
63
+ return {
64
+ changedRows: Array.from({ length: next.height }, (_, index) => index),
65
+ cursorChanged: true,
66
+ };
67
+ }
68
+ const previousRows = renderFrameRows(previous);
69
+ const nextRows = renderFrameRows(next);
70
+ const changedRows = [];
71
+ for (let index = 0; index < nextRows.length; index += 1) {
72
+ if (previousRows[index] !== nextRows[index]) {
73
+ changedRows.push(index);
74
+ }
75
+ }
76
+ return {
77
+ changedRows,
78
+ cursorChanged: previous.cursor.row !== next.cursor.row
79
+ || previous.cursor.column !== next.cursor.column
80
+ || previous.cursor.visible !== next.cursor.visible,
81
+ };
82
+ }
83
+ function createEmptyRow(width) {
84
+ return Array.from({ length: width }, () => ({ char: ' ', width: 1 }));
85
+ }
86
+ function charWidth(char) {
87
+ const width = (0, string_width_1.default)(char);
88
+ return width <= 0 ? 0 : width >= 2 ? 2 : 1;
89
+ }
90
+ function segmentText(text) {
91
+ const segmenter = getSegmenter();
92
+ if (segmenter) {
93
+ return Array.from(segmenter.segment(text), part => part.segment);
94
+ }
95
+ return Array.from(text);
96
+ }
97
+ function getSegmenter() {
98
+ const Segmenter = Intl.Segmenter;
99
+ return Segmenter ? new Segmenter(undefined, { granularity: 'grapheme' }) : null;
100
+ }
101
+ function clamp(value, min, max) {
102
+ return Math.min(max, Math.max(min, Math.floor(value)));
103
+ }
104
+ //# sourceMappingURL=frame.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frame.js","sourceRoot":"","sources":["../../src/tui-core/frame.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ export type TuiInputEvent = {
2
+ type: 'text';
3
+ value: string;
4
+ } | {
5
+ type: 'paste';
6
+ value: string;
7
+ } | {
8
+ type: 'key';
9
+ key: TuiKey;
10
+ raw: string;
11
+ };
12
+ export type TuiKey = 'enter' | 'tab' | 'escape' | 'backspace' | 'delete' | 'ctrl+c' | 'ctrl+u' | 'ctrl+w' | 'left' | 'right' | 'up' | 'down' | 'home' | 'end' | 'pageup' | 'pagedown';
13
+ export interface TuiInputParserState {
14
+ mode: 'normal' | 'paste';
15
+ incompleteUtf8: Buffer;
16
+ pasteBuffer: string;
17
+ pendingEscape: string;
18
+ }
19
+ export declare const initialTuiInputParserState: TuiInputParserState;
20
+ export declare class TuiInputParser {
21
+ private state;
22
+ reset(): void;
23
+ feed(chunk: Buffer | string): TuiInputEvent[];
24
+ }
25
+ //# sourceMappingURL=input-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input-parser.d.ts","sourceRoot":"","sources":["../../src/tui-core/input-parser.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9C,MAAM,MAAM,MAAM,GACd,OAAO,GACP,KAAK,GACL,QAAQ,GACR,WAAW,GACX,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,OAAO,GACP,IAAI,GACJ,MAAM,GACN,MAAM,GACN,KAAK,GACL,QAAQ,GACR,UAAU,CAAC;AAEf,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,0BAA0B,EAAE,mBAKxC,CAAC;AAmBF,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAKX;IAEF,KAAK,IAAI,IAAI;IASb,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,aAAa,EAAE;CA4F9C"}
@@ -0,0 +1,207 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TuiInputParser = exports.initialTuiInputParserState = void 0;
4
+ exports.initialTuiInputParserState = {
5
+ mode: 'normal',
6
+ incompleteUtf8: Buffer.alloc(0),
7
+ pasteBuffer: '',
8
+ pendingEscape: '',
9
+ };
10
+ const PASTE_START = '\x1b[200~';
11
+ const PASTE_END = '\x1b[201~';
12
+ const CSI_KEYS = {
13
+ '\x1b[A': 'up',
14
+ '\x1b[B': 'down',
15
+ '\x1b[C': 'right',
16
+ '\x1b[D': 'left',
17
+ '\x1b[H': 'home',
18
+ '\x1b[F': 'end',
19
+ '\x1b[1~': 'home',
20
+ '\x1b[4~': 'end',
21
+ '\x1b[5~': 'pageup',
22
+ '\x1b[6~': 'pagedown',
23
+ '\x1b[3~': 'delete',
24
+ };
25
+ class TuiInputParser {
26
+ constructor() {
27
+ this.state = {
28
+ mode: exports.initialTuiInputParserState.mode,
29
+ incompleteUtf8: exports.initialTuiInputParserState.incompleteUtf8,
30
+ pasteBuffer: exports.initialTuiInputParserState.pasteBuffer,
31
+ pendingEscape: exports.initialTuiInputParserState.pendingEscape,
32
+ };
33
+ }
34
+ reset() {
35
+ this.state = {
36
+ mode: 'normal',
37
+ incompleteUtf8: Buffer.alloc(0),
38
+ pasteBuffer: '',
39
+ pendingEscape: '',
40
+ };
41
+ }
42
+ feed(chunk) {
43
+ const { complete, incomplete } = splitCompleteUtf8(Buffer.concat([
44
+ this.state.incompleteUtf8,
45
+ Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, 'utf8'),
46
+ ]));
47
+ this.state.incompleteUtf8 = incomplete;
48
+ if (complete.length === 0)
49
+ return [];
50
+ const text = this.state.pendingEscape + complete.toString('utf8');
51
+ this.state.pendingEscape = '';
52
+ const events = [];
53
+ let index = 0;
54
+ const emitText = (value) => {
55
+ if (!value)
56
+ return;
57
+ if (this.state.mode === 'paste') {
58
+ this.state.pasteBuffer += value;
59
+ }
60
+ else {
61
+ events.push({ type: 'text', value });
62
+ }
63
+ };
64
+ while (index < text.length) {
65
+ const slice = text.slice(index);
66
+ if (slice.startsWith(PASTE_START)) {
67
+ this.state.mode = 'paste';
68
+ this.state.pasteBuffer = '';
69
+ index += PASTE_START.length;
70
+ continue;
71
+ }
72
+ if (slice.startsWith(PASTE_END)) {
73
+ if (this.state.mode === 'paste') {
74
+ events.push({ type: 'paste', value: normalizePastedText(this.state.pasteBuffer) });
75
+ }
76
+ this.state.mode = 'normal';
77
+ this.state.pasteBuffer = '';
78
+ index += PASTE_END.length;
79
+ continue;
80
+ }
81
+ const csiKey = readCsiKey(slice);
82
+ if (csiKey) {
83
+ if (this.state.mode === 'paste') {
84
+ this.state.pasteBuffer += csiKey.raw;
85
+ }
86
+ else {
87
+ events.push({ type: 'key', key: csiKey.key, raw: csiKey.raw });
88
+ }
89
+ index += csiKey.raw.length;
90
+ continue;
91
+ }
92
+ const char = text[index];
93
+ if (char === '\x1b') {
94
+ if (index === text.length - 1) {
95
+ this.state.pendingEscape = '\x1b';
96
+ }
97
+ else {
98
+ events.push({ type: 'key', key: 'escape', raw: '\x1b' });
99
+ }
100
+ index += 1;
101
+ continue;
102
+ }
103
+ if (this.state.mode === 'paste') {
104
+ const codePoint = text.codePointAt(index);
105
+ if (codePoint === undefined)
106
+ break;
107
+ const value = String.fromCodePoint(codePoint);
108
+ this.state.pasteBuffer += value;
109
+ index += value.length;
110
+ continue;
111
+ }
112
+ const control = controlKeyFromChar(char);
113
+ if (control) {
114
+ events.push({ type: 'key', key: control, raw: char });
115
+ index += 1;
116
+ continue;
117
+ }
118
+ const codePoint = text.codePointAt(index);
119
+ if (codePoint === undefined)
120
+ break;
121
+ const value = String.fromCodePoint(codePoint);
122
+ emitText(value);
123
+ index += value.length;
124
+ }
125
+ return coalesceTextEvents(events);
126
+ }
127
+ }
128
+ exports.TuiInputParser = TuiInputParser;
129
+ function readCsiKey(value) {
130
+ for (const [raw, key] of Object.entries(CSI_KEYS)) {
131
+ if (value.startsWith(raw))
132
+ return { key, raw };
133
+ }
134
+ return null;
135
+ }
136
+ function controlKeyFromChar(char) {
137
+ switch (char) {
138
+ case '\r':
139
+ case '\n':
140
+ return 'enter';
141
+ case '\t':
142
+ return 'tab';
143
+ case '\x7f':
144
+ case '\b':
145
+ return 'backspace';
146
+ case '\x03':
147
+ return 'ctrl+c';
148
+ case '\x15':
149
+ return 'ctrl+u';
150
+ case '\x17':
151
+ return 'ctrl+w';
152
+ default:
153
+ return null;
154
+ }
155
+ }
156
+ function coalesceTextEvents(events) {
157
+ const coalesced = [];
158
+ for (const event of events) {
159
+ const previous = coalesced[coalesced.length - 1];
160
+ if (event.type === 'text' && previous?.type === 'text') {
161
+ previous.value += event.value;
162
+ }
163
+ else {
164
+ coalesced.push(event);
165
+ }
166
+ }
167
+ return coalesced;
168
+ }
169
+ function normalizePastedText(value) {
170
+ return value.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
171
+ }
172
+ function splitCompleteUtf8(input) {
173
+ if (input.length === 0) {
174
+ return { complete: input, incomplete: Buffer.alloc(0) };
175
+ }
176
+ let start = input.length - 1;
177
+ while (start >= 0 && (input[start] & 0xc0) === 0x80) {
178
+ start -= 1;
179
+ }
180
+ if (start < 0) {
181
+ return { complete: Buffer.alloc(0), incomplete: input };
182
+ }
183
+ const expected = utf8SequenceLength(input[start]);
184
+ if (expected === 0) {
185
+ return { complete: input, incomplete: Buffer.alloc(0) };
186
+ }
187
+ const available = input.length - start;
188
+ if (available < expected) {
189
+ return {
190
+ complete: input.subarray(0, start),
191
+ incomplete: input.subarray(start),
192
+ };
193
+ }
194
+ return { complete: input, incomplete: Buffer.alloc(0) };
195
+ }
196
+ function utf8SequenceLength(byte) {
197
+ if ((byte & 0x80) === 0)
198
+ return 1;
199
+ if ((byte & 0xe0) === 0xc0)
200
+ return 2;
201
+ if ((byte & 0xf0) === 0xe0)
202
+ return 3;
203
+ if ((byte & 0xf8) === 0xf0)
204
+ return 4;
205
+ return 0;
206
+ }
207
+ //# sourceMappingURL=input-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input-parser.js","sourceRoot":"","sources":["../../src/tui-core/input-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import { type TuiFrame, type TuiFrameDiff } from './frame';
2
+ export interface TuiTerminalRenderResult {
3
+ output: string;
4
+ diff: TuiFrameDiff;
5
+ }
6
+ export interface TuiTerminalWriterOptions {
7
+ /**
8
+ * Hide the terminal cursor while row updates are written, then restore the
9
+ * frame-declared cursor state at the end of the batch.
10
+ */
11
+ bracketCursor?: boolean;
12
+ /**
13
+ * Disable terminal autowrap while painting exact-width rows. Writing a full
14
+ * border row into the last column can otherwise leave some terminals in a
15
+ * pending-wrap state, which makes the real cursor drift away from the input.
16
+ */
17
+ bracketAutoWrap?: boolean;
18
+ }
19
+ export declare class TuiTerminalWriter {
20
+ private readonly output;
21
+ private readonly options;
22
+ private previous;
23
+ constructor(output: Pick<NodeJS.WriteStream, 'write'>, options?: TuiTerminalWriterOptions);
24
+ render(frame: TuiFrame): TuiTerminalRenderResult;
25
+ reset(): void;
26
+ }
27
+ export declare function renderTerminalFrame(previous: TuiFrame | null, next: TuiFrame, options?: TuiTerminalWriterOptions): TuiTerminalRenderResult;
28
+ export declare function moveTo(row: number, column: number): string;
29
+ export declare function clearLine(): string;
30
+ export declare function cursorHide(): string;
31
+ export declare function cursorShow(): string;
32
+ export declare function disableAutoWrap(): string;
33
+ export declare function enableAutoWrap(): string;
34
+ //# sourceMappingURL=terminal-writer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-writer.d.ts","sourceRoot":"","sources":["../../src/tui-core/terminal-writer.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,QAAQ,EACb,KAAK,YAAY,EAClB,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,YAAY,CAAC;CACpB;AAED,MAAM,WAAW,wBAAwB;IACvC;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,qBAAa,iBAAiB;IAI1B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJ1B,OAAO,CAAC,QAAQ,CAAyB;gBAGtB,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,EACzC,OAAO,GAAE,wBAA6B;IAGzD,MAAM,CAAC,KAAK,EAAE,QAAQ,GAAG,uBAAuB;IAShD,KAAK,IAAI,IAAI;CAGd;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,QAAQ,GAAG,IAAI,EACzB,IAAI,EAAE,QAAQ,EACd,OAAO,GAAE,wBAA6B,GACrC,uBAAuB,CAwCzB;AAED,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,wBAAgB,cAAc,IAAI,MAAM,CAEvC"}
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TuiTerminalWriter = void 0;
4
+ exports.renderTerminalFrame = renderTerminalFrame;
5
+ exports.moveTo = moveTo;
6
+ exports.clearLine = clearLine;
7
+ exports.cursorHide = cursorHide;
8
+ exports.cursorShow = cursorShow;
9
+ exports.disableAutoWrap = disableAutoWrap;
10
+ exports.enableAutoWrap = enableAutoWrap;
11
+ const frame_1 = require("./frame");
12
+ class TuiTerminalWriter {
13
+ constructor(output, options = {}) {
14
+ this.output = output;
15
+ this.options = options;
16
+ this.previous = null;
17
+ }
18
+ render(frame) {
19
+ const result = renderTerminalFrame(this.previous, frame, this.options);
20
+ if (result.output) {
21
+ this.output.write(result.output);
22
+ }
23
+ this.previous = cloneFrame(frame);
24
+ return result;
25
+ }
26
+ reset() {
27
+ this.previous = null;
28
+ }
29
+ }
30
+ exports.TuiTerminalWriter = TuiTerminalWriter;
31
+ function renderTerminalFrame(previous, next, options = {}) {
32
+ const diff = (0, frame_1.diffTuiFrames)(previous, next);
33
+ const rows = (0, frame_1.renderFrameRows)(next);
34
+ const chunks = [];
35
+ const bracketCursor = options.bracketCursor ?? true;
36
+ const shouldPaint = diff.changedRows.length > 0 || diff.cursorChanged;
37
+ const bracketAutoWrap = options.bracketAutoWrap ?? true;
38
+ if (shouldPaint && bracketAutoWrap) {
39
+ chunks.push(disableAutoWrap());
40
+ }
41
+ if (bracketCursor && shouldPaint) {
42
+ chunks.push(cursorHide());
43
+ }
44
+ for (const rowIndex of diff.changedRows) {
45
+ chunks.push(moveTo(rowIndex, 0));
46
+ chunks.push(clearLine());
47
+ chunks.push(rows[rowIndex] ?? '');
48
+ }
49
+ if (diff.cursorChanged || diff.changedRows.length > 0) {
50
+ chunks.push(moveTo(next.cursor.row, next.cursor.column));
51
+ }
52
+ if (bracketCursor) {
53
+ chunks.push(next.cursor.visible ? cursorShow() : cursorHide());
54
+ }
55
+ else if (diff.cursorChanged && !next.cursor.visible) {
56
+ chunks.push(cursorHide());
57
+ }
58
+ if (shouldPaint && bracketAutoWrap) {
59
+ chunks.push(enableAutoWrap());
60
+ }
61
+ return {
62
+ output: chunks.join(''),
63
+ diff,
64
+ };
65
+ }
66
+ function moveTo(row, column) {
67
+ return `\x1b[${Math.max(1, Math.floor(row) + 1)};${Math.max(1, Math.floor(column) + 1)}H`;
68
+ }
69
+ function clearLine() {
70
+ return '\x1b[2K';
71
+ }
72
+ function cursorHide() {
73
+ return '\x1b[?25l';
74
+ }
75
+ function cursorShow() {
76
+ return '\x1b[?25h';
77
+ }
78
+ function disableAutoWrap() {
79
+ return '\x1b[?7l';
80
+ }
81
+ function enableAutoWrap() {
82
+ return '\x1b[?7h';
83
+ }
84
+ function cloneFrame(frame) {
85
+ return {
86
+ width: frame.width,
87
+ height: frame.height,
88
+ cursor: { ...frame.cursor },
89
+ rows: frame.rows.map(row => row.map(cell => ({ ...cell }))),
90
+ };
91
+ }
92
+ //# sourceMappingURL=terminal-writer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-writer.js","sourceRoot":"","sources":["../../src/tui-core/terminal-writer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { OpenHorseInkRuntime } from '../runtime/ui-events';
2
+ export interface TuiLaunchOptions {
3
+ input?: NodeJS.ReadStream;
4
+ output?: NodeJS.WriteStream;
5
+ }
6
+ export declare function launchTuiUI(runtime: OpenHorseInkRuntime, options?: TuiLaunchOptions): Promise<void>;
7
+ //# sourceMappingURL=launch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launch.d.ts","sourceRoot":"","sources":["../../src/tui-ui/launch.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAwB,MAAM,sBAAsB,CAAC;AAUtF,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC,WAAW,CAAC;CAC7B;AAED,wBAAsB,WAAW,CAC/B,OAAO,EAAE,mBAAmB,EAC5B,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAyKf"}