@dungle-scrubs/tallow 0.8.21 → 0.8.23

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 (217) hide show
  1. package/dist/cli.js +35 -4
  2. package/dist/cli.js.map +1 -1
  3. package/dist/config.d.ts +1 -1
  4. package/dist/config.js +1 -1
  5. package/dist/interactive-mode-patch.d.ts +2 -0
  6. package/dist/interactive-mode-patch.d.ts.map +1 -1
  7. package/dist/interactive-mode-patch.js +82 -0
  8. package/dist/interactive-mode-patch.js.map +1 -1
  9. package/dist/sdk.d.ts +17 -0
  10. package/dist/sdk.d.ts.map +1 -1
  11. package/dist/sdk.js +68 -1
  12. package/dist/sdk.js.map +1 -1
  13. package/dist/workspace-transition-relay.d.ts +40 -7
  14. package/dist/workspace-transition-relay.d.ts.map +1 -1
  15. package/dist/workspace-transition-relay.js +81 -16
  16. package/dist/workspace-transition-relay.js.map +1 -1
  17. package/extensions/__integration__/background-task-widget-ownership.test.ts +216 -0
  18. package/extensions/__integration__/claude-hooks-compat.test.ts +156 -0
  19. package/extensions/__integration__/slash-command-bridge.test.ts +169 -23
  20. package/extensions/_shared/atomic-write.ts +1 -1
  21. package/extensions/_shared/bordered-box.ts +102 -0
  22. package/extensions/_shared/interop-events.ts +5 -0
  23. package/extensions/_shared/pid-registry.ts +1 -1
  24. package/extensions/agent-commands-tool/index.ts +4 -1
  25. package/extensions/background-task-tool/__tests__/lifecycle.test.ts +50 -25
  26. package/extensions/background-task-tool/index.ts +139 -221
  27. package/extensions/bash-tool-enhanced/index.ts +1 -75
  28. package/extensions/cd-tool/index.ts +2 -2
  29. package/extensions/context-fork/spawn.ts +4 -1
  30. package/extensions/health/index.ts +6 -6
  31. package/extensions/hooks/__tests__/claude-compat.test.ts +35 -0
  32. package/extensions/hooks/__tests__/subprocess-hardening.test.ts +73 -0
  33. package/extensions/hooks/index.ts +27 -4
  34. package/extensions/loop/__tests__/loop.test.ts +168 -4
  35. package/extensions/loop/extension.json +6 -5
  36. package/extensions/loop/index.ts +242 -31
  37. package/extensions/plan-mode-tool/__tests__/agent-end-execution.test.ts +373 -0
  38. package/extensions/plan-mode-tool/index.ts +103 -41
  39. package/extensions/prompt-suggestions/__tests__/editor-compatibility.test.ts +42 -0
  40. package/extensions/prompt-suggestions/index.ts +41 -6
  41. package/extensions/slash-command-bridge/__tests__/slash-command-bridge.test.ts +267 -671
  42. package/extensions/slash-command-bridge/extension.json +1 -1
  43. package/extensions/slash-command-bridge/index.ts +230 -116
  44. package/extensions/subagent-tool/index.ts +2 -2
  45. package/extensions/subagent-tool/process.ts +4 -5
  46. package/extensions/tasks/commands/register-tasks-extension.ts +41 -0
  47. package/extensions/teams-tool/__tests__/peer-messaging.test.ts +29 -24
  48. package/extensions/teams-tool/dashboard.ts +3 -5
  49. package/extensions/teams-tool/dispatch/auto-dispatch.ts +18 -1
  50. package/extensions/teams-tool/tools/teammate-tools.ts +9 -6
  51. package/extensions/wezterm-pane-control/__tests__/index.test.ts +88 -4
  52. package/extensions/wezterm-pane-control/index.ts +113 -8
  53. package/package.json +6 -4
  54. package/packages/tallow-tui/README.md +51 -0
  55. package/packages/tallow-tui/dist/autocomplete.d.ts +48 -0
  56. package/packages/tallow-tui/dist/autocomplete.d.ts.map +1 -0
  57. package/packages/tallow-tui/dist/autocomplete.js +564 -0
  58. package/packages/tallow-tui/dist/autocomplete.js.map +1 -0
  59. package/packages/tallow-tui/dist/border-styles.d.ts +32 -0
  60. package/packages/tallow-tui/dist/border-styles.d.ts.map +1 -0
  61. package/packages/tallow-tui/dist/border-styles.js +46 -0
  62. package/packages/tallow-tui/dist/border-styles.js.map +1 -0
  63. package/packages/tallow-tui/dist/components/bordered-box.d.ts +52 -0
  64. package/packages/tallow-tui/dist/components/bordered-box.d.ts.map +1 -0
  65. package/packages/tallow-tui/dist/components/bordered-box.js +89 -0
  66. package/packages/tallow-tui/dist/components/bordered-box.js.map +1 -0
  67. package/packages/tallow-tui/dist/components/box.d.ts +22 -0
  68. package/packages/tallow-tui/dist/components/box.d.ts.map +1 -0
  69. package/packages/tallow-tui/dist/components/box.js +104 -0
  70. package/packages/tallow-tui/dist/components/box.js.map +1 -0
  71. package/packages/tallow-tui/dist/components/cancellable-loader.d.ts +22 -0
  72. package/packages/tallow-tui/dist/components/cancellable-loader.d.ts.map +1 -0
  73. package/packages/tallow-tui/dist/components/cancellable-loader.js +35 -0
  74. package/packages/tallow-tui/dist/components/cancellable-loader.js.map +1 -0
  75. package/packages/tallow-tui/dist/components/editor.d.ts +240 -0
  76. package/packages/tallow-tui/dist/components/editor.d.ts.map +1 -0
  77. package/packages/tallow-tui/dist/components/editor.js +1766 -0
  78. package/packages/tallow-tui/dist/components/editor.js.map +1 -0
  79. package/packages/tallow-tui/dist/components/image.d.ts +126 -0
  80. package/packages/tallow-tui/dist/components/image.d.ts.map +1 -0
  81. package/packages/tallow-tui/dist/components/image.js +245 -0
  82. package/packages/tallow-tui/dist/components/image.js.map +1 -0
  83. package/packages/tallow-tui/dist/components/input.d.ts +37 -0
  84. package/packages/tallow-tui/dist/components/input.d.ts.map +1 -0
  85. package/packages/tallow-tui/dist/components/input.js +439 -0
  86. package/packages/tallow-tui/dist/components/input.js.map +1 -0
  87. package/packages/tallow-tui/dist/components/loader.d.ts +88 -0
  88. package/packages/tallow-tui/dist/components/loader.d.ts.map +1 -0
  89. package/packages/tallow-tui/dist/components/loader.js +146 -0
  90. package/packages/tallow-tui/dist/components/loader.js.map +1 -0
  91. package/packages/tallow-tui/dist/components/markdown.d.ts +95 -0
  92. package/packages/tallow-tui/dist/components/markdown.d.ts.map +1 -0
  93. package/packages/tallow-tui/dist/components/markdown.js +633 -0
  94. package/packages/tallow-tui/dist/components/markdown.js.map +1 -0
  95. package/packages/tallow-tui/dist/components/select-list.d.ts +32 -0
  96. package/packages/tallow-tui/dist/components/select-list.d.ts.map +1 -0
  97. package/packages/tallow-tui/dist/components/select-list.js +156 -0
  98. package/packages/tallow-tui/dist/components/select-list.js.map +1 -0
  99. package/packages/tallow-tui/dist/components/settings-list.d.ts +50 -0
  100. package/packages/tallow-tui/dist/components/settings-list.d.ts.map +1 -0
  101. package/packages/tallow-tui/dist/components/settings-list.js +189 -0
  102. package/packages/tallow-tui/dist/components/settings-list.js.map +1 -0
  103. package/packages/tallow-tui/dist/components/spacer.d.ts +12 -0
  104. package/packages/tallow-tui/dist/components/spacer.d.ts.map +1 -0
  105. package/packages/tallow-tui/dist/components/spacer.js +23 -0
  106. package/packages/tallow-tui/dist/components/spacer.js.map +1 -0
  107. package/packages/tallow-tui/dist/components/text.d.ts +19 -0
  108. package/packages/tallow-tui/dist/components/text.d.ts.map +1 -0
  109. package/packages/tallow-tui/dist/components/text.js +91 -0
  110. package/packages/tallow-tui/dist/components/text.js.map +1 -0
  111. package/packages/tallow-tui/dist/components/truncated-text.d.ts +13 -0
  112. package/packages/tallow-tui/dist/components/truncated-text.d.ts.map +1 -0
  113. package/packages/tallow-tui/dist/components/truncated-text.js +51 -0
  114. package/packages/tallow-tui/dist/components/truncated-text.js.map +1 -0
  115. package/packages/tallow-tui/dist/editor-component.d.ts +50 -0
  116. package/packages/tallow-tui/dist/editor-component.d.ts.map +1 -0
  117. package/packages/tallow-tui/dist/editor-component.js +2 -0
  118. package/packages/tallow-tui/dist/editor-component.js.map +1 -0
  119. package/packages/tallow-tui/dist/fuzzy.d.ts +16 -0
  120. package/packages/tallow-tui/dist/fuzzy.d.ts.map +1 -0
  121. package/packages/tallow-tui/dist/fuzzy.js +107 -0
  122. package/packages/tallow-tui/dist/fuzzy.js.map +1 -0
  123. package/packages/tallow-tui/dist/index.d.ts +25 -0
  124. package/packages/tallow-tui/dist/index.d.ts.map +1 -0
  125. package/packages/tallow-tui/dist/index.js +35 -0
  126. package/packages/tallow-tui/dist/index.js.map +1 -0
  127. package/packages/tallow-tui/dist/keybindings.d.ts +39 -0
  128. package/packages/tallow-tui/dist/keybindings.d.ts.map +1 -0
  129. package/packages/tallow-tui/dist/keybindings.js +114 -0
  130. package/packages/tallow-tui/dist/keybindings.js.map +1 -0
  131. package/packages/tallow-tui/dist/keys.d.ts +168 -0
  132. package/packages/tallow-tui/dist/keys.d.ts.map +1 -0
  133. package/packages/tallow-tui/dist/keys.js +971 -0
  134. package/packages/tallow-tui/dist/keys.js.map +1 -0
  135. package/packages/tallow-tui/dist/kill-ring.d.ts +28 -0
  136. package/packages/tallow-tui/dist/kill-ring.d.ts.map +1 -0
  137. package/packages/tallow-tui/dist/kill-ring.js +44 -0
  138. package/packages/tallow-tui/dist/kill-ring.js.map +1 -0
  139. package/packages/tallow-tui/dist/stdin-buffer.d.ts +48 -0
  140. package/packages/tallow-tui/dist/stdin-buffer.d.ts.map +1 -0
  141. package/packages/tallow-tui/dist/stdin-buffer.js +317 -0
  142. package/packages/tallow-tui/dist/stdin-buffer.js.map +1 -0
  143. package/packages/tallow-tui/dist/terminal-image.d.ts +161 -0
  144. package/packages/tallow-tui/dist/terminal-image.d.ts.map +1 -0
  145. package/packages/tallow-tui/dist/terminal-image.js +460 -0
  146. package/packages/tallow-tui/dist/terminal-image.js.map +1 -0
  147. package/packages/tallow-tui/dist/terminal.d.ts +102 -0
  148. package/packages/tallow-tui/dist/terminal.d.ts.map +1 -0
  149. package/packages/tallow-tui/dist/terminal.js +263 -0
  150. package/packages/tallow-tui/dist/terminal.js.map +1 -0
  151. package/packages/tallow-tui/dist/test-utils/capability-env.d.ts +14 -0
  152. package/packages/tallow-tui/dist/test-utils/capability-env.d.ts.map +1 -0
  153. package/packages/tallow-tui/dist/test-utils/capability-env.js +55 -0
  154. package/packages/tallow-tui/dist/test-utils/capability-env.js.map +1 -0
  155. package/packages/tallow-tui/dist/tui.d.ts +239 -0
  156. package/packages/tallow-tui/dist/tui.d.ts.map +1 -0
  157. package/packages/tallow-tui/dist/tui.js +1058 -0
  158. package/packages/tallow-tui/dist/tui.js.map +1 -0
  159. package/packages/tallow-tui/dist/undo-stack.d.ts +17 -0
  160. package/packages/tallow-tui/dist/undo-stack.d.ts.map +1 -0
  161. package/packages/tallow-tui/dist/undo-stack.js +25 -0
  162. package/packages/tallow-tui/dist/undo-stack.js.map +1 -0
  163. package/packages/tallow-tui/dist/utils.d.ts +96 -0
  164. package/packages/tallow-tui/dist/utils.d.ts.map +1 -0
  165. package/packages/tallow-tui/dist/utils.js +843 -0
  166. package/packages/tallow-tui/dist/utils.js.map +1 -0
  167. package/packages/tallow-tui/package.json +24 -0
  168. package/packages/tallow-tui/src/__tests__/__snapshots__/render.test.ts.snap +121 -0
  169. package/packages/tallow-tui/src/__tests__/editor-border.test.ts +72 -0
  170. package/packages/tallow-tui/src/__tests__/editor-change-listener.test.ts +121 -0
  171. package/packages/tallow-tui/src/__tests__/editor-ghost-text.test.ts +112 -0
  172. package/packages/tallow-tui/src/__tests__/fuzzy.test.ts +91 -0
  173. package/packages/tallow-tui/src/__tests__/image-component.test.ts +113 -0
  174. package/packages/tallow-tui/src/__tests__/keys.test.ts +141 -0
  175. package/packages/tallow-tui/src/__tests__/render.test.ts +179 -0
  176. package/packages/tallow-tui/src/__tests__/stdin-buffer.test.ts +82 -0
  177. package/packages/tallow-tui/src/__tests__/terminal-image.test.ts +363 -0
  178. package/packages/tallow-tui/src/__tests__/tui-diff-regression.test.ts +454 -0
  179. package/packages/tallow-tui/src/__tests__/tui-render-scheduling.test.ts +256 -0
  180. package/packages/tallow-tui/src/__tests__/utils.test.ts +259 -0
  181. package/packages/tallow-tui/src/autocomplete.ts +716 -0
  182. package/packages/tallow-tui/src/border-styles.ts +60 -0
  183. package/packages/tallow-tui/src/components/bordered-box.ts +113 -0
  184. package/packages/tallow-tui/src/components/box.ts +137 -0
  185. package/packages/tallow-tui/src/components/cancellable-loader.ts +40 -0
  186. package/packages/tallow-tui/src/components/editor.ts +2143 -0
  187. package/packages/tallow-tui/src/components/image.ts +315 -0
  188. package/packages/tallow-tui/src/components/input.ts +522 -0
  189. package/packages/tallow-tui/src/components/loader.ts +187 -0
  190. package/packages/tallow-tui/src/components/markdown.ts +780 -0
  191. package/packages/tallow-tui/src/components/select-list.ts +197 -0
  192. package/packages/tallow-tui/src/components/settings-list.ts +264 -0
  193. package/packages/tallow-tui/src/components/spacer.ts +28 -0
  194. package/packages/tallow-tui/src/components/text.ts +113 -0
  195. package/packages/tallow-tui/src/components/truncated-text.ts +65 -0
  196. package/packages/tallow-tui/src/editor-component.ts +92 -0
  197. package/packages/tallow-tui/src/fuzzy.ts +133 -0
  198. package/packages/tallow-tui/src/index.ts +118 -0
  199. package/packages/tallow-tui/src/keybindings.ts +183 -0
  200. package/packages/tallow-tui/src/keys.ts +1189 -0
  201. package/packages/tallow-tui/src/kill-ring.ts +46 -0
  202. package/packages/tallow-tui/src/stdin-buffer.ts +386 -0
  203. package/packages/tallow-tui/src/terminal-image.ts +619 -0
  204. package/packages/tallow-tui/src/terminal.ts +350 -0
  205. package/packages/tallow-tui/src/test-utils/capability-env.ts +56 -0
  206. package/packages/tallow-tui/src/tui.ts +1336 -0
  207. package/packages/tallow-tui/src/undo-stack.ts +28 -0
  208. package/packages/tallow-tui/src/utils.ts +948 -0
  209. package/packages/tallow-tui/tsconfig.build.json +21 -0
  210. package/runtime/agent-runner.ts +20 -0
  211. package/runtime/atomic-write.ts +8 -0
  212. package/runtime/otel.ts +12 -0
  213. package/runtime/resolve-module.ts +23 -0
  214. package/runtime/runtime-path-provider.ts +12 -0
  215. package/runtime/runtime-provenance.ts +17 -0
  216. package/runtime/workspace-transition-relay.ts +21 -0
  217. package/runtime/workspace-transition.ts +29 -0
