@openviking/react 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (229) hide show
  1. package/README.md +18 -15
  2. package/dist/1~0.js +506 -0
  3. package/dist/2~0.js +122 -0
  4. package/dist/30~0.js +1332 -0
  5. package/dist/3~0.js +2113 -4
  6. package/dist/ark-message-list-view~0.js +310 -0
  7. package/dist/c7~0.js +24 -0
  8. package/dist/client/index.d.ts +2 -1
  9. package/dist/client/paths.d.ts +64 -0
  10. package/dist/client/response.d.ts +31 -0
  11. package/dist/client/sse.d.ts +39 -0
  12. package/dist/client/stream.d.ts +26 -0
  13. package/dist/client/types.d.ts +104 -0
  14. package/dist/client.js +1 -239
  15. package/dist/components/agent-connect/agent-connect-copy.d.ts +34 -0
  16. package/dist/components/agent-connect/agent-connect-design.d.ts +1781 -0
  17. package/dist/components/agent-connect/agent-connect-detail.d.ts +13 -0
  18. package/dist/components/agent-connect/agent-connect-installer.d.ts +3 -0
  19. package/dist/components/agent-connect/agent-connect-instructions-view.d.ts +14 -0
  20. package/dist/components/agent-connect/agent-connect-instructions.d.ts +145 -0
  21. package/dist/components/agent-connect/agent-connect-markdown.d.ts +3 -0
  22. package/dist/components/agent-connect/agent-connect.d.ts +3 -3
  23. package/dist/components/agent-connect/content-en.d.ts +137 -0
  24. package/dist/components/agent-connect/content-zh.d.ts +137 -0
  25. package/dist/components/agent-connect/style.css +495 -6
  26. package/dist/components/agent-connect/types.d.ts +20 -166
  27. package/dist/components/file-browser-entries/file-browser-entries-icons.d.ts +18 -0
  28. package/dist/components/file-browser-entries/file-browser-entries.d.ts +14 -0
  29. package/dist/components/file-browser-entries/index.d.ts +1 -0
  30. package/dist/components/file-browser-entries/style.css +155 -0
  31. package/dist/components/file-browser-entries/types.d.ts +45 -0
  32. package/dist/components/file-browser-entries.js +1 -0
  33. package/dist/components/file-preview/file-preview-adapters.d.ts +33 -0
  34. package/dist/components/file-preview/file-preview-body.d.ts +24 -12
  35. package/dist/components/file-preview/file-preview-breadcrumb-menu.d.ts +16 -0
  36. package/dist/components/file-preview/file-preview-breadcrumb.d.ts +21 -0
  37. package/dist/components/file-preview/file-preview-copy-path.d.ts +12 -0
  38. package/dist/components/file-preview/file-preview-directory.d.ts +32 -0
  39. package/dist/components/file-preview/file-preview-editor.d.ts +22 -0
  40. package/dist/components/file-preview/file-preview-handle-adapters.d.ts +26 -0
  41. package/dist/components/file-preview/file-preview-header.d.ts +41 -14
  42. package/dist/components/file-preview/file-preview-labels.d.ts +15 -4
  43. package/dist/components/file-preview/file-preview-lazy-viewer.d.ts +3 -0
  44. package/dist/components/file-preview/file-preview-panels.d.ts +41 -0
  45. package/dist/components/file-preview/file-preview-path.d.ts +30 -0
  46. package/dist/components/file-preview/file-preview-source.d.ts +24 -0
  47. package/dist/components/file-preview/file-preview-state.d.ts +35 -0
  48. package/dist/components/file-preview/file-preview-tab-row.d.ts +16 -0
  49. package/dist/components/file-preview/file-preview-viewer.d.ts +31 -0
  50. package/dist/components/file-preview/file-preview.d.ts +9 -11
  51. package/dist/components/file-preview/level-selection.d.ts +25 -0
  52. package/dist/components/file-preview/style.css +4055 -126
  53. package/dist/components/file-preview/types.d.ts +350 -170
  54. package/dist/components/file-preview/use-directory-level.d.ts +30 -0
  55. package/dist/components/file-preview/use-file-preview-actions-context.d.ts +27 -0
  56. package/dist/components/file-preview/use-file-preview-actions.d.ts +19 -0
  57. package/dist/components/file-preview/use-file-preview-editing.d.ts +21 -2
  58. package/dist/components/file-preview/use-file-preview-ids.d.ts +24 -0
  59. package/dist/components/file-preview.js +1 -442
  60. package/dist/components/file-tree/file-tree-body.d.ts +8 -4
  61. package/dist/components/file-tree/file-tree-entry-row.d.ts +9 -3
  62. package/dist/components/file-tree/file-tree-icons.d.ts +12 -5
  63. package/dist/components/file-tree/file-tree-info-labels.d.ts +21 -0
  64. package/dist/components/file-tree/file-tree-info-tooltip.d.ts +43 -0
  65. package/dist/components/file-tree/file-tree-info.d.ts +29 -0
  66. package/dist/components/file-tree/file-tree-keyboard.d.ts +8 -4
  67. package/dist/components/file-tree/file-tree-row-context.d.ts +29 -12
  68. package/dist/components/file-tree/file-tree-row-shared.d.ts +18 -0
  69. package/dist/components/file-tree/file-tree-spinner.d.ts +10 -0
  70. package/dist/components/file-tree/file-tree-state-row.d.ts +7 -0
  71. package/dist/components/file-tree/file-tree-tooltip-surface.d.ts +22 -0
  72. package/dist/components/file-tree/file-tree.d.ts +12 -1
  73. package/dist/components/file-tree/style.css +280 -75
  74. package/dist/components/file-tree/types.d.ts +203 -0
  75. package/dist/components/file-tree/use-file-tree-actions.d.ts +7 -0
  76. package/dist/components/file-tree.js +1 -1
  77. package/dist/components/scope-switcher/scope-panel.d.ts +9 -3
  78. package/dist/components/scope-switcher/scope-selector.d.ts +1 -1
  79. package/dist/components/scope-switcher/scope-switcher.d.ts +1 -1
  80. package/dist/components/scope-switcher/style.css +282 -76
  81. package/dist/components/scope-switcher/types.d.ts +230 -108
  82. package/dist/components/style.css +14128 -390
  83. package/dist/components/tui/command-catalog.d.ts +58 -0
  84. package/dist/components/tui/command-completion.d.ts +19 -0
  85. package/dist/components/tui/command-definitions.d.ts +10 -0
  86. package/dist/components/tui/command-input.d.ts +16 -0
  87. package/dist/components/tui/style.css +1543 -5
  88. package/dist/components/tui/tui-assist.d.ts +15 -0
  89. package/dist/components/tui/tui-code-block.d.ts +8 -0
  90. package/dist/components/tui/tui-command-help.d.ts +9 -0
  91. package/dist/components/tui/tui-command-text.d.ts +6 -0
  92. package/dist/components/tui/tui-composer.d.ts +24 -0
  93. package/dist/components/tui/tui-copy-button.d.ts +9 -0
  94. package/dist/components/tui/tui-input-mirror.d.ts +14 -0
  95. package/dist/components/tui/tui-labels-zh.d.ts +2 -0
  96. package/dist/components/tui/tui-labels.d.ts +5 -0
  97. package/dist/components/tui/tui-markdown-renderers.d.ts +10 -0
  98. package/dist/components/tui/tui-markdown.d.ts +6 -0
  99. package/dist/components/tui/tui-param-hint.d.ts +7 -0
  100. package/dist/components/tui/tui-record-time.d.ts +11 -0
  101. package/dist/components/tui/tui-record.d.ts +13 -0
  102. package/dist/components/tui/tui-resource-preview.d.ts +10 -0
  103. package/dist/components/tui/tui-resource-tree.d.ts +10 -0
  104. package/dist/components/tui/tui-result-header.d.ts +7 -0
  105. package/dist/components/tui/tui-result-text.d.ts +5 -0
  106. package/dist/components/tui/tui-search-list.d.ts +8 -0
  107. package/dist/components/tui/tui-skeleton.d.ts +6 -0
  108. package/dist/components/tui/tui-status-card.d.ts +7 -0
  109. package/dist/components/tui/tui-text.d.ts +10 -0
  110. package/dist/components/tui/tui-uri-text.d.ts +19 -0
  111. package/dist/components/tui/tui-write-result.d.ts +7 -0
  112. package/dist/components/tui/tui.d.ts +10 -2
  113. package/dist/components/tui/types.d.ts +57 -15
  114. package/dist/components/tui/use-tui-assist-position.d.ts +3 -0
  115. package/dist/components/tui/use-tui-completion.d.ts +14 -0
  116. package/dist/components/tui/use-tui-composer-keyboard.d.ts +25 -0
  117. package/dist/components/viking-bot/ark-adapter.d.ts +45 -0
  118. package/dist/components/viking-bot/ark-message-body.d.ts +16 -0
  119. package/dist/components/viking-bot/ark-message-list-view.d.ts +7 -0
  120. package/dist/components/viking-bot/ark-message-row.d.ts +19 -0
  121. package/dist/components/viking-bot/index.d.ts +10 -0
  122. package/dist/components/viking-bot/interaction/ask-human-fields.d.ts +10 -0
  123. package/dist/components/viking-bot/interaction/index.d.ts +4 -0
  124. package/dist/components/viking-bot/interaction/labels.d.ts +7 -0
  125. package/dist/components/viking-bot/interaction/lazy-interaction.d.ts +3 -0
  126. package/dist/components/viking-bot/interaction/schedule-input.d.ts +13 -0
  127. package/dist/components/viking-bot/interaction/style.css +189 -0
  128. package/dist/components/viking-bot/interaction/style.js +0 -0
  129. package/dist/components/viking-bot/interaction/types.d.ts +188 -0
  130. package/dist/components/viking-bot/interaction/viking-bot-interaction.d.ts +9 -0
  131. package/dist/components/viking-bot/interaction.js +2 -0
  132. package/dist/components/viking-bot/labels.d.ts +2 -0
  133. package/dist/components/viking-bot/lazy-composer.d.ts +3 -0
  134. package/dist/components/viking-bot/message-groups.d.ts +12 -0
  135. package/dist/components/viking-bot/model.d.ts +252 -0
  136. package/dist/components/viking-bot/render-part.d.ts +12 -0
  137. package/dist/components/viking-bot/style.css +7135 -0
  138. package/dist/components/viking-bot/style.js +0 -0
  139. package/dist/components/viking-bot/types.d.ts +140 -0
  140. package/dist/components/viking-bot/viking-bot-composer.d.ts +6 -0
  141. package/dist/components/viking-bot/viking-bot-message-list.d.ts +3 -0
  142. package/dist/components/viking-bot/viking-bot.d.ts +16 -0
  143. package/dist/components/viking-bot.js +4 -0
  144. package/dist/c~0.js +201 -0
  145. package/dist/file-preview-viewer~0.js +191 -0
  146. package/dist/f~0.js +149 -77
  147. package/dist/h~0.js +58 -0
  148. package/dist/icons/file-type-icon.d.ts +31 -0
  149. package/dist/icons/index.d.ts +33 -23
  150. package/dist/icons/nextjs-icon.d.ts +19 -0
  151. package/dist/icons.js +1 -25
  152. package/dist/index.d.ts +4 -2
  153. package/dist/index.js +2 -1
  154. package/dist/k~0.js +1440 -0
  155. package/dist/lk~0.js +25 -12
  156. package/dist/l~0.js +1464 -25
  157. package/dist/modules/console/style.css +83 -1
  158. package/dist/modules/file-browser/file-browser-detail-icons.d.ts +10 -0
  159. package/dist/modules/file-browser/file-browser-detail.d.ts +33 -0
  160. package/dist/modules/file-browser/file-browser-empty.d.ts +3 -0
  161. package/dist/modules/file-browser/file-browser-failure.d.ts +22 -0
  162. package/dist/modules/file-browser/file-browser-icons.d.ts +18 -0
  163. package/dist/modules/file-browser/file-browser-labels.d.ts +28 -0
  164. package/dist/modules/file-browser/file-browser-layout.d.ts +27 -0
  165. package/dist/modules/file-browser/file-browser-toolbar.d.ts +18 -0
  166. package/dist/modules/file-browser/file-browser-tree-pane.d.ts +30 -0
  167. package/dist/modules/file-browser/file-browser.d.ts +14 -5
  168. package/dist/modules/file-browser/find-result.d.ts +24 -0
  169. package/dist/modules/file-browser/fs-directories.d.ts +33 -0
  170. package/dist/modules/file-browser/fs-file-kind.d.ts +19 -0
  171. package/dist/modules/file-browser/fs-icon.d.ts +17 -0
  172. package/dist/modules/file-browser/fs-model.d.ts +106 -0
  173. package/dist/modules/file-browser/fs-page.d.ts +16 -0
  174. package/dist/modules/file-browser/fs-path.d.ts +16 -0
  175. package/dist/modules/file-browser/fs-read-directory.d.ts +20 -0
  176. package/dist/modules/file-browser/fs-scope.d.ts +22 -0
  177. package/dist/modules/file-browser/fs-stat.d.ts +25 -0
  178. package/dist/modules/file-browser/index.d.ts +3 -1
  179. package/dist/modules/file-browser/style.css +5009 -34
  180. package/dist/modules/file-browser/tree-info-copy.d.ts +15 -0
  181. package/dist/modules/file-browser/tree-info-copy.zh-CN.d.ts +15 -0
  182. package/dist/modules/file-browser/types.d.ts +189 -44
  183. package/dist/modules/file-browser/use-container-width.d.ts +17 -0
  184. package/dist/modules/file-browser/use-file-browser.d.ts +49 -0
  185. package/dist/modules/file-browser/use-fs-preview.d.ts +51 -0
  186. package/dist/modules/file-browser/use-fs-search.d.ts +35 -0
  187. package/dist/modules/file-browser/use-fs-tree.d.ts +43 -0
  188. package/dist/modules/file-browser/use-request-scope.d.ts +39 -0
  189. package/dist/modules/file-browser.js +1 -1
  190. package/dist/modules/scope-cascade/style.css +282 -76
  191. package/dist/modules/style.css +5445 -130
  192. package/dist/n~0.js +568 -236
  193. package/dist/o~0.js +103 -0
  194. package/dist/shared/components/divider/divider.d.ts +18 -0
  195. package/dist/shared/components/divider/index.d.ts +1 -0
  196. package/dist/shared/components/divider/types.d.ts +35 -0
  197. package/dist/shared/components/overlay/types.d.ts +7 -0
  198. package/dist/shared/components/overlay/use-overlay-position.d.ts +38 -0
  199. package/dist/shared/components/popover/index.d.ts +1 -0
  200. package/dist/shared/components/popover/popover.d.ts +23 -0
  201. package/dist/shared/components/popover/types.d.ts +50 -0
  202. package/dist/shared/components/resizable/clamp.d.ts +13 -0
  203. package/dist/shared/components/resizable/index.d.ts +2 -0
  204. package/dist/shared/components/resizable/resizable-handle.d.ts +25 -0
  205. package/dist/shared/components/resizable/types.d.ts +48 -0
  206. package/dist/shared/components/tooltip/index.d.ts +1 -0
  207. package/dist/shared/components/tooltip/tooltip.d.ts +25 -0
  208. package/dist/shared/components/tooltip/types.d.ts +42 -0
  209. package/dist/style.css +19664 -530
  210. package/dist/u~0.js +1597 -4
  211. package/dist/viking-bot-composer~0.js +164 -0
  212. package/dist/viking-bot-interaction~0.js +284 -0
  213. package/dist/w~0.js +19 -0
  214. package/package.json +23 -10
  215. package/dist/components/file-preview/file-preview-icons.d.ts +0 -2
  216. package/dist/components/file-preview/file-preview-operations.d.ts +0 -1
  217. package/dist/components/file-tree/file-tree-dom.d.ts +0 -4
  218. package/dist/components/file-tree/file-tree-labels.d.ts +0 -5
  219. package/dist/components/file-tree/file-tree-rows.d.ts +0 -12
  220. package/dist/components/file-tree/file-tree-tooltip.d.ts +0 -11
  221. package/dist/i~0.js +0 -21
  222. package/dist/modules/file-browser/file-browser-toolbar-button.d.ts +0 -10
  223. package/dist/modules/task-center/columns.d.ts +0 -129
  224. package/dist/modules/task-center/index.d.ts +0 -1
  225. package/dist/modules/task-center/style.css +0 -29
  226. package/dist/modules/task-center/task-center.d.ts +0 -4
  227. package/dist/modules/task-center/types.d.ts +0 -168
  228. package/dist/modules/task-center.js +0 -1
  229. /package/dist/{modules/task-center → components/file-browser-entries}/style.js +0 -0
