@nex-ai/nex 0.1.22 → 0.1.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (292) hide show
  1. package/README.md +9 -2
  2. package/dist/agent/adoption.d.ts +23 -0
  3. package/dist/agent/adoption.js +87 -0
  4. package/dist/agent/adoption.js.map +1 -0
  5. package/dist/agent/gossip.d.ts +17 -0
  6. package/dist/agent/gossip.js +48 -0
  7. package/dist/agent/gossip.js.map +1 -0
  8. package/dist/agent/loop.d.ts +59 -0
  9. package/dist/agent/loop.js +389 -0
  10. package/dist/agent/loop.js.map +1 -0
  11. package/dist/agent/queues.d.ts +16 -0
  12. package/dist/agent/queues.js +44 -0
  13. package/dist/agent/queues.js.map +1 -0
  14. package/dist/agent/session-store.d.ts +21 -0
  15. package/dist/agent/session-store.js +96 -0
  16. package/dist/agent/session-store.js.map +1 -0
  17. package/dist/agent/templates.d.ts +5 -0
  18. package/dist/agent/templates.js +48 -0
  19. package/dist/agent/templates.js.map +1 -0
  20. package/dist/agent/tools.d.ts +25 -0
  21. package/dist/agent/tools.js +238 -0
  22. package/dist/agent/tools.js.map +1 -0
  23. package/dist/agent/types.d.ts +59 -0
  24. package/dist/agent/types.js +5 -0
  25. package/dist/agent/types.js.map +1 -0
  26. package/dist/calendar/scheduler.d.ts +32 -0
  27. package/dist/calendar/scheduler.js +178 -0
  28. package/dist/calendar/scheduler.js.map +1 -0
  29. package/dist/calendar/store.d.ts +15 -0
  30. package/dist/calendar/store.js +50 -0
  31. package/dist/calendar/store.js.map +1 -0
  32. package/dist/calendar/types.d.ts +17 -0
  33. package/dist/calendar/types.js +5 -0
  34. package/dist/calendar/types.js.map +1 -0
  35. package/dist/chat/channel.d.ts +20 -0
  36. package/dist/chat/channel.js +84 -0
  37. package/dist/chat/channel.js.map +1 -0
  38. package/dist/chat/message-store.d.ts +18 -0
  39. package/dist/chat/message-store.js +82 -0
  40. package/dist/chat/message-store.js.map +1 -0
  41. package/dist/chat/router.d.ts +17 -0
  42. package/dist/chat/router.js +65 -0
  43. package/dist/chat/router.js.map +1 -0
  44. package/dist/chat/suggested-responses.d.ts +6 -0
  45. package/dist/chat/suggested-responses.js +99 -0
  46. package/dist/chat/suggested-responses.js.map +1 -0
  47. package/dist/chat/types.d.ts +28 -0
  48. package/dist/chat/types.js +5 -0
  49. package/dist/chat/types.js.map +1 -0
  50. package/dist/cli.js +3 -1
  51. package/dist/cli.js.map +1 -1
  52. package/dist/commands/dispatch.d.ts +39 -0
  53. package/dist/commands/dispatch.js +1293 -0
  54. package/dist/commands/dispatch.js.map +1 -0
  55. package/dist/commands/init.d.ts +49 -0
  56. package/dist/commands/init.js +315 -0
  57. package/dist/commands/init.js.map +1 -0
  58. package/dist/commands/parse-input.d.ts +5 -0
  59. package/dist/commands/parse-input.js +37 -0
  60. package/dist/commands/parse-input.js.map +1 -0
  61. package/dist/index.d.ts +6 -23
  62. package/dist/index.js +118 -50
  63. package/dist/index.js.map +1 -1
  64. package/dist/lib/client.js +1 -1
  65. package/dist/lib/client.js.map +1 -1
  66. package/dist/lib/errors.js +1 -1
  67. package/dist/lib/errors.js.map +1 -1
  68. package/dist/lib/integrations.d.ts +23 -0
  69. package/dist/lib/integrations.js +25 -0
  70. package/dist/lib/integrations.js.map +1 -0
  71. package/dist/lib/nex-mcp-config.d.ts +14 -0
  72. package/dist/lib/nex-mcp-config.js +26 -0
  73. package/dist/lib/nex-mcp-config.js.map +1 -0
  74. package/dist/orchestration/budget.d.ts +32 -0
  75. package/dist/orchestration/budget.js +72 -0
  76. package/dist/orchestration/budget.js.map +1 -0
  77. package/dist/orchestration/executor.d.ts +59 -0
  78. package/dist/orchestration/executor.js +197 -0
  79. package/dist/orchestration/executor.js.map +1 -0
  80. package/dist/orchestration/router.d.ts +30 -0
  81. package/dist/orchestration/router.js +98 -0
  82. package/dist/orchestration/router.js.map +1 -0
  83. package/dist/orchestration/templates.d.ts +11 -0
  84. package/dist/orchestration/templates.js +99 -0
  85. package/dist/orchestration/templates.js.map +1 -0
  86. package/dist/orchestration/types.d.ts +58 -0
  87. package/dist/orchestration/types.js +7 -0
  88. package/dist/orchestration/types.js.map +1 -0
  89. package/dist/plugin/shared.js +1 -1
  90. package/dist/plugin/shared.js.map +1 -1
  91. package/dist/tui/agent-colors.d.ts +19 -0
  92. package/dist/tui/agent-colors.js +34 -0
  93. package/dist/tui/agent-colors.js.map +1 -0
  94. package/dist/tui/app.d.ts +14 -0
  95. package/dist/tui/app.js +267 -0
  96. package/dist/tui/app.js.map +1 -0
  97. package/dist/tui/channel-colors.d.ts +16 -0
  98. package/dist/tui/channel-colors.js +43 -0
  99. package/dist/tui/channel-colors.js.map +1 -0
  100. package/dist/tui/components/agent-card.d.ts +11 -0
  101. package/dist/tui/components/agent-card.js +40 -0
  102. package/dist/tui/components/agent-card.js.map +1 -0
  103. package/dist/tui/components/banner.d.ts +44 -0
  104. package/dist/tui/components/banner.js +130 -0
  105. package/dist/tui/components/banner.js.map +1 -0
  106. package/dist/tui/components/channel-colors.d.ts +21 -0
  107. package/dist/tui/components/channel-colors.js +53 -0
  108. package/dist/tui/components/channel-colors.js.map +1 -0
  109. package/dist/tui/components/channel-message.d.ts +53 -0
  110. package/dist/tui/components/channel-message.js +66 -0
  111. package/dist/tui/components/channel-message.js.map +1 -0
  112. package/dist/tui/components/chat-input.d.ts +11 -0
  113. package/dist/tui/components/chat-input.js +19 -0
  114. package/dist/tui/components/chat-input.js.map +1 -0
  115. package/dist/tui/components/data-table.d.ts +11 -0
  116. package/dist/tui/components/data-table.js +47 -0
  117. package/dist/tui/components/data-table.js.map +1 -0
  118. package/dist/tui/components/error-box.d.ts +11 -0
  119. package/dist/tui/components/error-box.js +59 -0
  120. package/dist/tui/components/error-box.js.map +1 -0
  121. package/dist/tui/components/help-screen.d.ts +3 -0
  122. package/dist/tui/components/help-screen.js +63 -0
  123. package/dist/tui/components/help-screen.js.map +1 -0
  124. package/dist/tui/components/index.d.ts +17 -0
  125. package/dist/tui/components/index.js +10 -0
  126. package/dist/tui/components/index.js.map +1 -0
  127. package/dist/tui/components/inline-confirm.d.ts +14 -0
  128. package/dist/tui/components/inline-confirm.js +13 -0
  129. package/dist/tui/components/inline-confirm.js.map +1 -0
  130. package/dist/tui/components/inline-select.d.ts +21 -0
  131. package/dist/tui/components/inline-select.js +20 -0
  132. package/dist/tui/components/inline-select.js.map +1 -0
  133. package/dist/tui/components/markdown.d.ts +6 -0
  134. package/dist/tui/components/markdown.js +179 -0
  135. package/dist/tui/components/markdown.js.map +1 -0
  136. package/dist/tui/components/mention-autocomplete.d.ts +77 -0
  137. package/dist/tui/components/mention-autocomplete.js +235 -0
  138. package/dist/tui/components/mention-autocomplete.js.map +1 -0
  139. package/dist/tui/components/message-list.d.ts +18 -0
  140. package/dist/tui/components/message-list.js +29 -0
  141. package/dist/tui/components/message-list.js.map +1 -0
  142. package/dist/tui/components/picker.d.ts +16 -0
  143. package/dist/tui/components/picker.js +32 -0
  144. package/dist/tui/components/picker.js.map +1 -0
  145. package/dist/tui/components/progress-steps.d.ts +13 -0
  146. package/dist/tui/components/progress-steps.js +21 -0
  147. package/dist/tui/components/progress-steps.js.map +1 -0
  148. package/dist/tui/components/slack/compose.d.ts +27 -0
  149. package/dist/tui/components/slack/compose.js +123 -0
  150. package/dist/tui/components/slack/compose.js.map +1 -0
  151. package/dist/tui/components/slack/layout.d.ts +36 -0
  152. package/dist/tui/components/slack/layout.js +96 -0
  153. package/dist/tui/components/slack/layout.js.map +1 -0
  154. package/dist/tui/components/slack/messages.d.ts +72 -0
  155. package/dist/tui/components/slack/messages.js +177 -0
  156. package/dist/tui/components/slack/messages.js.map +1 -0
  157. package/dist/tui/components/slack/quick-switcher.d.ts +33 -0
  158. package/dist/tui/components/slack/quick-switcher.js +98 -0
  159. package/dist/tui/components/slack/quick-switcher.js.map +1 -0
  160. package/dist/tui/components/slack/sidebar-types.d.ts +65 -0
  161. package/dist/tui/components/slack/sidebar-types.js +7 -0
  162. package/dist/tui/components/slack/sidebar-types.js.map +1 -0
  163. package/dist/tui/components/slack/sidebar.d.ts +46 -0
  164. package/dist/tui/components/slack/sidebar.js +52 -0
  165. package/dist/tui/components/slack/sidebar.js.map +1 -0
  166. package/dist/tui/components/slack/thread-panel.d.ts +45 -0
  167. package/dist/tui/components/slack/thread-panel.js +47 -0
  168. package/dist/tui/components/slack/thread-panel.js.map +1 -0
  169. package/dist/tui/components/slash-autocomplete.d.ts +81 -0
  170. package/dist/tui/components/slash-autocomplete.js +218 -0
  171. package/dist/tui/components/slash-autocomplete.js.map +1 -0
  172. package/dist/tui/components/spinner.d.ts +17 -0
  173. package/dist/tui/components/spinner.js +30 -0
  174. package/dist/tui/components/spinner.js.map +1 -0
  175. package/dist/tui/components/status-bar.d.ts +23 -0
  176. package/dist/tui/components/status-bar.js +55 -0
  177. package/dist/tui/components/status-bar.js.map +1 -0
  178. package/dist/tui/components/success-box.d.ts +7 -0
  179. package/dist/tui/components/success-box.js +10 -0
  180. package/dist/tui/components/success-box.js.map +1 -0
  181. package/dist/tui/components/tool-indicator.d.ts +12 -0
  182. package/dist/tui/components/tool-indicator.js +18 -0
  183. package/dist/tui/components/tool-indicator.js.map +1 -0
  184. package/dist/tui/components/viewport.d.ts +9 -0
  185. package/dist/tui/components/viewport.js +24 -0
  186. package/dist/tui/components/viewport.js.map +1 -0
  187. package/dist/tui/generative/bindings.d.ts +27 -0
  188. package/dist/tui/generative/bindings.js +152 -0
  189. package/dist/tui/generative/bindings.js.map +1 -0
  190. package/dist/tui/generative/registry.d.ts +19 -0
  191. package/dist/tui/generative/registry.js +31 -0
  192. package/dist/tui/generative/registry.js.map +1 -0
  193. package/dist/tui/generative/renderer.d.ts +24 -0
  194. package/dist/tui/generative/renderer.js +160 -0
  195. package/dist/tui/generative/renderer.js.map +1 -0
  196. package/dist/tui/generative/types.d.ts +68 -0
  197. package/dist/tui/generative/types.js +7 -0
  198. package/dist/tui/generative/types.js.map +1 -0
  199. package/dist/tui/hooks/use-cancellable.d.ts +28 -0
  200. package/dist/tui/hooks/use-cancellable.js +51 -0
  201. package/dist/tui/hooks/use-cancellable.js.map +1 -0
  202. package/dist/tui/hooks/use-streaming.d.ts +44 -0
  203. package/dist/tui/hooks/use-streaming.js +105 -0
  204. package/dist/tui/hooks/use-streaming.js.map +1 -0
  205. package/dist/tui/index.d.ts +4 -0
  206. package/dist/tui/index.js +7 -0
  207. package/dist/tui/index.js.map +1 -0
  208. package/dist/tui/keybindings.d.ts +25 -0
  209. package/dist/tui/keybindings.js +277 -0
  210. package/dist/tui/keybindings.js.map +1 -0
  211. package/dist/tui/register-views.d.ts +8 -0
  212. package/dist/tui/register-views.js +116 -0
  213. package/dist/tui/register-views.js.map +1 -0
  214. package/dist/tui/router.d.ts +29 -0
  215. package/dist/tui/router.js +87 -0
  216. package/dist/tui/router.js.map +1 -0
  217. package/dist/tui/services/agent-service.d.ts +58 -0
  218. package/dist/tui/services/agent-service.js +197 -0
  219. package/dist/tui/services/agent-service.js.map +1 -0
  220. package/dist/tui/services/calendar-service.d.ts +31 -0
  221. package/dist/tui/services/calendar-service.js +133 -0
  222. package/dist/tui/services/calendar-service.js.map +1 -0
  223. package/dist/tui/services/chat-service.d.ts +28 -0
  224. package/dist/tui/services/chat-service.js +91 -0
  225. package/dist/tui/services/chat-service.js.map +1 -0
  226. package/dist/tui/services/orchestration-service.d.ts +42 -0
  227. package/dist/tui/services/orchestration-service.js +153 -0
  228. package/dist/tui/services/orchestration-service.js.map +1 -0
  229. package/dist/tui/slash-commands.d.ts +106 -0
  230. package/dist/tui/slash-commands.js +1421 -0
  231. package/dist/tui/slash-commands.js.map +1 -0
  232. package/dist/tui/store.d.ts +96 -0
  233. package/dist/tui/store.js +120 -0
  234. package/dist/tui/store.js.map +1 -0
  235. package/dist/tui/theme.d.ts +40 -0
  236. package/dist/tui/theme.js +39 -0
  237. package/dist/tui/theme.js.map +1 -0
  238. package/dist/tui/tui-context.d.ts +22 -0
  239. package/dist/tui/tui-context.js +17 -0
  240. package/dist/tui/tui-context.js.map +1 -0
  241. package/dist/tui/views/agent-list.d.ts +8 -0
  242. package/dist/tui/views/agent-list.js +11 -0
  243. package/dist/tui/views/agent-list.js.map +1 -0
  244. package/dist/tui/views/ask-chat.d.ts +9 -0
  245. package/dist/tui/views/ask-chat.js +40 -0
  246. package/dist/tui/views/ask-chat.js.map +1 -0
  247. package/dist/tui/views/calendar.d.ts +15 -0
  248. package/dist/tui/views/calendar.js +29 -0
  249. package/dist/tui/views/calendar.js.map +1 -0
  250. package/dist/tui/views/chat.d.ts +18 -0
  251. package/dist/tui/views/chat.js +28 -0
  252. package/dist/tui/views/chat.js.map +1 -0
  253. package/dist/tui/views/generative.d.ts +14 -0
  254. package/dist/tui/views/generative.js +37 -0
  255. package/dist/tui/views/generative.js.map +1 -0
  256. package/dist/tui/views/help.d.ts +6 -0
  257. package/dist/tui/views/help.js +9 -0
  258. package/dist/tui/views/help.js.map +1 -0
  259. package/dist/tui/views/home-screen.d.ts +67 -0
  260. package/dist/tui/views/home-screen.js +192 -0
  261. package/dist/tui/views/home-screen.js.map +1 -0
  262. package/dist/tui/views/home.d.ts +33 -0
  263. package/dist/tui/views/home.js +60 -0
  264. package/dist/tui/views/home.js.map +1 -0
  265. package/dist/tui/views/index.d.ts +20 -0
  266. package/dist/tui/views/index.js +11 -0
  267. package/dist/tui/views/index.js.map +1 -0
  268. package/dist/tui/views/insights.d.ts +19 -0
  269. package/dist/tui/views/insights.js +46 -0
  270. package/dist/tui/views/insights.js.map +1 -0
  271. package/dist/tui/views/orchestration.d.ts +18 -0
  272. package/dist/tui/views/orchestration.js +73 -0
  273. package/dist/tui/views/orchestration.js.map +1 -0
  274. package/dist/tui/views/record-detail.d.ts +10 -0
  275. package/dist/tui/views/record-detail.js +22 -0
  276. package/dist/tui/views/record-detail.js.map +1 -0
  277. package/dist/tui/views/record-list.d.ts +15 -0
  278. package/dist/tui/views/record-list.js +22 -0
  279. package/dist/tui/views/record-list.js.map +1 -0
  280. package/dist/tui/views/slack-channel-header.d.ts +15 -0
  281. package/dist/tui/views/slack-channel-header.js +16 -0
  282. package/dist/tui/views/slack-channel-header.js.map +1 -0
  283. package/dist/tui/views/slack-home.d.ts +21 -0
  284. package/dist/tui/views/slack-home.js +572 -0
  285. package/dist/tui/views/slack-home.js.map +1 -0
  286. package/dist/tui/views/task-board.d.ts +21 -0
  287. package/dist/tui/views/task-board.js +33 -0
  288. package/dist/tui/views/task-board.js.map +1 -0
  289. package/dist/tui/views/timeline.d.ts +17 -0
  290. package/dist/tui/views/timeline.js +24 -0
  291. package/dist/tui/views/timeline.js.map +1 -0
  292. package/package.json +8 -3
