@openviking/react 0.1.3 → 0.1.5

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 (209) hide show
  1. package/LICENSE.arco-design +21 -0
  2. package/README.md +27 -15
  3. package/dist/0~0.js +19 -0
  4. package/dist/28~0.js +15 -0
  5. package/dist/2~0.js +2270 -29
  6. package/dist/2~0.js.LICENSE.txt +23 -0
  7. package/dist/3c~0.js +2208 -0
  8. package/dist/3~0.js +1207 -1982
  9. package/dist/4~0.js +18 -0
  10. package/dist/9~0.js +43 -0
  11. package/dist/{1~0.js → ae~0.js} +11 -26
  12. package/dist/ark-message-list-view~0.js +530 -119
  13. package/dist/a~0.js +1300 -14
  14. package/dist/c7~0.js +38 -2
  15. package/dist/ck~0.js +23 -0
  16. package/dist/client/provider.d.ts +15 -9
  17. package/dist/client/types.d.ts +5 -5
  18. package/dist/client.js +2 -1
  19. package/dist/components/agent-connect/agent-connect-code-block.d.ts +14 -0
  20. package/dist/components/agent-connect/agent-connect-copy.d.ts +22 -33
  21. package/dist/components/agent-connect/agent-connect-design.d.ts +1936 -168
  22. package/dist/components/agent-connect/agent-connect-installer.d.ts +1 -0
  23. package/dist/components/agent-connect/agent-connect-instructions-view.d.ts +4 -6
  24. package/dist/components/agent-connect/agent-connect-instructions.d.ts +148 -0
  25. package/dist/components/agent-connect/agent-connect-markdown.d.ts +8 -2
  26. package/dist/components/agent-connect/agent-connect-mask.d.ts +10 -0
  27. package/dist/components/agent-connect/agent-connect.d.ts +1 -1
  28. package/dist/components/agent-connect/locales/en-US.d.ts +23 -0
  29. package/dist/components/agent-connect/locales/zh-CN.d.ts +3 -0
  30. package/dist/components/agent-connect/style.css +129 -3
  31. package/dist/components/agent-connect/types.d.ts +7 -4
  32. package/dist/components/agent-connect/use-agent-connect-copy.d.ts +6 -0
  33. package/dist/components/directory-tour/directory-tour.d.ts +3 -0
  34. package/dist/components/directory-tour/index.d.ts +3 -0
  35. package/dist/components/directory-tour/locales/en-US.d.ts +3 -0
  36. package/dist/components/directory-tour/locales/zh-CN.d.ts +3 -0
  37. package/dist/components/directory-tour/steps.d.ts +5 -0
  38. package/dist/components/directory-tour/style.css +237 -0
  39. package/dist/components/directory-tour/style.js +0 -0
  40. package/dist/components/directory-tour/types.d.ts +43 -0
  41. package/dist/components/directory-tour/use-tour-anchor.d.ts +5 -0
  42. package/dist/components/directory-tour/use-tour-position.d.ts +12 -0
  43. package/dist/components/directory-tour.js +40 -0
  44. package/dist/components/file-browser-entries/file-browser-entries.d.ts +5 -5
  45. package/dist/components/file-browser-entries/labels.d.ts +3 -0
  46. package/dist/components/file-browser-entries/locales/en-US.d.ts +6 -0
  47. package/dist/components/file-browser-entries/locales/zh-CN.d.ts +6 -0
  48. package/dist/components/file-browser-entries/style.css +866 -2
  49. package/dist/components/file-browser-entries/types.d.ts +34 -16
  50. package/dist/components/file-preview/file-preview-adapters.d.ts +2 -1
  51. package/dist/components/file-preview/file-preview-body.d.ts +2 -1
  52. package/dist/components/file-preview/file-preview-breadcrumb-menu.d.ts +2 -1
  53. package/dist/components/file-preview/file-preview-breadcrumb.d.ts +2 -1
  54. package/dist/components/file-preview/file-preview-directory.d.ts +2 -1
  55. package/dist/components/file-preview/file-preview-handle-adapters.d.ts +2 -1
  56. package/dist/components/file-preview/file-preview-header.d.ts +6 -2
  57. package/dist/components/file-preview/file-preview-image-frame.d.ts +5 -0
  58. package/dist/components/file-preview/file-preview-labels.d.ts +2 -14
  59. package/dist/components/file-preview/file-preview-level-tabs.d.ts +7 -0
  60. package/dist/components/file-preview/file-preview-markdown-images.d.ts +13 -0
  61. package/dist/components/file-preview/file-preview-panels.d.ts +5 -2
  62. package/dist/components/file-preview/file-preview-viewer.d.ts +2 -1
  63. package/dist/components/file-preview/file-preview.d.ts +0 -1
  64. package/dist/components/file-preview/index.d.ts +2 -1
  65. package/dist/components/file-preview/locales/en-US.d.ts +16 -0
  66. package/dist/components/file-preview/locales/zh-CN.d.ts +16 -0
  67. package/dist/components/file-preview/style.css +160 -2
  68. package/dist/components/file-preview/types.d.ts +34 -10
  69. package/dist/components/file-preview/use-file-preview-levels.d.ts +7 -0
  70. package/dist/components/file-preview/use-file-preview-view-state.d.ts +15 -0
  71. package/dist/components/file-preview.js +1 -1
  72. package/dist/components/file-tree/file-tree-info-labels.d.ts +0 -15
  73. package/dist/components/file-tree/file-tree-labels.d.ts +4 -0
  74. package/dist/components/file-tree/file-tree-row-shared.d.ts +2 -12
  75. package/dist/components/file-tree/file-tree-toolbar.d.ts +11 -0
  76. package/dist/components/file-tree/locales/en-US.d.ts +69 -0
  77. package/dist/components/file-tree/locales/zh-CN.d.ts +69 -0
  78. package/dist/components/file-tree/style.css +143 -15
  79. package/dist/components/file-tree/types.d.ts +38 -10
  80. package/dist/components/file-tree/use-file-tree-actions.d.ts +4 -1
  81. package/dist/components/scope-switcher/labels.d.ts +3 -0
  82. package/dist/components/scope-switcher/locales/en-US.d.ts +8 -0
  83. package/dist/components/scope-switcher/locales/zh-CN.d.ts +8 -0
  84. package/dist/components/scope-switcher/scope-panel.d.ts +1 -1
  85. package/dist/components/scope-switcher/scope-switcher.d.ts +2 -2
  86. package/dist/components/scope-switcher/style.css +14 -2
  87. package/dist/components/scope-switcher/types.d.ts +12 -6
  88. package/dist/components/style.css +10030 -6763
  89. package/dist/components/tui/locales/en-US.d.ts +35 -0
  90. package/dist/components/tui/locales/zh-CN.d.ts +35 -0
  91. package/dist/components/tui/style.css +310 -18
  92. package/dist/components/tui/tui-copy-button.d.ts +1 -1
  93. package/dist/components/tui/tui-empty.d.ts +25 -0
  94. package/dist/components/tui/tui-labels.d.ts +2 -2
  95. package/dist/components/tui/tui.d.ts +1 -1
  96. package/dist/components/tui/types.d.ts +35 -12
  97. package/dist/components/tui.js +1 -1
  98. package/dist/components/viking-bot/ark-adapter.d.ts +2 -0
  99. package/dist/components/viking-bot/ark-message-body.d.ts +1 -7
  100. package/dist/components/viking-bot/ark-message-list-view.d.ts +4 -1
  101. package/dist/components/viking-bot/ark-message-row.d.ts +3 -1
  102. package/dist/components/viking-bot/bot-popover.d.ts +9 -0
  103. package/dist/components/viking-bot/capabilities.d.ts +49 -0
  104. package/dist/components/viking-bot/composer-attachments.d.ts +13 -0
  105. package/dist/components/viking-bot/composer-controls.d.ts +10 -0
  106. package/dist/components/viking-bot/composer-footer.d.ts +17 -0
  107. package/dist/components/viking-bot/composer-references.d.ts +20 -0
  108. package/dist/components/viking-bot/composer-text.d.ts +10 -0
  109. package/dist/components/viking-bot/index.d.ts +3 -1
  110. package/dist/components/viking-bot/interaction/ask-human-fields.d.ts +1 -1
  111. package/dist/components/viking-bot/interaction/labels.d.ts +2 -1
  112. package/dist/components/viking-bot/interaction/locales/en-US.d.ts +17 -0
  113. package/dist/components/viking-bot/interaction/locales/zh-CN.d.ts +17 -0
  114. package/dist/components/viking-bot/interaction/types.d.ts +8 -3
  115. package/dist/components/viking-bot/interaction/viking-bot-interaction.d.ts +1 -1
  116. package/dist/components/viking-bot/labels.d.ts +2 -0
  117. package/dist/components/viking-bot/locales/en-US.d.ts +40 -0
  118. package/dist/components/viking-bot/locales/zh-CN.d.ts +40 -0
  119. package/dist/components/viking-bot/markdown-links.d.ts +27 -0
  120. package/dist/components/viking-bot/message-activity.d.ts +7 -0
  121. package/dist/components/viking-bot/message-code-block.d.ts +8 -0
  122. package/dist/components/viking-bot/message-footer.d.ts +8 -0
  123. package/dist/components/viking-bot/message-markdown.d.ts +9 -0
  124. package/dist/components/viking-bot/model.d.ts +37 -3
  125. package/dist/components/viking-bot/quick-input-tracker.d.ts +16 -0
  126. package/dist/components/viking-bot/quick-inputs.d.ts +6 -0
  127. package/dist/components/viking-bot/reference-picker.d.ts +16 -0
  128. package/dist/components/viking-bot/session-actions.d.ts +11 -0
  129. package/dist/components/viking-bot/style.css +1486 -48
  130. package/dist/components/viking-bot/tool-activity.d.ts +9 -0
  131. package/dist/components/viking-bot/tool-result-links.d.ts +6 -0
  132. package/dist/components/viking-bot/types.d.ts +20 -8
  133. package/dist/components/viking-bot/use-quick-input.d.ts +17 -0
  134. package/dist/components/viking-bot/viking-bot.d.ts +1 -6
  135. package/dist/components/viking-bot/welcome.d.ts +8 -0
  136. package/dist/components/viking-bot.js +1 -1
  137. package/dist/c~0.js +550 -69
  138. package/dist/e~0.js +335 -0
  139. package/dist/file-preview-viewer~0.js +90 -8
  140. package/dist/f~0.js +49 -51
  141. package/dist/h~0.js +5 -1
  142. package/dist/icons/console-icons.d.ts +12 -0
  143. package/dist/icons/index.d.ts +2 -0
  144. package/dist/icons/viking-bot-icons.d.ts +6 -0
  145. package/dist/icons.js +1 -0
  146. package/dist/index.d.ts +2 -0
  147. package/dist/index.js +2 -1
  148. package/dist/k~0.js +1 -0
  149. package/dist/lg~0.js +155 -0
  150. package/dist/lk~0.js +40 -8
  151. package/dist/l~0.js +170 -181
  152. package/dist/modules/console/command-messages.d.ts +19 -0
  153. package/dist/modules/console/command-parser.d.ts +15 -0
  154. package/dist/modules/console/command-specs.d.ts +15 -0
  155. package/dist/modules/console/commands.d.ts +6 -0
  156. package/dist/modules/console/console-history.d.ts +10 -0
  157. package/dist/modules/console/console-toolbar.d.ts +18 -0
  158. package/dist/modules/console/console.d.ts +1 -3
  159. package/dist/modules/console/controller.d.ts +17 -0
  160. package/dist/modules/console/index.d.ts +2 -0
  161. package/dist/modules/console/labels.d.ts +61 -0
  162. package/dist/modules/console/locales/en-US.d.ts +49 -0
  163. package/dist/modules/console/locales/zh-CN.d.ts +3 -0
  164. package/dist/modules/console/localize-records.d.ts +11 -0
  165. package/dist/modules/console/results.d.ts +2 -0
  166. package/dist/modules/console/style.css +10905 -15
  167. package/dist/modules/console/types.d.ts +59 -80
  168. package/dist/modules/console/use-console.d.ts +3 -0
  169. package/dist/modules/console.js +1 -1
  170. package/dist/modules/file-browser/file-browser-detail.d.ts +2 -1
  171. package/dist/modules/file-browser/file-browser-labels.d.ts +11 -12
  172. package/dist/modules/file-browser/file-browser-toolbar.d.ts +3 -4
  173. package/dist/modules/file-browser/file-browser-tree-pane.d.ts +7 -5
  174. package/dist/modules/file-browser/file-browser.d.ts +1 -1
  175. package/dist/modules/file-browser/fs-read-directory.d.ts +2 -6
  176. package/dist/modules/file-browser/locales/en-US.d.ts +25 -0
  177. package/dist/modules/file-browser/locales/zh-CN.d.ts +25 -0
  178. package/dist/modules/file-browser/style.css +1695 -126
  179. package/dist/modules/file-browser/types.d.ts +38 -29
  180. package/dist/modules/file-browser/use-file-browser.d.ts +6 -1
  181. package/dist/modules/file-browser/use-fs-preview.d.ts +15 -1
  182. package/dist/modules/scope-cascade/labels.d.ts +6 -0
  183. package/dist/modules/scope-cascade/locales/en-US.d.ts +6 -0
  184. package/dist/modules/scope-cascade/locales/zh-CN.d.ts +3 -0
  185. package/dist/modules/scope-cascade/scope-cascade.d.ts +2 -2
  186. package/dist/modules/scope-cascade/style.css +14 -2
  187. package/dist/modules/scope-cascade/types.d.ts +3 -0
  188. package/dist/modules/style.css +15938 -3455
  189. package/dist/nx~0.js +15 -0
  190. package/dist/n~0.js +240 -83
  191. package/dist/o~0.js +10 -7
  192. package/dist/p~0.js +27 -0
  193. package/dist/rslib-runtime~0.js +42 -0
  194. package/dist/r~0.js +152 -0
  195. package/dist/shared/components/drawer/drawer.d.ts +13 -0
  196. package/dist/shared/components/drawer/index.d.ts +1 -0
  197. package/dist/shared/components/overlay/use-overlay-position.d.ts +2 -2
  198. package/dist/shared/components/tooltip/use-portal-theme.d.ts +3 -0
  199. package/dist/shared/locale-context.d.ts +8 -0
  200. package/dist/shared/locale.d.ts +6 -0
  201. package/dist/style.css +26339 -10577
  202. package/dist/u~0.js +397 -152
  203. package/dist/viking-bot-composer~0.js +436 -77
  204. package/dist/viking-bot-interaction~0.js +13 -11
  205. package/package.json +15 -4
  206. package/dist/30~0.js +0 -1332
  207. package/dist/components/tui/tui-labels-zh.d.ts +0 -2
  208. package/dist/modules/file-browser/tree-info-copy.d.ts +0 -15
  209. package/dist/modules/file-browser/tree-info-copy.zh-CN.d.ts +0 -15