package/dist/n~0.js CHANGED
@@ -1,106 +1,442 @@
1
- import { jsx, jsxs } from "react/jsx-runtime";
2
- import { forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState } from "react";
3
- function Chevron({ expanded }) {
4
- return /*#__PURE__*/ jsx("svg", {
5
- "aria-hidden": "true",
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { cloneElement, forwardRef, useCallback, useEffect, useId, useImperativeHandle, useRef, useState } from "react";
3
+ import { createPortal } from "react-dom";
4
+ import { FolderOpenIcon, FolderIcon, ChevronRightIcon, DocumentIcon } from "./k~0.js";
5
+ import { useOverlayPosition } from "./o~0.js";
6
+ function FileTreeFolderIcon({ open }) {
7
+ return /*#__PURE__*/ jsxs("span", {
8
+ className: "ov-file-tree__folder",
9
+ children: [
10
+ /*#__PURE__*/ jsx(FolderIcon, {
11
+ className: "ov-file-tree__folder-layer",
12
+ "data-open": !open
13
+ }),
14
+ /*#__PURE__*/ jsx(FolderOpenIcon, {
15
+ className: "ov-file-tree__folder-layer",
16
+ "data-open": open
17
+ })
18
+ ]
19
+ });
20
+ }
21
+ function FileTreeFileIcon() {
22
+ return /*#__PURE__*/ jsx(DocumentIcon, {
23
+ className: "ov-file-tree__file-icon"
24
+ });
25
+ }
26
+ function FileTreeChevron({ open }) {
27
+ return /*#__PURE__*/ jsx(ChevronRightIcon, {
6
28
  className: "ov-file-tree__chevron",
7
- "data-expanded": expanded || void 0,
8
- viewBox: "0 0 16 16",
9
- width: "12",
10
- height: "12",
11
- children: /*#__PURE__*/ jsx("path", {
12
- d: "M6 3.5 10.5 8 6 12.5",
13
- fill: "none",
14
- stroke: "currentColor",
15
- strokeLinecap: "round",
16
- strokeLinejoin: "round",
17
- strokeWidth: "1.5"
18
- })
29
+ "data-expanded": open || void 0,
30
+ width: 12,
31
+ height: 12
19
32
  });
20
33
  }
21
- function FolderIcon({ open }) {
22
- return /*#__PURE__*/ jsx("svg", {
23
- "aria-hidden": "true",
24
- className: "ov-file-tree__icon",
25
- viewBox: "0 0 16 16",
26
- width: "14",
27
- height: "14",
28
- children: /*#__PURE__*/ jsx("path", {
29
- d: open ? 'M1.5 13V4.5A1 1 0 0 1 2.5 3.5h3l1.2 1.5h5.8a1 1 0 0 1 1 1V7M1.5 13l1.6-5h11.4l-1.6 5H1.5Z' : 'M1.5 12.5v-9a1 1 0 0 1 1-1h3l1.2 1.5h6.8a1 1 0 0 1 1 1v7.5a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1Z',
30
- fill: "none",
31
- stroke: "currentColor",
32
- strokeLinejoin: "round",
33
- strokeWidth: "1.2"
34
- })
34
+ const TOOLTIP_ONLY_KEYS = new Set([
35
+ 'profile',
36
+ 'preferences',
37
+ 'entities',
38
+ 'events',
39
+ 'identity',
40
+ 'soul',
41
+ 'cases',
42
+ 'trajectories',
43
+ 'experiences'
44
+ ]);
45
+ const ROOT_KEY_BY_SEGMENT = {
46
+ agent: 'agentRoot',
47
+ agents: 'agentRoot',
48
+ memory: 'memoryRoot',
49
+ memories: 'memoryRoot',
50
+ resource: 'resourceRoot',
51
+ resources: 'resourceRoot',
52
+ session: 'sessionRoot',
53
+ sessions: 'sessionRoot',
54
+ system: 'systemRoot'
55
+ };
56
+ const USER_SCOPE_KEY_BY_SEGMENT = {
57
+ memories: 'memories',
58
+ peers: 'peers',
59
+ privacy: 'privacy',
60
+ resources: 'userResources',
61
+ sessions: 'sessions',
62
+ skills: 'skills'
63
+ };
64
+ const AGENT_KEY_BY_SEGMENT = {
65
+ endpoints: 'agentEndpoints',
66
+ payments: 'agentPayments',
67
+ skills: 'agentSkills',
68
+ tools: 'agentTools'
69
+ };
70
+ const MEMORY_KEY_BY_SEGMENT = {
71
+ 'profile.md': 'profile',
72
+ preferences: 'preferences',
73
+ entities: 'entities',
74
+ events: 'events',
75
+ 'identity.md': 'identity',
76
+ 'soul.md': 'soul',
77
+ cases: 'cases',
78
+ trajectories: 'trajectories',
79
+ experiences: 'experiences'
80
+ };
81
+ const USER_SEGMENTS = new Set([
82
+ 'user',
83
+ 'users'
84
+ ]);
85
+ function splitVikingUri(uri) {
86
+ const withoutScheme = uri.replace(/^viking:\/*/i, '');
87
+ const withoutQuery = withoutScheme.split(/[?#]/)[0] ?? '';
88
+ return withoutQuery.split('/').map((segment)=>segment.trim()).filter(Boolean).map((segment)=>segment.toLowerCase());
89
+ }
90
+ function resolveFileTreeInfoKey(uri) {
91
+ const segments = splitVikingUri(uri);
92
+ const first = segments[0];
93
+ if (!first) return null;
94
+ if (USER_SEGMENTS.has(first)) {
95
+ if (segments.length <= 2) return 'userRoot';
96
+ const third = segments[2];
97
+ if (!third) return null;
98
+ if (3 === segments.length) return USER_SCOPE_KEY_BY_SEGMENT[third] ?? null;
99
+ if ('memories' !== third || 4 !== segments.length) return null;
100
+ const fourth = segments[3];
101
+ return fourth ? MEMORY_KEY_BY_SEGMENT[fourth] ?? null : null;
102
+ }
103
+ if (1 === segments.length) {
104
+ if ('resources' === first) return 'sharedResources';
105
+ return ROOT_KEY_BY_SEGMENT[first] ?? null;
106
+ }
107
+ if (('agent' === first || 'agents' === first) && 2 === segments.length) {
108
+ const second = segments[1];
109
+ return second ? AGENT_KEY_BY_SEGMENT[second] ?? null : null;
110
+ }
111
+ return null;
112
+ }
113
+ function showsInlineDescription(key) {
114
+ return null !== key && !TOOLTIP_ONLY_KEYS.has(key);
115
+ }
116
+ const DESCRIPTION = {
117
+ userRoot: 'Context data for the current user',
118
+ memories: 'Long-term memory accumulated across sessions',
119
+ peers: 'Context isolated per application or workspace',
120
+ privacy: 'Keys and other sensitive configuration',
121
+ userResources: 'Private knowledge of this user',
122
+ sessions: 'Conversation and task execution records',
123
+ skills: 'Skills and tools available to the agent',
124
+ profile: 'User identity and background',
125
+ preferences: 'Personalized user preferences',
126
+ entities: 'People, projects, organizations and other entities',
127
+ events: 'Key events archived by date',
128
+ identity: 'Agent name and persona',
129
+ soul: 'Agent behaviour guidelines and boundaries',
130
+ cases: 'Interaction cases used to train experience',
131
+ trajectories: 'Reusable task execution trajectories',
132
+ experiences: 'Execution experience distilled automatically',
133
+ sharedResources: 'External resources the agent can reference',
134
+ agentRoot: 'Agent capabilities, tools and experience',
135
+ agentEndpoints: 'Communication endpoints shared across the account',
136
+ agentPayments: 'Payment capabilities shared across the account',
137
+ agentSkills: 'Skill definitions callable across the account',
138
+ agentTools: 'Tool configuration shared across the account',
139
+ memoryRoot: 'Long-term memory and accumulated information',
140
+ resourceRoot: 'External knowledge the agent can reference',
141
+ sessionRoot: 'Raw session records of the user',
142
+ systemRoot: 'Built-in system resources'
143
+ };
144
+ const TRIGGER_BEHAVIOR = {
145
+ userRoot: 'Created from the current user identity; no manual setup needed',
146
+ memories: 'Committed sessions, explicit requests to remember, or continuous extraction from sessions',
147
+ peers: 'Created when connecting as a specific peer, isolating memory and material per peer_id',
148
+ userResources: 'Imported material, uploaded to this user’s private resource directory',
149
+ sessions: 'Created when a session calls OpenViking; messages, tool calls and archives are saved continuously',
150
+ skills: 'Created, installed or imported as a personal skill',
151
+ profile: 'A stable, explicit user background or working style appears in conversation',
152
+ preferences: 'The user explicitly states a specific preference, habit or style',
153
+ entities: 'A person, project or organization worth keeping appears in conversation',
154
+ events: 'An important decision, commitment, arrangement, progress or result appears in dialogue',
155
+ identity: 'Initialized on the first memory extraction run; later updated by write operations',
156
+ soul: 'Initialized on the first memory extraction run; later adjusted by write operations',
157
+ cases: 'A session with a clear task and an evaluable execution result is committed',
158
+ trajectories: 'A task containing decisions, tool calls or multi-step execution is committed',
159
+ experiences: 'Distilled from task cases and execution trajectories',
160
+ sharedResources: 'Imported material, uploaded to a shared resource space',
161
+ agentEndpoints: 'Configured when an integration endpoint is registered for the account',
162
+ agentPayments: 'Configured when a payment capability is enabled for the account',
163
+ agentSkills: 'Installed or imported as a shared skill available to every agent',
164
+ agentTools: 'Configured when a tool is registered for the account'
165
+ };
166
+ const DEFAULT_INFO_LABELS = {
167
+ description: DESCRIPTION,
168
+ triggerBehavior: TRIGGER_BEHAVIOR,
169
+ field: {
170
+ description: "Description",
171
+ triggerBehavior: 'Trigger',
172
+ path: 'Path'
173
+ }
174
+ };
175
+ function resolveInfoCopy(key, hostLabels) {
176
+ const description = hostLabels?.description?.[key] ?? DESCRIPTION[key] ?? void 0;
177
+ const triggerBehavior = hostLabels?.triggerBehavior?.[key] ?? TRIGGER_BEHAVIOR[key] ?? void 0;
178
+ return {
179
+ description: description || void 0,
180
+ triggerBehavior: triggerBehavior || void 0
181
+ };
182
+ }
183
+ function useMergedRef(ref, target) {
184
+ return useCallback((node)=>{
185
+ target.current = node;
186
+ if ('function' == typeof ref) ref(node);
187
+ else if (ref) ref.current = node;
188
+ }, [
189
+ ref,
190
+ target
191
+ ]);
192
+ }
193
+ function Popover({ children, content, placement = 'right', trigger = 'hover', delay = 300, disabled = false, className, style, onOpenChange }) {
194
+ const [open, setOpen] = useState(false);
195
+ const triggerRef = useRef(null);
196
+ const timerRef = useRef(void 0);
197
+ const [surfaceNode, setSurfaceNode] = useState(null);
198
+ const id = useId();
199
+ const position = useOverlayPosition(open, triggerRef, surfaceNode, placement);
200
+ const change = useCallback((next)=>{
201
+ setOpen(next);
202
+ onOpenChange?.(next);
203
+ }, [
204
+ onOpenChange
205
+ ]);
206
+ const clearTimer = useCallback(()=>{
207
+ if (void 0 !== timerRef.current) {
208
+ window.clearTimeout(timerRef.current);
209
+ timerRef.current = void 0;
210
+ }
211
+ }, []);
212
+ useEffect(()=>clearTimer, [
213
+ clearTimer
214
+ ]);
215
+ useEffect(()=>{
216
+ if (disabled) {
217
+ clearTimer();
218
+ setOpen(false);
219
+ }
220
+ }, [
221
+ disabled,
222
+ clearTimer
223
+ ]);
224
+ useEffect(()=>{
225
+ if (!open || 'click' !== trigger) return;
226
+ const onPointerDown = (event)=>{
227
+ const target = event.target;
228
+ if (surfaceNode?.contains(target) || triggerRef.current?.contains(target)) return;
229
+ change(false);
230
+ };
231
+ const onKeyDown = (event)=>{
232
+ if ('Escape' === event.key) change(false);
233
+ };
234
+ document.addEventListener('mousedown', onPointerDown);
235
+ document.addEventListener('keydown', onKeyDown);
236
+ return ()=>{
237
+ document.removeEventListener('mousedown', onPointerDown);
238
+ document.removeEventListener('keydown', onKeyDown);
239
+ };
240
+ }, [
241
+ change,
242
+ open,
243
+ surfaceNode,
244
+ trigger
245
+ ]);
246
+ const show = ()=>{
247
+ if (disabled) return;
248
+ if ('click' === trigger) return void change(!open);
249
+ clearTimer();
250
+ timerRef.current = window.setTimeout(()=>{
251
+ change(true);
252
+ timerRef.current = void 0;
253
+ }, delay);
254
+ };
255
+ const hide = ()=>{
256
+ if ('click' === trigger) return;
257
+ clearTimer();
258
+ change(false);
259
+ };
260
+ const child = children;
261
+ const childProps = child.props;
262
+ const childRef = child.ref;
263
+ const mergedRef = useMergedRef(childRef, triggerRef);
264
+ const declaresExpanded = 'aria-expanded' in childProps;
265
+ const triggerElement = /*#__PURE__*/ cloneElement(child, {
266
+ ref: mergedRef,
267
+ ...declaresExpanded ? {} : {
268
+ 'aria-expanded': open
269
+ },
270
+ onMouseEnter: (event)=>{
271
+ childProps.onMouseEnter?.(event);
272
+ if ('hover' === trigger) show();
273
+ },
274
+ onMouseLeave: (event)=>{
275
+ childProps.onMouseLeave?.(event);
276
+ if ('hover' === trigger) hide();
277
+ },
278
+ onClick: (event)=>{
279
+ childProps.onClick?.(event);
280
+ if ('click' === trigger) show();
281
+ }
282
+ });
283
+ const surface = open ? /*#__PURE__*/ createPortal(/*#__PURE__*/ jsx("div", {
284
+ ref: setSurfaceNode,
285
+ id: id,
286
+ role: 'click' === trigger ? 'dialog' : 'note',
287
+ className: [
288
+ 'ov-popover',
289
+ className
290
+ ].filter(Boolean).join(' '),
291
+ "data-placement": position.placement,
292
+ style: {
293
+ top: position.top,
294
+ left: position.left,
295
+ ...style
296
+ },
297
+ onMouseEnter: 'hover' === trigger ? clearTimer : void 0,
298
+ onMouseLeave: 'hover' === trigger ? hide : void 0,
299
+ children: content
300
+ }), document.body) : null;
301
+ return /*#__PURE__*/ jsxs(Fragment, {
302
+ children: [
303
+ triggerElement,
304
+ surface
305
+ ]
35
306
  });
36
307
  }
37
- function FileIcon() {
38
- return /*#__PURE__*/ jsxs("svg", {
39
- "aria-hidden": "true",
40
- className: "ov-file-tree__icon",
41
- viewBox: "0 0 16 16",
42
- width: "14",
43
- height: "14",
308
+ const DEFAULT_FIELDS = {
309
+ description: "Description",
310
+ triggerBehavior: 'Trigger',
311
+ path: 'Path'
312
+ };
313
+ function resolveFileTreeInfoCopy(row, infoLabels) {
314
+ const key = resolveFileTreeInfoKey(row.uri);
315
+ if (!key) return null;
316
+ const builtIn = resolveInfoCopy(key, infoLabels);
317
+ const description = row.description ?? builtIn.description;
318
+ if (!description && !builtIn.triggerBehavior) return null;
319
+ return {
320
+ title: row.name,
321
+ description,
322
+ triggerBehavior: builtIn.triggerBehavior,
323
+ path: row.uri,
324
+ fields: {
325
+ ...DEFAULT_FIELDS,
326
+ ...infoLabels?.field
327
+ }
328
+ };
329
+ }
330
+ function FileTreeInfoTooltip({ copy }) {
331
+ const { description, fields, path, title, triggerBehavior } = copy;
332
+ return /*#__PURE__*/ jsxs("div", {
333
+ className: "ov-file-tree__info",
44
334
  children: [
45
- /*#__PURE__*/ jsx("path", {
46
- d: "M4 1.5h5L12.5 5v9.5h-8.5V1.5Z",
47
- fill: "none",
48
- stroke: "currentColor",
49
- strokeLinejoin: "round",
50
- strokeWidth: "1.2"
335
+ /*#__PURE__*/ jsx("div", {
336
+ className: "ov-file-tree__info-title",
337
+ children: title
51
338
  }),
52
- /*#__PURE__*/ jsx("path", {
53
- d: "M9 1.5V5h3.5",
54
- fill: "none",
55
- stroke: "currentColor",
56
- strokeWidth: "1.2"
339
+ description ? /*#__PURE__*/ jsxs("div", {
340
+ className: "ov-file-tree__info-row",
341
+ children: [
342
+ /*#__PURE__*/ jsx("span", {
343
+ className: "ov-file-tree__info-label",
344
+ children: fields.description
345
+ }),
346
+ /*#__PURE__*/ jsx("span", {
347
+ className: "ov-file-tree__info-value",
348
+ children: description
349
+ })
350
+ ]
351
+ }) : null,
352
+ triggerBehavior ? /*#__PURE__*/ jsxs("div", {
353
+ className: "ov-file-tree__info-row",
354
+ children: [
355
+ /*#__PURE__*/ jsx("span", {
356
+ className: "ov-file-tree__info-label",
357
+ children: fields.triggerBehavior
358
+ }),
359
+ /*#__PURE__*/ jsx("span", {
360
+ className: "ov-file-tree__info-value",
361
+ children: triggerBehavior
362
+ })
363
+ ]
364
+ }) : null,
365
+ /*#__PURE__*/ jsxs("div", {
366
+ className: "ov-file-tree__info-row",
367
+ children: [
368
+ /*#__PURE__*/ jsx("span", {
369
+ className: "ov-file-tree__info-label",
370
+ children: fields.path
371
+ }),
372
+ /*#__PURE__*/ jsx("span", {
373
+ className: "ov-file-tree__info-path",
374
+ children: path
375
+ })
376
+ ]
57
377
  })
58
378
  ]
59
379
  });
60
380
  }
61
- function Spinner() {
62
- return /*#__PURE__*/ jsx("span", {
63
- "aria-hidden": "true",
64
- className: "ov-file-tree__spinner"
381
+ function FileTreeTooltipContent({ row, infoLabels, renderRowTooltip }) {
382
+ if (renderRowTooltip) {
383
+ const custom = renderRowTooltip(row);
384
+ if (null == custom || false === custom) return null;
385
+ return custom;
386
+ }
387
+ const copy = resolveFileTreeInfoCopy(row, infoLabels);
388
+ if (!copy) return null;
389
+ return /*#__PURE__*/ jsx(FileTreeInfoTooltip, {
390
+ copy: copy
65
391
  });
66
392
  }
67
- const DEFAULT_LABELS = {
68
- empty: 'No files yet',
69
- error: 'Failed to load',
70
- retry: 'Retry',
71
- loadMore: 'Load more',
72
- loading: 'Loading…',
73
- expand: 'Expand {name}',
74
- collapse: 'Collapse {name}'
75
- };
76
- function fillName(template, name) {
77
- return template.replace('{name}', name);
78
- }
79
- function rowIndent(row) {
393
+ const INDENT = 16;
394
+ const CHEVRON_SIZE = 16;
395
+ function rowStyle(depth) {
80
396
  return {
81
- paddingLeft: `calc(${row.depth} * 16px)`
397
+ paddingLeft: depth * INDENT
82
398
  };
83
399
  }
400
+ function Guides({ depth }) {
401
+ return /*#__PURE__*/ jsx(Fragment, {
402
+ children: Array.from({
403
+ length: depth
404
+ }, (_, level)=>/*#__PURE__*/ jsx("span", {
405
+ "aria-hidden": "true",
406
+ className: "ov-file-tree__guide",
407
+ style: {
408
+ left: level * INDENT + CHEVRON_SIZE / 2
409
+ }
410
+ }, level))
411
+ });
412
+ }
84
413
  const FILE_TREE_ROW_ATTRIBUTE = 'data-file-tree-row-id';
85
- function FileTreeEntryRowView({ row, ctx }) {
86
- const { text, selectedId, tooltipRowId, getRowAttributes, renderDashboard, renderRowTooltip, onSelect, onToggleExpand, onOpenRetentionSettings, onRowKeyDown, onRowEnter, onRowLeave } = ctx;
414
+ function FileTreeRowView({ row, ctx }) {
415
+ const { text, selectedId, getRowAttributes, renderDashboard, renderRowTooltip, renderRowIcon, onSelect, onToggleExpand, onOpenRetentionSettings, onRowKeyDown } = ctx;
87
416
  const isDirectory = 'directory' === row.type;
88
417
  const canExpand = isDirectory && false !== row.hasChildren;
418
+ const isExpanded = Boolean(row.expanded);
89
419
  const isSelected = selectedId === row.id;
90
- const { className: extraClassName, style: extraStyle, ...extraAttributes } = getRowAttributes?.(row) ?? {};
420
+ const extra = getRowAttributes?.(row) ?? {};
421
+ const { className: extraClassName, style: extraStyle, ...extraAttributes } = extra;
91
422
  const dashboard = renderDashboard?.(row) ?? null;
92
- const tooltip = renderRowTooltip?.(row) ?? null;
93
- const handleRowClick = (event)=>{
423
+ const infoKey = resolveFileTreeInfoKey(row.uri);
424
+ const description = row.description ?? (infoKey && showsInlineDescription(infoKey) ? resolveInfoCopy(infoKey, ctx.infoLabels).description : void 0);
425
+ const handleClick = (event)=>{
94
426
  if (event.target.closest('[data-role="toggle"]')) return;
95
427
  if (row.disabled) return;
96
428
  onSelect?.(row);
97
429
  };
98
- return /*#__PURE__*/ jsxs("div", {
430
+ const handleToggle = (event)=>{
431
+ event.stopPropagation();
432
+ onToggleExpand?.(row);
433
+ };
434
+ const rowNode = /*#__PURE__*/ jsxs("div", {
99
435
  role: "treeitem",
100
436
  tabIndex: 0,
101
437
  "aria-level": row.depth + 1,
102
438
  "aria-selected": isSelected,
103
- "aria-expanded": canExpand ? Boolean(row.expanded) : void 0,
439
+ "aria-expanded": canExpand ? isExpanded : void 0,
104
440
  "aria-disabled": row.disabled || void 0,
105
441
  ...extraAttributes,
106
442
  [FILE_TREE_ROW_ATTRIBUTE]: row.id,
@@ -112,29 +448,27 @@ function FileTreeEntryRowView({ row, ctx }) {
112
448
  "data-disabled": row.disabled || void 0,
113
449
  "data-kind": row.kind,
114
450
  style: {
115
- ...rowIndent(row),
451
+ ...rowStyle(row.depth),
116
452
  ...extraStyle
117
453
  },
118
- onClick: handleRowClick,
454
+ onClick: handleClick,
119
455
  onKeyDown: (event)=>onRowKeyDown(event, row),
120
- onMouseEnter: ()=>onRowEnter(row.id),
121
- onMouseLeave: onRowLeave,
122
- onFocus: ()=>onRowEnter(row.id),
123
- onBlur: onRowLeave,
124
456
  children: [
457
+ /*#__PURE__*/ jsx(Guides, {
458
+ depth: row.depth
459
+ }),
125
460
  canExpand ? /*#__PURE__*/ jsx("button", {
126
461
  type: "button",
127
462
  "data-role": "toggle",
128
463
  className: "ov-file-tree__toggle",
129
- "aria-label": fillName(row.expanded ? text.collapse : text.expand, row.name),
464
+ "aria-label": isExpanded ? text.collapse.replace('{name}', row.name) : text.expand.replace('{name}', row.name),
130
465
  tabIndex: -1,
131
- disabled: !onToggleExpand || row.disabled || row.busy,
132
- onClick: (event)=>{
133
- event.stopPropagation();
134
- onToggleExpand?.(row);
135
- },
136
- children: /*#__PURE__*/ jsx(Chevron, {
137
- expanded: Boolean(row.expanded)
466
+ disabled: !onToggleExpand || row.disabled,
467
+ onClick: handleToggle,
468
+ children: row.busy ? ctx.renderSpinner?.() ?? /*#__PURE__*/ jsx("span", {
469
+ className: "ov-file-tree__spinner"
470
+ }) : /*#__PURE__*/ jsx(FileTreeChevron, {
471
+ open: isExpanded
138
472
  })
139
473
  }) : /*#__PURE__*/ jsx("span", {
140
474
  "aria-hidden": "true",
@@ -142,9 +476,9 @@ function FileTreeEntryRowView({ row, ctx }) {
142
476
  }),
143
477
  /*#__PURE__*/ jsx("span", {
144
478
  className: "ov-file-tree__icon-slot",
145
- children: isDirectory ? /*#__PURE__*/ jsx(FolderIcon, {
146
- open: Boolean(row.expanded)
147
- }) : /*#__PURE__*/ jsx(FileIcon, {})
479
+ children: isDirectory ? /*#__PURE__*/ jsx(FileTreeFolderIcon, {
480
+ open: isExpanded
481
+ }) : renderRowIcon?.(row) ?? /*#__PURE__*/ jsx(FileTreeFileIcon, {})
148
482
  }),
149
483
  /*#__PURE__*/ jsxs("span", {
150
484
  className: "ov-file-tree__label-group",
@@ -154,16 +488,17 @@ function FileTreeEntryRowView({ row, ctx }) {
154
488
  title: row.name,
155
489
  children: row.name
156
490
  }),
157
- row.description ? /*#__PURE__*/ jsx("span", {
491
+ description ? /*#__PURE__*/ jsx("span", {
158
492
  className: "ov-file-tree__description",
159
- children: row.description
493
+ children: description
160
494
  }) : null
161
495
  ]
162
496
  }),
163
- row.busy ? /*#__PURE__*/ jsx(Spinner, {}) : null,
497
+ row.busy && !canExpand ? /*#__PURE__*/ jsx("span", {
498
+ className: "ov-file-tree__spinner"
499
+ }) : null,
164
500
  row.expiresAt ? /*#__PURE__*/ jsx("span", {
165
501
  className: "ov-file-tree__expiry",
166
- title: row.expiresAt,
167
502
  children: onOpenRetentionSettings ? /*#__PURE__*/ jsx("button", {
168
503
  type: "button",
169
504
  className: "ov-file-tree__expiry-action",
@@ -181,117 +516,122 @@ function FileTreeEntryRowView({ row, ctx }) {
181
516
  dashboard ? /*#__PURE__*/ jsx("span", {
182
517
  className: "ov-file-tree__dashboard",
183
518
  children: dashboard
184
- }) : null,
185
- tooltip && tooltipRowId === row.id ? /*#__PURE__*/ jsx("span", {
186
- role: "tooltip",
187
- className: "ov-file-tree__tooltip",
188
- children: tooltip
189
519
  }) : null
190
520
  ]
191
521
  });
192
- }
193
- function isWholeTreeError(rows) {
194
- if (1 !== rows.length) return false;
195
- const [row] = rows;
196
- return row?.kind === 'error' && !row.parentId;
197
- }
198
- function StateRow({ row, ctx, attributes, tone, children }) {
199
- const { className: extraClassName, style: extraStyle, ...extraAttributes } = ctx.getRowAttributes?.(row) ?? {};
200
- return /*#__PURE__*/ jsx("div", {
201
- role: "treeitem",
202
- "aria-level": row.depth + 1,
203
- "aria-selected": false,
204
- ...attributes,
205
- ...extraAttributes,
206
- [FILE_TREE_ROW_ATTRIBUTE]: row.id,
207
- className: [
208
- 'ov-file-tree__child-row',
209
- extraClassName
210
- ].filter(Boolean).join(' '),
211
- "data-tone": tone,
212
- style: {
213
- ...rowIndent(row),
214
- ...extraStyle
215
- },
216
- children: children
522
+ const custom = renderRowTooltip?.(row);
523
+ const hasContent = renderRowTooltip ? null != custom && false !== custom : null !== resolveFileTreeInfoCopy(row, ctx.infoLabels);
524
+ if (!hasContent) return rowNode;
525
+ const tooltipContent = /*#__PURE__*/ jsx(FileTreeTooltipContent, {
526
+ row: row,
527
+ infoLabels: ctx.infoLabels,
528
+ renderRowTooltip: renderRowTooltip
529
+ });
530
+ return /*#__PURE__*/ jsx(Popover, {
531
+ content: tooltipContent,
532
+ placement: "right",
533
+ trigger: "hover",
534
+ children: rowNode
217
535
  });
218
536
  }
219
- function ChildRow({ row, ctx }) {
220
- const { text, onLoadMore, onRetry } = ctx;
537
+ function FileTreeStateRow({ row, ctx }) {
538
+ const { text, onLoadMore, onRetry, getRowAttributes, renderSpinner } = ctx;
539
+ const spinner = renderSpinner?.() ?? /*#__PURE__*/ jsx("span", {
540
+ className: "ov-file-tree__spinner"
541
+ });
542
+ const extra = getRowAttributes?.(row) ?? {};
543
+ const { className: extraClassName, style: extraStyle, ...extraAttributes } = extra;
544
+ const shell = (children, busy = false)=>/*#__PURE__*/ jsxs("div", {
545
+ role: "treeitem",
546
+ "aria-level": row.depth + 1,
547
+ "aria-selected": false,
548
+ "aria-busy": busy || void 0,
549
+ ...extraAttributes,
550
+ [FILE_TREE_ROW_ATTRIBUTE]: row.id,
551
+ className: [
552
+ 'ov-file-tree__state-row',
553
+ extraClassName
554
+ ].filter(Boolean).join(' '),
555
+ style: {
556
+ ...rowStyle(row.depth),
557
+ ...extraStyle
558
+ },
559
+ children: [
560
+ /*#__PURE__*/ jsx(Guides, {
561
+ depth: row.depth
562
+ }),
563
+ children
564
+ ]
565
+ });
221
566
  switch(row.kind){
222
567
  case 'loading':
223
- return /*#__PURE__*/ jsxs(StateRow, {
224
- row: row,
225
- ctx: ctx,
226
- attributes: {
227
- 'aria-busy': true
228
- },
568
+ return shell(/*#__PURE__*/ jsxs(Fragment, {
229
569
  children: [
230
570
  /*#__PURE__*/ jsx("span", {
231
571
  className: "ov-file-tree__toggle-spacer"
232
572
  }),
233
- /*#__PURE__*/ jsx(Spinner, {}),
573
+ spinner,
234
574
  /*#__PURE__*/ jsx("span", {
235
575
  className: "ov-file-tree__muted",
236
576
  children: text.loading
237
577
  })
238
578
  ]
239
- });
579
+ }), true);
240
580
  case 'load-more':
241
- return /*#__PURE__*/ jsx(StateRow, {
242
- row: row,
243
- ctx: ctx,
244
- children: /*#__PURE__*/ jsxs("button", {
245
- type: "button",
246
- className: "ov-file-tree__child-action",
247
- disabled: row.loading || !onLoadMore,
248
- onClick: ()=>onLoadMore?.(row),
249
- children: [
250
- row.loading ? /*#__PURE__*/ jsx(Spinner, {}) : null,
251
- text.loadMore
252
- ]
253
- })
254
- });
581
+ return shell(/*#__PURE__*/ jsxs(Fragment, {
582
+ children: [
583
+ /*#__PURE__*/ jsx("span", {
584
+ className: "ov-file-tree__toggle-spacer"
585
+ }),
586
+ row.loading ? spinner : null,
587
+ /*#__PURE__*/ jsx("button", {
588
+ type: "button",
589
+ className: "ov-file-tree__action",
590
+ disabled: row.loading || !onLoadMore,
591
+ onClick: ()=>onLoadMore?.(row),
592
+ children: row.loading ? text.loading : text.loadMore
593
+ })
594
+ ]
595
+ }), Boolean(row.loading));
255
596
  case 'error':
256
- return /*#__PURE__*/ jsxs(StateRow, {
257
- row: row,
258
- ctx: ctx,
259
- tone: "error",
597
+ return shell(/*#__PURE__*/ jsxs(Fragment, {
260
598
  children: [
599
+ /*#__PURE__*/ jsx("span", {
600
+ className: "ov-file-tree__toggle-spacer"
601
+ }),
261
602
  /*#__PURE__*/ jsx("span", {
262
603
  className: "ov-file-tree__muted",
263
604
  children: row.message ?? text.error
264
605
  }),
265
606
  /*#__PURE__*/ jsx("button", {
266
607
  type: "button",
267
- className: "ov-file-tree__child-action",
608
+ className: "ov-file-tree__action",
268
609
  disabled: !onRetry,
269
610
  onClick: ()=>onRetry?.(row),
270
611
  children: text.retry
271
612
  })
272
613
  ]
273
- });
614
+ }));
274
615
  case 'empty':
275
- return /*#__PURE__*/ jsx(StateRow, {
276
- row: row,
277
- ctx: ctx,
278
- children: /*#__PURE__*/ jsx("span", {
279
- className: "ov-file-tree__muted",
280
- children: text.empty
281
- })
282
- });
616
+ return shell(/*#__PURE__*/ jsxs(Fragment, {
617
+ children: [
618
+ /*#__PURE__*/ jsx("span", {
619
+ className: "ov-file-tree__toggle-spacer"
620
+ }),
621
+ /*#__PURE__*/ jsx("span", {
622
+ className: "ov-file-tree__muted",
623
+ children: text.empty
624
+ })
625
+ ]
626
+ }));
283
627
  default:
284
- return /*#__PURE__*/ jsx(FileTreeEntryRowView, {
285
- row: row,
286
- ctx: ctx
287
- });
628
+ return null;
288
629
  }
289
630
  }
290
- function FileTreeRowView({ row, ctx }) {
291
- return /*#__PURE__*/ jsx(ChildRow, {
292
- row: row,
293
- ctx: ctx
294
- });
631
+ function isWholeTreeError(rows) {
632
+ if (1 !== rows.length) return false;
633
+ const [row] = rows;
634
+ return row?.kind === 'error' && !row.parentId;
295
635
  }
296
636
  function FileTreeBody({ rows, isReady, text, loadingFallback, errorFallback, emptyFallback, ctx }) {
297
637
  if (!isReady) return /*#__PURE__*/ jsx("div", {
@@ -321,85 +661,55 @@ function FileTreeBody({ rows, isReady, text, loadingFallback, errorFallback, emp
321
661
  return /*#__PURE__*/ jsx("div", {
322
662
  role: "group",
323
663
  className: "ov-file-tree__rows",
324
- children: rows.map((row)=>/*#__PURE__*/ jsx(FileTreeRowView, {
664
+ children: rows.map((row)=>'entry' === row.kind ? /*#__PURE__*/ jsx(FileTreeRowView, {
665
+ row: row,
666
+ ctx: ctx
667
+ }, row.id) : /*#__PURE__*/ jsx(FileTreeStateRow, {
325
668
  row: row,
326
669
  ctx: ctx
327
670
  }, row.id))
328
671
  });
329
672
  }
330
- function queryRowElements(root) {
673
+ function visibleRows(root) {
331
674
  if (!root) return [];
332
675
  return Array.from(root.querySelectorAll(`[${FILE_TREE_ROW_ATTRIBUTE}]`));
333
676
  }
334
- function findRowElement(root, id) {
335
- if (!root) return null;
336
- return root.querySelector(`[${FILE_TREE_ROW_ATTRIBUTE}="${CSS.escape(id)}"]`);
337
- }
338
- function moveFocus(current, root, delta) {
339
- const elements = queryRowElements(root);
340
- const index = elements.indexOf(current);
341
- if (-1 === index) return;
342
- elements[index + delta]?.focus();
343
- }
344
677
  function handleRowKeyDown(event, { root, row, onSelect, onToggleExpand }) {
678
+ const isDirectory = 'directory' === row.type;
679
+ const expanded = Boolean(row.expanded);
680
+ const canToggle = isDirectory && !row.disabled;
345
681
  switch(event.key){
346
682
  case 'ArrowDown':
347
- event.preventDefault();
348
- moveFocus(event.currentTarget, root, 1);
349
- break;
350
683
  case 'ArrowUp':
351
- event.preventDefault();
352
- moveFocus(event.currentTarget, root, -1);
353
- break;
684
+ {
685
+ event.preventDefault();
686
+ const rows = visibleRows(root);
687
+ const index = rows.indexOf(event.currentTarget);
688
+ if (-1 === index) return;
689
+ rows[index + ('ArrowDown' === event.key ? 1 : -1)]?.focus();
690
+ return;
691
+ }
354
692
  case 'ArrowRight':
355
- if (!row.disabled && !row.busy && 'directory' === row.type && !row.expanded) {
693
+ if (canToggle && !expanded) {
356
694
  event.preventDefault();
357
695
  onToggleExpand?.(row);
358
696
  }
359
- break;
697
+ return;
360
698
  case 'ArrowLeft':
361
- if (!row.disabled && !row.busy && 'directory' === row.type && row.expanded) {
699
+ if (canToggle && expanded) {
362
700
  event.preventDefault();
363
701
  onToggleExpand?.(row);
364
702
  }
365
- break;
703
+ return;
366
704
  case 'Enter':
367
705
  case ' ':
368
706
  event.preventDefault();
369
707
  if (!row.disabled) onSelect?.(row);
370
- break;
708
+ return;
371
709
  default:
372
- break;
710
+ return;
373
711
  }
374
712
  }
375
- function useRowTooltip(delay = 400) {
376
- const [tooltipRowId, setTooltipRowId] = useState(null);
377
- const timerRef = useRef(void 0);
378
- useEffect(()=>()=>{
379
- if (void 0 !== timerRef.current) window.clearTimeout(timerRef.current);
380
- }, []);
381
- const show = useCallback((rowId)=>{
382
- if (void 0 !== timerRef.current) window.clearTimeout(timerRef.current);
383
- timerRef.current = window.setTimeout(()=>{
384
- setTooltipRowId(rowId);
385
- timerRef.current = void 0;
386
- }, delay);
387
- }, [
388
- delay
389
- ]);
390
- const hide = useCallback(()=>{
391
- if (void 0 !== timerRef.current) {
392
- window.clearTimeout(timerRef.current);
393
- timerRef.current = void 0;
394
- }
395
- setTooltipRowId(null);
396
- }, []);
397
- return {
398
- tooltipRowId,
399
- show,
400
- hide
401
- };
402
- }
403
713
  function useFileTreeActions(props) {
404
714
  const pending = useRef(new Set());
405
715
  const { select, toggleExpand, loadMore, retry, openRetentionSettings } = props.operations ?? {};
@@ -423,13 +733,35 @@ function useFileTreeActions(props) {
423
733
  onOpenRetentionSettings: openRetentionSettings ? (uri)=>void run(`retention:${uri}`, openRetentionSettings, props.onOpenRetentionSettings, uri) : void 0
424
734
  };
425
735
  }
426
- const file_tree_FileTree = /*#__PURE__*/ forwardRef(function({ rows, operations, selectedId, isReady = true, loadingFallback, errorFallback, emptyFallback, slots, labels, getRowAttributes, renderDashboard, renderRowTooltip, onSelect, onToggleExpand, onLoadMore, onRetry, onOpenRetentionSettings, className, ...rest }, ref) {
736
+ function FileTreeSpinner({ className, ...rest }) {
737
+ return /*#__PURE__*/ jsx("span", {
738
+ "aria-hidden": "true",
739
+ ...rest,
740
+ className: [
741
+ 'ov-file-tree__spinner',
742
+ className
743
+ ].filter(Boolean).join(' ')
744
+ });
745
+ }
746
+ const DEFAULT_LABELS = {
747
+ empty: 'No files yet',
748
+ error: 'Failed to load',
749
+ retry: 'Retry',
750
+ loadMore: 'Load more',
751
+ loading: 'Loading…',
752
+ expand: 'Expand {name}',
753
+ collapse: 'Collapse {name}'
754
+ };
755
+ function findRow(root, id) {
756
+ return root?.querySelector(`[${FILE_TREE_ROW_ATTRIBUTE}="${CSS.escape(id)}"]`) ?? null;
757
+ }
758
+ const file_tree_FileTree = /*#__PURE__*/ forwardRef(function({ rows, operations, selectedId, isReady = true, loadingFallback, errorFallback, emptyFallback, slots, labels, getRowAttributes, renderDashboard, renderRowTooltip, renderRowIcon, onSelect, onToggleExpand, onLoadMore, onRetry, onOpenRetentionSettings, className, ...rest }, ref) {
427
759
  const rootRef = useRef(null);
428
760
  const text = {
429
761
  ...DEFAULT_LABELS,
430
- ...labels
762
+ ...labels,
763
+ info: labels?.info ?? DEFAULT_LABELS.info
431
764
  };
432
- const tooltip = useRowTooltip();
433
765
  const actions = useFileTreeActions({
434
766
  operations,
435
767
  onSelect,
@@ -439,9 +771,9 @@ const file_tree_FileTree = /*#__PURE__*/ forwardRef(function({ rows, operations,
439
771
  onOpenRetentionSettings
440
772
  });
441
773
  useImperativeHandle(ref, ()=>({
442
- getRowElement: (id)=>findRowElement(rootRef.current, id),
774
+ getRowElement: (id)=>findRow(rootRef.current, id),
443
775
  scrollToRow: (id, options)=>{
444
- const element = findRowElement(rootRef.current, id);
776
+ const element = findRow(rootRef.current, id);
445
777
  if (!element) return false;
446
778
  element.scrollIntoView({
447
779
  block: 'nearest',
@@ -450,22 +782,22 @@ const file_tree_FileTree = /*#__PURE__*/ forwardRef(function({ rows, operations,
450
782
  return true;
451
783
  }
452
784
  }), []);
453
- const rowContext = {
785
+ const ctx = {
454
786
  text,
787
+ infoLabels: labels?.info,
455
788
  selectedId,
456
- tooltipRowId: tooltip.tooltipRowId,
457
789
  getRowAttributes,
458
790
  renderDashboard,
459
791
  renderRowTooltip,
792
+ renderRowIcon,
793
+ renderSpinner: slots?.spinner ? ()=>slots.spinner : void 0,
460
794
  ...actions,
461
795
  onRowKeyDown: (event, row)=>handleRowKeyDown(event, {
462
796
  root: rootRef.current,
463
797
  row,
464
798
  onSelect: actions.onSelect,
465
799
  onToggleExpand: actions.onToggleExpand
466
- }),
467
- onRowEnter: tooltip.show,
468
- onRowLeave: tooltip.hide
800
+ })
469
801
  };
470
802
  return /*#__PURE__*/ jsxs("div", {
471
803
  ...rest,
@@ -490,10 +822,10 @@ const file_tree_FileTree = /*#__PURE__*/ forwardRef(function({ rows, operations,
490
822
  loadingFallback: loadingFallback,
491
823
  errorFallback: errorFallback,
492
824
  emptyFallback: emptyFallback,
493
- ctx: rowContext
825
+ ctx: ctx
494
826
  })
495
827
  })
496
828
  ]
497
829
  });
498
830
  });
499
- export { FILE_TREE_ROW_ATTRIBUTE, file_tree_FileTree as FileTree };
831
+ export { DEFAULT_INFO_LABELS, FILE_TREE_ROW_ATTRIBUTE, FileTreeSpinner, file_tree_FileTree as FileTree, resolveFileTreeInfoKey, resolveInfoCopy, showsInlineDescription, splitVikingUri };