@@ -0,0 +1,92 @@
1
+ import type { AutocompleteProvider } from "./autocomplete.js";
2
+ import type { Component } from "./tui.js";
3
+
4
+ /**
5
+ * Interface for custom editor components.
6
+ *
7
+ * This allows extensions to provide their own editor implementation
8
+ * (e.g., vim mode, emacs mode, custom keybindings) while maintaining
9
+ * compatibility with the core application.
10
+ */
11
+ export interface EditorComponent extends Component {
12
+ // =========================================================================
13
+ // Core text access (required)
14
+ // =========================================================================
15
+
16
+ /** Get the current text content */
17
+ getText(): string;
18
+
19
+ /** Set the text content */
20
+ setText(text: string): void;
21
+
22
+ /** Handle raw terminal input (key presses, paste sequences, etc.) */
23
+ handleInput(data: string): void;
24
+
25
+ // =========================================================================
26
+ // Callbacks (required)
27
+ // =========================================================================
28
+
29
+ /** Called when user submits (e.g., Enter key) */
30
+ onSubmit?: (text: string) => void;
31
+
32
+ /** Called when text changes */
33
+ onChange?: (text: string) => void;
34
+
35
+ // =========================================================================
36
+ // History support (optional)
37
+ // =========================================================================
38
+
39
+ /** Add text to history for up/down navigation */
40
+ addToHistory?(text: string): void;
41
+
42
+ // =========================================================================
43
+ // Advanced text manipulation (optional)
44
+ // =========================================================================
45
+
46
+ /** Insert text at current cursor position */
47
+ insertTextAtCursor?(text: string): void;
48
+
49
+ /**
50
+ * Get text with any markers expanded (e.g., paste markers).
51
+ * Falls back to getText() if not implemented.
52
+ */
53
+ getExpandedText?(): string;
54
+
55
+ // =========================================================================
56
+ // Autocomplete support (optional)
57
+ // =========================================================================
58
+
59
+ /** Set the autocomplete provider */
60
+ setAutocompleteProvider?(provider: AutocompleteProvider): void;
61
+
62
+ // =========================================================================
63
+ // Ghost text / inline suggestions (optional)
64
+ // =========================================================================
65
+
66
+ /**
67
+ * Register a change listener that fires alongside onChange.
68
+ * Unlike onChange, listeners aren't overwritten by framework wiring.
69
+ *
70
+ * @param fn - Callback receiving the new text content
71
+ */
72
+ addChangeListener?(fn: (text: string) => void): void;
73
+
74
+ /** Set ghost text (dim inline suggestion after cursor). Pass null to clear. */
75
+ setGhostText?(text: string | null): void;
76
+
77
+ /** Get current ghost text, or null if none. */
78
+ getGhostText?(): string | null;
79
+
80
+ // =========================================================================
81
+ // Appearance (optional)
82
+ // =========================================================================
83
+
84
+ /** Border color function */
85
+ borderColor?: (str: string) => string;
86
+
87
+ /** Set horizontal padding */
88
+ setPaddingX?(padding: number): void;
89
+
90
+ /** Set max visible items in autocomplete dropdown */
91
+ setAutocompleteMaxVisible?(maxVisible: number): void;
92
+ }
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Fuzzy matching utilities.
3
+ * Matches if all query characters appear in order (not necessarily consecutive).
4
+ * Lower score = better match.
5
+ */
6
+
7
+ export interface FuzzyMatch {
8
+ matches: boolean;
9
+ score: number;
10
+ }
11
+
12
+ export function fuzzyMatch(query: string, text: string): FuzzyMatch {
13
+ const queryLower = query.toLowerCase();
14
+ const textLower = text.toLowerCase();
15
+
16
+ const matchQuery = (normalizedQuery: string): FuzzyMatch => {
17
+ if (normalizedQuery.length === 0) {
18
+ return { matches: true, score: 0 };
19
+ }
20
+
21
+ if (normalizedQuery.length > textLower.length) {
22
+ return { matches: false, score: 0 };
23
+ }
24
+
25
+ let queryIndex = 0;
26
+ let score = 0;
27
+ let lastMatchIndex = -1;
28
+ let consecutiveMatches = 0;
29
+
30
+ for (let i = 0; i < textLower.length && queryIndex < normalizedQuery.length; i++) {
31
+ if (textLower[i] === normalizedQuery[queryIndex]) {
32
+ const isWordBoundary = i === 0 || /[\s\-_./:]/.test(textLower[i - 1]!);
33
+
34
+ // Reward consecutive matches
35
+ if (lastMatchIndex === i - 1) {
36
+ consecutiveMatches++;
37
+ score -= consecutiveMatches * 5;
38
+ } else {
39
+ consecutiveMatches = 0;
40
+ // Penalize gaps
41
+ if (lastMatchIndex >= 0) {
42
+ score += (i - lastMatchIndex - 1) * 2;
43
+ }
44
+ }
45
+
46
+ // Reward word boundary matches
47
+ if (isWordBoundary) {
48
+ score -= 10;
49
+ }
50
+
51
+ // Slight penalty for later matches
52
+ score += i * 0.1;
53
+
54
+ lastMatchIndex = i;
55
+ queryIndex++;
56
+ }
57
+ }
58
+
59
+ if (queryIndex < normalizedQuery.length) {
60
+ return { matches: false, score: 0 };
61
+ }
62
+
63
+ return { matches: true, score };
64
+ };
65
+
66
+ const primaryMatch = matchQuery(queryLower);
67
+ if (primaryMatch.matches) {
68
+ return primaryMatch;
69
+ }
70
+
71
+ const alphaNumericMatch = queryLower.match(/^(?<letters>[a-z]+)(?<digits>[0-9]+)$/);
72
+ const numericAlphaMatch = queryLower.match(/^(?<digits>[0-9]+)(?<letters>[a-z]+)$/);
73
+ const swappedQuery = alphaNumericMatch
74
+ ? `${alphaNumericMatch.groups?.digits ?? ""}${alphaNumericMatch.groups?.letters ?? ""}`
75
+ : numericAlphaMatch
76
+ ? `${numericAlphaMatch.groups?.letters ?? ""}${numericAlphaMatch.groups?.digits ?? ""}`
77
+ : "";
78
+
79
+ if (!swappedQuery) {
80
+ return primaryMatch;
81
+ }
82
+
83
+ const swappedMatch = matchQuery(swappedQuery);
84
+ if (!swappedMatch.matches) {
85
+ return primaryMatch;
86
+ }
87
+
88
+ return { matches: true, score: swappedMatch.score + 5 };
89
+ }
90
+
91
+ /**
92
+ * Filter and sort items by fuzzy match quality (best matches first).
93
+ * Supports space-separated tokens: all tokens must match.
94
+ */
95
+ export function fuzzyFilter<T>(items: T[], query: string, getText: (item: T) => string): T[] {
96
+ if (!query.trim()) {
97
+ return items;
98
+ }
99
+
100
+ const tokens = query
101
+ .trim()
102
+ .split(/\s+/)
103
+ .filter((t) => t.length > 0);
104
+
105
+ if (tokens.length === 0) {
106
+ return items;
107
+ }
108
+
109
+ const results: { item: T; totalScore: number }[] = [];
110
+
111
+ for (const item of items) {
112
+ const text = getText(item);
113
+ let totalScore = 0;
114
+ let allMatch = true;
115
+
116
+ for (const token of tokens) {
117
+ const match = fuzzyMatch(token, text);
118
+ if (match.matches) {
119
+ totalScore += match.score;
120
+ } else {
121
+ allMatch = false;
122
+ break;
123
+ }
124
+ }
125
+
126
+ if (allMatch) {
127
+ results.push({ item, totalScore });
128
+ }
129
+ }
130
+
131
+ results.sort((a, b) => a.totalScore - b.totalScore);
132
+ return results.map((r) => r.item);
133
+ }
@@ -0,0 +1,118 @@
1
+ // Core TUI interfaces and classes
2
+
3
+ // Autocomplete support
4
+ export {
5
+ type AutocompleteItem,
6
+ type AutocompleteProvider,
7
+ CombinedAutocompleteProvider,
8
+ type SlashCommand,
9
+ } from "./autocomplete.js";
10
+ // Border styles
11
+ export {
12
+ type BorderStyle,
13
+ defaultBorderStyle,
14
+ FLAT,
15
+ ROUNDED,
16
+ SHARP,
17
+ setDefaultBorderStyle,
18
+ } from "./border-styles.js";
19
+ // Components
20
+ export { BorderedBox, type BorderedBoxOptions } from "./components/bordered-box.js";
21
+ export { Box } from "./components/box.js";
22
+ export { CancellableLoader } from "./components/cancellable-loader.js";
23
+ export { Editor, type EditorOptions, type EditorTheme } from "./components/editor.js";
24
+ export {
25
+ Image,
26
+ type ImageOptions,
27
+ type ImageTheme,
28
+ setNextImageFilePath,
29
+ } from "./components/image.js";
30
+ export { Input } from "./components/input.js";
31
+ export { Loader, type LoaderOptions, type MessageTransformContext } from "./components/loader.js";
32
+ export { type DefaultTextStyle, Markdown, type MarkdownTheme } from "./components/markdown.js";
33
+ export { type SelectItem, SelectList, type SelectListTheme } from "./components/select-list.js";
34
+ export {
35
+ type SettingItem,
36
+ SettingsList,
37
+ type SettingsListTheme,
38
+ } from "./components/settings-list.js";
39
+ export { Spacer } from "./components/spacer.js";
40
+ export { Text } from "./components/text.js";
41
+ export { TruncatedText } from "./components/truncated-text.js";
42
+ // Editor component interface (for custom editors)
43
+ export type { EditorComponent } from "./editor-component.js";
44
+ // Fuzzy matching
45
+ export { type FuzzyMatch, fuzzyFilter, fuzzyMatch } from "./fuzzy.js";
46
+ // Keybindings
47
+ export {
48
+ DEFAULT_EDITOR_KEYBINDINGS,
49
+ type EditorAction,
50
+ type EditorKeybindingsConfig,
51
+ EditorKeybindingsManager,
52
+ getEditorKeybindings,
53
+ setEditorKeybindings,
54
+ } from "./keybindings.js";
55
+ // Keyboard input handling
56
+ export {
57
+ isKeyRelease,
58
+ isKeyRepeat,
59
+ isKittyProtocolActive,
60
+ Key,
61
+ type KeyEventType,
62
+ type KeyId,
63
+ matchesKey,
64
+ parseKey,
65
+ setKittyProtocolActive,
66
+ } from "./keys.js";
67
+ // Input buffering for batch splitting
68
+ export { StdinBuffer, type StdinBufferEventMap, type StdinBufferOptions } from "./stdin-buffer.js";
69
+ // Terminal interface and implementations
70
+ export { ProcessTerminal, type Terminal } from "./terminal.js";
71
+ // Terminal image support
72
+ export {
73
+ allocateImageId,
74
+ type CellDimensions,
75
+ calculateImageLayout,
76
+ createImageMetadata,
77
+ deleteAllKittyImages,
78
+ deleteKittyImage,
79
+ detectCapabilities,
80
+ detectImageFormat,
81
+ encodeITerm2,
82
+ encodeKitty,
83
+ formatImageDimensions,
84
+ getCapabilities,
85
+ getCellDimensions,
86
+ getGifDimensions,
87
+ getImageDimensions,
88
+ getJpegDimensions,
89
+ getPngDimensions,
90
+ getWebpDimensions,
91
+ type ImageDimensions,
92
+ type ImageFormat,
93
+ type ImageLayout,
94
+ type ImageMetadata,
95
+ type ImageProtocol,
96
+ type ImageRenderOptions,
97
+ imageFallback,
98
+ imageFormatToMime,
99
+ renderImage,
100
+ resetCapabilitiesCache,
101
+ setCellDimensions,
102
+ type TerminalCapabilities,
103
+ } from "./terminal-image.js";
104
+ export {
105
+ type Component,
106
+ Container,
107
+ CURSOR_MARKER,
108
+ type Focusable,
109
+ isFocusable,
110
+ type OverlayAnchor,
111
+ type OverlayHandle,
112
+ type OverlayMargin,
113
+ type OverlayOptions,
114
+ type SizeValue,
115
+ TUI,
116
+ } from "./tui.js";
117
+ // Utilities
118
+ export { fileLink, hyperlink, truncateToWidth, visibleWidth, wrapTextWithAnsi } from "./utils.js";
@@ -0,0 +1,183 @@
1
+ import { type KeyId, matchesKey } from "./keys.js";
2
+
3
+ /**
4
+ * Editor actions that can be bound to keys.
5
+ */
6
+ export type EditorAction =
7
+ // Cursor movement
8
+ | "cursorUp"
9
+ | "cursorDown"
10
+ | "cursorLeft"
11
+ | "cursorRight"
12
+ | "cursorWordLeft"
13
+ | "cursorWordRight"
14
+ | "cursorLineStart"
15
+ | "cursorLineEnd"
16
+ | "jumpForward"
17
+ | "jumpBackward"
18
+ | "pageUp"
19
+ | "pageDown"
20
+ // Deletion
21
+ | "deleteCharBackward"
22
+ | "deleteCharForward"
23
+ | "deleteWordBackward"
24
+ | "deleteWordForward"
25
+ | "deleteToLineStart"
26
+ | "deleteToLineEnd"
27
+ // Text input
28
+ | "newLine"
29
+ | "submit"
30
+ | "tab"
31
+ // Selection/autocomplete
32
+ | "selectUp"
33
+ | "selectDown"
34
+ | "selectPageUp"
35
+ | "selectPageDown"
36
+ | "selectConfirm"
37
+ | "selectCancel"
38
+ // Clipboard
39
+ | "copy"
40
+ // Kill ring
41
+ | "yank"
42
+ | "yankPop"
43
+ // Undo
44
+ | "undo"
45
+ // Tool output
46
+ | "expandTools"
47
+ // Session
48
+ | "toggleSessionPath"
49
+ | "toggleSessionSort"
50
+ | "renameSession"
51
+ | "deleteSession"
52
+ | "deleteSessionNoninvasive";
53
+
54
+ // Re-export KeyId from keys.ts
55
+ export type { KeyId };
56
+
57
+ /**
58
+ * Editor keybindings configuration.
59
+ */
60
+ export type EditorKeybindingsConfig = {
61
+ [K in EditorAction]?: KeyId | KeyId[];
62
+ };
63
+
64
+ /**
65
+ * Default editor keybindings.
66
+ */
67
+ export const DEFAULT_EDITOR_KEYBINDINGS: Required<EditorKeybindingsConfig> = {
68
+ // Cursor movement
69
+ cursorUp: "up",
70
+ cursorDown: "down",
71
+ cursorLeft: ["left", "ctrl+b"],
72
+ cursorRight: ["right", "ctrl+f"],
73
+ cursorWordLeft: ["alt+left", "ctrl+left", "alt+b"],
74
+ cursorWordRight: ["alt+right", "ctrl+right", "alt+f"],
75
+ cursorLineStart: ["home", "ctrl+a"],
76
+ cursorLineEnd: ["end", "ctrl+e"],
77
+ jumpForward: "ctrl+]",
78
+ jumpBackward: "ctrl+alt+]",
79
+ pageUp: "pageUp",
80
+ pageDown: "pageDown",
81
+ // Deletion
82
+ deleteCharBackward: "backspace",
83
+ deleteCharForward: ["delete", "ctrl+d"],
84
+ deleteWordBackward: ["ctrl+w", "alt+backspace"],
85
+ deleteWordForward: ["alt+d", "alt+delete"],
86
+ deleteToLineStart: "ctrl+u",
87
+ deleteToLineEnd: "ctrl+k",
88
+ // Text input
89
+ newLine: "shift+enter",
90
+ submit: "enter",
91
+ tab: "tab",
92
+ // Selection/autocomplete
93
+ selectUp: "up",
94
+ selectDown: "down",
95
+ selectPageUp: "pageUp",
96
+ selectPageDown: "pageDown",
97
+ selectConfirm: "enter",
98
+ selectCancel: ["escape", "ctrl+c"],
99
+ // Clipboard (ctrl+c in editor is handled as selectCancel/interrupt, not copy)
100
+ copy: "ctrl+shift+c",
101
+ // Kill ring
102
+ yank: "ctrl+y",
103
+ yankPop: "alt+y",
104
+ // Undo
105
+ undo: "ctrl+-",
106
+ // Tool output
107
+ expandTools: "ctrl+o",
108
+ // Session
109
+ toggleSessionPath: "ctrl+p",
110
+ toggleSessionSort: "ctrl+s",
111
+ renameSession: "ctrl+r",
112
+ deleteSession: "ctrl+d",
113
+ deleteSessionNoninvasive: "ctrl+backspace",
114
+ };
115
+
116
+ /**
117
+ * Manages keybindings for the editor.
118
+ */
119
+ export class EditorKeybindingsManager {
120
+ private actionToKeys: Map<EditorAction, KeyId[]>;
121
+
122
+ constructor(config: EditorKeybindingsConfig = {}) {
123
+ this.actionToKeys = new Map();
124
+ this.buildMaps(config);
125
+ }
126
+
127
+ private buildMaps(config: EditorKeybindingsConfig): void {
128
+ this.actionToKeys.clear();
129
+
130
+ // Start with defaults
131
+ for (const [action, keys] of Object.entries(DEFAULT_EDITOR_KEYBINDINGS)) {
132
+ const keyArray = Array.isArray(keys) ? keys : [keys];
133
+ this.actionToKeys.set(action as EditorAction, [...keyArray]);
134
+ }
135
+
136
+ // Override with user config
137
+ for (const [action, keys] of Object.entries(config)) {
138
+ if (keys === undefined) continue;
139
+ const keyArray = Array.isArray(keys) ? keys : [keys];
140
+ this.actionToKeys.set(action as EditorAction, keyArray);
141
+ }
142
+ }
143
+
144
+ /**
145
+ * Check if input matches a specific action.
146
+ */
147
+ matches(data: string, action: EditorAction): boolean {
148
+ const keys = this.actionToKeys.get(action);
149
+ if (!keys) return false;
150
+ for (const key of keys) {
151
+ if (matchesKey(data, key)) return true;
152
+ }
153
+ return false;
154
+ }
155
+
156
+ /**
157
+ * Get keys bound to an action.
158
+ */
159
+ getKeys(action: EditorAction): KeyId[] {
160
+ return this.actionToKeys.get(action) ?? [];
161
+ }
162
+
163
+ /**
164
+ * Update configuration.
165
+ */
166
+ setConfig(config: EditorKeybindingsConfig): void {
167
+ this.buildMaps(config);
168
+ }
169
+ }
170
+
171
+ // Global instance
172
+ let globalEditorKeybindings: EditorKeybindingsManager | null = null;
173
+
174
+ export function getEditorKeybindings(): EditorKeybindingsManager {
175
+ if (!globalEditorKeybindings) {
176
+ globalEditorKeybindings = new EditorKeybindingsManager();
177
+ }
178
+ return globalEditorKeybindings;
179
+ }
180
+
181
+ export function setEditorKeybindings(manager: EditorKeybindingsManager): void {
182
+ globalEditorKeybindings = manager;
183
+ }