package/dist/3c~0.js ADDED
@@ -0,0 +1,2208 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { Children, createContext, isValidElement, useCallback, useContext, useEffect, useId, useMemo, useRef, useState, useSyncExternalStore } from "react";
3
+ import react_markdown, { defaultUrlTransform } from "react-markdown";
4
+ import remark_gfm from "remark-gfm";
5
+ import { ArrowRightIcon } from "./k~0.js";
6
+ import { resolveLocale } from "./nx~0.js";
7
+ import { checkreact } from "./0~0.js";
8
+ import { Tooltip } from "./r~0.js";
9
+ import { useLocale } from "./28~0.js";
10
+ function getTuiCommandInputText(command) {
11
+ return command.inputText?.trim() || command.name;
12
+ }
13
+ function matchTuiCommandInput(value, commands) {
14
+ const content = value.trimStart();
15
+ const leadingWhitespace = value.slice(0, value.length - content.length);
16
+ const matches = commands.flatMap((command)=>{
17
+ const names = [
18
+ command.name,
19
+ ...command.aliases ?? []
20
+ ];
21
+ return [
22
+ getTuiCommandInputText(command),
23
+ ...names,
24
+ ...names.map((name)=>`/${name}`)
25
+ ].flatMap((prefix)=>{
26
+ const words = prefix.trim().split(/[ \t]+/);
27
+ const pattern = words.map((word)=>word.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('[ \t]+');
28
+ const match = pattern && new RegExp(`^${pattern}(?=$|\\s)`, 'i').exec(content);
29
+ return match ? [
30
+ {
31
+ command,
32
+ leadingWhitespace,
33
+ prefix: match[0],
34
+ rest: content.slice(match[0].length)
35
+ }
36
+ ] : [];
37
+ });
38
+ });
39
+ return matches.sort((left, right)=>right.prefix.length - left.prefix.length)[0];
40
+ }
41
+ function formatTuiCommandInput(value, commands) {
42
+ const match = matchTuiCommandInput(value, commands);
43
+ return match ? `${match.leadingWhitespace}${getTuiCommandInputText(match.command)}${match.rest}` : value;
44
+ }
45
+ function getTuiArgumentHints(command) {
46
+ const params = command.params ?? [];
47
+ const positional = params.filter((param)=>!param.label.startsWith('-'));
48
+ if (positional.length) return positional;
49
+ return [
50
+ ...params.filter((param)=>param.required),
51
+ ...(command.options ?? []).filter((option)=>option.required).map((option)=>({
52
+ label: option.token,
53
+ description: option.description
54
+ }))
55
+ ];
56
+ }
57
+ function TuiParamHint({ command, labels, onPick }) {
58
+ const examples = command.examples?.map((example)=>'string' == typeof example ? {
59
+ value: example,
60
+ label: example
61
+ } : example);
62
+ const params = [
63
+ ...(command.params ?? []).map((param)=>({
64
+ name: param.label,
65
+ description: param.description,
66
+ required: param.required ?? false,
67
+ defaultValue: param.defaultValue
68
+ })),
69
+ ...(command.options ?? []).map((option)=>({
70
+ name: option.token,
71
+ description: option.description,
72
+ required: option.required ?? false,
73
+ defaultValue: option.defaultValue
74
+ }))
75
+ ];
76
+ return /*#__PURE__*/ jsxs("div", {
77
+ className: "ov-tui__hint",
78
+ children: [
79
+ /*#__PURE__*/ jsxs("div", {
80
+ className: "ov-tui__hint-head",
81
+ children: [
82
+ /*#__PURE__*/ jsxs("code", {
83
+ className: "ov-tui__hint-name",
84
+ children: [
85
+ "/",
86
+ command.name
87
+ ]
88
+ }),
89
+ /*#__PURE__*/ jsx("span", {
90
+ className: "ov-tui__hint-desc",
91
+ children: command.description
92
+ })
93
+ ]
94
+ }),
95
+ examples?.length ? /*#__PURE__*/ jsxs("div", {
96
+ className: "ov-tui__hint-group",
97
+ children: [
98
+ /*#__PURE__*/ jsx("div", {
99
+ className: "ov-tui__hint-label",
100
+ children: labels.examples
101
+ }),
102
+ examples.map((example, index)=>/*#__PURE__*/ jsxs("button", {
103
+ type: "button",
104
+ className: "ov-tui__hint-example",
105
+ onMouseDown: (event)=>event.preventDefault(),
106
+ onClick: ()=>onPick(example.value),
107
+ children: [
108
+ /*#__PURE__*/ jsx("span", {
109
+ className: "ov-tui__hint-example-index",
110
+ "aria-hidden": "true",
111
+ children: index + 1
112
+ }),
113
+ /*#__PURE__*/ jsx("span", {
114
+ children: example.label ?? example.value
115
+ })
116
+ ]
117
+ }, example.value))
118
+ ]
119
+ }) : null,
120
+ /*#__PURE__*/ jsxs("div", {
121
+ className: "ov-tui__hint-group",
122
+ children: [
123
+ /*#__PURE__*/ jsx("div", {
124
+ className: "ov-tui__hint-section-title",
125
+ children: labels.parameters
126
+ }),
127
+ /*#__PURE__*/ jsx("code", {
128
+ className: "ov-tui__hint-usage",
129
+ children: command.usage
130
+ }),
131
+ params.length ? /*#__PURE__*/ jsx("div", {
132
+ className: "ov-tui__hint-table-frame",
133
+ children: /*#__PURE__*/ jsxs("table", {
134
+ className: "ov-tui__hint-table",
135
+ children: [
136
+ /*#__PURE__*/ jsx("thead", {
137
+ children: /*#__PURE__*/ jsxs("tr", {
138
+ children: [
139
+ /*#__PURE__*/ jsx("th", {
140
+ children: labels.parameter
141
+ }),
142
+ /*#__PURE__*/ jsx("th", {
143
+ children: labels.required
144
+ }),
145
+ /*#__PURE__*/ jsx("th", {
146
+ children: labels.description
147
+ }),
148
+ /*#__PURE__*/ jsx("th", {
149
+ children: labels.defaultValue
150
+ })
151
+ ]
152
+ })
153
+ }),
154
+ /*#__PURE__*/ jsx("tbody", {
155
+ children: params.map((param)=>/*#__PURE__*/ jsxs("tr", {
156
+ children: [
157
+ /*#__PURE__*/ jsx("td", {
158
+ children: /*#__PURE__*/ jsx("code", {
159
+ children: param.name
160
+ })
161
+ }),
162
+ /*#__PURE__*/ jsx("td", {
163
+ children: param.required ? labels.yes : labels.no
164
+ }),
165
+ /*#__PURE__*/ jsx("td", {
166
+ children: param.description
167
+ }),
168
+ /*#__PURE__*/ jsx("td", {
169
+ children: param.defaultValue ?? '—'
170
+ })
171
+ ]
172
+ }, param.name))
173
+ })
174
+ ]
175
+ })
176
+ }) : /*#__PURE__*/ jsx("div", {
177
+ className: "ov-tui__hint-empty",
178
+ children: labels.noParameters
179
+ })
180
+ ]
181
+ })
182
+ ]
183
+ });
184
+ }
185
+ function useTuiAssistPosition(anchorRef, open, onDismiss) {
186
+ const panelRef = useRef(null);
187
+ const anchorName = `--ov-tui-${useId().replace(/[^a-zA-Z0-9_-]/g, '')}`;
188
+ useEffect(()=>{
189
+ const panel = panelRef.current;
190
+ const anchor = anchorRef.current;
191
+ if (!open || !panel || !anchor) return;
192
+ const dismiss = ()=>onDismiss(anchor.querySelector('textarea')?.value ?? '');
193
+ const outside = (event)=>{
194
+ if (event.target instanceof Node && !panel.contains(event.target) && !anchor.contains(event.target)) dismiss();
195
+ };
196
+ const escape = (event)=>{
197
+ if (event.isComposing || 229 === event.keyCode) return;
198
+ if ('Escape' === event.key && (anchor.contains(document.activeElement) || panel.contains(document.activeElement))) {
199
+ event.preventDefault();
200
+ dismiss();
201
+ }
202
+ };
203
+ document.addEventListener('pointerdown', outside);
204
+ document.addEventListener('keydown', escape);
205
+ if (!('popover' in HTMLElement.prototype)) {
206
+ panel.removeAttribute('popover');
207
+ panel.dataset.inline = '';
208
+ return ()=>{
209
+ document.removeEventListener('pointerdown', outside);
210
+ document.removeEventListener('keydown', escape);
211
+ };
212
+ }
213
+ const nativeAnchors = CSS.supports('position-area', 'block-start span-inline-end');
214
+ const previousAnchor = anchor.style.getPropertyValue('anchor-name');
215
+ anchor.style.setProperty('anchor-name', anchorName);
216
+ panel.style.setProperty('position-anchor', anchorName);
217
+ panel.dataset.floating = '';
218
+ const place = ()=>{
219
+ const rect = anchor.getBoundingClientRect();
220
+ const above = Math.max(0, rect.top - 20);
221
+ const below = Math.max(0, window.innerHeight - rect.bottom - 20);
222
+ const onTop = above >= 160 || above >= below;
223
+ const available = Math.max(80, onTop ? above : below);
224
+ const width = Math.min(rect.width, window.innerWidth - 24);
225
+ const left = Math.max(12, Math.min(rect.left, window.innerWidth - width - 12));
226
+ panel.style.width = `${width}px`;
227
+ panel.style.setProperty('--ov-ui-tui-assist-height', `${Math.min(420, available)}px`);
228
+ const right = window.innerWidth - left - width;
229
+ panel.dataset.side = left >= 334 ? 'left' : right >= 334 ? 'right' : 'stack';
230
+ panel.style.setProperty('--ov-ui-tui-assist-detail-width', `${Math.min(400, (left >= 334 ? left : right) - 14)}px`);
231
+ panel.dataset.placement = onTop ? 'above' : 'below';
232
+ if (nativeAnchors) panel.style.setProperty('position-area', `${onTop ? 'block-start' : 'block-end'} span-inline-end`);
233
+ else {
234
+ panel.style.left = `${left}px`;
235
+ panel.style.top = onTop ? 'auto' : `${rect.bottom + 8}px`;
236
+ panel.style.bottom = onTop ? `${window.innerHeight - rect.top + 8}px` : 'auto';
237
+ }
238
+ };
239
+ place();
240
+ panel.showPopover();
241
+ const observer = new ResizeObserver(place);
242
+ observer.observe(anchor);
243
+ observer.observe(panel);
244
+ window.addEventListener('resize', place);
245
+ window.addEventListener('scroll', place, true);
246
+ return ()=>{
247
+ observer.disconnect();
248
+ window.removeEventListener('resize', place);
249
+ window.removeEventListener('scroll', place, true);
250
+ document.removeEventListener('pointerdown', outside);
251
+ document.removeEventListener('keydown', escape);
252
+ anchor.style.setProperty('anchor-name', previousAnchor);
253
+ if (panel.matches(':popover-open')) panel.hidePopover();
254
+ };
255
+ }, [
256
+ anchorRef,
257
+ anchorName,
258
+ open,
259
+ onDismiss
260
+ ]);
261
+ return panelRef;
262
+ }
263
+ function Highlighted({ text, keyword }) {
264
+ const normalized = keyword.trim().toLowerCase();
265
+ const index = normalized ? text.toLowerCase().indexOf(normalized) : -1;
266
+ if (index < 0) return /*#__PURE__*/ jsx(Fragment, {
267
+ children: text
268
+ });
269
+ return /*#__PURE__*/ jsxs(Fragment, {
270
+ children: [
271
+ text.slice(0, index),
272
+ /*#__PURE__*/ jsx("mark", {
273
+ className: "ov-tui__mark",
274
+ children: text.slice(index, index + normalized.length)
275
+ }),
276
+ text.slice(index + normalized.length)
277
+ ]
278
+ });
279
+ }
280
+ function TuiAssist({ anchorRef, assistId, labels, completion, activeIndex, onActiveIndexChange, onPick, onDismiss }) {
281
+ const options = completion.options;
282
+ const keyword = completion.query.keyword;
283
+ const selected = options[activeIndex];
284
+ const command = selected;
285
+ const open = completion.showSuggestions;
286
+ const panelRef = useTuiAssistPosition(anchorRef, open, onDismiss);
287
+ const listRef = useRef(null);
288
+ useEffect(()=>{
289
+ const list = listRef.current;
290
+ const option = list?.querySelector('[aria-selected="true"]');
291
+ if (!list || !option) return;
292
+ const listBox = list.getBoundingClientRect();
293
+ const optionBox = option.getBoundingClientRect();
294
+ if (optionBox.top < listBox.top) list.scrollTop -= listBox.top - optionBox.top;
295
+ if (optionBox.bottom > listBox.bottom) list.scrollTop += optionBox.bottom - listBox.bottom;
296
+ }, [
297
+ activeIndex,
298
+ options
299
+ ]);
300
+ if (!open) return null;
301
+ return /*#__PURE__*/ jsxs("div", {
302
+ ref: panelRef,
303
+ className: "ov-tui__assist",
304
+ popover: "manual",
305
+ "data-details-only": !options.length || void 0,
306
+ children: [
307
+ command ? /*#__PURE__*/ jsx("div", {
308
+ className: "ov-tui__assist-detail",
309
+ children: /*#__PURE__*/ jsx(TuiParamHint, {
310
+ command: command,
311
+ labels: labels,
312
+ onPick: onPick
313
+ })
314
+ }) : null,
315
+ options.length ? /*#__PURE__*/ jsx("div", {
316
+ className: "ov-tui__suggestions",
317
+ ref: listRef,
318
+ role: "listbox",
319
+ id: assistId,
320
+ "aria-label": labels.suggestions,
321
+ children: completion.suggestions.map((section)=>/*#__PURE__*/ jsxs("div", {
322
+ className: "ov-tui__suggestion-group",
323
+ children: [
324
+ /*#__PURE__*/ jsx("div", {
325
+ className: "ov-tui__suggestion-label",
326
+ children: section.group.label
327
+ }),
328
+ section.commands.map((item)=>{
329
+ const index = options.indexOf(item);
330
+ return /*#__PURE__*/ jsxs("button", {
331
+ id: `${assistId}-${index}`,
332
+ type: "button",
333
+ role: "option",
334
+ "aria-selected": item === selected,
335
+ className: "ov-tui__suggestion",
336
+ onMouseEnter: ()=>onActiveIndexChange(index),
337
+ onFocus: ()=>onActiveIndexChange(index),
338
+ onMouseDown: (event)=>event.preventDefault(),
339
+ onClick: ()=>onPick(`${getTuiCommandInputText(item)} `),
340
+ children: [
341
+ /*#__PURE__*/ jsx("code", {
342
+ className: "ov-tui__suggestion-name",
343
+ children: /*#__PURE__*/ jsx(Highlighted, {
344
+ text: item.name,
345
+ keyword: keyword
346
+ })
347
+ }),
348
+ /*#__PURE__*/ jsx("span", {
349
+ className: "ov-tui__suggestion-desc",
350
+ title: item.summary ?? item.description,
351
+ children: /*#__PURE__*/ jsx(Highlighted, {
352
+ text: item.summary ?? item.description,
353
+ keyword: keyword
354
+ })
355
+ })
356
+ ]
357
+ }, item.name);
358
+ })
359
+ ]
360
+ }, section.group.key))
361
+ }) : command ? null : /*#__PURE__*/ jsx("div", {
362
+ className: "ov-tui__no-suggestions",
363
+ role: "status",
364
+ children: labels.noSuggestions
365
+ })
366
+ ]
367
+ });
368
+ }
369
+ const LEADING_SLASH = /^\s*\//;
370
+ const COMMAND_NAME = /^([^\s]*)([\s\S]*)$/;
371
+ function parseTuiCommandInput(value) {
372
+ if (!LEADING_SLASH.test(value)) return null;
373
+ const body = value.replace(LEADING_SLASH, '');
374
+ const matched = COMMAND_NAME.exec(body);
375
+ if (!matched) return null;
376
+ const name = matched[1] ?? '';
377
+ const rest = matched[2] ?? '';
378
+ return {
379
+ name,
380
+ rest,
381
+ hasTrailingSpace: /^\s/.test(rest)
382
+ };
383
+ }
384
+ function resolveTuiSkeleton(command) {
385
+ return command?.skeleton ?? 'generic';
386
+ }
387
+ function findTuiCommand(text, commands) {
388
+ return matchTuiCommandInput(text, commands)?.command;
389
+ }
390
+ function filterTuiCommands(keyword, commands) {
391
+ const normalized = keyword.trim().toLowerCase();
392
+ if (!normalized) return commands;
393
+ return commands.filter((command)=>command.name.toLowerCase().includes(normalized) || (command.summary ?? command.description).toLowerCase().includes(normalized) || command.aliases?.some((alias)=>alias.toLowerCase().includes(normalized)));
394
+ }
395
+ function groupTuiCommands(commands, groups = []) {
396
+ const known = new Map(groups.map((group)=>[
397
+ group.key,
398
+ group
399
+ ]));
400
+ for (const command of commands){
401
+ const key = command.group ?? '';
402
+ if (!known.has(key)) known.set(key, {
403
+ key,
404
+ label: key
405
+ });
406
+ }
407
+ return Array.from(known.values(), (group)=>({
408
+ group,
409
+ commands: commands.filter((command)=>(command.group ?? '') === group.key)
410
+ })).filter((section)=>section.commands.length > 0);
411
+ }
412
+ const EMPTY_QUERY = {
413
+ keyword: '',
414
+ scope: null,
415
+ matches: [],
416
+ automatic: false,
417
+ canOpenPalette: false,
418
+ colorInput: false
419
+ };
420
+ const normalize = (text)=>text.replace(/[ \t]+/g, ' ');
421
+ function getTuiCommandQuery(value, commands) {
422
+ if (!commands.length || /[\r\n]/.test(value)) return EMPTY_QUERY;
423
+ const slash = parseTuiCommandInput(value);
424
+ const content = normalize(value.trimStart().slice(slash ? 1 : 0));
425
+ if (!slash && !content) return EMPTY_QUERY;
426
+ const boundary = content.lastIndexOf(' ') + 1;
427
+ const head = content.slice(0, boundary);
428
+ const keyword = content.slice(boundary);
429
+ const entries = commands.flatMap((command)=>(slash ? [
430
+ command.name,
431
+ ...command.aliases ?? []
432
+ ] : [
433
+ getTuiCommandInputText(command)
434
+ ]).map((text)=>({
435
+ command,
436
+ text: normalize(text)
437
+ })));
438
+ const definitions = (items)=>[
439
+ ...new Set(items.map((entry)=>entry.command))
440
+ ];
441
+ const scoped = entries.filter((entry)=>entry.text.toLowerCase().startsWith(head.toLowerCase()));
442
+ if (!scoped.length) return EMPTY_QUERY;
443
+ const matching = scoped.filter((entry)=>entry.text.toLowerCase().startsWith(content.toLowerCase()));
444
+ const input = matchTuiCommandInput(value, commands);
445
+ if (input && (!slash || input.rest) && !matching.some((entry)=>entry.text.length > content.trimEnd().length)) return EMPTY_QUERY;
446
+ const base = {
447
+ ...EMPTY_QUERY,
448
+ keyword,
449
+ scope: slash ? '/' : head.trimEnd(),
450
+ automatic: Boolean(slash)
451
+ };
452
+ if (slash) return {
453
+ ...base,
454
+ matches: head ? matching.length ? definitions(matching) : filterTuiCommands(keyword, definitions(scoped)) : filterTuiCommands(keyword, commands)
455
+ };
456
+ if (!keyword) return {
457
+ ...base,
458
+ matches: matching.map((entry)=>entry.command),
459
+ canOpenPalette: matching.length > 0,
460
+ colorInput: matching.length > 0
461
+ };
462
+ const words = content.split(' ').length;
463
+ if (matching.length && matching.every((entry)=>entry.text.split(' ').length > words)) {
464
+ const targets = [
465
+ ...new Set(matching.map((entry)=>entry.text.split(' ').slice(0, words).join(' ')))
466
+ ];
467
+ const target = 1 === targets.length ? targets[0] : void 0;
468
+ return {
469
+ ...base,
470
+ matches: matching.map((entry)=>entry.command),
471
+ colorInput: true,
472
+ prefixTarget: target,
473
+ canOpenPalette: !target || target.toLowerCase() === content.toLowerCase()
474
+ };
475
+ }
476
+ return {
477
+ ...base,
478
+ matches: matching.length ? matching.map((entry)=>entry.command) : filterTuiCommands(keyword, scoped.map((entry)=>entry.command)),
479
+ colorInput: matching.length > 0
480
+ };
481
+ }
482
+ function getTuiInlineCompletion(value, query, selected, paletteOpen = false) {
483
+ const leading = value.slice(0, value.length - value.trimStart().length);
484
+ const content = normalize(value.trimStart());
485
+ if (query.prefixTarget) {
486
+ const suffix = query.prefixTarget.slice(content.length);
487
+ return suffix ? {
488
+ kind: 'prefix',
489
+ suffix,
490
+ value: `${leading}${query.prefixTarget}`
491
+ } : void 0;
492
+ }
493
+ if (!selected || !query.keyword && (!paletteOpen || '/' === query.scope)) return;
494
+ if ('/' === query.scope) {
495
+ const typed = content.slice(1);
496
+ const name = [
497
+ selected.name,
498
+ ...selected.aliases ?? []
499
+ ].map(normalize).find((name)=>name.toLowerCase().startsWith(typed.toLowerCase()));
500
+ const suffix = name?.slice(typed.length);
501
+ return suffix ? {
502
+ kind: 'command',
503
+ suffix,
504
+ value: `${leading}${getTuiCommandInputText(selected)} `
505
+ } : void 0;
506
+ }
507
+ const text = getTuiCommandInputText(selected);
508
+ const normalized = normalize(text);
509
+ if (!normalized.toLowerCase().startsWith(content.toLowerCase())) return;
510
+ const suffix = normalized.slice(content.length);
511
+ return suffix ? {
512
+ kind: 'command',
513
+ suffix,
514
+ value: `${leading}${text} `
515
+ } : void 0;
516
+ }
517
+ function useTuiComposerKeyboard({ inputRef, value, history, completion, inline, disabled, readOnly, canSubmit, activeIndex, onActiveIndexChange, onValueChange, onSubmit, onDismiss, onRequestPalette }) {
518
+ const historyKey = JSON.stringify(history);
519
+ const historyRef = useMemo(()=>({
520
+ current: {
521
+ historyKey,
522
+ offset: -1,
523
+ draft: '',
524
+ value: ''
525
+ }
526
+ }), [
527
+ historyKey
528
+ ]);
529
+ const change = (next)=>{
530
+ historyRef.current.offset = -1;
531
+ onValueChange?.(next);
532
+ };
533
+ const accept = (next)=>{
534
+ change(next);
535
+ inputRef.current?.focus({
536
+ preventScroll: true
537
+ });
538
+ };
539
+ const handleKeyDown = (event)=>{
540
+ if (event.nativeEvent.isComposing || 229 === event.nativeEvent.keyCode) return;
541
+ const input = event.currentTarget;
542
+ const atEnd = input.selectionStart === input.selectionEnd && input.selectionEnd === value.length;
543
+ if ('Tab' === event.key) {
544
+ if (event.shiftKey || event.ctrlKey || event.altKey || event.metaKey) return;
545
+ event.preventDefault();
546
+ if (!atEnd) return;
547
+ }
548
+ const options = completion.options;
549
+ const listOpen = completion.showSuggestions;
550
+ if ('Escape' === event.key && (inline || listOpen)) {
551
+ event.preventDefault();
552
+ onDismiss(value);
553
+ return;
554
+ }
555
+ if (!disabled && !readOnly) {
556
+ if ('Tab' === event.key && inline?.kind === 'prefix') {
557
+ event.preventDefault();
558
+ accept(inline.value);
559
+ return;
560
+ }
561
+ if (' ' === event.key && atEnd && inline?.kind === 'prefix' && !event.shiftKey && !event.ctrlKey && !event.altKey && !event.metaKey) {
562
+ event.preventDefault();
563
+ accept(`${inline.value} `);
564
+ return;
565
+ }
566
+ if ('Tab' === event.key && completion.query.canOpenPalette && !listOpen) {
567
+ event.preventDefault();
568
+ onRequestPalette();
569
+ return;
570
+ }
571
+ if (listOpen && options.length) {
572
+ if ('ArrowDown' === event.key || 'ArrowUp' === event.key) {
573
+ event.preventDefault();
574
+ const delta = 'ArrowDown' === event.key ? 1 : -1;
575
+ onActiveIndexChange((index)=>index < 0 ? delta > 0 ? 0 : options.length - 1 : (index + delta + options.length) % options.length);
576
+ return;
577
+ }
578
+ const spaceCommand = ' ' === event.key && atEnd ? matchTuiCommandInput(value, options)?.command : void 0;
579
+ if ('Tab' === event.key || 'Enter' === event.key && !event.shiftKey || spaceCommand) {
580
+ event.preventDefault();
581
+ const picked = spaceCommand ?? options[activeIndex];
582
+ if (picked) accept(`${getTuiCommandInputText(picked)} `);
583
+ else if ('Tab' === event.key && inline) accept(inline.value);
584
+ return;
585
+ }
586
+ }
587
+ if ('Tab' === event.key && inline) {
588
+ event.preventDefault();
589
+ accept(inline.value);
590
+ return;
591
+ }
592
+ }
593
+ const previous = historyRef.current;
594
+ const browsing = previous.offset >= 0 && previous.value === value;
595
+ if (!disabled && !readOnly && history.length > 0 && input.selectionStart === input.selectionEnd && !event.shiftKey && ('ArrowUp' === event.key && !value.slice(0, input.selectionStart).includes('\n') || 'ArrowDown' === event.key && browsing && !value.slice(input.selectionEnd).includes('\n'))) {
596
+ event.preventDefault();
597
+ const offset = Math.max(-1, Math.min(history.length - 1, (browsing ? previous.offset : -1) + ('ArrowUp' === event.key ? 1 : -1)));
598
+ const draft = browsing ? previous.draft : value;
599
+ const next = offset < 0 ? draft : history[history.length - 1 - offset];
600
+ historyRef.current = {
601
+ historyKey,
602
+ offset,
603
+ draft,
604
+ value: next
605
+ };
606
+ onValueChange?.(next);
607
+ onDismiss(next);
608
+ inputRef.current?.focus({
609
+ preventScroll: true
610
+ });
611
+ return;
612
+ }
613
+ if ('Enter' === event.key && !event.shiftKey) {
614
+ event.preventDefault();
615
+ if (value.trim() && !disabled && !readOnly && canSubmit) onSubmit?.(value.trim());
616
+ }
617
+ };
618
+ return {
619
+ change,
620
+ handleKeyDown
621
+ };
622
+ }
623
+ const TUI_URI_PATTERN = /viking:\/\/[^\s"'<>`]+/g;
624
+ const TUI_PROSE_URI_PATTERN = /viking:\/\/[^\s,,。;;、"'<>()[\]]+/g;
625
+ function getTuiSafeHref(uri) {
626
+ const href = uri?.trim();
627
+ return href && /^(?:viking|https?):\/\/[^\s]+$/i.test(href) ? href : void 0;
628
+ }
629
+ async function copyTuiText(text) {
630
+ if ("u" < typeof navigator) return false;
631
+ try {
632
+ if (navigator.clipboard?.writeText) {
633
+ await navigator.clipboard.writeText(text);
634
+ return true;
635
+ }
636
+ } catch {}
637
+ return false;
638
+ }
639
+ function formatTuiJson(text) {
640
+ const trimmed = text.trim();
641
+ if (!trimmed || !/^[[{]/.test(trimmed)) return text;
642
+ try {
643
+ JSON.parse(trimmed);
644
+ } catch {
645
+ return text;
646
+ }
647
+ const tokens = trimmed.match(/"(?:\\.|[^"\\])*"|[^\s]/g) ?? [];
648
+ let depth = 0;
649
+ let output = '';
650
+ const newline = ()=>`\n${' '.repeat(depth)}`;
651
+ for (const [index, token] of tokens.entries())if ('{' === token || '[' === token) {
652
+ output += token;
653
+ depth++;
654
+ if ('}' !== tokens[index + 1] && ']' !== tokens[index + 1]) output += newline();
655
+ } else if ('}' === token || ']' === token) {
656
+ depth--;
657
+ if ('{' !== tokens[index - 1] && '[' !== tokens[index - 1]) output += newline();
658
+ output += token;
659
+ } else if (',' === token) output += `,${newline()}`;
660
+ else if (':' === token) output += ': ';
661
+ else output += token;
662
+ return output;
663
+ }
664
+ function TuiUriLink({ uri, children, onOpenUri, editor = false, className = 'ov-tui__link' }) {
665
+ const href = getTuiSafeHref(uri);
666
+ if (!href) return /*#__PURE__*/ jsx(Fragment, {
667
+ children: children
668
+ });
669
+ return /*#__PURE__*/ jsx("a", {
670
+ href: href,
671
+ className: className,
672
+ onMouseDown: editor ? (event)=>event.preventDefault() : void 0,
673
+ onClick: onOpenUri ? (event)=>{
674
+ event.preventDefault();
675
+ onOpenUri(href);
676
+ } : void 0,
677
+ children: children
678
+ });
679
+ }
680
+ function TuiUriText({ text, onOpenUri, editor = false, mode }) {
681
+ const parts = [];
682
+ let cursor = 0;
683
+ const pattern = new RegExp(('prose' === mode ? TUI_PROSE_URI_PATTERN : TUI_URI_PATTERN).source, 'gi');
684
+ const plain = (value, key)=>editor ? /*#__PURE__*/ jsx("span", {
685
+ "aria-hidden": "true",
686
+ children: value
687
+ }, key) : value;
688
+ for (const matched of text.matchAll(pattern)){
689
+ const index = matched.index ?? 0;
690
+ const uri = 'prose' === mode ? matched[0].replace(/[.!?;;::!?]+$/u, '') : matched[0];
691
+ if (index > cursor) parts.push(plain(text.slice(cursor, index), cursor));
692
+ parts.push(/*#__PURE__*/ jsx(TuiUriLink, {
693
+ uri: uri,
694
+ onOpenUri: onOpenUri,
695
+ editor: editor,
696
+ children: uri
697
+ }, `${index}-${uri}`));
698
+ cursor = index + uri.length;
699
+ }
700
+ if (!parts.length) return /*#__PURE__*/ jsx(Fragment, {
701
+ children: plain(text, 0)
702
+ });
703
+ if (cursor < text.length) parts.push(plain(text.slice(cursor), cursor));
704
+ return /*#__PURE__*/ jsx(Fragment, {
705
+ children: parts
706
+ });
707
+ }
708
+ function TuiCommandText({ text, name, namespaceOnly = false }) {
709
+ const namedStart = name ? text.length - name.length : -1;
710
+ const matchesName = namedStart >= 0 && text.slice(namedStart).toLowerCase() === name?.toLowerCase() && (0 === namedStart || /\s/.test(text[namedStart - 1]));
711
+ const lastToken = text.search(/\S+$/);
712
+ const start = namespaceOnly ? text.length : matchesName ? namedStart : lastToken < 0 ? text.length : lastToken;
713
+ return /*#__PURE__*/ jsxs(Fragment, {
714
+ children: [
715
+ start > 0 ? /*#__PURE__*/ jsx("span", {
716
+ className: "ov-tui__command-prefix",
717
+ children: text.slice(0, start)
718
+ }) : null,
719
+ start < text.length ? /*#__PURE__*/ jsx("span", {
720
+ className: "ov-tui__command-name",
721
+ children: text.slice(start)
722
+ }) : null
723
+ ]
724
+ });
725
+ }
726
+ function TuiInputMirror({ value, input, inline, colorInput, onOpenUri, onScroll, mirrorRef, hintId }) {
727
+ const hints = input && !input.rest.trim() ? getTuiArgumentHints(input.command) : [];
728
+ return /*#__PURE__*/ jsxs(Fragment, {
729
+ children: [
730
+ /*#__PURE__*/ jsxs("span", {
731
+ className: "ov-tui__input-mirror",
732
+ ref: mirrorRef,
733
+ onScroll: onScroll,
734
+ children: [
735
+ input ? /*#__PURE__*/ jsxs(Fragment, {
736
+ children: [
737
+ input.leadingWhitespace,
738
+ /*#__PURE__*/ jsx("span", {
739
+ "aria-hidden": "true",
740
+ children: /*#__PURE__*/ jsx("span", {
741
+ className: "ov-tui__input-command",
742
+ children: /*#__PURE__*/ jsx(TuiCommandText, {
743
+ text: input.prefix,
744
+ name: input.command.name
745
+ })
746
+ })
747
+ }),
748
+ /*#__PURE__*/ jsx(TuiUriText, {
749
+ text: input.rest,
750
+ mode: "literal",
751
+ onOpenUri: onOpenUri,
752
+ editor: true
753
+ })
754
+ ]
755
+ }) : colorInput ? /*#__PURE__*/ jsx("span", {
756
+ className: "ov-tui__input-command",
757
+ "aria-hidden": "true",
758
+ children: /*#__PURE__*/ jsx(TuiCommandText, {
759
+ text: value,
760
+ namespaceOnly: inline?.kind !== 'command'
761
+ })
762
+ }) : /*#__PURE__*/ jsx(TuiUriText, {
763
+ text: value,
764
+ mode: "literal",
765
+ onOpenUri: onOpenUri,
766
+ editor: true
767
+ }),
768
+ /*#__PURE__*/ jsxs("span", {
769
+ "aria-hidden": "true",
770
+ children: [
771
+ inline ? /*#__PURE__*/ jsx("span", {
772
+ className: "ov-tui__input-completion",
773
+ children: inline.suffix
774
+ }) : null,
775
+ hints.length ? /*#__PURE__*/ jsxs("span", {
776
+ className: "ov-tui__input-arguments",
777
+ children: [
778
+ input?.rest.endsWith(' ') ? '' : ' ',
779
+ hints.map((hint)=>hint.label).join(' ')
780
+ ]
781
+ }) : null,
782
+ value.endsWith('\n') ? '\u200b' : null
783
+ ]
784
+ })
785
+ ]
786
+ }),
787
+ /*#__PURE__*/ jsxs("span", {
788
+ id: hintId,
789
+ className: "ov-tui__input-hint-description",
790
+ "aria-live": inline?.kind === 'prefix' ? 'polite' : void 0,
791
+ children: [
792
+ inline?.value,
793
+ hints.map((hint)=>`${hint.label}: ${hint.description}`).join('; ')
794
+ ]
795
+ })
796
+ ]
797
+ });
798
+ }
799
+ function TuiComposer({ anchorRef, assistId, onFocus, onDismiss, onRequestPalette, value, history, labels, completion, disabled, readOnly, canSubmit, activeIndex, onActiveIndexChange, onValueChange, onSubmit, onOpenUri }) {
800
+ const inputRef = useRef(null);
801
+ const inputId = useId();
802
+ const mirrorRef = useRef(null);
803
+ const showSuggestions = completion.showSuggestions && completion.options.length > 0;
804
+ const preview = completion.options[activeIndex] ?? (completion.query.keyword ? completion.options[0] : void 0);
805
+ const inline = completion.enabled ? getTuiInlineCompletion(value, completion.query, preview, completion.showSuggestions) : void 0;
806
+ const keyboard = useTuiComposerKeyboard({
807
+ inputRef,
808
+ value,
809
+ history,
810
+ completion,
811
+ inline,
812
+ disabled,
813
+ readOnly,
814
+ canSubmit,
815
+ activeIndex,
816
+ onActiveIndexChange,
817
+ onValueChange,
818
+ onSubmit,
819
+ onDismiss,
820
+ onRequestPalette
821
+ });
822
+ return /*#__PURE__*/ jsxs("div", {
823
+ ref: anchorRef,
824
+ className: "ov-tui__composer",
825
+ "data-disabled": disabled || void 0,
826
+ children: [
827
+ /*#__PURE__*/ jsxs("div", {
828
+ className: "ov-tui__input-row",
829
+ "data-value": `${value}\n`,
830
+ children: [
831
+ /*#__PURE__*/ jsx("label", {
832
+ className: "ov-tui__input-label",
833
+ htmlFor: inputId,
834
+ children: labels.placeholder
835
+ }),
836
+ /*#__PURE__*/ jsx(TuiInputMirror, {
837
+ value: value,
838
+ input: completion.activeInput,
839
+ inline: inline,
840
+ colorInput: completion.query.colorInput,
841
+ onOpenUri: onOpenUri,
842
+ onScroll: (event)=>{
843
+ if (inputRef.current) {
844
+ inputRef.current.scrollTop = event.currentTarget.scrollTop;
845
+ inputRef.current.scrollLeft = event.currentTarget.scrollLeft;
846
+ }
847
+ },
848
+ mirrorRef: mirrorRef,
849
+ hintId: `${inputId}-hint`
850
+ }),
851
+ /*#__PURE__*/ jsx("textarea", {
852
+ id: inputId,
853
+ name: "command",
854
+ ref: inputRef,
855
+ className: "ov-tui__input",
856
+ rows: 1,
857
+ value: value,
858
+ placeholder: labels.placeholder,
859
+ readOnly: readOnly,
860
+ disabled: disabled,
861
+ autoCapitalize: "off",
862
+ autoCorrect: "off",
863
+ spellCheck: false,
864
+ enterKeyHint: "send",
865
+ onFocus: onFocus,
866
+ "aria-describedby": `${inputId}-shortcuts ${inputId}-hint`,
867
+ "aria-autocomplete": inline ? 'both' : 'list',
868
+ "aria-haspopup": "listbox",
869
+ "aria-controls": showSuggestions ? assistId : void 0,
870
+ "aria-activedescendant": showSuggestions && activeIndex >= 0 ? `${assistId}-${activeIndex}` : void 0,
871
+ onChange: (event)=>keyboard.change(event.target.value),
872
+ onScroll: (event)=>{
873
+ if (mirrorRef.current) {
874
+ mirrorRef.current.scrollTop = event.currentTarget.scrollTop;
875
+ mirrorRef.current.scrollLeft = event.currentTarget.scrollLeft;
876
+ }
877
+ },
878
+ onKeyDown: keyboard.handleKeyDown
879
+ })
880
+ ]
881
+ }),
882
+ /*#__PURE__*/ jsxs("div", {
883
+ className: "ov-tui__shortcuts",
884
+ id: `${inputId}-shortcuts`,
885
+ children: [
886
+ /*#__PURE__*/ jsxs("span", {
887
+ className: "ov-tui__shortcut",
888
+ children: [
889
+ /*#__PURE__*/ jsx("kbd", {
890
+ children: "/"
891
+ }),
892
+ labels.allCommands
893
+ ]
894
+ }),
895
+ /*#__PURE__*/ jsxs("span", {
896
+ className: "ov-tui__shortcut",
897
+ children: [
898
+ /*#__PURE__*/ jsx("kbd", {
899
+ children: "↑"
900
+ }),
901
+ labels.historyCommands
902
+ ]
903
+ }),
904
+ /*#__PURE__*/ jsxs("span", {
905
+ className: "ov-tui__shortcut",
906
+ children: [
907
+ /*#__PURE__*/ jsx("kbd", {
908
+ children: "↵"
909
+ }),
910
+ labels.send
911
+ ]
912
+ })
913
+ ]
914
+ }),
915
+ disabled ? /*#__PURE__*/ jsx("div", {
916
+ className: "ov-tui__unavailable",
917
+ role: "status",
918
+ children: labels.unavailableMessage
919
+ }) : null
920
+ ]
921
+ });
922
+ }
923
+ function pickTuiCommands(names = [], commands) {
924
+ const byName = new Map(commands.map((command)=>[
925
+ command.name,
926
+ command
927
+ ]));
928
+ return [
929
+ ...new Set(names)
930
+ ].flatMap((name)=>byName.get(name) ?? []);
931
+ }
932
+ function TuiEmptyRegion({ emptyState, commands, labels, disabled, onPick }) {
933
+ if (void 0 !== emptyState) return null === emptyState ? null : /*#__PURE__*/ jsx("div", {
934
+ className: "ov-tui__empty",
935
+ children: emptyState
936
+ });
937
+ if (!commands.length) return null;
938
+ return /*#__PURE__*/ jsxs("div", {
939
+ className: "ov-tui__empty ov-tui__empty--hero",
940
+ children: [
941
+ /*#__PURE__*/ jsx("h3", {
942
+ className: "ov-tui__empty-title",
943
+ children: labels.emptyTitle
944
+ }),
945
+ /*#__PURE__*/ jsx("p", {
946
+ className: "ov-tui__empty-subtitle",
947
+ children: labels.emptyDescription
948
+ }),
949
+ /*#__PURE__*/ jsx("p", {
950
+ className: "ov-tui__empty-quick-label",
951
+ children: labels.quickStart
952
+ }),
953
+ /*#__PURE__*/ jsx("ul", {
954
+ className: "ov-tui__empty-list",
955
+ children: commands.map((command)=>/*#__PURE__*/ jsx("li", {
956
+ className: "ov-tui__empty-item",
957
+ children: /*#__PURE__*/ jsxs("button", {
958
+ type: "button",
959
+ className: "ov-tui__empty-action",
960
+ disabled: disabled,
961
+ onClick: ()=>onPick(command),
962
+ children: [
963
+ /*#__PURE__*/ jsx(ArrowRightIcon, {
964
+ width: 14,
965
+ height: 14,
966
+ focusable: "false"
967
+ }),
968
+ /*#__PURE__*/ jsx("span", {
969
+ className: "ov-tui__empty-name",
970
+ children: command.name
971
+ }),
972
+ /*#__PURE__*/ jsx("span", {
973
+ className: "ov-tui__empty-desc",
974
+ children: command.summary ?? command.description
975
+ })
976
+ ]
977
+ })
978
+ }, command.name))
979
+ })
980
+ ]
981
+ });
982
+ }
983
+ const messages = {
984
+ placeholder: '>_ Enter CLI commands, e.g. ov find OpenViking',
985
+ unavailableMessage: 'Commands are unavailable right now.',
986
+ send: 'Send',
987
+ allCommands: 'All commands',
988
+ historyCommands: 'History',
989
+ suggestions: 'Command suggestions',
990
+ noSuggestions: 'No matching commands',
991
+ pending: 'Running',
992
+ success: 'Succeeded',
993
+ error: 'Failed',
994
+ copy: 'Copy',
995
+ copied: 'Copied',
996
+ emptyTitle: 'OpenViking CLI',
997
+ emptyDescription: 'Work directly with your context through the CLI',
998
+ quickStart: 'Quick start:',
999
+ noResult: 'No result returned',
1000
+ justNow: 'Just now',
1001
+ formatMinutesAgo: (minutes)=>`${minutes} minute${1 === minutes ? '' : 's'} ago`,
1002
+ formatHoursAgo: (hours)=>`${hours} hour${1 === hours ? '' : 's'} ago`,
1003
+ availableCommands: 'Available commands',
1004
+ helpHint: 'Type / to open the command palette.',
1005
+ parameters: 'Parameters',
1006
+ examples: 'Examples',
1007
+ noParameters: 'No parameters',
1008
+ loadMore: 'Load more',
1009
+ resource: 'Resource',
1010
+ parameter: 'Parameter',
1011
+ required: 'Required',
1012
+ description: "Description",
1013
+ defaultValue: 'Default',
1014
+ yes: 'Yes',
1015
+ no: 'No'
1016
+ };
1017
+ const en_US = messages;
1018
+ const zh_CN_messages = {
1019
+ placeholder: '>_ 输入 CLI 命令,如 ov find OpenViking',
1020
+ unavailableMessage: '当前无法执行命令。',
1021
+ send: '发送',
1022
+ allCommands: '全部指令',
1023
+ historyCommands: '历史指令',
1024
+ suggestions: '命令建议',
1025
+ noSuggestions: '没有匹配的命令',
1026
+ pending: '执行中',
1027
+ success: '执行成功',
1028
+ error: '执行失败',
1029
+ copy: '复制',
1030
+ copied: '复制成功',
1031
+ emptyTitle: 'OpenViking CLI',
1032
+ emptyDescription: 'CLI 直接操作上下文',
1033
+ quickStart: '快速体验:',
1034
+ noResult: '暂无返回结果',
1035
+ justNow: '刚刚',
1036
+ formatMinutesAgo: (minutes)=>`${minutes} 分钟前`,
1037
+ formatHoursAgo: (hours)=>`${hours} 小时前`,
1038
+ availableCommands: '可用命令',
1039
+ helpHint: '输入 / 可打开命令面板。',
1040
+ parameters: '参数详情',
1041
+ examples: '快速体验',
1042
+ noParameters: '此命令不需要参数',
1043
+ loadMore: '加载更多',
1044
+ resource: '资源',
1045
+ parameter: '参数',
1046
+ required: '必填',
1047
+ description: '说明',
1048
+ defaultValue: '默认值',
1049
+ yes: '是',
1050
+ no: '否'
1051
+ };
1052
+ const zh_CN = zh_CN_messages;
1053
+ const LOCALES = {
1054
+ 'en-US': en_US,
1055
+ 'zh-CN': zh_CN
1056
+ };
1057
+ function resolveTuiLabels(labels, locale = 'en-US') {
1058
+ return resolveLocale(LOCALES, locale, labels);
1059
+ }
1060
+ function TuiCommandHelp({ content, onPick, labels }) {
1061
+ return /*#__PURE__*/ jsxs("div", {
1062
+ className: "ov-tui__help",
1063
+ children: [
1064
+ /*#__PURE__*/ jsx("div", {
1065
+ className: "ov-tui__help-lead",
1066
+ children: labels.availableCommands
1067
+ }),
1068
+ content.sections.map((section)=>/*#__PURE__*/ jsxs("section", {
1069
+ className: "ov-tui__help-section",
1070
+ children: [
1071
+ /*#__PURE__*/ jsx("div", {
1072
+ className: "ov-tui__help-section-label",
1073
+ children: section.label
1074
+ }),
1075
+ /*#__PURE__*/ jsx("div", {
1076
+ className: "ov-tui__help-items",
1077
+ children: section.items.map((item)=>/*#__PURE__*/ jsxs("button", {
1078
+ type: "button",
1079
+ className: "ov-tui__help-item",
1080
+ disabled: !onPick,
1081
+ onClick: ()=>onPick?.(item.name),
1082
+ children: [
1083
+ /*#__PURE__*/ jsx("span", {
1084
+ className: "ov-tui__help-name",
1085
+ children: item.name
1086
+ }),
1087
+ item.description ? /*#__PURE__*/ jsx("span", {
1088
+ className: "ov-tui__help-desc",
1089
+ children: item.description
1090
+ }) : null
1091
+ ]
1092
+ }, item.key))
1093
+ })
1094
+ ]
1095
+ }, section.key)),
1096
+ /*#__PURE__*/ jsx("div", {
1097
+ className: "ov-tui__help-footer",
1098
+ children: labels.helpHint
1099
+ })
1100
+ ]
1101
+ });
1102
+ }
1103
+ function formatTuiRecordTime(record, labels, now = Date.now()) {
1104
+ const timestamp = record.createdAtMs;
1105
+ if ('number' != typeof timestamp || !Number.isFinite(timestamp)) return record.createdAt;
1106
+ const date = new Date(timestamp);
1107
+ if (!Number.isFinite(date.getTime())) return record.createdAt;
1108
+ const elapsed = Math.max(0, now - timestamp);
1109
+ if (elapsed < 60000) return labels.justNow;
1110
+ if (elapsed < 3600000) return labels.formatMinutesAgo(Math.floor(elapsed / 60000));
1111
+ if (elapsed < 86400000) return labels.formatHoursAgo(Math.floor(elapsed / 3600000));
1112
+ const pad = (value)=>String(value).padStart(2, '0');
1113
+ return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}`;
1114
+ }
1115
+ const subscribe = ()=>()=>{};
1116
+ const clientSnapshot = ()=>true;
1117
+ const serverSnapshot = ()=>false;
1118
+ function TuiRecordTime({ record, labels }) {
1119
+ const client = useSyncExternalStore(subscribe, clientSnapshot, serverSnapshot);
1120
+ const text = client ? formatTuiRecordTime(record, labels) : record.createdAt;
1121
+ return text ? /*#__PURE__*/ jsx("span", {
1122
+ className: "ov-tui__bubble-time",
1123
+ children: text
1124
+ }) : null;
1125
+ }
1126
+ const SvgCopy = (props)=>/*#__PURE__*/ jsxs("svg", {
1127
+ xmlns: "http://www.w3.org/2000/svg",
1128
+ width: 16,
1129
+ height: 16,
1130
+ fill: "none",
1131
+ viewBox: "0 0 16 16",
1132
+ ...props,
1133
+ children: [
1134
+ /*#__PURE__*/ jsx("rect", {
1135
+ width: 8,
1136
+ height: 8,
1137
+ x: 5.5,
1138
+ y: 5.5,
1139
+ stroke: "currentColor",
1140
+ strokeWidth: 1.2,
1141
+ rx: 1.5
1142
+ }),
1143
+ /*#__PURE__*/ jsx("path", {
1144
+ stroke: "currentColor",
1145
+ strokeLinecap: "round",
1146
+ strokeWidth: 1.2,
1147
+ d: "M10.5 3.5V3A1.5 1.5 0 0 0 9 1.5H3A1.5 1.5 0 0 0 1.5 3v6A1.5 1.5 0 0 0 3 10.5h.5"
1148
+ })
1149
+ ]
1150
+ });
1151
+ const copyreact = SvgCopy;
1152
+ function TuiCopyButton({ text, label, copiedLabel, onCopy, className }) {
1153
+ const [copied, setCopied] = useState(false);
1154
+ const resetTimer = useRef(void 0);
1155
+ useEffect(()=>()=>window.clearTimeout(resetTimer.current), []);
1156
+ const handleCopy = ()=>{
1157
+ copyTuiText(text).then((succeeded)=>{
1158
+ if (!succeeded) return;
1159
+ window.clearTimeout(resetTimer.current);
1160
+ setCopied(true);
1161
+ onCopy?.(text);
1162
+ resetTimer.current = window.setTimeout(()=>setCopied(false), 1500);
1163
+ });
1164
+ };
1165
+ return /*#__PURE__*/ jsx(Tooltip, {
1166
+ content: copied ? copiedLabel : label,
1167
+ children: /*#__PURE__*/ jsx("button", {
1168
+ type: "button",
1169
+ className: [
1170
+ 'ov-tui__copy',
1171
+ className
1172
+ ].filter(Boolean).join(' '),
1173
+ "aria-label": copied ? copiedLabel : label,
1174
+ onClick: handleCopy,
1175
+ children: copied ? /*#__PURE__*/ jsx(checkreact, {
1176
+ "aria-hidden": "true",
1177
+ focusable: "false"
1178
+ }) : /*#__PURE__*/ jsx(copyreact, {
1179
+ "aria-hidden": "true",
1180
+ focusable: "false"
1181
+ })
1182
+ })
1183
+ });
1184
+ }
1185
+ function TuiCodeBlock({ text, labels, onCopy, onOpenUri }) {
1186
+ return /*#__PURE__*/ jsxs("div", {
1187
+ className: "ov-tui__code-block",
1188
+ children: [
1189
+ /*#__PURE__*/ jsx(TuiCopyButton, {
1190
+ className: "ov-tui__copy--inline",
1191
+ text: text,
1192
+ label: labels.copy,
1193
+ copiedLabel: labels.copied,
1194
+ onCopy: onCopy
1195
+ }),
1196
+ /*#__PURE__*/ jsx("pre", {
1197
+ className: "ov-tui__code-content",
1198
+ children: /*#__PURE__*/ jsx(TuiUriText, {
1199
+ text: formatTuiJson(text),
1200
+ mode: "literal",
1201
+ onOpenUri: onOpenUri
1202
+ })
1203
+ })
1204
+ ]
1205
+ });
1206
+ }
1207
+ const TuiMarkdownContext = /*#__PURE__*/ createContext(null);
1208
+ const InsideLink = /*#__PURE__*/ createContext(false);
1209
+ function textOf(children) {
1210
+ if ('string' == typeof children || 'number' == typeof children) return String(children);
1211
+ if (Array.isArray(children)) return children.map(textOf).join('');
1212
+ if (/*#__PURE__*/ isValidElement(children)) return textOf(children.props.children);
1213
+ return '';
1214
+ }
1215
+ function LinkedText({ children }) {
1216
+ const options = useContext(TuiMarkdownContext);
1217
+ const insideLink = useContext(InsideLink);
1218
+ return /*#__PURE__*/ jsx(Fragment, {
1219
+ children: insideLink ? children : Children.map(children, (child)=>'string' == typeof child ? /*#__PURE__*/ jsx(TuiUriText, {
1220
+ text: child,
1221
+ mode: "prose",
1222
+ onOpenUri: options.onOpenUri
1223
+ }) : child)
1224
+ });
1225
+ }
1226
+ function MarkdownCode({ children }) {
1227
+ const options = useContext(TuiMarkdownContext);
1228
+ const insideLink = useContext(InsideLink);
1229
+ return /*#__PURE__*/ jsx("code", {
1230
+ children: insideLink ? children : /*#__PURE__*/ jsx(TuiUriText, {
1231
+ text: textOf(children),
1232
+ mode: "literal",
1233
+ onOpenUri: options.onOpenUri
1234
+ })
1235
+ });
1236
+ }
1237
+ function MarkdownPre({ children }) {
1238
+ const options = useContext(TuiMarkdownContext);
1239
+ return /*#__PURE__*/ jsx(TuiCodeBlock, {
1240
+ text: textOf(children).replace(/\n$/, ''),
1241
+ ...options
1242
+ });
1243
+ }
1244
+ function MarkdownLink({ children, href, title }) {
1245
+ const { onOpenUri } = useContext(TuiMarkdownContext);
1246
+ const isViking = /^viking:/i.test(href ?? '');
1247
+ const target = isViking ? getTuiSafeHref(href) : href;
1248
+ return /*#__PURE__*/ jsx(InsideLink.Provider, {
1249
+ value: true,
1250
+ children: target ? /*#__PURE__*/ jsx("a", {
1251
+ href: target,
1252
+ title: title,
1253
+ className: isViking ? 'ov-tui__link' : void 0,
1254
+ target: isViking ? void 0 : '_blank',
1255
+ rel: isViking ? void 0 : 'noreferrer',
1256
+ onClick: isViking && onOpenUri ? (event)=>{
1257
+ event.preventDefault();
1258
+ onOpenUri(target);
1259
+ } : void 0,
1260
+ children: children
1261
+ }) : children
1262
+ });
1263
+ }
1264
+ const TUI_MARKDOWN_COMPONENTS = {
1265
+ p: ({ children })=>/*#__PURE__*/ jsx("p", {
1266
+ children: /*#__PURE__*/ jsx(LinkedText, {
1267
+ children: children
1268
+ })
1269
+ }),
1270
+ li: ({ children })=>/*#__PURE__*/ jsx("li", {
1271
+ children: /*#__PURE__*/ jsx(LinkedText, {
1272
+ children: children
1273
+ })
1274
+ }),
1275
+ h1: ({ children })=>/*#__PURE__*/ jsx("h1", {
1276
+ children: /*#__PURE__*/ jsx(LinkedText, {
1277
+ children: children
1278
+ })
1279
+ }),
1280
+ h2: ({ children })=>/*#__PURE__*/ jsx("h2", {
1281
+ children: /*#__PURE__*/ jsx(LinkedText, {
1282
+ children: children
1283
+ })
1284
+ }),
1285
+ h3: ({ children })=>/*#__PURE__*/ jsx("h3", {
1286
+ children: /*#__PURE__*/ jsx(LinkedText, {
1287
+ children: children
1288
+ })
1289
+ }),
1290
+ h4: ({ children })=>/*#__PURE__*/ jsx("h4", {
1291
+ children: /*#__PURE__*/ jsx(LinkedText, {
1292
+ children: children
1293
+ })
1294
+ }),
1295
+ h5: ({ children })=>/*#__PURE__*/ jsx("h5", {
1296
+ children: /*#__PURE__*/ jsx(LinkedText, {
1297
+ children: children
1298
+ })
1299
+ }),
1300
+ h6: ({ children })=>/*#__PURE__*/ jsx("h6", {
1301
+ children: /*#__PURE__*/ jsx(LinkedText, {
1302
+ children: children
1303
+ })
1304
+ }),
1305
+ strong: ({ children })=>/*#__PURE__*/ jsx("strong", {
1306
+ children: /*#__PURE__*/ jsx(LinkedText, {
1307
+ children: children
1308
+ })
1309
+ }),
1310
+ em: ({ children })=>/*#__PURE__*/ jsx("em", {
1311
+ children: /*#__PURE__*/ jsx(LinkedText, {
1312
+ children: children
1313
+ })
1314
+ }),
1315
+ del: ({ children })=>/*#__PURE__*/ jsx("del", {
1316
+ children: /*#__PURE__*/ jsx(LinkedText, {
1317
+ children: children
1318
+ })
1319
+ }),
1320
+ td: ({ children, style })=>/*#__PURE__*/ jsx("td", {
1321
+ style: style,
1322
+ children: /*#__PURE__*/ jsx(LinkedText, {
1323
+ children: children
1324
+ })
1325
+ }),
1326
+ th: ({ children, style })=>/*#__PURE__*/ jsx("th", {
1327
+ style: style,
1328
+ children: /*#__PURE__*/ jsx(LinkedText, {
1329
+ children: children
1330
+ })
1331
+ }),
1332
+ code: MarkdownCode,
1333
+ pre: MarkdownPre,
1334
+ a: MarkdownLink,
1335
+ table: ({ children })=>/*#__PURE__*/ jsx("div", {
1336
+ className: "ov-tui__table-frame",
1337
+ children: /*#__PURE__*/ jsx("table", {
1338
+ children: children
1339
+ })
1340
+ })
1341
+ };
1342
+ function TuiMarkdown({ text, ...options }) {
1343
+ return /*#__PURE__*/ jsx(TuiMarkdownContext.Provider, {
1344
+ value: options,
1345
+ children: /*#__PURE__*/ jsx("div", {
1346
+ className: "ov-tui__markdown",
1347
+ children: /*#__PURE__*/ jsx(react_markdown, {
1348
+ remarkPlugins: [
1349
+ [
1350
+ remark_gfm,
1351
+ {
1352
+ singleTilde: false
1353
+ }
1354
+ ]
1355
+ ],
1356
+ urlTransform: (url)=>/^viking:/i.test(url) ? getTuiSafeHref(url) ?? '' : defaultUrlTransform(url),
1357
+ components: TUI_MARKDOWN_COMPONENTS,
1358
+ children: text
1359
+ })
1360
+ })
1361
+ });
1362
+ }
1363
+ function getVisibleTuiResultTitle(title, command) {
1364
+ if (!title || !command) return title;
1365
+ const candidate = title.trim().replace(/^\*\*([\s\S]*)\*\*$/, '$1').replace(/^\/+/, '').trim();
1366
+ const match = matchTuiCommandInput(candidate, [
1367
+ command
1368
+ ]);
1369
+ return match && !match.rest.trim() ? void 0 : title;
1370
+ }
1371
+ function getTuiResultText(text, command) {
1372
+ const heading = text.match(/^\s*(\*\*\/?[^\r\n]+\*\*|\/[^\r\n]+)\r?\n(?:[ \t]*\r?\n)?/);
1373
+ return heading && void 0 === getVisibleTuiResultTitle(heading[1], command) ? text.slice(heading[0].length) : text;
1374
+ }
1375
+ function isTuiJson(text) {
1376
+ const first = text.trimStart().charAt(0);
1377
+ if ('{' !== first && '[' !== first) return false;
1378
+ try {
1379
+ JSON.parse(text);
1380
+ return true;
1381
+ } catch {
1382
+ return false;
1383
+ }
1384
+ }
1385
+ function TuiResourcePreview({ content, onOpenUri, onCopy, labels }) {
1386
+ const metaLabel = content.meta?.filter(Boolean).join(' · ') || content.description;
1387
+ const target = content.navigationUri ?? content.uri;
1388
+ return /*#__PURE__*/ jsxs("div", {
1389
+ className: "ov-tui__preview",
1390
+ children: [
1391
+ metaLabel ? /*#__PURE__*/ jsx("div", {
1392
+ className: "ov-tui__result-meta",
1393
+ children: /*#__PURE__*/ jsx(TuiUriText, {
1394
+ text: metaLabel,
1395
+ mode: "prose",
1396
+ onOpenUri: onOpenUri
1397
+ })
1398
+ }) : null,
1399
+ content.title ? /*#__PURE__*/ jsx("div", {
1400
+ className: "ov-tui__card-title",
1401
+ children: /*#__PURE__*/ jsx(TuiUriText, {
1402
+ text: content.title,
1403
+ mode: "literal",
1404
+ onOpenUri: onOpenUri
1405
+ })
1406
+ }) : null,
1407
+ /*#__PURE__*/ jsxs("div", {
1408
+ className: "ov-tui__preview-body",
1409
+ children: [
1410
+ content.uri ? /*#__PURE__*/ jsx(TuiUriLink, {
1411
+ uri: target,
1412
+ onOpenUri: onOpenUri,
1413
+ className: "ov-tui__link ov-tui__preview-uri",
1414
+ children: content.uri
1415
+ }) : null,
1416
+ isTuiJson(content.content) ? /*#__PURE__*/ jsx(TuiCodeBlock, {
1417
+ text: content.content,
1418
+ labels: labels,
1419
+ onCopy: onCopy,
1420
+ onOpenUri: onOpenUri
1421
+ }) : /*#__PURE__*/ jsx("pre", {
1422
+ className: "ov-tui__preview-content",
1423
+ children: /*#__PURE__*/ jsx(TuiUriText, {
1424
+ text: content.content,
1425
+ mode: "literal",
1426
+ onOpenUri: onOpenUri
1427
+ })
1428
+ })
1429
+ ]
1430
+ })
1431
+ ]
1432
+ });
1433
+ }
1434
+ const PAGE_SIZE = 20;
1435
+ function TreeIdentity({ item, onOpenUri }) {
1436
+ return /*#__PURE__*/ jsxs(Fragment, {
1437
+ children: [
1438
+ /*#__PURE__*/ jsx("span", {
1439
+ className: "ov-tui__tree-title",
1440
+ children: item.uri ? /*#__PURE__*/ jsx(TuiUriLink, {
1441
+ uri: item.uri,
1442
+ onOpenUri: onOpenUri,
1443
+ children: item.title
1444
+ }) : /*#__PURE__*/ jsx(TuiUriText, {
1445
+ text: item.title,
1446
+ mode: "literal",
1447
+ onOpenUri: onOpenUri
1448
+ })
1449
+ }),
1450
+ item.metaLabel ? /*#__PURE__*/ jsx("span", {
1451
+ className: "ov-tui__tree-meta",
1452
+ children: /*#__PURE__*/ jsx(TuiUriText, {
1453
+ text: item.metaLabel,
1454
+ mode: "prose",
1455
+ onOpenUri: onOpenUri
1456
+ })
1457
+ }) : null
1458
+ ]
1459
+ });
1460
+ }
1461
+ function TuiResourceTree({ content, onOpenUri, loadMoreLabel, noResultLabel, resourceLabel }) {
1462
+ const [visibleCount, setVisibleCount] = useState(PAGE_SIZE);
1463
+ const columns = Array.from(new Set(content.items.flatMap((item)=>item.detailRows?.map((row)=>row.label) ?? [])));
1464
+ const visibleItems = content.items.slice(0, visibleCount);
1465
+ const hiddenCount = content.items.length - visibleItems.length;
1466
+ return /*#__PURE__*/ jsxs("div", {
1467
+ className: "ov-tui__tree",
1468
+ children: [
1469
+ content.title ? /*#__PURE__*/ jsx("div", {
1470
+ className: "ov-tui__card-title",
1471
+ children: /*#__PURE__*/ jsx(TuiUriText, {
1472
+ text: content.title,
1473
+ mode: "literal",
1474
+ onOpenUri: onOpenUri
1475
+ })
1476
+ }) : null,
1477
+ content.items.length ? null : /*#__PURE__*/ jsx("div", {
1478
+ className: "ov-tui__no-result",
1479
+ children: noResultLabel
1480
+ }),
1481
+ columns.length ? /*#__PURE__*/ jsx("div", {
1482
+ className: "ov-tui__table-frame",
1483
+ children: /*#__PURE__*/ jsxs("table", {
1484
+ className: "ov-tui__table",
1485
+ children: [
1486
+ /*#__PURE__*/ jsx("thead", {
1487
+ children: /*#__PURE__*/ jsxs("tr", {
1488
+ children: [
1489
+ /*#__PURE__*/ jsx("th", {
1490
+ scope: "col",
1491
+ children: resourceLabel
1492
+ }),
1493
+ columns.map((column)=>/*#__PURE__*/ jsx("th", {
1494
+ scope: "col",
1495
+ children: column
1496
+ }, column))
1497
+ ]
1498
+ })
1499
+ }),
1500
+ /*#__PURE__*/ jsx("tbody", {
1501
+ children: visibleItems.map((item)=>/*#__PURE__*/ jsxs("tr", {
1502
+ children: [
1503
+ /*#__PURE__*/ jsx("td", {
1504
+ children: /*#__PURE__*/ jsx(TreeIdentity, {
1505
+ item: item,
1506
+ onOpenUri: onOpenUri
1507
+ })
1508
+ }),
1509
+ columns.map((column)=>{
1510
+ const value = item.detailRows?.find((row)=>row.label === column)?.value ?? '';
1511
+ return /*#__PURE__*/ jsx("td", {
1512
+ children: /*#__PURE__*/ jsx(TuiUriText, {
1513
+ text: value,
1514
+ mode: "literal",
1515
+ onOpenUri: onOpenUri
1516
+ })
1517
+ }, column);
1518
+ })
1519
+ ]
1520
+ }, item.id))
1521
+ })
1522
+ ]
1523
+ })
1524
+ }) : /*#__PURE__*/ jsx("div", {
1525
+ className: "ov-tui__tree-items",
1526
+ children: visibleItems.map((item)=>/*#__PURE__*/ jsx("div", {
1527
+ className: "ov-tui__tree-item",
1528
+ children: /*#__PURE__*/ jsx(TreeIdentity, {
1529
+ item: item,
1530
+ onOpenUri: onOpenUri
1531
+ })
1532
+ }, item.id))
1533
+ }),
1534
+ hiddenCount > 0 ? /*#__PURE__*/ jsxs("button", {
1535
+ type: "button",
1536
+ className: "ov-tui__load-more",
1537
+ onClick: ()=>setVisibleCount((count)=>count + PAGE_SIZE),
1538
+ children: [
1539
+ loadMoreLabel,
1540
+ " (",
1541
+ hiddenCount,
1542
+ ")"
1543
+ ]
1544
+ }) : null
1545
+ ]
1546
+ });
1547
+ }
1548
+ function TuiResultHeader({ command, status, label }) {
1549
+ return /*#__PURE__*/ jsxs("header", {
1550
+ className: "ov-tui__result-head",
1551
+ children: [
1552
+ /*#__PURE__*/ jsx("span", {
1553
+ className: "ov-tui__result-state",
1554
+ "data-status": status,
1555
+ role: "img",
1556
+ "aria-label": label
1557
+ }),
1558
+ /*#__PURE__*/ jsx("span", {
1559
+ className: "ov-tui__result-command",
1560
+ children: command
1561
+ })
1562
+ ]
1563
+ });
1564
+ }
1565
+ function ScoreDetails({ item }) {
1566
+ const [hovered, setHovered] = useState(false);
1567
+ const [pinned, setPinned] = useState(false);
1568
+ if (!item.scoreDetails) return /*#__PURE__*/ jsx("span", {
1569
+ className: "ov-tui__search-score",
1570
+ children: item.scoreLabel
1571
+ });
1572
+ const open = hovered || pinned;
1573
+ return /*#__PURE__*/ jsxs("span", {
1574
+ className: "ov-tui__search-score-wrap",
1575
+ children: [
1576
+ /*#__PURE__*/ jsx("button", {
1577
+ type: "button",
1578
+ className: "ov-tui__search-score",
1579
+ "aria-expanded": open,
1580
+ onClick: ()=>setPinned((current)=>!current),
1581
+ onMouseEnter: ()=>setHovered(true),
1582
+ onMouseLeave: ()=>setHovered(false),
1583
+ onFocus: ()=>setHovered(true),
1584
+ onBlur: ()=>{
1585
+ setHovered(false);
1586
+ setPinned(false);
1587
+ },
1588
+ children: item.scoreLabel
1589
+ }),
1590
+ open ? /*#__PURE__*/ jsx("span", {
1591
+ role: "tooltip",
1592
+ className: "ov-tui__score-details",
1593
+ children: item.scoreDetails
1594
+ }) : null
1595
+ ]
1596
+ });
1597
+ }
1598
+ function ResourceUri({ text }) {
1599
+ const boundary = text.lastIndexOf('/');
1600
+ return boundary > 9 ? /*#__PURE__*/ jsxs("span", {
1601
+ className: "ov-tui__search-uri",
1602
+ children: [
1603
+ /*#__PURE__*/ jsx("span", {
1604
+ className: "ov-tui__search-uri-prefix",
1605
+ children: text.slice(0, boundary + 1)
1606
+ }),
1607
+ /*#__PURE__*/ jsx("span", {
1608
+ className: "ov-tui__search-uri-suffix",
1609
+ children: text.slice(boundary + 1)
1610
+ })
1611
+ ]
1612
+ }) : /*#__PURE__*/ jsx("span", {
1613
+ className: "ov-tui__search-uri-full",
1614
+ children: text
1615
+ });
1616
+ }
1617
+ function SearchRow({ item, onOpenUri }) {
1618
+ return /*#__PURE__*/ jsxs(Fragment, {
1619
+ children: [
1620
+ item.scoreLabel || item.typeLabel ? /*#__PURE__*/ jsxs("span", {
1621
+ className: "ov-tui__search-metrics",
1622
+ children: [
1623
+ item.scoreLabel ? /*#__PURE__*/ jsx(ScoreDetails, {
1624
+ item: item
1625
+ }) : null,
1626
+ item.typeLabel ? /*#__PURE__*/ jsx("span", {
1627
+ className: "ov-tui__search-type",
1628
+ children: item.typeLabel
1629
+ }) : null
1630
+ ]
1631
+ }) : null,
1632
+ /*#__PURE__*/ jsxs("span", {
1633
+ className: "ov-tui__search-body",
1634
+ children: [
1635
+ /*#__PURE__*/ jsxs("span", {
1636
+ className: "ov-tui__search-main",
1637
+ children: [
1638
+ /*#__PURE__*/ jsx("span", {
1639
+ className: "ov-tui__search-title",
1640
+ title: item.uri ?? item.title,
1641
+ children: item.uri ? /*#__PURE__*/ jsx(TuiUriLink, {
1642
+ uri: item.uri,
1643
+ onOpenUri: onOpenUri,
1644
+ className: "ov-tui__link ov-tui__search-open",
1645
+ children: /*#__PURE__*/ jsx(ResourceUri, {
1646
+ text: item.uri
1647
+ })
1648
+ }) : /*#__PURE__*/ jsx(TuiUriText, {
1649
+ text: item.title,
1650
+ mode: "literal",
1651
+ onOpenUri: onOpenUri
1652
+ })
1653
+ }),
1654
+ item.levelLabel ? /*#__PURE__*/ jsx("span", {
1655
+ className: "ov-tui__search-level",
1656
+ children: item.levelLabel
1657
+ }) : null
1658
+ ]
1659
+ }),
1660
+ item.preview ? /*#__PURE__*/ jsx("span", {
1661
+ className: "ov-tui__search-preview",
1662
+ children: /*#__PURE__*/ jsx(TuiUriText, {
1663
+ text: item.preview,
1664
+ mode: "prose",
1665
+ onOpenUri: onOpenUri
1666
+ })
1667
+ }) : null,
1668
+ item.metaLabel ? /*#__PURE__*/ jsx("span", {
1669
+ className: "ov-tui__search-meta",
1670
+ children: /*#__PURE__*/ jsx(TuiUriText, {
1671
+ text: item.metaLabel,
1672
+ mode: "prose",
1673
+ onOpenUri: onOpenUri
1674
+ })
1675
+ }) : null
1676
+ ]
1677
+ })
1678
+ ]
1679
+ });
1680
+ }
1681
+ function TuiSearchList({ content, onOpenUri, noResultLabel }) {
1682
+ return /*#__PURE__*/ jsxs("div", {
1683
+ className: "ov-tui__search",
1684
+ children: [
1685
+ content.summary ? /*#__PURE__*/ jsx("div", {
1686
+ className: "ov-tui__search-summary",
1687
+ children: 'string' == typeof content.summary ? /*#__PURE__*/ jsx(TuiUriText, {
1688
+ text: content.summary,
1689
+ mode: "prose",
1690
+ onOpenUri: onOpenUri
1691
+ }) : content.summary
1692
+ }) : null,
1693
+ content.items.length ? /*#__PURE__*/ jsx("div", {
1694
+ className: "ov-tui__search-items",
1695
+ children: content.items.map((item)=>/*#__PURE__*/ jsx("article", {
1696
+ className: "ov-tui__search-item",
1697
+ children: /*#__PURE__*/ jsx(SearchRow, {
1698
+ item: item,
1699
+ onOpenUri: onOpenUri
1700
+ })
1701
+ }, item.id))
1702
+ }) : /*#__PURE__*/ jsx("div", {
1703
+ className: "ov-tui__no-result",
1704
+ children: noResultLabel
1705
+ })
1706
+ ]
1707
+ });
1708
+ }
1709
+ function Line({ width }) {
1710
+ return /*#__PURE__*/ jsx("span", {
1711
+ className: "ov-tui__skeleton-line",
1712
+ style: {
1713
+ width
1714
+ }
1715
+ });
1716
+ }
1717
+ function TuiSkeleton({ kind }) {
1718
+ if ('search' === kind) return /*#__PURE__*/ jsxs("div", {
1719
+ className: "ov-tui__skeleton",
1720
+ "aria-hidden": "true",
1721
+ children: [
1722
+ /*#__PURE__*/ jsxs("div", {
1723
+ className: "ov-tui__skeleton-summary",
1724
+ children: [
1725
+ /*#__PURE__*/ jsx(Line, {
1726
+ width: "100%"
1727
+ }),
1728
+ /*#__PURE__*/ jsx(Line, {
1729
+ width: "56%"
1730
+ })
1731
+ ]
1732
+ }),
1733
+ [
1734
+ 0,
1735
+ 1,
1736
+ 2
1737
+ ].map((index)=>/*#__PURE__*/ jsxs("div", {
1738
+ className: "ov-tui__skeleton-item",
1739
+ children: [
1740
+ /*#__PURE__*/ jsx("span", {
1741
+ className: "ov-tui__skeleton-icon"
1742
+ }),
1743
+ /*#__PURE__*/ jsxs("span", {
1744
+ className: "ov-tui__skeleton-lines",
1745
+ children: [
1746
+ /*#__PURE__*/ jsx(Line, {
1747
+ width: "72%"
1748
+ }),
1749
+ /*#__PURE__*/ jsx(Line, {
1750
+ width: "44%"
1751
+ })
1752
+ ]
1753
+ })
1754
+ ]
1755
+ }, index))
1756
+ ]
1757
+ });
1758
+ if ('tree' === kind) return /*#__PURE__*/ jsx("div", {
1759
+ className: "ov-tui__skeleton",
1760
+ "aria-hidden": "true",
1761
+ children: [
1762
+ 0,
1763
+ 1,
1764
+ 2,
1765
+ 3
1766
+ ].map((index)=>/*#__PURE__*/ jsx("div", {
1767
+ className: "ov-tui__skeleton-row",
1768
+ children: /*#__PURE__*/ jsx(Line, {
1769
+ width: index % 2 ? '52%' : '68%'
1770
+ })
1771
+ }, index))
1772
+ });
1773
+ if ('status' === kind) return /*#__PURE__*/ jsx("div", {
1774
+ className: "ov-tui__skeleton",
1775
+ "aria-hidden": "true",
1776
+ children: [
1777
+ 0,
1778
+ 1,
1779
+ 2
1780
+ ].map((index)=>/*#__PURE__*/ jsxs("div", {
1781
+ className: "ov-tui__skeleton-row",
1782
+ children: [
1783
+ /*#__PURE__*/ jsx(Line, {
1784
+ width: "28%"
1785
+ }),
1786
+ /*#__PURE__*/ jsx(Line, {
1787
+ width: "46%"
1788
+ })
1789
+ ]
1790
+ }, index))
1791
+ });
1792
+ if ('resource' === kind) return /*#__PURE__*/ jsxs("div", {
1793
+ className: "ov-tui__skeleton",
1794
+ "aria-hidden": "true",
1795
+ children: [
1796
+ /*#__PURE__*/ jsx(Line, {
1797
+ width: "38%"
1798
+ }),
1799
+ /*#__PURE__*/ jsxs("div", {
1800
+ className: "ov-tui__skeleton-block",
1801
+ children: [
1802
+ /*#__PURE__*/ jsx(Line, {
1803
+ width: "100%"
1804
+ }),
1805
+ /*#__PURE__*/ jsx(Line, {
1806
+ width: "92%"
1807
+ }),
1808
+ /*#__PURE__*/ jsx(Line, {
1809
+ width: "76%"
1810
+ })
1811
+ ]
1812
+ })
1813
+ ]
1814
+ });
1815
+ if ('write' === kind) return /*#__PURE__*/ jsxs("div", {
1816
+ className: "ov-tui__skeleton",
1817
+ "aria-hidden": "true",
1818
+ children: [
1819
+ /*#__PURE__*/ jsx("div", {
1820
+ className: "ov-tui__skeleton-row",
1821
+ children: /*#__PURE__*/ jsx(Line, {
1822
+ width: "64%"
1823
+ })
1824
+ }),
1825
+ /*#__PURE__*/ jsx("div", {
1826
+ className: "ov-tui__skeleton-row",
1827
+ children: /*#__PURE__*/ jsx(Line, {
1828
+ width: "42%"
1829
+ })
1830
+ })
1831
+ ]
1832
+ });
1833
+ return /*#__PURE__*/ jsx("div", {
1834
+ className: "ov-tui__skeleton",
1835
+ "aria-hidden": "true",
1836
+ children: /*#__PURE__*/ jsxs("div", {
1837
+ className: "ov-tui__skeleton-summary",
1838
+ children: [
1839
+ /*#__PURE__*/ jsx(Line, {
1840
+ width: "100%"
1841
+ }),
1842
+ /*#__PURE__*/ jsx(Line, {
1843
+ width: "64%"
1844
+ })
1845
+ ]
1846
+ })
1847
+ });
1848
+ }
1849
+ function TuiStatusCard({ content, onOpenUri }) {
1850
+ return /*#__PURE__*/ jsxs("div", {
1851
+ className: "ov-tui__status",
1852
+ children: [
1853
+ content.title ? /*#__PURE__*/ jsx("div", {
1854
+ className: "ov-tui__card-title",
1855
+ children: /*#__PURE__*/ jsx(TuiUriText, {
1856
+ text: content.title,
1857
+ mode: "prose",
1858
+ onOpenUri: onOpenUri
1859
+ })
1860
+ }) : null,
1861
+ /*#__PURE__*/ jsx("dl", {
1862
+ className: "ov-tui__status-rows",
1863
+ children: content.rows.map((row)=>/*#__PURE__*/ jsxs("div", {
1864
+ className: "ov-tui__status-row",
1865
+ "data-variant": row.variant ?? 'inline',
1866
+ children: [
1867
+ /*#__PURE__*/ jsx("dt", {
1868
+ className: "ov-tui__status-label",
1869
+ children: row.label
1870
+ }),
1871
+ /*#__PURE__*/ jsx("dd", {
1872
+ className: "ov-tui__status-value",
1873
+ children: 'string' == typeof row.value ? /*#__PURE__*/ jsx(TuiUriText, {
1874
+ text: row.value,
1875
+ mode: "literal",
1876
+ onOpenUri: onOpenUri
1877
+ }) : row.value
1878
+ })
1879
+ ]
1880
+ }, row.label))
1881
+ })
1882
+ ]
1883
+ });
1884
+ }
1885
+ function TuiWriteResult({ content, onOpenUri }) {
1886
+ return /*#__PURE__*/ jsxs("div", {
1887
+ className: "ov-tui__write",
1888
+ children: [
1889
+ content.title ? /*#__PURE__*/ jsx("div", {
1890
+ className: "ov-tui__card-title",
1891
+ children: /*#__PURE__*/ jsx(TuiUriText, {
1892
+ text: content.title,
1893
+ mode: "prose",
1894
+ onOpenUri: onOpenUri
1895
+ })
1896
+ }) : null,
1897
+ /*#__PURE__*/ jsx("div", {
1898
+ className: "ov-tui__write-lines",
1899
+ children: content.lines.map((line, index)=>/*#__PURE__*/ jsx("div", {
1900
+ className: "ov-tui__write-line",
1901
+ children: 'string' == typeof line ? /*#__PURE__*/ jsx(TuiUriText, {
1902
+ text: line,
1903
+ mode: "prose",
1904
+ onOpenUri: onOpenUri
1905
+ }) : line
1906
+ }, index))
1907
+ })
1908
+ ]
1909
+ });
1910
+ }
1911
+ function RecordBody({ record, command, labels, onOpenUri, onCopy, onPickCommand }) {
1912
+ const { content } = record;
1913
+ if ('pending' === record.status) return /*#__PURE__*/ jsx(TuiSkeleton, {
1914
+ kind: resolveTuiSkeleton(command)
1915
+ });
1916
+ if (!content) return /*#__PURE__*/ jsx("div", {
1917
+ className: "ov-tui__muted",
1918
+ children: 'error' === record.status ? labels.error : labels.noResult
1919
+ });
1920
+ switch(content.variant){
1921
+ case 'search-list':
1922
+ return /*#__PURE__*/ jsx(TuiSearchList, {
1923
+ content: content,
1924
+ onOpenUri: onOpenUri,
1925
+ noResultLabel: labels.noResult
1926
+ });
1927
+ case 'resource-preview':
1928
+ return /*#__PURE__*/ jsx(TuiResourcePreview, {
1929
+ content: {
1930
+ ...content,
1931
+ title: getVisibleTuiResultTitle(content.title, command) ?? ''
1932
+ },
1933
+ labels: labels,
1934
+ onCopy: onCopy,
1935
+ onOpenUri: onOpenUri
1936
+ });
1937
+ case 'resource-tree':
1938
+ return /*#__PURE__*/ jsx(TuiResourceTree, {
1939
+ content: {
1940
+ ...content,
1941
+ title: getVisibleTuiResultTitle(content.title, command)
1942
+ },
1943
+ onOpenUri: onOpenUri,
1944
+ resourceLabel: labels.resource,
1945
+ loadMoreLabel: labels.loadMore,
1946
+ noResultLabel: labels.noResult
1947
+ });
1948
+ case 'status':
1949
+ return /*#__PURE__*/ jsx(TuiStatusCard, {
1950
+ content: {
1951
+ ...content,
1952
+ title: getVisibleTuiResultTitle(content.title, command)
1953
+ },
1954
+ onOpenUri: onOpenUri
1955
+ });
1956
+ case 'write-result':
1957
+ return /*#__PURE__*/ jsx(TuiWriteResult, {
1958
+ content: {
1959
+ ...content,
1960
+ title: getVisibleTuiResultTitle(content.title, command)
1961
+ },
1962
+ onOpenUri: onOpenUri
1963
+ });
1964
+ case 'command-help':
1965
+ return /*#__PURE__*/ jsx(TuiCommandHelp, {
1966
+ content: content,
1967
+ onPick: onPickCommand,
1968
+ labels: labels
1969
+ });
1970
+ default:
1971
+ {
1972
+ const text = getTuiResultText(formatTuiJson(content.text), command);
1973
+ return /*#__PURE__*/ jsx("div", {
1974
+ className: "ov-tui__text",
1975
+ children: 'markdown' === content.format ? /*#__PURE__*/ jsx(TuiMarkdown, {
1976
+ text: text,
1977
+ labels: labels,
1978
+ onCopy: onCopy,
1979
+ onOpenUri: onOpenUri
1980
+ }) : isTuiJson(text) ? /*#__PURE__*/ jsx(TuiCodeBlock, {
1981
+ text: text,
1982
+ labels: labels,
1983
+ onCopy: onCopy,
1984
+ onOpenUri: onOpenUri
1985
+ }) : /*#__PURE__*/ jsx("pre", {
1986
+ className: "ov-tui__plain",
1987
+ children: /*#__PURE__*/ jsx(TuiUriText, {
1988
+ text: text,
1989
+ mode: "prose",
1990
+ onOpenUri: onOpenUri
1991
+ })
1992
+ })
1993
+ });
1994
+ }
1995
+ }
1996
+ }
1997
+ const STATUS_TEXT = {
1998
+ pending: 'pending',
1999
+ success: 'success',
2000
+ error: 'error'
2001
+ };
2002
+ function TuiRecordItem(props) {
2003
+ const { record, labels } = props;
2004
+ const statusLabel = labels[STATUS_TEXT[record.status]];
2005
+ const input = props.command ? matchTuiCommandInput(record.command, [
2006
+ props.command
2007
+ ]) : void 0;
2008
+ const prefix = input ? getTuiCommandInputText(input.command) : '';
2009
+ return /*#__PURE__*/ jsxs("div", {
2010
+ className: "ov-tui__record",
2011
+ "data-status": record.status,
2012
+ children: [
2013
+ /*#__PURE__*/ jsxs("div", {
2014
+ className: "ov-tui__bubble",
2015
+ children: [
2016
+ /*#__PURE__*/ jsx("code", {
2017
+ className: "ov-tui__bubble-text",
2018
+ children: input ? /*#__PURE__*/ jsxs(Fragment, {
2019
+ children: [
2020
+ input.leadingWhitespace,
2021
+ /*#__PURE__*/ jsx("span", {
2022
+ className: "ov-tui__bubble-command",
2023
+ children: /*#__PURE__*/ jsx(TuiCommandText, {
2024
+ text: prefix,
2025
+ name: input.command.name
2026
+ })
2027
+ }),
2028
+ /*#__PURE__*/ jsx(TuiUriText, {
2029
+ text: input.rest,
2030
+ mode: "literal",
2031
+ onOpenUri: props.onOpenUri
2032
+ })
2033
+ ]
2034
+ }) : /*#__PURE__*/ jsx(TuiUriText, {
2035
+ text: record.command,
2036
+ mode: "literal",
2037
+ onOpenUri: props.onOpenUri
2038
+ })
2039
+ }),
2040
+ record.createdAt || void 0 !== record.createdAtMs ? /*#__PURE__*/ jsx(TuiRecordTime, {
2041
+ record: record,
2042
+ labels: labels
2043
+ }) : null
2044
+ ]
2045
+ }),
2046
+ /*#__PURE__*/ jsxs("article", {
2047
+ className: "ov-tui__result",
2048
+ children: [
2049
+ /*#__PURE__*/ jsx(TuiResultHeader, {
2050
+ command: prefix || record.command,
2051
+ status: record.status,
2052
+ label: statusLabel
2053
+ }),
2054
+ /*#__PURE__*/ jsx("div", {
2055
+ className: "ov-tui__result-body",
2056
+ children: /*#__PURE__*/ jsx(RecordBody, {
2057
+ ...props
2058
+ })
2059
+ })
2060
+ ]
2061
+ })
2062
+ ]
2063
+ });
2064
+ }
2065
+ function useTuiCompletion(value, enabled, commands, groups = [], paletteScope = null) {
2066
+ const query = getTuiCommandQuery(value, commands);
2067
+ const suggestions = groupTuiCommands(enabled ? query.matches : [], groups);
2068
+ return {
2069
+ query,
2070
+ suggestions,
2071
+ options: suggestions.flatMap((section)=>section.commands),
2072
+ enabled,
2073
+ activeInput: '/' === query.scope ? void 0 : matchTuiCommandInput(value, commands),
2074
+ showSuggestions: enabled && (query.automatic || null !== query.scope && paletteScope === query.scope)
2075
+ };
2076
+ }
2077
+ function Tui({ records, value, disabled = false, emptyState, quickCommands, locale: localeProp, commands = [], commandGroups = [], onValueChange, onSubmit, onOpenUri, onCopy, labels, className, ...rest }) {
2078
+ const locale = useLocale(localeProp);
2079
+ const text = resolveTuiLabels(labels, locale);
2080
+ const bodyRef = useRef(null);
2081
+ const followOutput = useRef(true);
2082
+ const composerRef = useRef(null);
2083
+ const assistId = useId();
2084
+ const [dismissedValue, setDismissedValue] = useState(null);
2085
+ const [paletteScope, setPaletteScope] = useState(null);
2086
+ const [selection, setSelection] = useState({
2087
+ queryKey: value,
2088
+ index: -1
2089
+ });
2090
+ const dismissCompletion = useCallback((next)=>{
2091
+ setDismissedValue(next);
2092
+ setPaletteScope(null);
2093
+ setSelection({
2094
+ queryKey: next,
2095
+ index: -1
2096
+ });
2097
+ }, []);
2098
+ const updateValue = (next)=>{
2099
+ setDismissedValue(null);
2100
+ setSelection({
2101
+ queryKey: next,
2102
+ index: -1
2103
+ });
2104
+ if (getTuiCommandQuery(next, commands).scope !== paletteScope) setPaletteScope(null);
2105
+ onValueChange?.(next);
2106
+ };
2107
+ const readOnly = !onValueChange;
2108
+ const fillCommand = (next)=>{
2109
+ if (disabled || readOnly) return;
2110
+ updateValue(formatTuiCommandInput(next, commands));
2111
+ composerRef.current?.querySelector('textarea')?.focus({
2112
+ preventScroll: true
2113
+ });
2114
+ };
2115
+ const completion = useTuiCompletion(value, !disabled && !readOnly && dismissedValue !== value, commands, commandGroups, paletteScope);
2116
+ const queryKey = value;
2117
+ const activeIndex = selection.queryKey === queryKey && selection.index < completion.options.length ? selection.index : -1;
2118
+ const setActiveIndexSafely = useCallback((next)=>{
2119
+ setSelection((current)=>{
2120
+ const index = current.queryKey === queryKey && current.index < completion.options.length ? current.index : -1;
2121
+ return {
2122
+ queryKey,
2123
+ index: 'function' == typeof next ? next(index) : next
2124
+ };
2125
+ });
2126
+ }, [
2127
+ queryKey,
2128
+ completion.options.length
2129
+ ]);
2130
+ useEffect(()=>{
2131
+ const body = bodyRef.current;
2132
+ if (body && followOutput.current) body.scrollTop = body.scrollHeight;
2133
+ }, [
2134
+ records
2135
+ ]);
2136
+ return /*#__PURE__*/ jsxs("div", {
2137
+ className: [
2138
+ 'ov-tui',
2139
+ className
2140
+ ].filter(Boolean).join(' '),
2141
+ ...rest,
2142
+ children: [
2143
+ /*#__PURE__*/ jsx("div", {
2144
+ ref: bodyRef,
2145
+ className: "ov-tui__body",
2146
+ onScroll: (event)=>{
2147
+ const body = event.currentTarget;
2148
+ followOutput.current = body.scrollHeight - body.scrollTop - body.clientHeight <= 24;
2149
+ },
2150
+ children: records.length ? records.map((record)=>/*#__PURE__*/ jsx(TuiRecordItem, {
2151
+ record: record,
2152
+ command: findTuiCommand(record.command, commands),
2153
+ labels: text,
2154
+ onOpenUri: onOpenUri,
2155
+ onCopy: onCopy,
2156
+ onPickCommand: disabled || readOnly ? void 0 : (command)=>fillCommand(`${command} `)
2157
+ }, record.id)) : /*#__PURE__*/ jsx(TuiEmptyRegion, {
2158
+ emptyState: emptyState,
2159
+ commands: pickTuiCommands(quickCommands, commands),
2160
+ labels: text,
2161
+ disabled: disabled || readOnly,
2162
+ onPick: (command)=>fillCommand(`${command.name} `)
2163
+ })
2164
+ }),
2165
+ /*#__PURE__*/ jsx(TuiAssist, {
2166
+ assistId: assistId,
2167
+ anchorRef: composerRef,
2168
+ onDismiss: dismissCompletion,
2169
+ labels: text,
2170
+ completion: completion,
2171
+ activeIndex: activeIndex,
2172
+ onActiveIndexChange: setActiveIndexSafely,
2173
+ onPick: fillCommand
2174
+ }),
2175
+ /*#__PURE__*/ jsx(TuiComposer, {
2176
+ onDismiss: dismissCompletion,
2177
+ onRequestPalette: ()=>{
2178
+ setDismissedValue(null);
2179
+ setSelection({
2180
+ queryKey: value,
2181
+ index: -1
2182
+ });
2183
+ setPaletteScope(completion.query.scope);
2184
+ },
2185
+ assistId: assistId,
2186
+ anchorRef: composerRef,
2187
+ onFocus: ()=>setDismissedValue(null),
2188
+ value: value,
2189
+ history: records.map((record)=>formatTuiCommandInput(record.command, commands)),
2190
+ labels: text,
2191
+ completion: completion,
2192
+ disabled: disabled,
2193
+ readOnly: readOnly,
2194
+ canSubmit: Boolean(onSubmit) && !readOnly,
2195
+ activeIndex: activeIndex,
2196
+ onActiveIndexChange: setActiveIndexSafely,
2197
+ onValueChange: onValueChange ? updateValue : void 0,
2198
+ onSubmit: (command)=>{
2199
+ if (disabled || readOnly) return;
2200
+ followOutput.current = true;
2201
+ onSubmit?.(command);
2202
+ },
2203
+ onOpenUri: onOpenUri
2204
+ })
2205
+ ]
2206
+ });
2207
+ }
2208
+ export { Tui };