@neurocode-ai/tui 1.18.8

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 (241) hide show
  1. package/bunfig.toml +4 -0
  2. package/package.json +72 -0
  3. package/src/app.tsx +1134 -0
  4. package/src/attention.ts +260 -0
  5. package/src/audio.d.ts +9 -0
  6. package/src/audio.ts +53 -0
  7. package/src/clipboard.ts +124 -0
  8. package/src/component/bg-pulse-render.ts +436 -0
  9. package/src/component/bg-pulse.tsx +99 -0
  10. package/src/component/command-palette.tsx +79 -0
  11. package/src/component/dialog-agent.tsx +31 -0
  12. package/src/component/dialog-console-org.tsx +135 -0
  13. package/src/component/dialog-debug.tsx +90 -0
  14. package/src/component/dialog-mcp.tsx +85 -0
  15. package/src/component/dialog-model.tsx +197 -0
  16. package/src/component/dialog-move-session.tsx +353 -0
  17. package/src/component/dialog-provider.tsx +469 -0
  18. package/src/component/dialog-retry-action.tsx +160 -0
  19. package/src/component/dialog-session-delete-failed.tsx +99 -0
  20. package/src/component/dialog-session-list.tsx +364 -0
  21. package/src/component/dialog-session-rename.tsx +31 -0
  22. package/src/component/dialog-skill.tsx +70 -0
  23. package/src/component/dialog-stash.tsx +87 -0
  24. package/src/component/dialog-status.tsx +168 -0
  25. package/src/component/dialog-tag.tsx +47 -0
  26. package/src/component/dialog-theme-list.tsx +50 -0
  27. package/src/component/dialog-variant.tsx +39 -0
  28. package/src/component/dialog-workspace-create.tsx +308 -0
  29. package/src/component/dialog-workspace-file-changes.tsx +144 -0
  30. package/src/component/dialog-workspace-list.tsx +112 -0
  31. package/src/component/dialog-workspace-unavailable.tsx +69 -0
  32. package/src/component/error-component.tsx +240 -0
  33. package/src/component/logo.tsx +61 -0
  34. package/src/component/plugin-route-missing.tsx +14 -0
  35. package/src/component/prompt/autocomplete.tsx +781 -0
  36. package/src/component/prompt/cwd.ts +0 -0
  37. package/src/component/prompt/frecency.tsx +1 -0
  38. package/src/component/prompt/history.tsx +1 -0
  39. package/src/component/prompt/index.tsx +1713 -0
  40. package/src/component/prompt/local-attachment.ts +48 -0
  41. package/src/component/prompt/move.tsx +205 -0
  42. package/src/component/prompt/stash.tsx +1 -0
  43. package/src/component/prompt/workspace.tsx +137 -0
  44. package/src/component/register-spinner.ts +6 -0
  45. package/src/component/spinner.tsx +26 -0
  46. package/src/component/startup-loading.tsx +63 -0
  47. package/src/component/todo-item.tsx +32 -0
  48. package/src/component/use-connected.tsx +12 -0
  49. package/src/component/workspace-label.tsx +19 -0
  50. package/src/config/index.tsx +129 -0
  51. package/src/config/keybind.ts +471 -0
  52. package/src/context/args.tsx +16 -0
  53. package/src/context/clipboard.tsx +18 -0
  54. package/src/context/data.tsx +569 -0
  55. package/src/context/directory.ts +17 -0
  56. package/src/context/editor.ts +408 -0
  57. package/src/context/epilogue.tsx +6 -0
  58. package/src/context/event.ts +36 -0
  59. package/src/context/exit.tsx +8 -0
  60. package/src/context/helper.tsx +26 -0
  61. package/src/context/kv.tsx +66 -0
  62. package/src/context/local.tsx +542 -0
  63. package/src/context/location.tsx +14 -0
  64. package/src/context/path-format.tsx +24 -0
  65. package/src/context/permission.tsx +26 -0
  66. package/src/context/project.tsx +115 -0
  67. package/src/context/prompt.tsx +18 -0
  68. package/src/context/route.tsx +60 -0
  69. package/src/context/runtime.tsx +62 -0
  70. package/src/context/sdk.tsx +151 -0
  71. package/src/context/sync.tsx +666 -0
  72. package/src/context/theme.tsx +332 -0
  73. package/src/context/thinking.ts +67 -0
  74. package/src/editor-zed.ts +286 -0
  75. package/src/editor.ts +101 -0
  76. package/src/feature-plugins/builtins.ts +36 -0
  77. package/src/feature-plugins/home/footer.tsx +100 -0
  78. package/src/feature-plugins/home/tips-view.tsx +287 -0
  79. package/src/feature-plugins/home/tips.tsx +59 -0
  80. package/src/feature-plugins/sidebar/context.tsx +65 -0
  81. package/src/feature-plugins/sidebar/files.tsx +70 -0
  82. package/src/feature-plugins/sidebar/footer.tsx +98 -0
  83. package/src/feature-plugins/sidebar/lsp.tsx +65 -0
  84. package/src/feature-plugins/sidebar/mcp.tsx +97 -0
  85. package/src/feature-plugins/sidebar/todo.tsx +49 -0
  86. package/src/feature-plugins/system/diff-viewer-file-tree-utils.ts +232 -0
  87. package/src/feature-plugins/system/diff-viewer-file-tree.tsx +162 -0
  88. package/src/feature-plugins/system/diff-viewer-ui.tsx +103 -0
  89. package/src/feature-plugins/system/diff-viewer.tsx +1077 -0
  90. package/src/feature-plugins/system/notifications.ts +94 -0
  91. package/src/feature-plugins/system/plugins.tsx +269 -0
  92. package/src/feature-plugins/system/which-key.tsx +608 -0
  93. package/src/index.tsx +1 -0
  94. package/src/keymap.tsx +290 -0
  95. package/src/logo.ts +11 -0
  96. package/src/parsers-config.ts +386 -0
  97. package/src/plugin/adapters.tsx +355 -0
  98. package/src/plugin/api.ts +52 -0
  99. package/src/plugin/command-shim.ts +109 -0
  100. package/src/plugin/runtime.tsx +81 -0
  101. package/src/plugin/slots.tsx +65 -0
  102. package/src/prompt/display.ts +48 -0
  103. package/src/prompt/frecency.tsx +80 -0
  104. package/src/prompt/history.tsx +111 -0
  105. package/src/prompt/part.ts +29 -0
  106. package/src/prompt/stash.tsx +89 -0
  107. package/src/prompt/traits.ts +29 -0
  108. package/src/routes/home/session-destination.tsx +41 -0
  109. package/src/routes/home.tsx +95 -0
  110. package/src/routes/session/dialog-fork-from-timeline.tsx +76 -0
  111. package/src/routes/session/dialog-message.tsx +109 -0
  112. package/src/routes/session/dialog-subagent.tsx +26 -0
  113. package/src/routes/session/dialog-timeline.tsx +47 -0
  114. package/src/routes/session/footer.tsx +91 -0
  115. package/src/routes/session/index.tsx +2710 -0
  116. package/src/routes/session/permission.tsx +718 -0
  117. package/src/routes/session/question.tsx +514 -0
  118. package/src/routes/session/sidebar.tsx +103 -0
  119. package/src/routes/session/subagent-footer.tsx +132 -0
  120. package/src/runtime.tsx +9 -0
  121. package/src/terminal-win32.ts +130 -0
  122. package/src/theme/assets/aura.json +69 -0
  123. package/src/theme/assets/ayu.json +80 -0
  124. package/src/theme/assets/carbonfox.json +248 -0
  125. package/src/theme/assets/catppuccin-frappe.json +230 -0
  126. package/src/theme/assets/catppuccin-macchiato.json +230 -0
  127. package/src/theme/assets/catppuccin.json +112 -0
  128. package/src/theme/assets/cobalt2.json +225 -0
  129. package/src/theme/assets/cursor.json +249 -0
  130. package/src/theme/assets/dracula.json +219 -0
  131. package/src/theme/assets/everforest.json +241 -0
  132. package/src/theme/assets/flexoki.json +237 -0
  133. package/src/theme/assets/github.json +233 -0
  134. package/src/theme/assets/gruvbox.json +242 -0
  135. package/src/theme/assets/kanagawa.json +77 -0
  136. package/src/theme/assets/lucent-orng.json +234 -0
  137. package/src/theme/assets/material.json +235 -0
  138. package/src/theme/assets/matrix.json +77 -0
  139. package/src/theme/assets/mercury.json +252 -0
  140. package/src/theme/assets/monokai.json +221 -0
  141. package/src/theme/assets/nightowl.json +221 -0
  142. package/src/theme/assets/nord.json +223 -0
  143. package/src/theme/assets/one-dark.json +84 -0
  144. package/src/theme/assets/opencode.json +245 -0
  145. package/src/theme/assets/orng.json +249 -0
  146. package/src/theme/assets/osaka-jade.json +93 -0
  147. package/src/theme/assets/palenight.json +222 -0
  148. package/src/theme/assets/rosepine.json +234 -0
  149. package/src/theme/assets/solarized.json +223 -0
  150. package/src/theme/assets/synthwave84.json +226 -0
  151. package/src/theme/assets/tokyonight.json +243 -0
  152. package/src/theme/assets/vercel.json +245 -0
  153. package/src/theme/assets/vesper.json +218 -0
  154. package/src/theme/assets/zenburn.json +223 -0
  155. package/src/theme/index.ts +1089 -0
  156. package/src/ui/border.ts +21 -0
  157. package/src/ui/dialog-alert.tsx +66 -0
  158. package/src/ui/dialog-confirm.tsx +108 -0
  159. package/src/ui/dialog-export-options.tsx +217 -0
  160. package/src/ui/dialog-help.tsx +40 -0
  161. package/src/ui/dialog-prompt.tsx +126 -0
  162. package/src/ui/dialog-select.tsx +790 -0
  163. package/src/ui/dialog.tsx +231 -0
  164. package/src/ui/link.tsx +34 -0
  165. package/src/ui/spinner.ts +368 -0
  166. package/src/ui/toast.tsx +102 -0
  167. package/src/util/collapse-tool-output.ts +19 -0
  168. package/src/util/error.ts +182 -0
  169. package/src/util/filetype.ts +130 -0
  170. package/src/util/format.ts +20 -0
  171. package/src/util/layout.ts +25 -0
  172. package/src/util/locale.ts +86 -0
  173. package/src/util/model.ts +28 -0
  174. package/src/util/path.ts +12 -0
  175. package/src/util/persistence.ts +33 -0
  176. package/src/util/presentation.ts +38 -0
  177. package/src/util/provider-origin.ts +7 -0
  178. package/src/util/record.ts +3 -0
  179. package/src/util/renderer.ts +7 -0
  180. package/src/util/revert-diff.ts +18 -0
  181. package/src/util/scroll.ts +27 -0
  182. package/src/util/selection.ts +79 -0
  183. package/src/util/session.ts +3 -0
  184. package/src/util/signal.ts +51 -0
  185. package/src/util/system.ts +20 -0
  186. package/src/util/tool-display.ts +13 -0
  187. package/src/util/transcript.ts +112 -0
  188. package/sst-env.d.ts +10 -0
  189. package/test/app-lifecycle.test.tsx +128 -0
  190. package/test/cli/cmd/tui/dialog-workspace-create.test.ts +28 -0
  191. package/test/cli/cmd/tui/model-options.test.ts +32 -0
  192. package/test/cli/cmd/tui/notifications.test.ts +267 -0
  193. package/test/cli/cmd/tui/provider-options.test.ts +41 -0
  194. package/test/cli/cmd/tui/sync-fixture.tsx +70 -0
  195. package/test/cli/cmd/tui/sync-live-hydration.test.tsx +262 -0
  196. package/test/cli/cmd/tui/sync-undefined-messages.test.tsx +43 -0
  197. package/test/cli/cmd/tui/sync.test.tsx +65 -0
  198. package/test/cli/tui/__snapshots__/inline-tool-wrap-snapshot.test.tsx.snap +92 -0
  199. package/test/cli/tui/data.test.tsx +486 -0
  200. package/test/cli/tui/dialog-prompt.test.tsx +147 -0
  201. package/test/cli/tui/diff-viewer-file-tree.test.tsx +200 -0
  202. package/test/cli/tui/diff-viewer.test.tsx +268 -0
  203. package/test/cli/tui/inline-tool-wrap-snapshot.test.tsx +351 -0
  204. package/test/cli/tui/prompt-submit-race.test.ts +98 -0
  205. package/test/cli/tui/thinking.test.ts +36 -0
  206. package/test/cli/tui/use-event.test.tsx +148 -0
  207. package/test/clipboard.test.ts +19 -0
  208. package/test/component/dialog-session-list.test.ts +46 -0
  209. package/test/config.test.tsx +127 -0
  210. package/test/context/local.test.ts +22 -0
  211. package/test/editor.test.ts +32 -0
  212. package/test/feature-plugins/diff-viewer-file-tree-utils.test.ts +323 -0
  213. package/test/fixture/fixture.ts +13 -0
  214. package/test/fixture/tui-environment.tsx +32 -0
  215. package/test/fixture/tui-plugin.ts +36 -0
  216. package/test/fixture/tui-runtime.ts +12 -0
  217. package/test/fixture/tui-sdk.ts +109 -0
  218. package/test/index.test.tsx +6 -0
  219. package/test/keymap.test.tsx +141 -0
  220. package/test/plugin/runtime.test.ts +50 -0
  221. package/test/plugin/slots.test.tsx +38 -0
  222. package/test/prompt/display.test.ts +33 -0
  223. package/test/prompt/history.test.ts +39 -0
  224. package/test/prompt/jsonl.test.ts +24 -0
  225. package/test/prompt/local-attachment.test.ts +43 -0
  226. package/test/prompt/part.test.ts +53 -0
  227. package/test/prompt/persistence.test.ts +23 -0
  228. package/test/prompt/traits.test.ts +25 -0
  229. package/test/runtime.test.tsx +37 -0
  230. package/test/theme.test.ts +81 -0
  231. package/test/util/error.test.ts +49 -0
  232. package/test/util/filetype.test.ts +16 -0
  233. package/test/util/format.test.ts +59 -0
  234. package/test/util/model.test.ts +9 -0
  235. package/test/util/presentation.test.ts +8 -0
  236. package/test/util/renderer.test.ts +30 -0
  237. package/test/util/revert-diff.test.ts +35 -0
  238. package/test/util/session.test.ts +10 -0
  239. package/test/util/tool-display.test.ts +40 -0
  240. package/test/util/transcript.test.ts +421 -0
  241. package/tsconfig.json +10 -0