@@ -0,0 +1,218 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * Slash command autocomplete overlay and hook.
4
+ *
5
+ * Shows a small overlay Box above the input line listing matching slash
6
+ * commands when the input starts with "/". Tab cycles through matches,
7
+ * Enter accepts the current match, Escape dismisses.
8
+ *
9
+ * This is a standalone component — wire it into the home/conversation
10
+ * view by:
11
+ * 1. Calling useSlashAutocomplete(inputValue, slashCommands)
12
+ * 2. Rendering <SlashAutocomplete {...autocomplete} /> above the input
13
+ * 3. Intercepting Tab/Enter/Escape in useInput and calling the
14
+ * returned handlers (onTab, onAccept, onDismiss)
15
+ */
16
+ import React from "react";
17
+ import { Box, Text } from "ink";
18
+ // ── Pure functions ──────────────────────────────────────────────────
19
+ /**
20
+ * Filter and rank commands that match a prefix query.
21
+ */
22
+ export function filterCommands(query, commands) {
23
+ const q = query.toLowerCase();
24
+ if (!q)
25
+ return commands;
26
+ return commands.filter((cmd) => cmd.name.toLowerCase().startsWith(q));
27
+ }
28
+ /**
29
+ * Create initial autocomplete state.
30
+ */
31
+ export function createAutocompleteState() {
32
+ return {
33
+ visible: false,
34
+ matches: [],
35
+ selectedIndex: 0,
36
+ query: "",
37
+ };
38
+ }
39
+ /**
40
+ * Compute new autocomplete state from current input value.
41
+ */
42
+ export function computeAutocompleteState(input, commands) {
43
+ const trimmed = input.trimStart();
44
+ // Only activate when input starts with "/" and has no space yet
45
+ // (space means the user has moved on to arguments)
46
+ if (!trimmed.startsWith("/") || trimmed.includes(" ")) {
47
+ return createAutocompleteState();
48
+ }
49
+ const query = trimmed.slice(1); // everything after "/"
50
+ const matches = filterCommands(query, commands);
51
+ // Don't show if there's exactly one match that equals the query
52
+ if (matches.length === 1 && matches[0].name === query) {
53
+ return createAutocompleteState();
54
+ }
55
+ // Don't show if no matches
56
+ if (matches.length === 0) {
57
+ return { visible: false, matches: [], selectedIndex: 0, query };
58
+ }
59
+ return {
60
+ visible: true,
61
+ matches,
62
+ selectedIndex: 0,
63
+ query,
64
+ };
65
+ }
66
+ /**
67
+ * Create actions that manage autocomplete state.
68
+ * This is a factory for use in React state management.
69
+ */
70
+ export function createAutocompleteActions(state, setState, commands) {
71
+ const accept = (index) => {
72
+ if (!state.visible || state.matches.length === 0)
73
+ return null;
74
+ const match = state.matches[index];
75
+ if (!match)
76
+ return null;
77
+ setState(createAutocompleteState());
78
+ return { text: `/${match.name} `, command: match.name };
79
+ };
80
+ return {
81
+ onTab: () => {
82
+ if (!state.visible || state.matches.length === 0)
83
+ return null;
84
+ // If only one match, accept it immediately
85
+ if (state.matches.length === 1) {
86
+ return accept(0);
87
+ }
88
+ // Cycle to next
89
+ const nextIndex = (state.selectedIndex + 1) % state.matches.length;
90
+ setState({ ...state, selectedIndex: nextIndex });
91
+ return null;
92
+ },
93
+ onShiftTab: () => {
94
+ if (!state.visible || state.matches.length === 0)
95
+ return null;
96
+ if (state.matches.length === 1) {
97
+ return accept(0);
98
+ }
99
+ const nextIndex = (state.selectedIndex - 1 + state.matches.length) % state.matches.length;
100
+ setState({ ...state, selectedIndex: nextIndex });
101
+ return null;
102
+ },
103
+ onAccept: () => {
104
+ return accept(state.selectedIndex);
105
+ },
106
+ onDismiss: () => {
107
+ setState(createAutocompleteState());
108
+ },
109
+ update: (input) => {
110
+ const newState = computeAutocompleteState(input, commands);
111
+ setState(newState);
112
+ },
113
+ };
114
+ }
115
+ // ── React hook ──────────────────────────────────────────────────────
116
+ /**
117
+ * Hook that manages slash command autocomplete state.
118
+ *
119
+ * Usage:
120
+ * ```tsx
121
+ * const { state, actions } = useSlashAutocomplete(commands);
122
+ *
123
+ * // In your onChange handler:
124
+ * actions.update(newValue);
125
+ *
126
+ * // In your useInput handler:
127
+ * if (key.name === "tab" && acState.visible) {
128
+ * const result = actions.onTab();
129
+ * if (result) setInputValue(result.text);
130
+ * return;
131
+ * }
132
+ * ```
133
+ */
134
+ import { useState, useRef } from "react";
135
+ export function useSlashAutocomplete(commands) {
136
+ const [acState, setAcState] = useState(createAutocompleteState());
137
+ const commandsRef = useRef(commands);
138
+ commandsRef.current = commands;
139
+ const stateRef = useRef(acState);
140
+ stateRef.current = acState;
141
+ // Stable reference — reads state/commands through refs so the object never changes
142
+ const actions = React.useMemo(() => {
143
+ const accept = (index) => {
144
+ const s = stateRef.current;
145
+ if (!s.visible || s.matches.length === 0)
146
+ return null;
147
+ const match = s.matches[index];
148
+ if (!match)
149
+ return null;
150
+ setAcState(createAutocompleteState());
151
+ return { text: `/${match.name} `, command: match.name };
152
+ };
153
+ return {
154
+ onTab: () => {
155
+ const s = stateRef.current;
156
+ if (!s.visible || s.matches.length === 0)
157
+ return null;
158
+ if (s.matches.length === 1)
159
+ return accept(0);
160
+ const next = (s.selectedIndex + 1) % s.matches.length;
161
+ setAcState({ ...s, selectedIndex: next });
162
+ return null;
163
+ },
164
+ onShiftTab: () => {
165
+ const s = stateRef.current;
166
+ if (!s.visible || s.matches.length === 0)
167
+ return null;
168
+ if (s.matches.length === 1)
169
+ return accept(0);
170
+ const next = (s.selectedIndex - 1 + s.matches.length) % s.matches.length;
171
+ setAcState({ ...s, selectedIndex: next });
172
+ return null;
173
+ },
174
+ onAccept: () => accept(stateRef.current.selectedIndex),
175
+ onDismiss: () => setAcState(createAutocompleteState()),
176
+ update: (input) => {
177
+ const newState = computeAutocompleteState(input, commandsRef.current);
178
+ const cur = stateRef.current;
179
+ // Skip setState when nothing meaningful changed to avoid extra renders
180
+ if (cur.visible === newState.visible &&
181
+ cur.query === newState.query &&
182
+ cur.selectedIndex === newState.selectedIndex &&
183
+ cur.matches.length === newState.matches.length)
184
+ return;
185
+ setAcState(newState);
186
+ },
187
+ };
188
+ }, []); // stable — reads through refs
189
+ return { state: acState, actions };
190
+ }
191
+ // ── Component ───────────────────────────────────────────────────────
192
+ /**
193
+ * Overlay rendering the list of matching slash commands.
194
+ * Position this above the input line.
195
+ */
196
+ export function SlashAutocomplete({ state, maxVisible = 8, }) {
197
+ if (!state.visible || state.matches.length === 0) {
198
+ return null;
199
+ }
200
+ // Determine visible window
201
+ const total = state.matches.length;
202
+ const visible = Math.min(total, maxVisible);
203
+ let startIdx = 0;
204
+ if (state.selectedIndex >= startIdx + visible) {
205
+ startIdx = state.selectedIndex - visible + 1;
206
+ }
207
+ if (state.selectedIndex < startIdx) {
208
+ startIdx = state.selectedIndex;
209
+ }
210
+ const visibleItems = state.matches.slice(startIdx, startIdx + visible);
211
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, borderStyle: "single", borderColor: "cyan", children: [visibleItems.map((cmd, i) => {
212
+ const actualIndex = startIdx + i;
213
+ const isSelected = actualIndex === state.selectedIndex;
214
+ return (_jsxs(Box, { gap: 1, children: [_jsx(Text, { color: isSelected ? "cyan" : undefined, bold: isSelected, dimColor: !isSelected, children: isSelected ? ">" : " " }), _jsx(Text, { color: isSelected ? "cyan" : "white", bold: isSelected, children: `/${cmd.name}` }), _jsx(Text, { dimColor: true, children: cmd.description })] }, cmd.name));
215
+ }), total > visible && (_jsx(Box, { justifyContent: "flex-end", children: _jsx(Text, { dimColor: true, children: `${state.selectedIndex + 1}/${total}` }) }))] }));
216
+ }
217
+ export default SlashAutocomplete;
218
+ //# sourceMappingURL=slash-autocomplete.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slash-autocomplete.js","sourceRoot":"","sources":["../../../src/tui/components/slash-autocomplete.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import React from "react";
2
+ export interface SpinnerProps {
3
+ /** Label displayed after the spinner character */
4
+ label?: string;
5
+ /** Animation interval in ms (default: 80) */
6
+ interval?: number;
7
+ /** Ink Text color for the spinner character */
8
+ color?: string;
9
+ /** When true, the spinner stops animating */
10
+ stopped?: boolean;
11
+ }
12
+ /**
13
+ * Returns the current braille spinner frame, advancing every `interval` ms.
14
+ */
15
+ export declare function useSpinner(interval?: number): string;
16
+ export declare function Spinner({ label, interval, color, stopped, }: SpinnerProps): React.JSX.Element;
17
+ export default Spinner;
@@ -0,0 +1,30 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState, useEffect } from "react";
3
+ import { Text } from "ink";
4
+ // ── Braille spinner frames ──────────────────────────────────────────
5
+ const FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
6
+ const DEFAULT_INTERVAL = 80;
7
+ // ── Hook ────────────────────────────────────────────────────────────
8
+ /**
9
+ * Returns the current braille spinner frame, advancing every `interval` ms.
10
+ */
11
+ export function useSpinner(interval = DEFAULT_INTERVAL) {
12
+ const [index, setIndex] = useState(0);
13
+ useEffect(() => {
14
+ const id = setInterval(() => {
15
+ setIndex((prev) => (prev + 1) % FRAMES.length);
16
+ }, interval);
17
+ return () => clearInterval(id);
18
+ }, [interval]);
19
+ return FRAMES[index];
20
+ }
21
+ // ── Component ───────────────────────────────────────────────────────
22
+ export function Spinner({ label, interval = DEFAULT_INTERVAL, color = "cyan", stopped = false, }) {
23
+ const frame = useSpinner(interval);
24
+ if (stopped) {
25
+ return label ? _jsx(Text, { dimColor: true, children: label }) : _jsx(Text, { children: "" });
26
+ }
27
+ return (_jsxs(Text, { children: [_jsx(Text, { color: color, children: frame }), label ? _jsx(Text, { children: ` ${label}` }) : null] }));
28
+ }
29
+ export default Spinner;
30
+ //# sourceMappingURL=spinner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spinner.js","sourceRoot":"","sources":["../../../src/tui/components/spinner.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAG3B,uEAAuE;AAEvE,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAU,CAAC;AAC3E,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAe5B,uEAAuE;AAEvE;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,QAAQ,GAAG,gBAAgB;IACpD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAEtC,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE;YAC1B,QAAQ,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;QACjD,CAAC,EAAE,QAAQ,CAAC,CAAC;QACb,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;IACjC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED,uEAAuE;AAEvE,MAAM,UAAU,OAAO,CAAC,EACtB,KAAK,EACL,QAAQ,GAAG,gBAAgB,EAC3B,KAAK,GAAG,MAAM,EACd,OAAO,GAAG,KAAK,GACF;IACb,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IAEnC,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,KAAK,CAAC,CAAC,CAAC,KAAC,IAAI,IAAC,QAAQ,kBAAE,KAAK,GAAQ,CAAC,CAAC,CAAC,KAAC,IAAI,cAAE,EAAE,GAAQ,CAAC;IACnE,CAAC;IAED,OAAO,CACL,MAAC,IAAI,eACH,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,YAAG,KAAK,GAAQ,EACjC,KAAK,CAAC,CAAC,CAAC,KAAC,IAAI,cAAE,IAAI,KAAK,EAAE,GAAQ,CAAC,CAAC,CAAC,IAAI,IACrC,CACR,CAAC;AACJ,CAAC;AAED,eAAe,OAAO,CAAC"}
@@ -0,0 +1,23 @@
1
+ import React from "react";
2
+ export type Mode = "normal" | "insert";
3
+ export interface SessionStats {
4
+ tokensUsed?: number;
5
+ costUsd?: number;
6
+ model?: string;
7
+ startTime?: number;
8
+ }
9
+ export interface StatusBarProps {
10
+ mode: Mode;
11
+ breadcrumbs: string[];
12
+ scrollPercent?: number;
13
+ hint?: string;
14
+ /** When true, hides the mode badge (conversation view handles its own input) */
15
+ conversationMode?: boolean;
16
+ /** Session stats for token/cost/elapsed display */
17
+ session?: SessionStats;
18
+ }
19
+ export declare function formatTokens(n: number): string;
20
+ export declare function formatCost(usd: number): string;
21
+ export declare function formatElapsed(startTime: number, now?: number): string;
22
+ export declare function StatusBar({ mode, breadcrumbs, scrollPercent, hint, conversationMode, session, }: StatusBarProps): React.JSX.Element;
23
+ export default StatusBar;
@@ -0,0 +1,55 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ // --- Colors (Bubbletea scheme) ---
4
+ const NEX_BLUE = "#2980fb";
5
+ const NEX_PURPLE = "#cf72d9";
6
+ const MODE_NORMAL_BG = NEX_BLUE;
7
+ const MODE_INSERT_BG = "#03a04c";
8
+ // --- Formatting helpers ---
9
+ export function formatTokens(n) {
10
+ if (n < 1000)
11
+ return String(n);
12
+ if (n < 10_000)
13
+ return `${(n / 1000).toFixed(1)}k`;
14
+ if (n < 1_000_000)
15
+ return `${Math.round(n / 1000)}k`;
16
+ return `${(n / 1_000_000).toFixed(1)}M`;
17
+ }
18
+ export function formatCost(usd) {
19
+ if (usd < 0.001)
20
+ return "$0.00";
21
+ if (usd < 1)
22
+ return `$${usd.toFixed(3)}`;
23
+ return `$${usd.toFixed(2)}`;
24
+ }
25
+ export function formatElapsed(startTime, now) {
26
+ const ms = (now ?? Date.now()) - startTime;
27
+ const totalSecs = Math.max(0, Math.floor(ms / 1000));
28
+ const mins = Math.floor(totalSecs / 60);
29
+ const secs = totalSecs % 60;
30
+ if (mins === 0)
31
+ return `${secs}s`;
32
+ return `${mins}m${String(secs).padStart(2, "0")}s`;
33
+ }
34
+ // --- Separator ---
35
+ const SEP = " \u2503 "; // ┃
36
+ // --- Session stats fragment ---
37
+ function SessionStatsFragment({ session }) {
38
+ if (!session)
39
+ return null;
40
+ return (_jsxs(_Fragment, { children: [session.tokensUsed !== undefined && session.tokensUsed > 0 && (_jsxs(_Fragment, { children: [_jsx(Text, { dimColor: true, children: SEP }), _jsx(Text, { dimColor: true, children: "tokens " }), _jsx(Text, { children: formatTokens(session.tokensUsed) })] })), session.costUsd !== undefined && session.costUsd > 0 && (_jsxs(_Fragment, { children: [_jsx(Text, { dimColor: true, children: SEP }), _jsx(Text, { children: formatCost(session.costUsd) })] })), session.startTime !== undefined && (_jsxs(_Fragment, { children: [_jsx(Text, { dimColor: true, children: SEP }), _jsx(Text, { dimColor: true, children: formatElapsed(session.startTime) })] }))] }));
41
+ }
42
+ // --- Component ---
43
+ export function StatusBar({ mode, breadcrumbs, scrollPercent, hint, conversationMode = false, session, }) {
44
+ const breadcrumbText = breadcrumbs.join(" > ");
45
+ if (conversationMode) {
46
+ // Simplified bar for conversation mode — brand + tokens + cost on left, hint on right
47
+ return (_jsxs(Box, { justifyContent: "space-between", children: [_jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: " " }), _jsx(Text, { color: NEX_PURPLE, bold: true, children: "\u258C" }), _jsx(Text, { bold: true, children: "nex" }), _jsx(SessionStatsFragment, { session: session }), scrollPercent !== undefined && (_jsxs(_Fragment, { children: [_jsx(Text, { dimColor: true, children: SEP }), _jsx(Text, { children: `${scrollPercent}%` })] }))] }), _jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: hint || "/help for commands | Esc=back" }), _jsx(Text, { dimColor: true, children: " " })] })] }));
48
+ }
49
+ // Sub-view mode — show mode badge with Bubbletea colors
50
+ const modeBg = mode === "normal" ? MODE_NORMAL_BG : MODE_INSERT_BG;
51
+ const modeLabel = mode.toUpperCase();
52
+ return (_jsxs(Box, { justifyContent: "space-between", children: [_jsxs(Box, { children: [_jsx(Text, { backgroundColor: modeBg, color: "black", bold: true, children: ` ${modeLabel} ` }), _jsx(Text, { children: " " }), _jsx(Text, { children: breadcrumbText }), scrollPercent !== undefined && (_jsxs(_Fragment, { children: [_jsx(Text, { dimColor: true, children: SEP }), _jsx(Text, { children: `${scrollPercent}%` })] })), _jsx(SessionStatsFragment, { session: session }), hint && (_jsxs(_Fragment, { children: [_jsx(Text, { dimColor: true, children: SEP }), _jsx(Text, { dimColor: true, children: hint })] }))] }), _jsxs(Box, { children: [_jsx(Text, { color: NEX_PURPLE, bold: true, children: "\u258C" }), _jsx(Text, { bold: true, children: "nex" }), _jsx(Text, { children: " " })] })] }));
53
+ }
54
+ export default StatusBar;
55
+ //# sourceMappingURL=status-bar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status-bar.js","sourceRoot":"","sources":["../../../src/tui/components/status-bar.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+ export interface SuccessBoxProps {
3
+ message: string;
4
+ detail?: string;
5
+ }
6
+ export declare function SuccessBox({ message, detail }: SuccessBoxProps): React.JSX.Element;
7
+ export default SuccessBox;
@@ -0,0 +1,10 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ // --- Colors ---
4
+ const SYS_SUCCESS = "#03a04c";
5
+ // --- Component ---
6
+ export function SuccessBox({ message, detail }) {
7
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: SYS_SUCCESS, paddingX: 1, children: [_jsxs(Box, { children: [_jsx(Text, { color: SYS_SUCCESS, bold: true, children: "✔ " }), _jsx(Text, { color: SYS_SUCCESS, children: message })] }), detail && (_jsx(Box, { marginTop: 0, children: _jsxs(Text, { dimColor: true, children: [" ", detail] }) }))] }));
8
+ }
9
+ export default SuccessBox;
10
+ //# sourceMappingURL=success-box.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"success-box.js","sourceRoot":"","sources":["../../../src/tui/components/success-box.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAEhC,iBAAiB;AAEjB,MAAM,WAAW,GAAG,SAAS,CAAC;AAS9B,oBAAoB;AAEpB,MAAM,UAAU,UAAU,CAAC,EAAE,OAAO,EAAE,MAAM,EAAmB;IAC7D,OAAO,CACL,MAAC,GAAG,IACF,aAAa,EAAC,QAAQ,EACtB,WAAW,EAAC,OAAO,EACnB,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,CAAC,aAGX,MAAC,GAAG,eACF,KAAC,IAAI,IAAC,KAAK,EAAE,WAAW,EAAE,IAAI,kBAAE,IAAI,GAAQ,EAC5C,KAAC,IAAI,IAAC,KAAK,EAAE,WAAW,YAAG,OAAO,GAAQ,IACtC,EAGL,MAAM,IAAI,CACT,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,MAAC,IAAI,IAAC,QAAQ,mBAAE,IAAI,EAAE,MAAM,IAAQ,GAChC,CACP,IACG,CACP,CAAC;AACJ,CAAC;AAED,eAAe,UAAU,CAAC"}
@@ -0,0 +1,12 @@
1
+ import React from "react";
2
+ export type ToolStatus = "running" | "done" | "error";
3
+ export interface ToolIndicatorProps {
4
+ /** Name of the tool being executed */
5
+ name: string;
6
+ /** Current status */
7
+ status: ToolStatus;
8
+ /** Elapsed time in seconds (shown when done) */
9
+ elapsed?: number;
10
+ }
11
+ export declare function ToolIndicator({ name, status, elapsed, }: ToolIndicatorProps): React.JSX.Element;
12
+ export default ToolIndicator;
@@ -0,0 +1,18 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Text } from "ink";
3
+ import { useSpinner } from "./spinner.js";
4
+ // ── Component ───────────────────────────────────────────────────────
5
+ export function ToolIndicator({ name, status, elapsed, }) {
6
+ const frame = useSpinner();
7
+ if (status === "done") {
8
+ const time = elapsed !== undefined ? ` (${elapsed.toFixed(1)}s)` : "";
9
+ return (_jsxs(Text, { children: [_jsx(Text, { color: "green", children: "✓" }), _jsx(Text, { children: ` ${name}` }), _jsx(Text, { dimColor: true, children: time })] }));
10
+ }
11
+ if (status === "error") {
12
+ return (_jsxs(Text, { children: [_jsx(Text, { color: "red", children: "✗" }), _jsx(Text, { children: ` ${name}` })] }));
13
+ }
14
+ // running
15
+ return (_jsxs(Text, { children: [_jsx(Text, { color: "cyan", children: frame }), _jsx(Text, { children: ` ${name}` })] }));
16
+ }
17
+ export default ToolIndicator;
18
+ //# sourceMappingURL=tool-indicator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-indicator.js","sourceRoot":"","sources":["../../../src/tui/components/tool-indicator.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAe1C,uEAAuE;AAEvE,MAAM,UAAU,aAAa,CAAC,EAC5B,IAAI,EACJ,MAAM,EACN,OAAO,GACY;IACnB,MAAM,KAAK,GAAG,UAAU,EAAE,CAAC;IAE3B,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,MAAM,IAAI,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QACtE,OAAO,CACL,MAAC,IAAI,eACH,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,YAAE,GAAG,GAAQ,EAChC,KAAC,IAAI,cAAE,IAAI,IAAI,EAAE,GAAQ,EACzB,KAAC,IAAI,IAAC,QAAQ,kBAAE,IAAI,GAAQ,IACvB,CACR,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;QACvB,OAAO,CACL,MAAC,IAAI,eACH,KAAC,IAAI,IAAC,KAAK,EAAC,KAAK,YAAE,GAAG,GAAQ,EAC9B,KAAC,IAAI,cAAE,IAAI,IAAI,EAAE,GAAQ,IACpB,CACR,CAAC;IACJ,CAAC;IAED,UAAU;IACV,OAAO,CACL,MAAC,IAAI,eACH,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,YAAE,KAAK,GAAQ,EACjC,KAAC,IAAI,cAAE,IAAI,IAAI,EAAE,GAAQ,IACpB,CACR,CAAC;AACJ,CAAC;AAED,eAAe,aAAa,CAAC"}
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ export interface ViewportProps {
3
+ content: string;
4
+ scrollOffset: number;
5
+ onScroll: (offset: number) => void;
6
+ height?: number;
7
+ }
8
+ export declare function Viewport({ content, scrollOffset, onScroll: _onScroll, height, }: ViewportProps): React.JSX.Element;
9
+ export default Viewport;
@@ -0,0 +1,24 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useMemo } from "react";
3
+ import { Box, Text } from "ink";
4
+ // --- Component ---
5
+ export function Viewport({ content, scrollOffset, onScroll: _onScroll, height, }) {
6
+ const effectiveHeight = height ?? 20;
7
+ const { visibleLines, scrollPercent, totalLines } = useMemo(() => {
8
+ const allLines = content.split("\n");
9
+ const total = allLines.length;
10
+ const clampedOffset = Math.max(0, Math.min(scrollOffset, Math.max(0, total - effectiveHeight)));
11
+ const slice = allLines.slice(clampedOffset, clampedOffset + effectiveHeight);
12
+ const pct = total <= effectiveHeight
13
+ ? 100
14
+ : Math.round((clampedOffset / (total - effectiveHeight)) * 100);
15
+ return {
16
+ visibleLines: slice,
17
+ scrollPercent: pct,
18
+ totalLines: total,
19
+ };
20
+ }, [content, scrollOffset, effectiveHeight]);
21
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { flexDirection: "column", height: effectiveHeight, children: visibleLines.map((line, i) => (_jsx(Text, { wrap: "truncate", children: line }, i))) }), totalLines > effectiveHeight && (_jsx(Box, { justifyContent: "flex-end", children: _jsx(Text, { dimColor: true, children: `${scrollPercent}%` }) }))] }));
22
+ }
23
+ export default Viewport;
24
+ //# sourceMappingURL=viewport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"viewport.js","sourceRoot":"","sources":["../../../src/tui/components/viewport.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAWhC,oBAAoB;AAEpB,MAAM,UAAU,QAAQ,CAAC,EACvB,OAAO,EACP,YAAY,EACZ,QAAQ,EAAE,SAAS,EACnB,MAAM,GACQ;IACd,MAAM,eAAe,GAAG,MAAM,IAAI,EAAE,CAAC;IAErC,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE;QAC/D,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACrC,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC;QAC9B,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAC5B,CAAC,EACD,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,eAAe,CAAC,CAAC,CAC7D,CAAC;QACF,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,aAAa,EAAE,aAAa,GAAG,eAAe,CAAC,CAAC;QAE7E,MAAM,GAAG,GACP,KAAK,IAAI,eAAe;YACtB,CAAC,CAAC,GAAG;YACL,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,aAAa,GAAG,CAAC,KAAK,GAAG,eAAe,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;QAEpE,OAAO;YACL,YAAY,EAAE,KAAK;YACnB,aAAa,EAAE,GAAG;YAClB,UAAU,EAAE,KAAK;SAClB,CAAC;IACJ,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,eAAe,CAAC,CAAC,CAAC;IAE7C,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACzB,KAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,MAAM,EAAE,eAAe,YAChD,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAC7B,KAAC,IAAI,IAAS,IAAI,EAAC,UAAU,YAC1B,IAAI,IADI,CAAC,CAEL,CACR,CAAC,GACE,EACL,UAAU,GAAG,eAAe,IAAI,CAC/B,KAAC,GAAG,IAAC,cAAc,EAAC,UAAU,YAC5B,KAAC,IAAI,IAAC,QAAQ,kBAAE,GAAG,aAAa,GAAG,GAAQ,GACvC,CACP,IACG,CACP,CAAC;AACJ,CAAC;AAED,eAAe,QAAQ,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * RFC 6901 JSON Pointer implementation for A2UI data binding.
3
+ * Provides resolve/set/apply operations over a flat data model.
4
+ */
5
+ import type { A2UIDataModel, A2UIUpdate } from './types.js';
6
+ /**
7
+ * Resolve a JSON Pointer against a data object.
8
+ *
9
+ * @example
10
+ * resolvePointer({ user: { name: "Alice" } }, "/user/name") // "Alice"
11
+ * resolvePointer({ items: [{ status: "done" }] }, "/items/0/status") // "done"
12
+ */
13
+ export declare function resolvePointer(data: unknown, pointer: string): unknown;
14
+ /**
15
+ * Set a value at a JSON Pointer path, creating intermediate objects as needed.
16
+ * Mutates the data object in place.
17
+ */
18
+ export declare function setPointer(data: Record<string, unknown>, pointer: string, value: unknown): void;
19
+ /**
20
+ * Check if a string looks like a JSON Pointer (starts with "/").
21
+ */
22
+ export declare function isPointer(value: string): boolean;
23
+ /**
24
+ * Apply a batch of updates to a data model.
25
+ * Returns a shallow copy of the model with updates applied.
26
+ */
27
+ export declare function applyUpdates(model: A2UIDataModel, updates: A2UIUpdate[]): A2UIDataModel;