package/src/keymap.tsx ADDED
@@ -0,0 +1,290 @@
1
+ import { InputRenderable, TextareaRenderable, type CliRenderer, type KeyEvent, type Renderable } from "@opentui/core"
2
+ import {
3
+ registerBackspacePopsPendingSequence,
4
+ registerBaseLayoutFallback,
5
+ registerCommaBindings,
6
+ registerEscapeClearsPendingSequence,
7
+ registerManagedTextareaLayer,
8
+ registerTimedLeader,
9
+ } from "@opentui/keymap/addons/opentui"
10
+ import { stringifyKeyStroke, type Binding } from "@opentui/keymap"
11
+ import {
12
+ formatCommandBindings as formatCommandBindingsExtra,
13
+ formatKeySequence as formatKeySequenceExtra,
14
+ } from "@opentui/keymap/extras"
15
+ import { KeymapProvider, useKeymap, useKeymapSelector, useBindings } from "@opentui/keymap/solid"
16
+ import { createMemo, type Accessor } from "solid-js"
17
+ import { useTuiConfig } from "./config"
18
+ import { TuiKeybind } from "./config/keybind"
19
+
20
+ export const LEADER_TOKEN = "leader"
21
+ export const NEUROCODE_BASE_MODE = "base"
22
+ export const COMMAND_PALETTE_COMMAND = "command.palette.show"
23
+
24
+ const NEUROCODE_MODE_KEY = "neurocode.mode"
25
+
26
+ export const NeurocodeKeymapProvider = KeymapProvider
27
+ export const useNeurocodeKeymap = useKeymap
28
+
29
+ export { useBindings, useKeymapSelector }
30
+
31
+ export type OpenTuiKeymap = ReturnType<typeof useKeymap>
32
+ type NeurocodeModeStack = ReturnType<typeof createNeurocodeModeStack>
33
+ type CommandSlashEntry = {
34
+ display: string
35
+ description?: string
36
+ aliases?: string[]
37
+ onSelect: () => void
38
+ }
39
+ type Command = ReturnType<OpenTuiKeymap["getCommands"]>[number]
40
+ type BindingLookup = {
41
+ get(command: string): readonly Binding<Renderable, KeyEvent>[]
42
+ gather(name: string, commands: readonly string[]): readonly Binding<Renderable, KeyEvent>[]
43
+ }
44
+ type FormatConfig = { keybinds: BindingLookup }
45
+ type ResolvedKeymapConfig = FormatConfig & { leader_timeout: number }
46
+
47
+ const modeStacks = new WeakMap<OpenTuiKeymap, NeurocodeModeStack>()
48
+
49
+ function isVisiblePaletteCommand(command: Command) {
50
+ return command.hidden !== true && command.name !== COMMAND_PALETTE_COMMAND
51
+ }
52
+
53
+ export function createNeurocodeModeStack(keymap: OpenTuiKeymap) {
54
+ keymap.setData(NEUROCODE_MODE_KEY, NEUROCODE_BASE_MODE)
55
+
56
+ const offFields = keymap.registerLayerFields({
57
+ mode(value, ctx) {
58
+ ctx.require(NEUROCODE_MODE_KEY, value)
59
+ },
60
+ })
61
+
62
+ const stack: { id: symbol; mode: string }[] = []
63
+ let disposed = false
64
+
65
+ const update = () => {
66
+ keymap.setData(NEUROCODE_MODE_KEY, stack.at(-1)?.mode ?? NEUROCODE_BASE_MODE)
67
+ }
68
+
69
+ const stackApi = {
70
+ current() {
71
+ return stack.at(-1)?.mode ?? NEUROCODE_BASE_MODE
72
+ },
73
+ push(mode: string) {
74
+ if (disposed) return () => {}
75
+ const id = Symbol(mode)
76
+ let active = true
77
+ stack.push({ id, mode })
78
+ update()
79
+
80
+ return () => {
81
+ if (!active) return
82
+ active = false
83
+ const index = stack.findIndex((item) => item.id === id)
84
+ if (index !== -1) stack.splice(index, 1)
85
+ update()
86
+ }
87
+ },
88
+ dispose() {
89
+ if (disposed) return
90
+ disposed = true
91
+ stack.length = 0
92
+ offFields()
93
+ keymap.setData(NEUROCODE_MODE_KEY, undefined)
94
+ modeStacks.delete(keymap)
95
+ },
96
+ }
97
+
98
+ modeStacks.set(keymap, stackApi)
99
+ return stackApi
100
+ }
101
+
102
+ export function useNeurocodeModeStack() {
103
+ return getNeurocodeModeStack(useNeurocodeKeymap())
104
+ }
105
+
106
+ export function getNeurocodeModeStack(keymap: OpenTuiKeymap) {
107
+ const value = modeStacks.get(keymap)
108
+ if (!value) throw new Error("Opencode mode stack is not registered for this keymap")
109
+ return value
110
+ }
111
+
112
+ const KEY_ALIASES = {
113
+ enter: "return",
114
+ esc: "escape",
115
+ pgdown: "pagedown",
116
+ pgup: "pageup",
117
+ } as const
118
+
119
+ function expandKeyAliases(input: string) {
120
+ const result = Object.entries(KEY_ALIASES).reduce(
121
+ (acc, [alias, key]) => acc.replace(new RegExp(`(^|[+,\\s>])${alias}(?=$|[+,\\s<])`, "gi"), `$1${key}`),
122
+ input,
123
+ )
124
+ if (result === input) return
125
+ return result
126
+ }
127
+
128
+ function registerKeyAliases(keymap: OpenTuiKeymap) {
129
+ return keymap.appendBindingExpander((ctx) => {
130
+ const key = expandKeyAliases(ctx.input)
131
+ if (!key) return
132
+ return [{ key, displays: ctx.displays }]
133
+ })
134
+ }
135
+
136
+ const inputCommands = [
137
+ "input.move.left",
138
+ "input.move.right",
139
+ "input.move.up",
140
+ "input.move.down",
141
+ "input.select.left",
142
+ "input.select.right",
143
+ "input.select.up",
144
+ "input.select.down",
145
+ "input.line.home",
146
+ "input.line.end",
147
+ "input.select.line.home",
148
+ "input.select.line.end",
149
+ "input.visual.line.home",
150
+ "input.visual.line.end",
151
+ "input.select.visual.line.home",
152
+ "input.select.visual.line.end",
153
+ "input.buffer.home",
154
+ "input.buffer.end",
155
+ "input.select.buffer.home",
156
+ "input.select.buffer.end",
157
+ "input.delete.line",
158
+ "input.delete.to.line.end",
159
+ "input.delete.to.line.start",
160
+ "input.backspace",
161
+ "input.delete",
162
+ "input.newline",
163
+ "input.undo",
164
+ "input.redo",
165
+ "input.word.forward",
166
+ "input.word.backward",
167
+ "input.select.word.forward",
168
+ "input.select.word.backward",
169
+ "input.delete.word.forward",
170
+ "input.delete.word.backward",
171
+ "input.select.all",
172
+ "input.submit",
173
+ ] as const
174
+
175
+ function hasManagedTextareaFocus(renderer: CliRenderer) {
176
+ const editor = renderer.currentFocusedEditor
177
+ return editor instanceof TextareaRenderable && !(editor instanceof InputRenderable)
178
+ }
179
+
180
+ function leaderDisplay(config: FormatConfig) {
181
+ const key = config.keybinds.get(LEADER_TOKEN)?.[0]?.key
182
+ if (!key) return TuiKeybind.LeaderDefault
183
+ return typeof key === "string" ? key : stringifyKeyStroke(key)
184
+ }
185
+
186
+ function leaderKey(config: FormatConfig) {
187
+ return config.keybinds.get(LEADER_TOKEN)?.[0]?.key
188
+ }
189
+
190
+ function formatOptions(config: FormatConfig) {
191
+ return {
192
+ tokenDisplay: {
193
+ [LEADER_TOKEN]: leaderDisplay(config),
194
+ },
195
+ keyNameAliases: {
196
+ pageup: "pgup",
197
+ pagedown: "pgdn",
198
+ delete: "del",
199
+ },
200
+ modifierAliases: {
201
+ meta: "alt",
202
+ },
203
+ } as const
204
+ }
205
+
206
+ export function formatKeySequence(parts: Parameters<typeof formatKeySequenceExtra>[0], config: FormatConfig) {
207
+ return formatKeySequenceExtra(parts, formatOptions(config))
208
+ }
209
+
210
+ export function formatKeyBindings(bindings: Parameters<typeof formatCommandBindingsExtra>[0], config: FormatConfig) {
211
+ return formatCommandBindingsExtra(bindings, formatOptions(config))
212
+ }
213
+
214
+ export function registerNeurocodeKeymap(keymap: OpenTuiKeymap, renderer: CliRenderer, config: ResolvedKeymapConfig) {
215
+ const modeStack = createNeurocodeModeStack(keymap)
216
+ const offCommaBindings = registerCommaBindings(keymap)
217
+ const offAliasExpander = registerKeyAliases(keymap)
218
+ const offBaseLayout = registerBaseLayoutFallback(keymap)
219
+ const leader = leaderKey(config)
220
+ const offLeader = leader
221
+ ? registerTimedLeader(keymap, {
222
+ trigger: leader,
223
+ name: LEADER_TOKEN,
224
+ timeoutMs: config.leader_timeout,
225
+ })
226
+ : () => {}
227
+ const offEscape = registerEscapeClearsPendingSequence(keymap)
228
+ const offBackspace = registerBackspacePopsPendingSequence(keymap)
229
+ const offInputBindings = registerManagedTextareaLayer(keymap, renderer, {
230
+ enabled: () => hasManagedTextareaFocus(renderer),
231
+ bindings: config.keybinds.gather("input", inputCommands),
232
+ })
233
+
234
+ return () => {
235
+ offInputBindings()
236
+ offBackspace()
237
+ offEscape()
238
+ offLeader()
239
+ offAliasExpander()
240
+ offBaseLayout()
241
+ offCommaBindings()
242
+ modeStack.dispose()
243
+ }
244
+ }
245
+
246
+ export function useLeaderActive(): Accessor<boolean> {
247
+ return useKeymapSelector((keymap: OpenTuiKeymap) => keymap.getPendingSequence()[0]?.tokenName === LEADER_TOKEN)
248
+ }
249
+
250
+ export function useCommandShortcut(command: string): Accessor<string> {
251
+ const config = useTuiConfig()
252
+ return useKeymapSelector((keymap: OpenTuiKeymap) =>
253
+ formatKeySequence(
254
+ keymap.getCommandBindings({ visibility: "registered", commands: [command] }).get(command)?.[0]?.sequence,
255
+ config,
256
+ ),
257
+ )
258
+ }
259
+
260
+ export function useCommandSlashes(): Accessor<readonly CommandSlashEntry[]> {
261
+ const keymap = useNeurocodeKeymap()
262
+ const entries = useKeymapSelector((keymap: OpenTuiKeymap) =>
263
+ keymap.getCommandEntries({
264
+ visibility: "reachable",
265
+ namespace: "palette",
266
+ filter: isVisiblePaletteCommand,
267
+ }),
268
+ )
269
+
270
+ return createMemo<CommandSlashEntry[]>(() =>
271
+ entries().flatMap((entry) => {
272
+ const slashName = entry.command.slashName
273
+ if (typeof slashName !== "string" || !slashName) return []
274
+ const slashAliases = entry.command.slashAliases
275
+ return {
276
+ display: `/${slashName}`,
277
+ description:
278
+ typeof entry.command.desc === "string"
279
+ ? entry.command.desc
280
+ : typeof entry.command.title === "string"
281
+ ? entry.command.title
282
+ : undefined,
283
+ aliases: Array.isArray(slashAliases)
284
+ ? slashAliases.filter((alias): alias is string => typeof alias === "string").map((alias) => `/${alias}`)
285
+ : undefined,
286
+ onSelect: () => keymap.dispatchCommand(entry.command.name),
287
+ }
288
+ }),
289
+ )
290
+ }
package/src/logo.ts ADDED
@@ -0,0 +1,11 @@
1
+ export const logo = {
2
+ left: [" ", "█▀▀▄ █▀▀█ █▀▀█ █▀▀▄ █▀▀█", "█__█ █^^^ █__█ █▀▀▀ █__█", "▀~~▀ ▀▀▀▀ ▀▀▀▀ ▀__▀ ▀▀▀▀"],
3
+ right: [" ▄ ", "█▀▀▀ █▀▀█ █▀▀▄ █▀▀█", "█___ █__█ █__█ █^^^", "▀▀▀▀ ▀▀▀▀ ▀▀▀▀ ▀▀▀▀"],
4
+ }
5
+
6
+ export const go = {
7
+ left: [" ", "█▀▀▀", "█_^█", "▀▀▀▀"],
8
+ right: [" ", "█▀▀█", "█__█", "▀▀▀▀"],
9
+ }
10
+
11
+ export const marks = "_^~,"
@@ -0,0 +1,386 @@
1
+ export default {
2
+ // NOTE: FOR markdown, javascript and typescript, we use the opentui built-in parsers
3
+ // Warn: when taking queries from the nvim-treesitter repo, make sure to include the query dependencies as well
4
+ // marked with for example `; inherits: ecma` at the top of the file. Just put the dependencies before the actual query.
5
+ // ALSO: Some queries use breaking changes in the nvim-treesitter repo, that are not compatible with the (web-)tree-sitter parser.
6
+ parsers: [
7
+ {
8
+ filetype: "python",
9
+ wasm: "https://github.com/tree-sitter/tree-sitter-python/releases/download/v0.23.6/tree-sitter-python.wasm",
10
+ queries: {
11
+ highlights: [
12
+ // NOTE: This nvim-treesitter query is currently broken, because the parser is not compatible with the query apparently.
13
+ // it is using "except" nodes that the parser is complaining about, but it has been in the query for 3+ years.
14
+ // Unclear.
15
+ // "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/python/highlights.scm",
16
+ "https://github.com/tree-sitter/tree-sitter-python/raw/refs/heads/master/queries/highlights.scm",
17
+ ],
18
+ locals: [
19
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/python/locals.scm",
20
+ ],
21
+ },
22
+ },
23
+ {
24
+ filetype: "rust",
25
+ wasm: "https://github.com/tree-sitter/tree-sitter-rust/releases/download/v0.24.0/tree-sitter-rust.wasm",
26
+ queries: {
27
+ highlights: [
28
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/rust/highlights.scm",
29
+ ],
30
+ locals: [
31
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/rust/locals.scm",
32
+ ],
33
+ },
34
+ },
35
+ {
36
+ filetype: "go",
37
+ wasm: "https://github.com/tree-sitter/tree-sitter-go/releases/download/v0.25.0/tree-sitter-go.wasm",
38
+ queries: {
39
+ highlights: [
40
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/go/highlights.scm",
41
+ ],
42
+ locals: [
43
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/go/locals.scm",
44
+ ],
45
+ },
46
+ },
47
+ {
48
+ filetype: "cpp",
49
+ wasm: "https://github.com/tree-sitter/tree-sitter-cpp/releases/download/v0.23.4/tree-sitter-cpp.wasm",
50
+ queries: {
51
+ highlights: [
52
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/cpp/highlights.scm",
53
+ ],
54
+ locals: [
55
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/cpp/locals.scm",
56
+ ],
57
+ },
58
+ },
59
+ {
60
+ filetype: "csharp",
61
+ wasm: "https://github.com/tree-sitter/tree-sitter-c-sharp/releases/download/v0.23.1/tree-sitter-c_sharp.wasm",
62
+ queries: {
63
+ highlights: [
64
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/c_sharp/highlights.scm",
65
+ ],
66
+ locals: [
67
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/c_sharp/locals.scm",
68
+ ],
69
+ },
70
+ },
71
+ {
72
+ filetype: "bash",
73
+ wasm: "https://github.com/tree-sitter/tree-sitter-bash/releases/download/v0.25.0/tree-sitter-bash.wasm",
74
+ queries: {
75
+ highlights: [
76
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/bash/highlights.scm",
77
+ ],
78
+ },
79
+ },
80
+ {
81
+ filetype: "c",
82
+ wasm: "https://github.com/tree-sitter/tree-sitter-c/releases/download/v0.24.1/tree-sitter-c.wasm",
83
+ queries: {
84
+ highlights: [
85
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/c/highlights.scm",
86
+ ],
87
+ locals: [
88
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/c/locals.scm",
89
+ ],
90
+ },
91
+ },
92
+ {
93
+ filetype: "java",
94
+ wasm: "https://github.com/tree-sitter/tree-sitter-java/releases/download/v0.23.5/tree-sitter-java.wasm",
95
+ queries: {
96
+ highlights: [
97
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/java/highlights.scm",
98
+ ],
99
+ locals: [
100
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/java/locals.scm",
101
+ ],
102
+ },
103
+ },
104
+ {
105
+ filetype: "kotlin",
106
+ wasm: "https://github.com/fwcd/tree-sitter-kotlin/releases/download/0.3.8/tree-sitter-kotlin.wasm",
107
+ queries: {
108
+ highlights: ["https://raw.githubusercontent.com/fwcd/tree-sitter-kotlin/0.3.8/queries/highlights.scm"],
109
+ locals: ["https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/master/queries/kotlin/locals.scm"],
110
+ },
111
+ },
112
+ {
113
+ filetype: "ruby",
114
+ wasm: "https://github.com/tree-sitter/tree-sitter-ruby/releases/download/v0.23.1/tree-sitter-ruby.wasm",
115
+ queries: {
116
+ highlights: [
117
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/ruby/highlights.scm",
118
+ ],
119
+ locals: [
120
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/ruby/locals.scm",
121
+ ],
122
+ },
123
+ },
124
+ {
125
+ filetype: "php",
126
+ wasm: "https://github.com/tree-sitter/tree-sitter-php/releases/download/v0.24.2/tree-sitter-php.wasm",
127
+ queries: {
128
+ highlights: [
129
+ // NOTE: This nvim-treesitter query is currently broken, because the parser is not compatible with the query apparently.
130
+ // "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/php/highlights.scm",
131
+ "https://github.com/tree-sitter/tree-sitter-php/raw/refs/heads/master/queries/highlights.scm",
132
+ ],
133
+ },
134
+ },
135
+ {
136
+ filetype: "scala",
137
+ wasm: "https://github.com/tree-sitter/tree-sitter-scala/releases/download/v0.24.0/tree-sitter-scala.wasm",
138
+ queries: {
139
+ highlights: [
140
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/scala/highlights.scm",
141
+ ],
142
+ },
143
+ },
144
+ {
145
+ filetype: "html",
146
+ wasm: "https://github.com/tree-sitter/tree-sitter-html/releases/download/v0.23.2/tree-sitter-html.wasm",
147
+ queries: {
148
+ highlights: [
149
+ // NOTE: This nvim-treesitter query is currently broken, because the parser is not compatible with the query apparently.
150
+ // "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/html/highlights.scm",
151
+ "https://github.com/tree-sitter/tree-sitter-html/raw/refs/heads/master/queries/highlights.scm",
152
+ ],
153
+ // TODO: Injections not working for some reason
154
+ // injections: [
155
+ // "https://github.com/tree-sitter/tree-sitter-html/raw/refs/heads/master/queries/injections.scm",
156
+ // ],
157
+ },
158
+ // injectionMapping: {
159
+ // nodeTypes: {
160
+ // script_element: "javascript",
161
+ // style_element: "css",
162
+ // },
163
+ // infoStringMap: {
164
+ // javascript: "javascript",
165
+ // css: "css",
166
+ // },
167
+ // },
168
+ },
169
+ {
170
+ filetype: "vue",
171
+ wasm: "https://github.com/anomalyco/tree-sitter-vue/releases/download/v0.1.2/tree-sitter-vue.wasm",
172
+ queries: {
173
+ highlights: [
174
+ "https://raw.githubusercontent.com/anomalyco/tree-sitter-vue/v0.1.2/queries/html_tags/highlights.scm",
175
+ "https://raw.githubusercontent.com/anomalyco/tree-sitter-vue/v0.1.2/queries/vue/highlights.scm",
176
+ ],
177
+ },
178
+ },
179
+ {
180
+ filetype: "hcl",
181
+ wasm: "https://github.com/tree-sitter-grammars/tree-sitter-hcl/releases/download/v1.2.0/tree-sitter-hcl.wasm",
182
+ queries: {
183
+ highlights: [
184
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/master/queries/hcl/highlights.scm",
185
+ ],
186
+ },
187
+ },
188
+ {
189
+ filetype: "json",
190
+ wasm: "https://github.com/tree-sitter/tree-sitter-json/releases/download/v0.24.8/tree-sitter-json.wasm",
191
+ queries: {
192
+ highlights: [
193
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/json/highlights.scm",
194
+ ],
195
+ },
196
+ },
197
+ {
198
+ filetype: "yaml",
199
+ wasm: "https://github.com/tree-sitter-grammars/tree-sitter-yaml/releases/download/v0.7.2/tree-sitter-yaml.wasm",
200
+ queries: {
201
+ highlights: [
202
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/yaml/highlights.scm",
203
+ ],
204
+ },
205
+ },
206
+ {
207
+ filetype: "haskell",
208
+ wasm: "https://github.com/tree-sitter/tree-sitter-haskell/releases/download/v0.23.1/tree-sitter-haskell.wasm",
209
+ queries: {
210
+ highlights: [
211
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/haskell/highlights.scm",
212
+ ],
213
+ },
214
+ },
215
+ {
216
+ filetype: "css",
217
+ wasm: "https://github.com/tree-sitter/tree-sitter-css/releases/download/v0.25.0/tree-sitter-css.wasm",
218
+ queries: {
219
+ highlights: [
220
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/css/highlights.scm",
221
+ ],
222
+ },
223
+ },
224
+ {
225
+ filetype: "julia",
226
+ wasm: "https://github.com/tree-sitter/tree-sitter-julia/releases/download/v0.23.1/tree-sitter-julia.wasm",
227
+ queries: {
228
+ highlights: [
229
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/julia/highlights.scm",
230
+ ],
231
+ },
232
+ },
233
+ {
234
+ filetype: "lua",
235
+ wasm: "https://github.com/tree-sitter-grammars/tree-sitter-lua/releases/download/v0.5.0/tree-sitter-lua.wasm",
236
+ queries: {
237
+ highlights: [
238
+ "https://raw.githubusercontent.com/tree-sitter-grammars/tree-sitter-lua/v0.5.0/queries/highlights.scm",
239
+ ],
240
+ locals: ["https://raw.githubusercontent.com/tree-sitter-grammars/tree-sitter-lua/v0.5.0/queries/locals.scm"],
241
+ },
242
+ },
243
+ {
244
+ filetype: "ocaml",
245
+ wasm: "https://github.com/tree-sitter/tree-sitter-ocaml/releases/download/v0.24.2/tree-sitter-ocaml.wasm",
246
+ queries: {
247
+ highlights: [
248
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/ocaml/highlights.scm",
249
+ ],
250
+ },
251
+ },
252
+ {
253
+ filetype: "clojure",
254
+ // temporarily using fork to fix issues
255
+ wasm: "https://github.com/anomalyco/tree-sitter-clojure/releases/download/v0.0.1/tree-sitter-clojure.wasm",
256
+ queries: {
257
+ highlights: [
258
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/clojure/highlights.scm",
259
+ ],
260
+ },
261
+ },
262
+ {
263
+ filetype: "swift",
264
+ wasm: "https://github.com/alex-pinkus/tree-sitter-swift/releases/download/0.7.1/tree-sitter-swift.wasm",
265
+ queries: {
266
+ highlights: [
267
+ // NOTE: Using parser repo queries instead of nvim-treesitter due to incompatible #lua-match? predicates
268
+ // "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/highlights.scm
269
+ "https://raw.githubusercontent.com/alex-pinkus/tree-sitter-swift/main/queries/highlights.scm",
270
+ ],
271
+ locals: [
272
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/swift/locals.scm",
273
+ ],
274
+ },
275
+ },
276
+ {
277
+ filetype: "toml",
278
+ wasm: "https://github.com/tree-sitter-grammars/tree-sitter-toml/releases/download/v0.7.0/tree-sitter-toml.wasm",
279
+ queries: {
280
+ highlights: [
281
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/master/queries/toml/highlights.scm",
282
+ ],
283
+ },
284
+ },
285
+ {
286
+ filetype: "nix",
287
+ // TODO: Replace with official tree-sitter-nix WASM when published
288
+ // See: https://github.com/nix-community/tree-sitter-nix/issues/66
289
+ wasm: "https://github.com/ast-grep/ast-grep.github.io/raw/40b84530640aa83a0d34a20a2b0623d7b8e5ea97/website/public/parsers/tree-sitter-nix.wasm",
290
+ queries: {
291
+ highlights: [
292
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/nix/highlights.scm",
293
+ ],
294
+ locals: [
295
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/nix/locals.scm",
296
+ ],
297
+ },
298
+ },
299
+ {
300
+ filetype: "diff",
301
+ aliases: ["udiff", "patch"],
302
+ wasm: "https://github.com/tree-sitter-grammars/tree-sitter-diff/releases/download/v0.1.0/tree-sitter-diff.wasm",
303
+ queries: {
304
+ highlights: [
305
+ "https://raw.githubusercontent.com/tree-sitter-grammars/tree-sitter-diff/master/queries/highlights.scm",
306
+ ],
307
+ },
308
+ },
309
+ {
310
+ filetype: "elixir",
311
+ wasm: "https://github.com/elixir-lang/tree-sitter-elixir/releases/download/v0.3.5/tree-sitter-elixir.wasm",
312
+ queries: {
313
+ highlights: [
314
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/elixir/highlights.scm",
315
+ ],
316
+ locals: [
317
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/elixir/locals.scm",
318
+ ],
319
+ },
320
+ },
321
+ {
322
+ filetype: "fsharp",
323
+ wasm: "https://github.com/ionide/tree-sitter-fsharp/releases/download/0.3.0/tree-sitter-fsharp.wasm",
324
+ queries: {
325
+ highlights: [
326
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/fsharp/highlights.scm",
327
+ ],
328
+ },
329
+ },
330
+ {
331
+ filetype: "r",
332
+ wasm: "https://github.com/r-lib/tree-sitter-r/releases/download/v1.2.0/tree-sitter-r.wasm",
333
+ queries: {
334
+ highlights: [
335
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/r/highlights.scm",
336
+ ],
337
+ locals: [
338
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/r/locals.scm",
339
+ ],
340
+ },
341
+ },
342
+ {
343
+ filetype: "make",
344
+ aliases: ["makefile"],
345
+ wasm: "https://github.com/tree-sitter-grammars/tree-sitter-make/releases/download/v1.1.1/tree-sitter-make.wasm",
346
+ queries: {
347
+ highlights: [
348
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/make/highlights.scm",
349
+ ],
350
+ },
351
+ },
352
+ {
353
+ filetype: "vim",
354
+ wasm: "https://github.com/tree-sitter-grammars/tree-sitter-vim/releases/download/v0.8.1/tree-sitter-vim.wasm",
355
+ queries: {
356
+ highlights: [
357
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/vim/highlights.scm",
358
+ ],
359
+ locals: [
360
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/vim/locals.scm",
361
+ ],
362
+ },
363
+ },
364
+ {
365
+ filetype: "xml",
366
+ wasm: "https://github.com/tree-sitter-grammars/tree-sitter-xml/releases/download/v0.7.0/tree-sitter-xml.wasm",
367
+ queries: {
368
+ highlights: [
369
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/xml/highlights.scm",
370
+ ],
371
+ locals: [
372
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/xml/locals.scm",
373
+ ],
374
+ },
375
+ },
376
+ {
377
+ filetype: "agda",
378
+ wasm: "https://github.com/tree-sitter/tree-sitter-agda/releases/download/v1.3.3/tree-sitter-agda.wasm",
379
+ queries: {
380
+ highlights: [
381
+ "https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/agda/highlights.scm",
382
+ ],
383
+ },
384
+ },
385
+ ],
386
+ }