nastechai-desktop 18.1.0

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 (546) hide show
  1. package/.prettierrc +11 -0
  2. package/DESIGN.md +167 -0
  3. package/README.md +141 -0
  4. package/assets/icon.icns +0 -0
  5. package/assets/icon.ico +0 -0
  6. package/assets/icon.png +0 -0
  7. package/components.json +21 -0
  8. package/electron/backend-env.cjs +112 -0
  9. package/electron/backend-env.test.cjs +111 -0
  10. package/electron/backend-probes.cjs +106 -0
  11. package/electron/backend-probes.test.cjs +82 -0
  12. package/electron/backend-ready.cjs +66 -0
  13. package/electron/bootstrap-platform.cjs +91 -0
  14. package/electron/bootstrap-platform.test.cjs +111 -0
  15. package/electron/bootstrap-runner.cjs +720 -0
  16. package/electron/bootstrap-runner.test.cjs +138 -0
  17. package/electron/connection-config.cjs +254 -0
  18. package/electron/connection-config.test.cjs +329 -0
  19. package/electron/dashboard-token.cjs +99 -0
  20. package/electron/dashboard-token.test.cjs +142 -0
  21. package/electron/desktop-uninstall.cjs +232 -0
  22. package/electron/desktop-uninstall.test.cjs +246 -0
  23. package/electron/entitlements.mac.inherit.plist +14 -0
  24. package/electron/entitlements.mac.plist +14 -0
  25. package/electron/fs-read-dir.cjs +109 -0
  26. package/electron/fs-read-dir.test.cjs +364 -0
  27. package/electron/gateway-ws-probe.cjs +188 -0
  28. package/electron/gateway-ws-probe.test.cjs +122 -0
  29. package/electron/git-root.cjs +54 -0
  30. package/electron/git-root.test.cjs +40 -0
  31. package/electron/git-worktrees.cjs +174 -0
  32. package/electron/hardening.cjs +184 -0
  33. package/electron/hardening.test.cjs +116 -0
  34. package/electron/main.cjs +5762 -0
  35. package/electron/oauth-net-request.cjs +20 -0
  36. package/electron/oauth-net-request.test.cjs +34 -0
  37. package/electron/preload.cjs +135 -0
  38. package/electron/session-windows.cjs +99 -0
  39. package/electron/session-windows.test.cjs +177 -0
  40. package/electron/update-remote.cjs +56 -0
  41. package/electron/update-remote.test.cjs +78 -0
  42. package/electron/vscode-marketplace.cjs +331 -0
  43. package/electron/vscode-marketplace.test.cjs +113 -0
  44. package/electron/windows-child-process.test.cjs +57 -0
  45. package/electron/windows-user-env.cjs +76 -0
  46. package/electron/windows-user-env.test.cjs +90 -0
  47. package/electron/workspace-cwd.cjs +38 -0
  48. package/electron/workspace-cwd.test.cjs +45 -0
  49. package/eslint.config.mjs +122 -0
  50. package/index.html +17 -0
  51. package/package.json +254 -0
  52. package/pr-assets/session-source-folders.png +0 -0
  53. package/preview-demo.html +65 -0
  54. package/public/apple-touch-icon.png +0 -0
  55. package/public/ds-assets/filler-bg0.jpg +0 -0
  56. package/public/nastech-frames/nastech-frame-0.png +0 -0
  57. package/public/nastech-frames/nastech-frame-1.png +0 -0
  58. package/public/nastech-frames/nastech-frame-2.png +0 -0
  59. package/public/nastech-frames/nastech-frame-3.png +0 -0
  60. package/public/nastech-frames/nastech-frame-4.png +0 -0
  61. package/public/nastech-frames/nastech-frame-5.png +0 -0
  62. package/public/nastech-frames/nastech-frame-6.png +0 -0
  63. package/public/nastech-frames/nastech-frame-7.png +0 -0
  64. package/public/nastech-girl.jpg +0 -0
  65. package/public/nastech-sprite.png +0 -0
  66. package/public/nastech.png +0 -0
  67. package/scripts/after-pack.cjs +41 -0
  68. package/scripts/assert-dist-built.cjs +70 -0
  69. package/scripts/assert-dist-built.test.cjs +84 -0
  70. package/scripts/assert-root-install.cjs +13 -0
  71. package/scripts/before-build.cjs +11 -0
  72. package/scripts/before-pack.cjs +78 -0
  73. package/scripts/before-pack.test.cjs +53 -0
  74. package/scripts/click-session.mjs +51 -0
  75. package/scripts/dev-no-hmr.mjs +22 -0
  76. package/scripts/diag-jump.mjs +115 -0
  77. package/scripts/diag-scroll-reset.mjs +229 -0
  78. package/scripts/eval.mjs +21 -0
  79. package/scripts/leak-typing.mjs +222 -0
  80. package/scripts/measure-jump.mjs +108 -0
  81. package/scripts/measure-latency.mjs +184 -0
  82. package/scripts/measure-real-stream.mjs +252 -0
  83. package/scripts/measure-submit.mjs +179 -0
  84. package/scripts/measure-synthetic-stream.mjs +322 -0
  85. package/scripts/notarize-artifact.cjs +77 -0
  86. package/scripts/notarize.cjs +100 -0
  87. package/scripts/patch-electron-builder-mac-binary.cjs +59 -0
  88. package/scripts/probe-renderer.mjs +38 -0
  89. package/scripts/probe-thread.mjs +40 -0
  90. package/scripts/profile-long-stream.mjs +191 -0
  91. package/scripts/profile-real-stream.mjs +137 -0
  92. package/scripts/profile-synth-stream.mjs +103 -0
  93. package/scripts/profile-typing-lag.md +381 -0
  94. package/scripts/profile-typing.mjs +260 -0
  95. package/scripts/reload-renderer.mjs +25 -0
  96. package/scripts/reload.mjs +36 -0
  97. package/scripts/set-exe-identity.cjs +94 -0
  98. package/scripts/stage-native-deps.cjs +159 -0
  99. package/scripts/test-desktop.mjs +425 -0
  100. package/scripts/write-build-stamp.cjs +126 -0
  101. package/src/app/agents/index.tsx +398 -0
  102. package/src/app/artifacts/index.test.ts +62 -0
  103. package/src/app/artifacts/index.tsx +906 -0
  104. package/src/app/chat/chat-drop-overlay.tsx +48 -0
  105. package/src/app/chat/chat-swap-overlay.tsx +47 -0
  106. package/src/app/chat/composer/attachments.tsx +114 -0
  107. package/src/app/chat/composer/completion-drawer.tsx +63 -0
  108. package/src/app/chat/composer/context-menu.tsx +172 -0
  109. package/src/app/chat/composer/controls.tsx +289 -0
  110. package/src/app/chat/composer/drop-affordance.ts +2 -0
  111. package/src/app/chat/composer/enter-submit-dom-race.test.tsx +218 -0
  112. package/src/app/chat/composer/focus.ts +134 -0
  113. package/src/app/chat/composer/help-hint.tsx +59 -0
  114. package/src/app/chat/composer/hooks/use-at-completions.ts +141 -0
  115. package/src/app/chat/composer/hooks/use-live-completion-adapter.ts +119 -0
  116. package/src/app/chat/composer/hooks/use-mic-recorder.ts +291 -0
  117. package/src/app/chat/composer/hooks/use-slash-completions.ts +114 -0
  118. package/src/app/chat/composer/hooks/use-voice-conversation.ts +390 -0
  119. package/src/app/chat/composer/hooks/use-voice-recorder.ts +116 -0
  120. package/src/app/chat/composer/ime-composition-dom-repro.test.tsx +108 -0
  121. package/src/app/chat/composer/index.tsx +1611 -0
  122. package/src/app/chat/composer/inline-refs.ts +138 -0
  123. package/src/app/chat/composer/model-pill.tsx +86 -0
  124. package/src/app/chat/composer/queue-panel.tsx +130 -0
  125. package/src/app/chat/composer/rich-editor.test.ts +18 -0
  126. package/src/app/chat/composer/rich-editor.ts +165 -0
  127. package/src/app/chat/composer/skin-slash-popover.tsx +61 -0
  128. package/src/app/chat/composer/slash-nav-dom-repro.test.tsx +186 -0
  129. package/src/app/chat/composer/status-stack/index.tsx +202 -0
  130. package/src/app/chat/composer/status-stack/status-row.tsx +155 -0
  131. package/src/app/chat/composer/text-utils.test.ts +77 -0
  132. package/src/app/chat/composer/text-utils.ts +107 -0
  133. package/src/app/chat/composer/trigger-popover.test.tsx +42 -0
  134. package/src/app/chat/composer/trigger-popover.tsx +116 -0
  135. package/src/app/chat/composer/types.ts +64 -0
  136. package/src/app/chat/composer/url-dialog.tsx +82 -0
  137. package/src/app/chat/composer/voice-activity.tsx +252 -0
  138. package/src/app/chat/hooks/use-composer-actions.test.ts +57 -0
  139. package/src/app/chat/hooks/use-composer-actions.ts +525 -0
  140. package/src/app/chat/hooks/use-file-drop-zone.ts +118 -0
  141. package/src/app/chat/index.tsx +390 -0
  142. package/src/app/chat/perf-probe.tsx +269 -0
  143. package/src/app/chat/right-rail/index.ts +1 -0
  144. package/src/app/chat/right-rail/preview-console-state.ts +82 -0
  145. package/src/app/chat/right-rail/preview-console.tsx +290 -0
  146. package/src/app/chat/right-rail/preview-file.tsx +559 -0
  147. package/src/app/chat/right-rail/preview-pane.test.tsx +43 -0
  148. package/src/app/chat/right-rail/preview-pane.tsx +657 -0
  149. package/src/app/chat/right-rail/preview.tsx +171 -0
  150. package/src/app/chat/scroll-to-bottom-button.test.tsx +67 -0
  151. package/src/app/chat/scroll-to-bottom-button.tsx +74 -0
  152. package/src/app/chat/sidebar/cron-jobs-section.tsx +325 -0
  153. package/src/app/chat/sidebar/index.tsx +1219 -0
  154. package/src/app/chat/sidebar/load-more-row.tsx +30 -0
  155. package/src/app/chat/sidebar/order.test.ts +21 -0
  156. package/src/app/chat/sidebar/order.ts +17 -0
  157. package/src/app/chat/sidebar/profile-switcher.tsx +516 -0
  158. package/src/app/chat/sidebar/session-actions-menu.tsx +264 -0
  159. package/src/app/chat/sidebar/session-row.tsx +257 -0
  160. package/src/app/chat/sidebar/virtual-session-list.tsx +154 -0
  161. package/src/app/chat/sidebar/workspace-groups.test.ts +149 -0
  162. package/src/app/chat/sidebar/workspace-groups.ts +326 -0
  163. package/src/app/chat/thread-loading.test.ts +34 -0
  164. package/src/app/chat/thread-loading.ts +26 -0
  165. package/src/app/command-center/index.tsx +654 -0
  166. package/src/app/command-palette/index.tsx +513 -0
  167. package/src/app/command-palette/marketplace-theme-page.tsx +157 -0
  168. package/src/app/cron/index.tsx +942 -0
  169. package/src/app/cron/job-state.ts +29 -0
  170. package/src/app/desktop-controller.tsx +938 -0
  171. package/src/app/floating-hud.ts +22 -0
  172. package/src/app/gateway/hooks/use-gateway-boot.test.tsx +265 -0
  173. package/src/app/gateway/hooks/use-gateway-boot.ts +387 -0
  174. package/src/app/gateway/hooks/use-gateway-request.ts +138 -0
  175. package/src/app/hooks/use-keybinds.ts +186 -0
  176. package/src/app/hooks/use-refresh-hotkey.ts +45 -0
  177. package/src/app/hooks/use-route-enum-param.ts +38 -0
  178. package/src/app/index.tsx +1 -0
  179. package/src/app/layout-constants.ts +13 -0
  180. package/src/app/messaging/index.tsx +648 -0
  181. package/src/app/messaging/platform-icon.tsx +93 -0
  182. package/src/app/model-picker-overlay.tsx +42 -0
  183. package/src/app/model-visibility-overlay.tsx +31 -0
  184. package/src/app/overlays/overlay-chrome.tsx +66 -0
  185. package/src/app/overlays/overlay-search-input.tsx +33 -0
  186. package/src/app/overlays/overlay-split-layout.tsx +130 -0
  187. package/src/app/overlays/overlay-view.tsx +91 -0
  188. package/src/app/page-search-shell.tsx +75 -0
  189. package/src/app/profiles/create-profile-dialog.tsx +154 -0
  190. package/src/app/profiles/delete-profile-dialog.tsx +65 -0
  191. package/src/app/profiles/index.tsx +671 -0
  192. package/src/app/profiles/rename-profile-dialog.tsx +125 -0
  193. package/src/app/right-sidebar/files/dnd-manager.ts +27 -0
  194. package/src/app/right-sidebar/files/ipc.test.ts +100 -0
  195. package/src/app/right-sidebar/files/ipc.ts +161 -0
  196. package/src/app/right-sidebar/files/remote-picker.tsx +177 -0
  197. package/src/app/right-sidebar/files/tree.tsx +224 -0
  198. package/src/app/right-sidebar/files/use-project-tree.test.ts +190 -0
  199. package/src/app/right-sidebar/files/use-project-tree.ts +268 -0
  200. package/src/app/right-sidebar/index.test.tsx +75 -0
  201. package/src/app/right-sidebar/index.tsx +395 -0
  202. package/src/app/right-sidebar/store.ts +15 -0
  203. package/src/app/right-sidebar/terminal/buffer.ts +65 -0
  204. package/src/app/right-sidebar/terminal/index.tsx +98 -0
  205. package/src/app/right-sidebar/terminal/persistent.tsx +122 -0
  206. package/src/app/right-sidebar/terminal/selection.ts +75 -0
  207. package/src/app/right-sidebar/terminal/use-terminal-session.ts +504 -0
  208. package/src/app/routes.ts +88 -0
  209. package/src/app/session/hooks/use-context-suggestions.ts +58 -0
  210. package/src/app/session/hooks/use-cwd-actions.ts +109 -0
  211. package/src/app/session/hooks/use-message-stream.ts +957 -0
  212. package/src/app/session/hooks/use-model-controls.test.tsx +198 -0
  213. package/src/app/session/hooks/use-model-controls.ts +106 -0
  214. package/src/app/session/hooks/use-nastech-config.ts +74 -0
  215. package/src/app/session/hooks/use-preview-routing.test.tsx +168 -0
  216. package/src/app/session/hooks/use-preview-routing.ts +223 -0
  217. package/src/app/session/hooks/use-prompt-actions.test.tsx +316 -0
  218. package/src/app/session/hooks/use-prompt-actions.ts +1030 -0
  219. package/src/app/session/hooks/use-route-resume.test.tsx +136 -0
  220. package/src/app/session/hooks/use-route-resume.ts +115 -0
  221. package/src/app/session/hooks/use-session-actions.test.tsx +119 -0
  222. package/src/app/session/hooks/use-session-actions.ts +885 -0
  223. package/src/app/session/hooks/use-session-state-cache.test.tsx +118 -0
  224. package/src/app/session/hooks/use-session-state-cache.ts +191 -0
  225. package/src/app/session-picker-overlay.tsx +32 -0
  226. package/src/app/session-switcher.tsx +107 -0
  227. package/src/app/settings/about-settings.tsx +173 -0
  228. package/src/app/settings/appearance-settings.tsx +162 -0
  229. package/src/app/settings/config-settings.tsx +384 -0
  230. package/src/app/settings/constants.ts +545 -0
  231. package/src/app/settings/credential-key-ui.tsx +373 -0
  232. package/src/app/settings/env-credentials.tsx +198 -0
  233. package/src/app/settings/env-var-actions-menu.tsx +136 -0
  234. package/src/app/settings/field-copy.ts +56 -0
  235. package/src/app/settings/gateway-settings.tsx +620 -0
  236. package/src/app/settings/helpers.test.ts +138 -0
  237. package/src/app/settings/helpers.ts +151 -0
  238. package/src/app/settings/index.tsx +237 -0
  239. package/src/app/settings/keys-settings.tsx +96 -0
  240. package/src/app/settings/mcp-settings.tsx +271 -0
  241. package/src/app/settings/model-settings.test.tsx +157 -0
  242. package/src/app/settings/model-settings.tsx +559 -0
  243. package/src/app/settings/notifications-settings.tsx +150 -0
  244. package/src/app/settings/primitives.tsx +115 -0
  245. package/src/app/settings/providers-settings.test.tsx +100 -0
  246. package/src/app/settings/providers-settings.tsx +258 -0
  247. package/src/app/settings/sessions-settings.tsx +276 -0
  248. package/src/app/settings/toolset-config-panel.test.tsx +289 -0
  249. package/src/app/settings/toolset-config-panel.tsx +449 -0
  250. package/src/app/settings/types.ts +42 -0
  251. package/src/app/settings/uninstall-section.tsx +185 -0
  252. package/src/app/settings/use-deep-link-highlight.ts +60 -0
  253. package/src/app/shell/app-shell.tsx +167 -0
  254. package/src/app/shell/gateway-menu-panel.tsx +150 -0
  255. package/src/app/shell/hooks/use-overlay-routing.ts +71 -0
  256. package/src/app/shell/hooks/use-status-snapshot.ts +57 -0
  257. package/src/app/shell/hooks/use-statusbar-items.tsx +403 -0
  258. package/src/app/shell/keybind-panel.tsx +220 -0
  259. package/src/app/shell/model-edit-submenu.test.tsx +84 -0
  260. package/src/app/shell/model-edit-submenu.tsx +245 -0
  261. package/src/app/shell/model-menu-panel.tsx +295 -0
  262. package/src/app/shell/sidebar-label.tsx +22 -0
  263. package/src/app/shell/statusbar-controls.tsx +185 -0
  264. package/src/app/shell/titlebar-controls.tsx +244 -0
  265. package/src/app/shell/titlebar.test.ts +26 -0
  266. package/src/app/shell/titlebar.ts +45 -0
  267. package/src/app/shell/use-group-registry.ts +39 -0
  268. package/src/app/skills/index.test.tsx +103 -0
  269. package/src/app/skills/index.tsx +371 -0
  270. package/src/app/types.ts +99 -0
  271. package/src/app/updates-overlay.tsx +369 -0
  272. package/src/components/Backdrop.tsx +114 -0
  273. package/src/components/assistant-ui/ansi-text.tsx +34 -0
  274. package/src/components/assistant-ui/clarify-tool.tsx +281 -0
  275. package/src/components/assistant-ui/directive-text.test.ts +39 -0
  276. package/src/components/assistant-ui/directive-text.tsx +389 -0
  277. package/src/components/assistant-ui/markdown-text.test.ts +204 -0
  278. package/src/components/assistant-ui/markdown-text.tsx +497 -0
  279. package/src/components/assistant-ui/message-render-boundary.test.tsx +80 -0
  280. package/src/components/assistant-ui/message-render-boundary.tsx +48 -0
  281. package/src/components/assistant-ui/streaming.test.tsx +739 -0
  282. package/src/components/assistant-ui/thread-list.tsx +307 -0
  283. package/src/components/assistant-ui/thread-virtualizer.tsx +512 -0
  284. package/src/components/assistant-ui/thread.tsx +1474 -0
  285. package/src/components/assistant-ui/todo-tool.tsx +109 -0
  286. package/src/components/assistant-ui/tool-approval-group.test.tsx +158 -0
  287. package/src/components/assistant-ui/tool-approval.test.tsx +81 -0
  288. package/src/components/assistant-ui/tool-approval.tsx +209 -0
  289. package/src/components/assistant-ui/tool-fallback-model.test.ts +66 -0
  290. package/src/components/assistant-ui/tool-fallback-model.ts +1368 -0
  291. package/src/components/assistant-ui/tool-fallback.tsx +466 -0
  292. package/src/components/assistant-ui/tooltip-icon-button.tsx +33 -0
  293. package/src/components/assistant-ui/user-message-edit.test.tsx +141 -0
  294. package/src/components/assistant-ui/user-message-text.tsx +150 -0
  295. package/src/components/boot-failure-overlay.tsx +246 -0
  296. package/src/components/boot-failure-reauth.test.ts +100 -0
  297. package/src/components/boot-failure-reauth.ts +81 -0
  298. package/src/components/brand-mark.tsx +19 -0
  299. package/src/components/chat/activity-timer-text.tsx +24 -0
  300. package/src/components/chat/activity-timer.test.tsx +43 -0
  301. package/src/components/chat/activity-timer.ts +64 -0
  302. package/src/components/chat/code-card.tsx +78 -0
  303. package/src/components/chat/compact-markdown.tsx +113 -0
  304. package/src/components/chat/composer-dock.ts +31 -0
  305. package/src/components/chat/diff-lines.tsx +54 -0
  306. package/src/components/chat/disclosure-row.tsx +63 -0
  307. package/src/components/chat/generated-image-context.tsx +19 -0
  308. package/src/components/chat/generated-image-result.tsx +174 -0
  309. package/src/components/chat/image-generation-placeholder.tsx +279 -0
  310. package/src/components/chat/intro-copy.jsonl +75 -0
  311. package/src/components/chat/intro.tsx +182 -0
  312. package/src/components/chat/preview-attachment.tsx +125 -0
  313. package/src/components/chat/shiki-highlighter.tsx +107 -0
  314. package/src/components/chat/status-row.tsx +70 -0
  315. package/src/components/chat/status-section.tsx +42 -0
  316. package/src/components/chat/terminal-output.tsx +50 -0
  317. package/src/components/chat/zoomable-image.tsx +177 -0
  318. package/src/components/desktop-install-overlay.tsx +595 -0
  319. package/src/components/desktop-onboarding-overlay.test.tsx +100 -0
  320. package/src/components/desktop-onboarding-overlay.tsx +1286 -0
  321. package/src/components/error-boundary.tsx +77 -0
  322. package/src/components/gateway-connecting-overlay.test.tsx +143 -0
  323. package/src/components/gateway-connecting-overlay.tsx +183 -0
  324. package/src/components/haptics-provider.tsx +19 -0
  325. package/src/components/language-switcher.test.tsx +53 -0
  326. package/src/components/language-switcher.tsx +175 -0
  327. package/src/components/model-picker.tsx +340 -0
  328. package/src/components/model-visibility-dialog.tsx +155 -0
  329. package/src/components/notifications.tsx +196 -0
  330. package/src/components/page-loader.tsx +34 -0
  331. package/src/components/pane-shell/context.ts +14 -0
  332. package/src/components/pane-shell/index.ts +4 -0
  333. package/src/components/pane-shell/pane-shell.test.tsx +333 -0
  334. package/src/components/pane-shell/pane-shell.tsx +330 -0
  335. package/src/components/prompt-overlays.tsx +234 -0
  336. package/src/components/session-picker.tsx +108 -0
  337. package/src/components/status-dot.tsx +26 -0
  338. package/src/components/ui/action-status.tsx +25 -0
  339. package/src/components/ui/alert.tsx +53 -0
  340. package/src/components/ui/badge.tsx +35 -0
  341. package/src/components/ui/braille-spinner.tsx +61 -0
  342. package/src/components/ui/button.tsx +81 -0
  343. package/src/components/ui/checkbox.tsx +27 -0
  344. package/src/components/ui/codicon.tsx +20 -0
  345. package/src/components/ui/command.tsx +111 -0
  346. package/src/components/ui/confirm-dialog.tsx +109 -0
  347. package/src/components/ui/context-menu.tsx +141 -0
  348. package/src/components/ui/control.ts +25 -0
  349. package/src/components/ui/copy-button.test.tsx +36 -0
  350. package/src/components/ui/copy-button.tsx +229 -0
  351. package/src/components/ui/dialog.tsx +152 -0
  352. package/src/components/ui/disclosure-caret.tsx +20 -0
  353. package/src/components/ui/dropdown-menu.tsx +291 -0
  354. package/src/components/ui/error-state.tsx +50 -0
  355. package/src/components/ui/fade-text.tsx +110 -0
  356. package/src/components/ui/glyph-spinner.tsx +63 -0
  357. package/src/components/ui/input.tsx +22 -0
  358. package/src/components/ui/kbd.tsx +37 -0
  359. package/src/components/ui/loader.tsx +558 -0
  360. package/src/components/ui/log-view.tsx +17 -0
  361. package/src/components/ui/pagination.tsx +114 -0
  362. package/src/components/ui/popover.tsx +44 -0
  363. package/src/components/ui/scroll-area.tsx +43 -0
  364. package/src/components/ui/search-field.tsx +80 -0
  365. package/src/components/ui/segmented-control.tsx +51 -0
  366. package/src/components/ui/select.tsx +92 -0
  367. package/src/components/ui/separator.tsx +26 -0
  368. package/src/components/ui/sheet.tsx +116 -0
  369. package/src/components/ui/sidebar.tsx +674 -0
  370. package/src/components/ui/skeleton.tsx +7 -0
  371. package/src/components/ui/switch.tsx +49 -0
  372. package/src/components/ui/tabs.tsx +36 -0
  373. package/src/components/ui/text-tab.tsx +43 -0
  374. package/src/components/ui/textarea.tsx +11 -0
  375. package/src/components/ui/tool-icon.tsx +65 -0
  376. package/src/components/ui/tooltip.tsx +69 -0
  377. package/src/fonts/JetBrainsMono-Bold.woff2 +0 -0
  378. package/src/fonts/JetBrainsMono-Italic.woff2 +0 -0
  379. package/src/fonts/JetBrainsMono-Regular.woff2 +0 -0
  380. package/src/global.d.ts +457 -0
  381. package/src/hooks/use-image-download.ts +85 -0
  382. package/src/hooks/use-media-query.ts +24 -0
  383. package/src/hooks/use-mobile.ts +3 -0
  384. package/src/hooks/use-resize-observer.ts +38 -0
  385. package/src/hooks/use-worktree-info.ts +68 -0
  386. package/src/i18n/catalog.ts +12 -0
  387. package/src/i18n/context.test.tsx +232 -0
  388. package/src/i18n/context.tsx +183 -0
  389. package/src/i18n/define-locale.ts +41 -0
  390. package/src/i18n/en.ts +1779 -0
  391. package/src/i18n/index.ts +20 -0
  392. package/src/i18n/ja.ts +1890 -0
  393. package/src/i18n/languages.test.ts +43 -0
  394. package/src/i18n/languages.ts +86 -0
  395. package/src/i18n/runtime.test.ts +75 -0
  396. package/src/i18n/runtime.ts +53 -0
  397. package/src/i18n/types.ts +1452 -0
  398. package/src/i18n/zh-hant.ts +1849 -0
  399. package/src/i18n/zh.ts +1923 -0
  400. package/src/lib/ansi.test.ts +123 -0
  401. package/src/lib/ansi.ts +175 -0
  402. package/src/lib/chat-messages.test.ts +708 -0
  403. package/src/lib/chat-messages.ts +885 -0
  404. package/src/lib/chat-runtime.test.ts +18 -0
  405. package/src/lib/chat-runtime.ts +335 -0
  406. package/src/lib/clipboard.ts +28 -0
  407. package/src/lib/commit-changelog.test.ts +114 -0
  408. package/src/lib/commit-changelog.ts +177 -0
  409. package/src/lib/completion-sound.ts +519 -0
  410. package/src/lib/desktop-fs.test.ts +116 -0
  411. package/src/lib/desktop-fs.ts +113 -0
  412. package/src/lib/desktop-slash-commands.test.ts +126 -0
  413. package/src/lib/desktop-slash-commands.ts +286 -0
  414. package/src/lib/embedded-images.test.ts +35 -0
  415. package/src/lib/embedded-images.ts +60 -0
  416. package/src/lib/external-link.test.tsx +168 -0
  417. package/src/lib/external-link.tsx +303 -0
  418. package/src/lib/gateway-events.test.ts +27 -0
  419. package/src/lib/gateway-events.ts +49 -0
  420. package/src/lib/gateway-ws-url.test.ts +78 -0
  421. package/src/lib/gateway-ws-url.ts +91 -0
  422. package/src/lib/generated-images.test.ts +97 -0
  423. package/src/lib/generated-images.ts +116 -0
  424. package/src/lib/haptics.ts +129 -0
  425. package/src/lib/icons.ts +203 -0
  426. package/src/lib/incremental-external-store-runtime.ts +188 -0
  427. package/src/lib/katex-memo.ts +260 -0
  428. package/src/lib/keybinds/actions.ts +125 -0
  429. package/src/lib/keybinds/combo.test.ts +86 -0
  430. package/src/lib/keybinds/combo.ts +169 -0
  431. package/src/lib/local-preview.ts +126 -0
  432. package/src/lib/markdown-code.test.ts +23 -0
  433. package/src/lib/markdown-code.ts +195 -0
  434. package/src/lib/markdown-preprocess.ts +386 -0
  435. package/src/lib/media.remote.test.ts +58 -0
  436. package/src/lib/media.ts +111 -0
  437. package/src/lib/model-status-label.test.ts +31 -0
  438. package/src/lib/model-status-label.ts +103 -0
  439. package/src/lib/mutable-ref.ts +6 -0
  440. package/src/lib/preview-targets.test.ts +27 -0
  441. package/src/lib/preview-targets.ts +63 -0
  442. package/src/lib/profile-color.ts +58 -0
  443. package/src/lib/provider-setup-errors.test.ts +26 -0
  444. package/src/lib/provider-setup-errors.ts +12 -0
  445. package/src/lib/query-client.ts +13 -0
  446. package/src/lib/remend-tail.test.ts +105 -0
  447. package/src/lib/remend-tail.ts +108 -0
  448. package/src/lib/runtime-readiness.test.ts +65 -0
  449. package/src/lib/runtime-readiness.ts +147 -0
  450. package/src/lib/session-export.ts +57 -0
  451. package/src/lib/session-search.test.ts +58 -0
  452. package/src/lib/session-search.ts +19 -0
  453. package/src/lib/session-source.ts +62 -0
  454. package/src/lib/speech-text.ts +35 -0
  455. package/src/lib/statusbar.ts +91 -0
  456. package/src/lib/storage.test.ts +25 -0
  457. package/src/lib/storage.ts +107 -0
  458. package/src/lib/todos.test.ts +35 -0
  459. package/src/lib/todos.ts +51 -0
  460. package/src/lib/tool-result-summary.test.ts +106 -0
  461. package/src/lib/tool-result-summary.ts +467 -0
  462. package/src/lib/update-copy.test.ts +38 -0
  463. package/src/lib/update-copy.ts +44 -0
  464. package/src/lib/use-enter-animation.ts +100 -0
  465. package/src/lib/utils.ts +6 -0
  466. package/src/lib/voice-playback.ts +128 -0
  467. package/src/lib/yolo-session.ts +26 -0
  468. package/src/main.tsx +43 -0
  469. package/src/nastech.test.ts +49 -0
  470. package/src/nastech.ts +718 -0
  471. package/src/store/activity.ts +100 -0
  472. package/src/store/boot.ts +91 -0
  473. package/src/store/clarify.test.ts +81 -0
  474. package/src/store/clarify.ts +69 -0
  475. package/src/store/command-palette.ts +20 -0
  476. package/src/store/compaction.test.ts +53 -0
  477. package/src/store/compaction.ts +38 -0
  478. package/src/store/completion-sound.ts +32 -0
  479. package/src/store/composer-input-history.test.ts +147 -0
  480. package/src/store/composer-input-history.ts +158 -0
  481. package/src/store/composer-queue.test.ts +148 -0
  482. package/src/store/composer-queue.ts +239 -0
  483. package/src/store/composer-status.test.ts +99 -0
  484. package/src/store/composer-status.ts +277 -0
  485. package/src/store/composer.test.ts +106 -0
  486. package/src/store/composer.ts +184 -0
  487. package/src/store/cron.ts +19 -0
  488. package/src/store/gateway.ts +290 -0
  489. package/src/store/haptics.ts +17 -0
  490. package/src/store/keybinds.ts +139 -0
  491. package/src/store/layout.ts +176 -0
  492. package/src/store/model-presets.test.ts +51 -0
  493. package/src/store/model-presets.ts +86 -0
  494. package/src/store/model-visibility.test.ts +37 -0
  495. package/src/store/model-visibility.ts +108 -0
  496. package/src/store/native-notifications.test.ts +192 -0
  497. package/src/store/native-notifications.ts +203 -0
  498. package/src/store/notifications.ts +165 -0
  499. package/src/store/onboarding.test.ts +372 -0
  500. package/src/store/onboarding.ts +866 -0
  501. package/src/store/panes.test.ts +146 -0
  502. package/src/store/panes.ts +145 -0
  503. package/src/store/preview.test.ts +135 -0
  504. package/src/store/preview.ts +466 -0
  505. package/src/store/profile.test.ts +89 -0
  506. package/src/store/profile.ts +365 -0
  507. package/src/store/prompts.test.ts +121 -0
  508. package/src/store/prompts.ts +115 -0
  509. package/src/store/session-switcher.test.ts +115 -0
  510. package/src/store/session-switcher.ts +128 -0
  511. package/src/store/session-sync.ts +25 -0
  512. package/src/store/session.test.ts +131 -0
  513. package/src/store/session.ts +255 -0
  514. package/src/store/subagents.test.ts +111 -0
  515. package/src/store/subagents.ts +260 -0
  516. package/src/store/thread-scroll.ts +46 -0
  517. package/src/store/todos.test.ts +47 -0
  518. package/src/store/todos.ts +64 -0
  519. package/src/store/tool-diffs.ts +23 -0
  520. package/src/store/tool-dismiss.ts +45 -0
  521. package/src/store/tool-view.ts +91 -0
  522. package/src/store/translucency.ts +38 -0
  523. package/src/store/updates.test.ts +77 -0
  524. package/src/store/updates.ts +315 -0
  525. package/src/store/voice-playback.ts +24 -0
  526. package/src/store/windows.test.ts +143 -0
  527. package/src/store/windows.ts +77 -0
  528. package/src/styles.css +1235 -0
  529. package/src/themes/color.ts +142 -0
  530. package/src/themes/context.tsx +339 -0
  531. package/src/themes/index.ts +3 -0
  532. package/src/themes/install.test.ts +119 -0
  533. package/src/themes/install.ts +95 -0
  534. package/src/themes/presets.test.ts +33 -0
  535. package/src/themes/presets.ts +293 -0
  536. package/src/themes/profile-theme.test.ts +41 -0
  537. package/src/themes/types.ts +66 -0
  538. package/src/themes/use-skin-command.ts +60 -0
  539. package/src/themes/user-themes.test.ts +63 -0
  540. package/src/themes/user-themes.ts +122 -0
  541. package/src/themes/vscode.test.ts +171 -0
  542. package/src/themes/vscode.ts +343 -0
  543. package/src/types/nastech.ts +646 -0
  544. package/src/vite-env.d.ts +1 -0
  545. package/tsconfig.json +25 -0
  546. package/vite.config.ts +56 -0
package/src/i18n/en.ts ADDED
@@ -0,0 +1,1779 @@
1
+ import { FIELD_DESCRIPTIONS, FIELD_LABELS } from '@/app/settings/constants'
2
+
3
+ import type { Translations } from './types'
4
+
5
+ export const en: Translations = {
6
+ common: {
7
+ apply: 'Apply',
8
+ back: 'Back',
9
+ save: 'Save',
10
+ saving: 'Saving…',
11
+ cancel: 'Cancel',
12
+ change: 'Change',
13
+ choose: 'Choose',
14
+ clear: 'Clear',
15
+ close: 'Close',
16
+ collapse: 'Collapse',
17
+ confirm: 'Confirm',
18
+ connect: 'Connect',
19
+ connecting: 'Connecting',
20
+ continue: 'Continue',
21
+ copied: 'Copied',
22
+ copy: 'Copy',
23
+ copyFailed: 'Copy failed',
24
+ delete: 'Delete',
25
+ docs: 'Docs',
26
+ done: 'Done',
27
+ error: 'Error',
28
+ failed: 'Failed',
29
+ free: 'Free',
30
+ loading: 'Loading…',
31
+ notSet: 'Not set',
32
+ refresh: 'Refresh',
33
+ remove: 'Remove',
34
+ replace: 'Replace',
35
+ retry: 'Retry',
36
+ run: 'Run',
37
+ send: 'Send',
38
+ set: 'Set',
39
+ skip: 'Skip',
40
+ update: 'Update',
41
+ on: 'On',
42
+ off: 'Off'
43
+ },
44
+
45
+ boot: {
46
+ ready: 'NasTech Desktop is ready',
47
+ desktopBootFailedWithMessage: message => `Desktop boot failed: ${message}`,
48
+ steps: {
49
+ connectingGateway: 'Connecting live desktop gateway',
50
+ loadingSettings: 'Loading NasTech settings',
51
+ loadingSessions: 'Loading recent sessions',
52
+ startingDesktopConnection: 'Starting desktop connection',
53
+ startingNasTechDesktop: 'Starting NasTech Desktop…'
54
+ },
55
+ errors: {
56
+ backgroundExited: 'NasTech background process exited.',
57
+ backgroundExitedDuringStartup: 'NasTech background process exited during startup.',
58
+ backendStopped: 'Backend stopped',
59
+ desktopBootFailed: 'Desktop boot failed',
60
+ gatewaySignInRequired: 'Gateway sign-in required',
61
+ ipcBridgeUnavailable: 'Desktop IPC bridge is unavailable.'
62
+ },
63
+ failure: {
64
+ title: "NasTech couldn't start",
65
+ description:
66
+ "The background gateway didn't come up. Try one of the recovery steps below. Nothing here deletes your chats or settings.",
67
+ remoteTitle: 'Remote gateway sign-in required',
68
+ remoteDescription:
69
+ 'Your remote gateway session has expired. Sign in again to reconnect. Nothing here deletes your chats or settings.',
70
+ retry: 'Retry',
71
+ repairInstall: 'Repair install',
72
+ useLocalGateway: 'Use local gateway',
73
+ openLogs: 'Open logs',
74
+ repairHint: 'Repair re-runs the installer and can take a few minutes on a fresh machine.',
75
+ remoteSignInHint: 'Opens the gateway login window. Use local gateway to switch to the bundled backend instead.',
76
+ hideRecentLogs: 'Hide recent logs',
77
+ showRecentLogs: 'Show recent logs',
78
+ signedInTitle: 'Signed in',
79
+ signedInMessage: 'Reconnecting to the remote gateway…',
80
+ signInIncompleteTitle: 'Sign-in incomplete',
81
+ signInIncompleteMessage: 'The login window closed before authentication finished.',
82
+ signInFailed: 'Sign-in failed',
83
+ signInToRemoteGateway: 'Sign in to remote gateway',
84
+ signInWithProvider: provider => `Sign in with ${provider}`,
85
+ identityProvider: 'your identity provider'
86
+ }
87
+ },
88
+
89
+ notifications: {
90
+ region: 'Notifications',
91
+ hide: 'Hide',
92
+ show: 'Show',
93
+ more: count => `${count} more ${count === 1 ? 'notification' : 'notifications'}`,
94
+ clearAll: 'Clear all',
95
+ dismiss: 'Dismiss notification',
96
+ details: 'Details',
97
+ copyDetail: 'Copy detail',
98
+ copyDetailFailed: 'Could not copy notification detail',
99
+ backendOutOfDateTitle: 'Backend out of date',
100
+ backendOutOfDateMessage:
101
+ 'Your NasTech backend is older than this desktop build and may not work correctly. Update to align them.',
102
+ updateNasTech: 'Update NasTech',
103
+ updateReadyTitle: 'Update ready',
104
+ updateReadyMessage: count => `${count} new change${count === 1 ? '' : 's'} available.`,
105
+ seeWhatsNew: "See what's new",
106
+ errors: {
107
+ elevenLabsNeedsKey: 'ElevenLabs STT needs ELEVENLABS_API_KEY.',
108
+ elevenLabsRejectedKey: 'ElevenLabs rejected the API key (401).',
109
+ methodNotAllowed:
110
+ 'The desktop backend rejected that request (405 Method Not Allowed). Try restarting NasTech Desktop.',
111
+ microphonePermission: 'Microphone permission was denied.',
112
+ openaiRejectedApiKey: 'OpenAI rejected the API key.',
113
+ openaiRejectedApiKeyWithStatus: status => `OpenAI rejected the API key (${status} invalid_api_key).`,
114
+ openaiTtsNeedsKey: 'OpenAI TTS needs VOICE_TOOLS_OPENAI_KEY or OPENAI_API_KEY.'
115
+ },
116
+ voice: {
117
+ configureSpeechToText: 'Configure speech-to-text to use voice mode.',
118
+ couldNotStartSession: 'Could not start voice session',
119
+ microphoneAccessDenied: 'Microphone access denied.',
120
+ microphoneConstraintsUnsupported: 'Microphone constraints are not supported by this device.',
121
+ microphoneFailed: 'Microphone failed',
122
+ microphoneInUse: 'Microphone is already in use by another app.',
123
+ microphonePermissionDenied: 'Microphone permission was denied.',
124
+ microphoneStartFailed: 'Could not start microphone recording.',
125
+ microphoneUnsupported: 'This runtime does not support microphone recording.',
126
+ noMicrophone: 'No microphone was found.',
127
+ noSpeechDetected: 'No speech detected',
128
+ playbackFailed: 'Voice playback failed',
129
+ recordingFailed: 'Voice recording failed',
130
+ transcriptionFailed: 'Voice transcription failed',
131
+ transcriptionUnavailable: 'Voice transcription is not available yet.',
132
+ tryRecordingAgain: 'Try recording again.',
133
+ unavailable: 'Voice unavailable'
134
+ }
135
+ },
136
+
137
+ titlebar: {
138
+ hideSidebar: 'Hide sidebar',
139
+ showSidebar: 'Show sidebar',
140
+ search: 'Search',
141
+ searchTitle: 'Search sessions, views, and actions',
142
+ swapSidebarSides: 'Swap sidebar sides',
143
+ swapSidebarSidesTitle: 'Swap the sessions and file browser sides',
144
+ hideRightSidebar: 'Hide right sidebar',
145
+ showRightSidebar: 'Show right sidebar',
146
+ muteHaptics: 'Mute haptics',
147
+ unmuteHaptics: 'Unmute haptics',
148
+ openSettings: 'Open settings',
149
+ openKeybinds: 'Keyboard shortcuts'
150
+ },
151
+
152
+ keybinds: {
153
+ title: 'Keyboard shortcuts',
154
+ subtitle: open => `Click a shortcut to rebind it · ${open} reopens this panel.`,
155
+ rebind: 'Rebind',
156
+ reset: 'Reset to default',
157
+ resetAll: 'Reset all',
158
+ pressKey: 'Press a key…',
159
+ set: 'set',
160
+ conflictWith: label => `Also bound to “${label}”`,
161
+ categories: {
162
+ composer: 'Composer',
163
+ profiles: 'Profiles',
164
+ session: 'Session',
165
+ navigation: 'Navigation',
166
+ view: 'View'
167
+ },
168
+ actions: {
169
+ 'keybinds.openPanel': 'Open keyboard shortcuts',
170
+ 'nav.commandPalette': 'Open command palette',
171
+ 'nav.commandCenter': 'Open command center',
172
+ 'nav.settings': 'Open settings',
173
+ 'nav.profiles': 'Open profiles',
174
+ 'nav.skills': 'Open skills',
175
+ 'nav.messaging': 'Open messaging',
176
+ 'nav.artifacts': 'Open artifacts',
177
+ 'nav.cron': 'Open scheduled jobs',
178
+ 'nav.agents': 'Open agents',
179
+ 'session.new': 'New session',
180
+ 'session.next': 'Next session',
181
+ 'session.prev': 'Previous session',
182
+ 'session.focusSearch': 'Search sessions',
183
+ 'session.togglePin': 'Pin / unpin current session',
184
+ 'composer.focus': 'Focus composer',
185
+ 'composer.modelPicker': 'Open model picker',
186
+ 'view.toggleSidebar': 'Toggle sessions sidebar',
187
+ 'view.toggleRightSidebar': 'Toggle file browser',
188
+ 'view.showFiles': 'Show file browser',
189
+ 'view.showTerminal': 'Show terminal',
190
+ 'view.terminalSelection': 'Send terminal selection to composer',
191
+ 'view.closePreviewTab': 'Close preview tab',
192
+ 'view.flipPanes': 'Swap sidebar sides',
193
+ 'appearance.toggleMode': 'Toggle light / dark',
194
+ 'profile.default': 'Switch to default profile',
195
+ 'profile.switch.1': 'Switch to profile 1',
196
+ 'profile.switch.2': 'Switch to profile 2',
197
+ 'profile.switch.3': 'Switch to profile 3',
198
+ 'profile.switch.4': 'Switch to profile 4',
199
+ 'profile.switch.5': 'Switch to profile 5',
200
+ 'profile.switch.6': 'Switch to profile 6',
201
+ 'profile.switch.7': 'Switch to profile 7',
202
+ 'profile.switch.8': 'Switch to profile 8',
203
+ 'profile.switch.9': 'Switch to profile 9',
204
+ 'profile.switch.10': 'Switch to profile 10',
205
+ 'profile.switch.11': 'Switch to profile 11',
206
+ 'profile.switch.12': 'Switch to profile 12',
207
+ 'profile.switch.13': 'Switch to profile 13',
208
+ 'profile.switch.14': 'Switch to profile 14',
209
+ 'profile.switch.15': 'Switch to profile 15',
210
+ 'profile.switch.16': 'Switch to profile 16',
211
+ 'profile.switch.17': 'Switch to profile 17',
212
+ 'profile.switch.18': 'Switch to profile 18',
213
+ 'profile.next': 'Next profile',
214
+ 'profile.prev': 'Previous profile',
215
+ 'profile.toggleAll': 'Toggle all-profiles view',
216
+ 'profile.create': 'Create profile',
217
+ 'composer.send': 'Send message',
218
+ 'composer.newline': 'Insert newline',
219
+ 'composer.steer': 'Steer the running turn',
220
+ 'composer.sendQueued': 'Send next queued turn',
221
+ 'composer.mention': 'Reference files, folders, URLs',
222
+ 'composer.slash': 'Slash command palette',
223
+ 'composer.help': 'Quick help',
224
+ 'composer.history': 'Cycle popover / history',
225
+ 'composer.cancel': 'Close popover · cancel run'
226
+ }
227
+ },
228
+
229
+ language: {
230
+ label: 'Language',
231
+ description: 'Choose the language for the desktop interface.',
232
+ saving: 'Saving language…',
233
+ saveError: 'Language update failed',
234
+ switchTo: 'Switch language',
235
+ searchPlaceholder: 'Search languages…',
236
+ noResults: 'No languages found'
237
+ },
238
+
239
+ settings: {
240
+ closeSettings: 'Close settings',
241
+ exportConfig: 'Export config',
242
+ importConfig: 'Import config',
243
+ resetToDefaults: 'Reset to defaults',
244
+ resetConfirm: 'Reset all settings to NasTech defaults?',
245
+ exportFailed: 'Export failed',
246
+ resetFailed: 'Reset failed',
247
+ nav: {
248
+ providers: 'Providers',
249
+ providerAccounts: 'Accounts',
250
+ providerApiKeys: 'API keys',
251
+ gateway: 'Gateway',
252
+ apiKeys: 'Tools & Keys',
253
+ keysTools: 'Tools',
254
+ keysSettings: 'Settings',
255
+ mcp: 'MCP',
256
+ archivedChats: 'Archived Chats',
257
+ about: 'About'
258
+ },
259
+ sections: {
260
+ model: 'Model',
261
+ chat: 'Chat',
262
+ appearance: 'Appearance',
263
+ workspace: 'Workspace',
264
+ safety: 'Safety',
265
+ memory: 'Memory & Context',
266
+ voice: 'Voice',
267
+ advanced: 'Advanced'
268
+ },
269
+ searchPlaceholder: {
270
+ about: 'About NasTech Desktop',
271
+ config: 'Search settings...',
272
+ gateway: 'Gateway connection...',
273
+ keys: 'Search API keys...',
274
+ mcp: 'Search MCP servers...',
275
+ sessions: 'Search archived sessions...'
276
+ },
277
+ modeOptions: {
278
+ light: { label: 'Light', description: 'Bright desktop surfaces' },
279
+ dark: { label: 'Dark', description: 'Low-glare workspace' },
280
+ system: { label: 'System', description: 'Follow OS appearance' }
281
+ },
282
+ appearance: {
283
+ title: 'Appearance',
284
+ intro:
285
+ 'These are desktop-only display preferences. Mode controls brightness; theme controls the accent palette and chat surface styling.',
286
+ colorMode: 'Color Mode',
287
+ colorModeDesc: 'Pick a fixed mode or let NasTech follow your system setting.',
288
+ toolViewTitle: 'Tool Call Display',
289
+ toolViewDesc: 'Product hides raw tool payloads; Technical shows full input/output.',
290
+ product: 'Product',
291
+ productDesc: 'Human-friendly tool activity with concise summaries.',
292
+ technical: 'Technical',
293
+ technicalDesc: 'Include raw tool args/results and low-level details.',
294
+ themeTitle: 'Theme',
295
+ themeDesc: 'Desktop palettes only. The selected mode is applied on top.'
296
+ },
297
+ fieldLabels: FIELD_LABELS,
298
+ fieldDescriptions: FIELD_DESCRIPTIONS,
299
+ about: {
300
+ heading: 'NasTech Desktop',
301
+ version: value => `Version ${value}`,
302
+ versionUnavailable: 'Version unavailable',
303
+ updates: 'Updates',
304
+ checkNow: 'Check now',
305
+ checking: 'Checking…',
306
+ seeWhatsNew: "See what's new",
307
+ releaseNotes: 'Release notes',
308
+ onLatest: "You're on the latest version.",
309
+ installing: 'An update is currently installing.',
310
+ cantUpdate: "This build can't update itself from inside the app.",
311
+ cantReach: "We couldn't reach the update server.",
312
+ tapCheck: 'Tap "Check now" to look for updates.',
313
+ updateReady: count => `A new update is ready (${count} change${count === 1 ? '' : 's'} included).`,
314
+ lastChecked: age => `Last checked ${age}`,
315
+ justNowSuffix: ' · just now',
316
+ automaticUpdates: 'Automatic updates',
317
+ automaticUpdatesDesc:
318
+ 'NasTech checks for updates automatically in the background and lets you know when one is ready.',
319
+ branchCommit: (branch, commit) => `Branch ${branch} · Commit ${commit}`,
320
+ never: 'never',
321
+ justNow: 'just now',
322
+ minAgo: count => `${count} min ago`,
323
+ hoursAgo: count => `${count} hours ago`,
324
+ daysAgo: count => `${count} days ago`
325
+ },
326
+ config: {
327
+ none: 'None',
328
+ noneParen: '(none)',
329
+ notSet: 'Not set',
330
+ commaSeparated: 'comma-separated values',
331
+ loading: 'Loading NasTech configuration...',
332
+ emptyTitle: 'Nothing to configure',
333
+ emptyDesc: 'This section has no adjustable settings.',
334
+ failedLoad: 'Settings failed to load',
335
+ autosaveFailed: 'Autosave failed',
336
+ imported: 'Config imported',
337
+ invalidJson: 'Invalid config JSON'
338
+ },
339
+ credentials: {
340
+ pasteKey: 'Paste key',
341
+ pasteLabelKey: label => `Paste ${label} key`,
342
+ optional: 'Optional',
343
+ enterValueFirst: 'Enter a value first.',
344
+ couldNotSave: 'Could not save credential.',
345
+ remove: 'Remove',
346
+ or: 'or',
347
+ escToCancel: 'esc to cancel',
348
+ getKey: 'Get a key',
349
+ saving: 'Saving'
350
+ },
351
+ envActions: {
352
+ actionsFor: label => `Actions for ${label}`,
353
+ credentialActions: 'Credential actions',
354
+ docs: 'Docs',
355
+ hideValue: 'Hide value',
356
+ revealValue: 'Reveal value',
357
+ replace: 'Replace',
358
+ set: 'Set',
359
+ clear: 'Clear'
360
+ },
361
+ gateway: {
362
+ loading: 'Loading gateway settings...',
363
+ unavailableTitle: 'Gateway settings unavailable',
364
+ unavailableDesc: 'The desktop IPC bridge does not expose gateway settings.',
365
+ title: 'Gateway Connection',
366
+ envOverride: 'env override',
367
+ intro:
368
+ 'NasTech Desktop starts its own local gateway by default. Use a remote gateway when you want this app to control an already-running NasTech backend on another machine or behind a trusted proxy. Pick a profile below to give it its own remote host.',
369
+ appliesTo: 'Applies to',
370
+ allProfiles: 'All profiles',
371
+ defaultConnection: 'Default connection for every profile that has no override of its own.',
372
+ profileConnection: profile =>
373
+ `Connection used only when “${profile}” is the active profile. Set it to Local to inherit the default.`,
374
+ envOverrideTitle: 'Environment variables are controlling this desktop session.',
375
+ envOverrideDesc:
376
+ 'Unset NASTECH_DESKTOP_REMOTE_URL and NASTECH_DESKTOP_REMOTE_TOKEN to use the saved setting below.',
377
+ localTitle: 'Local gateway',
378
+ localDesc: 'Start a private NasTech backend on localhost. This is the default and works offline.',
379
+ remoteTitle: 'Remote gateway',
380
+ remoteDesc:
381
+ 'Connect this desktop shell to a remote NasTech backend. Hosted gateways use OAuth or a username and password; self-hosted ones may use a session token.',
382
+ remoteUrlTitle: 'Remote URL',
383
+ remoteUrlDesc: 'Base URL for the remote dashboard backend. Path prefixes are supported, for example /nastech.',
384
+ probing: 'Checking how this gateway authenticates…',
385
+ probeError: 'Could not reach this gateway yet. Check the URL — the auth method will appear once it responds.',
386
+ signedIn: 'Signed in',
387
+ signIn: 'Sign in',
388
+ signOut: 'Sign out',
389
+ signInWith: provider => `Sign in with ${provider}`,
390
+ authTitle: 'Authentication',
391
+ authSignedInPassword:
392
+ 'This gateway uses a username and password. You are signed in; the session refreshes automatically.',
393
+ authSignedInOauth: 'This gateway uses OAuth. You are signed in; the session refreshes automatically.',
394
+ authNeedsPassword: 'This gateway uses a username and password. Sign in to authorize this desktop app.',
395
+ authNeedsOauth: provider => `This gateway uses OAuth. Sign in with ${provider} to authorize this desktop app.`,
396
+ tokenTitle: 'Session token',
397
+ tokenDesc: 'The dashboard session token used for REST and WebSocket access. Leave blank to keep the saved token.',
398
+ existingToken: value => `Existing token ${value}`,
399
+ savedToken: 'saved',
400
+ pasteSessionToken: 'Paste session token',
401
+ testRemote: 'Test remote',
402
+ saveForRestart: 'Save for next restart',
403
+ saveAndReconnect: 'Save and reconnect',
404
+ diagnostics: 'Diagnostics',
405
+ diagnosticsDesc: 'Reveal desktop.log in your file manager — useful when the gateway fails to start.',
406
+ openLogs: 'Open logs',
407
+ incompleteTitle: 'Remote gateway incomplete',
408
+ incompleteSignIn: 'Enter a remote URL and sign in before switching to remote.',
409
+ incompleteToken: 'Enter a remote URL and session token before switching to remote.',
410
+ incompleteSignInTest: 'Enter a remote URL and sign in before testing.',
411
+ incompleteTokenTest: 'Enter a remote URL and session token before testing.',
412
+ enterUrlFirst: 'Enter a remote URL first.',
413
+ restartingTitle: 'Gateway connection restarting',
414
+ savedTitle: 'Gateway settings saved',
415
+ restartingMessage: 'NasTech Desktop will reconnect using the saved settings.',
416
+ savedMessage: 'Saved for the next restart.',
417
+ connectedTo: (baseUrl, version) => `Connected to ${baseUrl}${version ? ` · NasTech ${version}` : ''}`,
418
+ reachableTitle: 'Remote gateway reachable',
419
+ signedOutTitle: 'Signed out',
420
+ signedOutMessage: 'Cleared the remote gateway session.',
421
+ failedLoad: 'Gateway settings failed to load',
422
+ signInFailed: 'Sign-in failed',
423
+ signOutFailed: 'Sign-out failed',
424
+ testFailed: 'Remote gateway test failed',
425
+ applyFailed: 'Could not apply gateway settings',
426
+ saveFailed: 'Could not save gateway settings'
427
+ },
428
+ keys: {
429
+ loading: 'Loading API keys and credentials...',
430
+ failedLoad: 'API keys failed to load',
431
+ empty: 'Nothing configured in this category yet.'
432
+ },
433
+ mcp: {
434
+ loading: 'Loading MCP servers...',
435
+ failedLoad: 'MCP config failed to load',
436
+ nameRequiredTitle: 'Name required',
437
+ nameRequiredMessage: 'Give this MCP server a config key.',
438
+ objectRequired: 'Server config must be a JSON object',
439
+ invalidJson: 'Invalid MCP JSON',
440
+ saveFailed: 'Save failed',
441
+ removeFailed: 'Remove failed',
442
+ gatewayUnavailableTitle: 'Gateway unavailable',
443
+ gatewayUnavailableMessage: 'Reconnect the gateway before reloading MCP.',
444
+ reloadedTitle: 'MCP tools reloaded',
445
+ reloadedMessage: 'New tool schemas apply to fresh turns.',
446
+ reloadFailed: 'MCP reload failed',
447
+ savedTitle: 'MCP server saved',
448
+ savedMessage: name => `${name} applies after MCP reload.`,
449
+ newServer: 'New server',
450
+ reload: 'Reload MCP',
451
+ reloading: 'Reloading...',
452
+ emptyTitle: 'No MCP servers',
453
+ emptyDesc: 'Add a stdio or HTTP server to expose MCP tools.',
454
+ disabled: 'disabled',
455
+ editServer: 'Edit server',
456
+ name: 'Name',
457
+ serverJson: 'Server JSON',
458
+ remove: 'Remove',
459
+ saveServer: 'Save server'
460
+ },
461
+ model: {
462
+ loading: 'Loading model configuration...',
463
+ appliesDesc: 'Applies to new sessions. Use the model picker in the composer to hot-swap the active chat.',
464
+ provider: 'Provider',
465
+ model: 'Model',
466
+ applying: 'Applying...',
467
+ auxiliaryTitle: 'Auxiliary models',
468
+ resetAllToMain: 'Reset all to main',
469
+ auxiliaryDesc: 'Helper tasks run on the main model by default. Assign a dedicated model to any task to override.',
470
+ setToMain: 'Set to main',
471
+ change: 'Change',
472
+ autoUseMain: 'auto · use main model',
473
+ providerDefault: '(provider default)',
474
+ tasks: {
475
+ vision: { label: 'Vision', hint: 'Image analysis' },
476
+ web_extract: { label: 'Web extract', hint: 'Page summarization' },
477
+ compression: { label: 'Compression', hint: 'Context compaction' },
478
+ skills_hub: { label: 'Skills hub', hint: 'Skill search' },
479
+ approval: { label: 'Approval', hint: 'Smart auto-approve' },
480
+ mcp: { label: 'MCP', hint: 'MCP tool routing' },
481
+ title_generation: { label: 'Title gen', hint: 'Session titles' },
482
+ curator: { label: 'Curator', hint: 'Skill-usage review' }
483
+ }
484
+ },
485
+ providers: {
486
+ connectAccount: 'Connect an account',
487
+ haveApiKey: 'Have an API key instead?',
488
+ intro:
489
+ 'Sign in with a subscription — no API key to copy. NasTech runs the browser sign-in for you, right here in the app.',
490
+ connected: 'Connected',
491
+ collapse: 'Collapse',
492
+ connectAnother: 'Connect another provider',
493
+ otherProviders: 'Other providers',
494
+ noProviderKeys: 'No provider API keys available.',
495
+ loading: 'Loading providers...'
496
+ },
497
+ sessions: {
498
+ loading: 'Loading archived sessions…',
499
+ archivedTitle: 'Archived sessions',
500
+ archivedIntro:
501
+ 'Archived chats are hidden from the sidebar but keep all their messages. Ctrl/⌘-click a chat in the sidebar to archive it.',
502
+ emptyArchivedTitle: 'Nothing archived',
503
+ emptyArchivedDesc: 'Archive a chat to hide it here.',
504
+ unarchive: 'Unarchive',
505
+ deletePermanently: 'Delete permanently',
506
+ messages: count => `${count} ${count === 1 ? 'message' : 'messages'}`,
507
+ restored: 'Restored',
508
+ deleteConfirm: title => `Permanently delete "${title}"? This cannot be undone.`,
509
+ defaultDirTitle: 'Default project directory',
510
+ defaultDirDesc:
511
+ 'New sessions start in this folder unless you pick another. Leave it unset to use your home directory.',
512
+ defaultDirUpdated: 'Default project directory updated',
513
+ defaultsTo: label => `Defaults to ${label}.`,
514
+ change: 'Change',
515
+ choose: 'Choose',
516
+ clear: 'Clear',
517
+ notSet: 'Not set',
518
+ failedLoad: 'Could not load archived sessions',
519
+ unarchiveFailed: 'Unarchive failed',
520
+ deleteFailed: 'Delete failed',
521
+ updateDirFailed: 'Could not update default directory',
522
+ clearDirFailed: 'Could not clear default directory'
523
+ },
524
+ toolsets: {
525
+ loadingConfig: 'Loading configuration',
526
+ savedTitle: 'Credential saved',
527
+ savedMessage: key => `${key} updated.`,
528
+ removedTitle: 'Credential removed',
529
+ removedMessage: key => `${key} removed.`,
530
+ failedSave: key => `Failed to save ${key}`,
531
+ failedRemove: key => `Failed to remove ${key}`,
532
+ failedReveal: key => `Failed to reveal ${key}`,
533
+ removeConfirm: key => `Remove ${key} from .env?`,
534
+ set: 'Set',
535
+ notSet: 'Not set',
536
+ selectedTitle: 'Provider selected',
537
+ selectedMessage: provider => `${provider} is now active.`,
538
+ failedSelect: provider => `Failed to select ${provider}`,
539
+ failedLoad: 'Tool configuration failed to load',
540
+ noProviderOptions: 'This toolset has no provider options — enable it and it works with your current setup.',
541
+ noProviders: 'No providers are available for this toolset right now.',
542
+ ready: 'Ready',
543
+ nousIncluded: 'Included with a NasTech subscription — sign in to NasTech Portal to activate.',
544
+ noApiKeyRequired: 'No API key required.',
545
+ postSetupRun: 'Run setup',
546
+ postSetupRunning: 'Installing…',
547
+ postSetupHint: step => `This backend requires a one-time install (${step}). It will run on this machine and may take a few minutes.`,
548
+ postSetupStarting: 'Starting…',
549
+ postSetupCompleteTitle: 'Setup complete',
550
+ postSetupCompleteMessage: step => `${step} has been installed.`,
551
+ postSetupErrorTitle: 'Setup completed with errors',
552
+ postSetupErrorMessage: step => `Check the ${step} logs.`,
553
+ postSetupFailed: step => `Failed to run ${step} setup`
554
+ }
555
+ },
556
+
557
+ skills: {
558
+ tabSkills: 'Skills',
559
+ tabToolsets: 'Toolsets',
560
+ all: 'All',
561
+ searchSkills: 'Search skills...',
562
+ searchToolsets: 'Search toolsets...',
563
+ refresh: 'Refresh skills',
564
+ refreshing: 'Refreshing skills',
565
+ loading: 'Loading capabilities...',
566
+ noSkillsTitle: 'No skills found',
567
+ noSkillsDesc: 'Try a broader search or different category.',
568
+ noToolsetsTitle: 'No toolsets found',
569
+ noToolsetsDesc: 'Try a broader search query.',
570
+ noDescription: 'No description.',
571
+ configured: 'Configured',
572
+ needsKeys: 'Needs keys',
573
+ toolsetsEnabled: (enabled, total) => `${enabled}/${total} toolsets enabled`,
574
+ configureToolset: label => `Configure ${label}`,
575
+ toggleToolset: label => `Toggle ${label} toolset`,
576
+ skillsLoadFailed: 'Skills failed to load',
577
+ toolsetsRefreshFailed: 'Toolsets failed to refresh',
578
+ skillEnabled: 'Skill enabled',
579
+ skillDisabled: 'Skill disabled',
580
+ toolsetEnabled: 'Toolset enabled',
581
+ toolsetDisabled: 'Toolset disabled',
582
+ appliesToNewSessions: name => `${name} applies to new sessions.`,
583
+ failedToUpdate: name => `Failed to update ${name}`
584
+ },
585
+
586
+ agents: {
587
+ close: 'Close agents',
588
+ title: 'Spawn tree',
589
+ subtitle: 'Live subagent activity for the current turn.',
590
+ emptyTitle: 'No live subagents',
591
+ emptyDesc: 'When a turn delegates work, child agents stream their progress here.',
592
+ running: 'Running',
593
+ failed: 'Failed',
594
+ done: 'Done',
595
+ streaming: 'Streaming',
596
+ files: 'Files',
597
+ moreFiles: count => `+${count} more files`,
598
+ delegation: index => `Delegation ${index}`,
599
+ workers: count => `${count} workers`,
600
+ workersActive: count => `${count} active`,
601
+ agentsCount: count => `${count} ${count === 1 ? 'agent' : 'agents'}`,
602
+ activeCount: count => `${count} active`,
603
+ failedCount: count => `${count} failed`,
604
+ toolsCount: count => `${count} tools`,
605
+ filesCount: count => `${count} files`,
606
+ updatedAgo: age => `updated ${age}`,
607
+ ageNow: 'now',
608
+ ageSeconds: seconds => `${seconds}s ago`,
609
+ ageMinutes: minutes => `${minutes}m ago`,
610
+ ageHours: hours => `${hours}h ago`,
611
+ durationSeconds: seconds => `${seconds}s`,
612
+ durationMinutes: (minutes, seconds) => `${minutes}m ${seconds}s`,
613
+ tokensK: k => `${k}k tok`,
614
+ tokens: value => `${value} tok`
615
+ },
616
+
617
+ commandCenter: {
618
+ close: 'Close command center',
619
+ paletteTitle: 'Command palette',
620
+ back: 'Back',
621
+ searchPlaceholder: 'Search sessions, views, and actions',
622
+ goTo: 'Go to',
623
+ commandCenter: 'Command Center',
624
+ appearance: 'Appearance',
625
+ settings: 'Settings',
626
+ changeTheme: 'Change theme...',
627
+ changeColorMode: 'Change color mode...',
628
+ installTheme: {
629
+ title: 'Install theme...',
630
+ placeholder: 'Search the VS Code Marketplace...',
631
+ loading: 'Searching the Marketplace...',
632
+ error: 'Could not reach the Marketplace.',
633
+ empty: 'No matching themes.',
634
+ install: 'Install',
635
+ installing: 'Installing...',
636
+ installed: 'Installed',
637
+ installs: count => `${count} installs`
638
+ },
639
+ settingsFields: 'Settings fields',
640
+ mcpServers: 'MCP servers',
641
+ archivedChats: 'Archived chats',
642
+ sections: { sessions: 'Sessions', system: 'System', usage: 'Usage' },
643
+ sectionDescriptions: {
644
+ sessions: 'Search and manage sessions',
645
+ system: 'Status, logs, and system actions',
646
+ usage: 'Token, cost, and skill activity over time'
647
+ },
648
+ nav: {
649
+ newChat: { title: 'New session', detail: 'Start a fresh session' },
650
+ settings: { title: 'Settings', detail: 'Configure NasTech desktop' },
651
+ skills: { title: 'Skills & Tools', detail: 'Enable skills, toolsets, and providers' },
652
+ messaging: { title: 'Messaging', detail: 'Set up Telegram, Slack, Discord, and more' },
653
+ artifacts: { title: 'Artifacts', detail: 'Browse generated outputs' }
654
+ },
655
+ sectionEntries: {
656
+ sessions: { title: 'Sessions panel', detail: 'Search, pin, and manage sessions' },
657
+ system: { title: 'System panel', detail: 'Gateway status, logs, restart/update' },
658
+ usage: { title: 'Usage panel', detail: 'Token, cost, and skill activity' }
659
+ },
660
+ providerNavigate: 'Navigate',
661
+ providerSessions: 'Sessions',
662
+ refresh: 'Refresh',
663
+ refreshing: 'Refreshing...',
664
+ noResults: 'No matching results found.',
665
+ pinSession: 'Pin session',
666
+ unpinSession: 'Unpin session',
667
+ exportSession: 'Export session',
668
+ deleteSession: 'Delete session',
669
+ noSessions: 'No sessions yet.',
670
+ gatewayRunning: 'Messaging gateway running',
671
+ gatewayStopped: 'Messaging gateway stopped',
672
+ NASTECHActiveSessions: (version, count) => `NasTech ${version} · Active sessions ${count}`,
673
+ restartMessaging: 'Restart messaging',
674
+ updateNasTech: 'Update NasTech',
675
+ actionRunning: 'running',
676
+ actionDone: 'done',
677
+ actionFailed: 'failed',
678
+ actionStartedWaiting: 'Action started, waiting for status...',
679
+ loadingStatus: 'Loading status...',
680
+ recentLogs: 'Recent logs',
681
+ noLogs: 'No logs loaded yet.',
682
+ days: count => `${count}d`,
683
+ statSessions: 'Sessions',
684
+ statApiCalls: 'API calls',
685
+ statTokens: 'Tokens in/out',
686
+ statCost: 'Est. cost',
687
+ actualCost: cost => `actual ${cost}`,
688
+ loadingUsage: 'Loading usage...',
689
+ noUsage: period => `No usage in the last ${period} days.`,
690
+ retry: 'Retry',
691
+ dailyTokens: 'Daily tokens',
692
+ input: 'input',
693
+ output: 'output',
694
+ noDailyActivity: 'No daily activity.',
695
+ topModels: 'Top models',
696
+ noModelUsage: 'No model usage yet.',
697
+ topSkills: 'Top skills',
698
+ noSkillActivity: 'No skill activity yet.',
699
+ actions: count => `${count} actions`
700
+ },
701
+
702
+ messaging: {
703
+ search: 'Search messaging...',
704
+ loading: 'Loading messaging platforms...',
705
+ loadFailed: 'Messaging platforms failed to load',
706
+ states: {
707
+ connected: 'Connected',
708
+ connecting: 'Connecting',
709
+ disabled: 'Disabled',
710
+ fatal: 'Error',
711
+ gateway_stopped: 'Messaging gateway stopped',
712
+ not_configured: 'Needs setup',
713
+ pending_restart: 'Restart needed',
714
+ retrying: 'Retrying',
715
+ startup_failed: 'Startup failed'
716
+ },
717
+ unknown: 'Unknown',
718
+ hintPendingRestart: 'Restart the gateway from the status bar to apply this change.',
719
+ hintGatewayStopped: 'Start the gateway from the status bar to connect.',
720
+ credentialsSet: 'Credentials set',
721
+ needsSetup: 'Needs setup',
722
+ gatewayStopped: 'Messaging gateway stopped',
723
+ getCredentials: 'Get your credentials',
724
+ openSetupGuide: 'Open setup guide',
725
+ required: 'Required',
726
+ recommended: 'Recommended',
727
+ advanced: count => `Advanced (${count})`,
728
+ noTokenNeeded: 'This platform does not need a token here. Use the setup guide above, then enable it below.',
729
+ enabled: 'Enabled',
730
+ disabled: 'Disabled',
731
+ unsavedChanges: 'Unsaved changes',
732
+ saving: 'Saving...',
733
+ saveChanges: 'Save changes',
734
+ saved: 'Saved',
735
+ replaceValue: 'Replace current value',
736
+ openDocs: 'Open docs',
737
+ clearField: key => `Clear ${key}`,
738
+ enableAria: name => `Enable ${name}`,
739
+ disableAria: name => `Disable ${name}`,
740
+ platformEnabled: name => `${name} enabled`,
741
+ platformDisabled: name => `${name} disabled`,
742
+ restartToApply: 'Restart the gateway for this change to take effect.',
743
+ setupSaved: name => `${name} setup saved`,
744
+ restartToReconnect: 'Restart the gateway to reconnect with the new credentials.',
745
+ keyCleared: key => `${key} cleared`,
746
+ setupUpdated: name => `${name} setup was updated.`,
747
+ failedUpdate: name => `Failed to update ${name}`,
748
+ failedSave: name => `Failed to save ${name}`,
749
+ failedClear: key => `Failed to clear ${key}`,
750
+ fieldCopy: {
751
+ TELEGRAM_BOT_TOKEN: {
752
+ label: 'Bot token',
753
+ help: 'Create a bot with @BotFather, then paste the token it gives you.',
754
+ placeholder: 'Paste Telegram bot token'
755
+ },
756
+ TELEGRAM_ALLOWED_USERS: {
757
+ label: 'Allowed Telegram user IDs',
758
+ help: 'Recommended. Comma-separated numeric IDs from @userinfobot. Without this, anyone can DM your bot.'
759
+ },
760
+ TELEGRAM_PROXY: { label: 'Proxy URL', help: 'Only needed on networks where Telegram is blocked.' },
761
+ DISCORD_BOT_TOKEN: {
762
+ label: 'Bot token',
763
+ help: 'Create an application in the Discord Developer Portal, add a bot, then paste its token.'
764
+ },
765
+ DISCORD_ALLOWED_USERS: {
766
+ label: 'Allowed Discord user IDs',
767
+ help: 'Recommended. Comma-separated Discord user IDs.'
768
+ },
769
+ DISCORD_REPLY_TO_MODE: { label: 'Reply style', help: 'first, all, or off.' },
770
+ DISCORD_ALLOW_ALL_USERS: {
771
+ label: 'Allow all Discord users',
772
+ help: 'Development only. When true, anyone can DM the bot without an allowlist.'
773
+ },
774
+ DISCORD_HOME_CHANNEL: {
775
+ label: 'Home channel ID',
776
+ help: 'Channel where the bot sends proactive messages (cron output, reminders).'
777
+ },
778
+ DISCORD_HOME_CHANNEL_NAME: {
779
+ label: 'Home channel name',
780
+ help: 'Display name for the home channel in logs and status output.'
781
+ },
782
+ BLUEBUBBLES_ALLOW_ALL_USERS: {
783
+ label: 'Allow all iMessage users',
784
+ help: 'When true, skip the BlueBubbles allowlist.'
785
+ },
786
+ MATTERMOST_ALLOW_ALL_USERS: { label: 'Allow all Mattermost users' },
787
+ MATTERMOST_HOME_CHANNEL: { label: 'Home channel' },
788
+ QQ_ALLOW_ALL_USERS: { label: 'Allow all QQ users' },
789
+ QQBOT_HOME_CHANNEL: { label: 'QQ home channel', help: 'Default channel or group for cron delivery.' },
790
+ QQBOT_HOME_CHANNEL_NAME: { label: 'QQ home channel name' },
791
+ SLACK_BOT_TOKEN: {
792
+ label: 'Slack bot token',
793
+ help: 'Use the bot token from OAuth & Permissions after installing your Slack app.',
794
+ placeholder: 'Paste Slack bot token'
795
+ },
796
+ SLACK_APP_TOKEN: {
797
+ label: 'Slack app token',
798
+ help: 'Use the app-level token required for Socket Mode.',
799
+ placeholder: 'Paste Slack app token'
800
+ },
801
+ SLACK_ALLOWED_USERS: { label: 'Allowed Slack user IDs', help: 'Recommended. Comma-separated Slack user IDs.' },
802
+ MATTERMOST_URL: { label: 'Server URL', placeholder: 'https://mattermost.example.com' },
803
+ MATTERMOST_TOKEN: { label: 'Bot token' },
804
+ MATTERMOST_ALLOWED_USERS: {
805
+ label: 'Allowed user IDs',
806
+ help: 'Recommended. Comma-separated Mattermost user IDs.'
807
+ },
808
+ MATRIX_HOMESERVER: { label: 'Homeserver URL', placeholder: 'https://matrix.org' },
809
+ MATRIX_ACCESS_TOKEN: { label: 'Access token' },
810
+ MATRIX_USER_ID: { label: 'Bot user ID', placeholder: '@nastech:example.org' },
811
+ MATRIX_ALLOWED_USERS: {
812
+ label: 'Allowed Matrix user IDs',
813
+ help: 'Recommended. Comma-separated user IDs in @user:server format.'
814
+ },
815
+ SIGNAL_HTTP_URL: {
816
+ label: 'Signal bridge URL',
817
+ placeholder: 'http://127.0.0.1:8080',
818
+ help: 'URL of a running signal-cli REST bridge.'
819
+ },
820
+ SIGNAL_ACCOUNT: { label: 'Phone number', help: 'The number registered with your signal-cli bridge.' },
821
+ SIGNAL_ALLOWED_USERS: { label: 'Allowed Signal users', help: 'Recommended. Comma-separated Signal identifiers.' },
822
+ WHATSAPP_ENABLED: {
823
+ label: 'Enable WhatsApp bridge',
824
+ help: 'Set automatically by the toggle below. Leave alone unless you know you need it.'
825
+ },
826
+ WHATSAPP_MODE: { label: 'Bridge mode' },
827
+ WHATSAPP_ALLOWED_USERS: {
828
+ label: 'Allowed WhatsApp users',
829
+ help: 'Recommended. Comma-separated phone numbers or WhatsApp IDs.'
830
+ }
831
+ },
832
+ platformIntro: {}
833
+ },
834
+
835
+ profiles: {
836
+ close: 'Close profiles',
837
+ nameHint: 'Lowercase letters, digits, hyphens, and underscores. Must start with a letter or digit.',
838
+ title: 'Profiles',
839
+ count: count => `${count} ${count === 1 ? 'profile' : 'profiles'}`,
840
+ loading: 'Loading profiles...',
841
+ newProfile: 'New profile',
842
+ allProfiles: 'All profiles',
843
+ showAllProfiles: 'Show all profiles',
844
+ switchToProfile: name => `Switch to ${name}`,
845
+ manageProfiles: 'Manage profiles...',
846
+ actionsFor: name => `Actions for ${name}`,
847
+ color: 'Color...',
848
+ colorFor: name => `Color for ${name}`,
849
+ setColor: color => `Set color ${color}`,
850
+ autoColor: 'Auto',
851
+ noProfiles: 'No profiles yet.',
852
+ selectPrompt: 'Select a profile to view its details.',
853
+ refresh: 'Refresh profiles',
854
+ refreshing: 'Refreshing profiles',
855
+ default: 'default',
856
+ skills: count => `${count} ${count === 1 ? 'skill' : 'skills'}`,
857
+ env: 'env',
858
+ defaultBadge: 'Default',
859
+ rename: 'Rename',
860
+ copySetup: 'Copy setup',
861
+ copying: 'Copying...',
862
+ modelLabel: 'Model',
863
+ skillsLabel: 'Skills',
864
+ notSet: 'Not set',
865
+ soulDesc: 'The system prompt and persona instructions baked into this profile.',
866
+ soulOptional: 'optional',
867
+ soulPlaceholder: mode => `The system prompt / persona for this profile.\nLeave blank to keep the ${mode} default.`,
868
+ soulPlaceholderCloned: 'cloned',
869
+ soulPlaceholderEmpty: 'empty',
870
+ unsavedChanges: 'Unsaved changes',
871
+ loadingSoul: 'Loading SOUL.md...',
872
+ emptySoul: 'Empty SOUL.md — start writing the persona...',
873
+ saving: 'Saving...',
874
+ saveSoul: 'Save SOUL.md',
875
+ deleteTitle: 'Delete profile?',
876
+ deleteDescPrefix: 'This will delete ',
877
+ deleteDescMid: ' and remove its ',
878
+ deleteDescSuffix: ' directory. This cannot be undone.',
879
+ deleting: 'Deleting...',
880
+ createDesc: 'Profiles are independent NasTech environments: separate config, skills, and SOUL.md.',
881
+ nameLabel: 'Name',
882
+ cloneFromDefault: 'Clone from default',
883
+ cloneFromDefaultDesc: 'Copy config, skills, and SOUL.md from your default profile.',
884
+ invalidName: hint => `Invalid name. ${hint}`,
885
+ nameRequired: 'Name is required.',
886
+ creating: 'Creating...',
887
+ createAction: 'Create profile',
888
+ renameTitle: 'Rename profile',
889
+ renameDescPrefix: 'Renaming updates the profile directory and any wrapper scripts in ',
890
+ renameDescSuffix: '.',
891
+ newNameLabel: 'New name',
892
+ renaming: 'Renaming...',
893
+ created: 'Profile created',
894
+ renamed: 'Profile renamed',
895
+ deleted: 'Profile deleted',
896
+ setupCopied: 'Setup command copied',
897
+ soulSaved: 'SOUL.md saved',
898
+ failedLoad: 'Failed to load profiles',
899
+ failedDelete: 'Failed to delete profile',
900
+ failedCopy: 'Failed to copy setup command',
901
+ failedLoadSoul: 'Failed to load SOUL.md',
902
+ failedSaveSoul: 'Failed to save SOUL.md',
903
+ failedCreate: 'Failed to create profile',
904
+ failedRename: 'Failed to rename profile'
905
+ },
906
+
907
+ cron: {
908
+ close: 'Close cron',
909
+ search: 'Search cron jobs...',
910
+ loading: 'Loading cron jobs...',
911
+ states: {
912
+ enabled: 'enabled',
913
+ scheduled: 'scheduled',
914
+ running: 'running',
915
+ paused: 'paused',
916
+ disabled: 'disabled',
917
+ error: 'error',
918
+ completed: 'completed'
919
+ },
920
+ deliveryLabels: {
921
+ local: 'This desktop',
922
+ telegram: 'Telegram',
923
+ discord: 'Discord',
924
+ slack: 'Slack',
925
+ email: 'Email'
926
+ },
927
+ scheduleLabels: {
928
+ daily: 'Daily',
929
+ weekdays: 'Weekdays',
930
+ weekly: 'Weekly',
931
+ monthly: 'Monthly',
932
+ hourly: 'Hourly',
933
+ 'every-15-minutes': 'Every 15 minutes',
934
+ custom: 'Custom'
935
+ },
936
+ scheduleHints: {
937
+ daily: 'Every day at 9:00 AM',
938
+ weekdays: 'Monday through Friday at 9:00 AM',
939
+ weekly: 'Every Monday at 9:00 AM',
940
+ monthly: 'The first day of each month at 9:00 AM',
941
+ hourly: 'At the top of every hour',
942
+ 'every-15-minutes': 'Every 15 minutes',
943
+ custom: 'Cron syntax or natural language'
944
+ },
945
+ days: {
946
+ '0': 'Sunday',
947
+ '1': 'Monday',
948
+ '2': 'Tuesday',
949
+ '3': 'Wednesday',
950
+ '4': 'Thursday',
951
+ '5': 'Friday',
952
+ '6': 'Saturday',
953
+ '7': 'Sunday'
954
+ },
955
+ dayFallback: value => `day ${value}`,
956
+ everyDayAt: time => `Every day at ${time}`,
957
+ weekdaysAt: time => `Weekdays at ${time}`,
958
+ everyDayOfWeekAt: (day, time) => `Every ${day} at ${time}`,
959
+ monthlyOnDayAt: (dayOfMonth, time) => `Monthly on day ${dayOfMonth} at ${time}`,
960
+ topOfHour: 'At the top of every hour',
961
+ everyHourAt: minute => `Every hour at :${minute}`,
962
+ active: (enabled: number, total: number) => `${enabled}/${total} active`,
963
+ newCron: 'New cron',
964
+ createFirst: 'Create first cron',
965
+ emptyDescNew:
966
+ 'Schedule a prompt to run on a cron expression. NasTech will run it and deliver results to the destination you pick.',
967
+ emptyDescSearch: 'Try a broader search query.',
968
+ emptyTitleNew: 'No scheduled jobs yet',
969
+ emptyTitleSearch: 'No matches',
970
+ last: 'Last:',
971
+ next: 'Next:',
972
+ actionsFor: title => `Actions for ${title}`,
973
+ actionsTitle: 'Cron job actions',
974
+ resume: 'Resume cron',
975
+ pause: 'Pause cron',
976
+ resumeTitle: 'Resume',
977
+ pauseTitle: 'Pause',
978
+ triggerNow: 'Trigger now',
979
+ edit: 'Edit cron',
980
+ deleteTitle: 'Delete cron job?',
981
+ deleteDescPrefix: 'This will remove ',
982
+ deleteDescSuffix: ' permanently. It will stop firing immediately.',
983
+ deleting: 'Deleting...',
984
+ resumed: 'Cron resumed',
985
+ paused: 'Cron paused',
986
+ triggered: 'Cron triggered',
987
+ deleted: 'Cron deleted',
988
+ created: 'Cron created',
989
+ updated: 'Cron updated',
990
+ failedLoad: 'Failed to load cron jobs',
991
+ failedUpdate: 'Failed to update cron job',
992
+ failedTrigger: 'Failed to trigger cron job',
993
+ failedDelete: 'Failed to delete cron job',
994
+ failedSave: 'Failed to save cron job',
995
+ editTitle: 'Edit cron job',
996
+ createTitle: 'New cron job',
997
+ editDesc: 'Update the schedule, prompt, or delivery target. Changes apply on next run.',
998
+ createDesc: 'Schedule a prompt to run automatically. Use cron syntax or a natural phrase like "every 15 minutes".',
999
+ nameLabel: 'Name',
1000
+ namePlaceholder: 'Morning briefing',
1001
+ promptLabel: 'Prompt',
1002
+ promptPlaceholder: 'Summarize my unread Slack threads and email me the top 5...',
1003
+ frequencyLabel: 'Frequency',
1004
+ deliverLabel: 'Deliver to',
1005
+ customScheduleLabel: 'Custom schedule',
1006
+ customPlaceholder: '0 9 * * * or weekdays at 9am',
1007
+ customHint: 'Cron expression, or phrases like "every hour" or "weekdays at 9am".',
1008
+ optional: 'Optional',
1009
+ promptScheduleRequired: 'Prompt and schedule are required.',
1010
+ saveChanges: 'Save changes',
1011
+ createAction: 'Create cron'
1012
+ },
1013
+
1014
+ artifacts: {
1015
+ search: 'Search artifacts...',
1016
+ refresh: 'Refresh artifacts',
1017
+ refreshing: 'Refreshing artifacts',
1018
+ indexing: 'Indexing recent session artifacts',
1019
+ tabAll: 'All',
1020
+ tabImages: 'Images',
1021
+ tabFiles: 'Files',
1022
+ tabLinks: 'Links',
1023
+ noArtifactsTitle: 'No artifacts found',
1024
+ noArtifactsDesc: 'Generated images and file outputs will appear here as sessions produce them.',
1025
+ failedLoad: 'Artifacts failed to load',
1026
+ openFailed: 'Open failed',
1027
+ itemsImage: 'images',
1028
+ itemsLink: 'links',
1029
+ itemsFile: 'files',
1030
+ itemsGeneric: 'items',
1031
+ zero: '0',
1032
+ rangeOf: (start, end, total) => `${start}-${end} of ${total}`,
1033
+ goToPage: (itemLabel, page) => `Go to ${itemLabel} page ${page}`,
1034
+ colTitleLink: 'Link title',
1035
+ colTitleFile: 'Name',
1036
+ colTitleDefault: 'Title / name',
1037
+ colLocationLink: 'URL',
1038
+ colLocationFile: 'Path',
1039
+ colLocationDefault: 'Location',
1040
+ colSession: 'Session',
1041
+ kindImage: 'image',
1042
+ kindFile: 'file',
1043
+ kindLink: 'link',
1044
+ chat: 'Chat',
1045
+ copyUrl: 'Copy URL',
1046
+ copyPath: 'Copy path'
1047
+ },
1048
+
1049
+ sidebar: {
1050
+ nav: {
1051
+ 'new-session': 'New session',
1052
+ skills: 'Skills & Tools',
1053
+ messaging: 'Messaging',
1054
+ artifacts: 'Artifacts'
1055
+ },
1056
+ searchAria: 'Search sessions',
1057
+ searchPlaceholder: 'Search sessions…',
1058
+ clearSearch: 'Clear search',
1059
+ noMatch: query => `No sessions match “${query}”.`,
1060
+ results: 'Results',
1061
+ pinned: 'Pinned',
1062
+ sessions: 'Sessions',
1063
+ cronJobs: 'Cron Jobs',
1064
+ groupAriaGrouped: 'Show sessions as a single list',
1065
+ groupAriaUngrouped: 'Group sessions by workspace',
1066
+ groupTitleGrouped: 'Ungroup sessions',
1067
+ groupTitleUngrouped: 'Group by workspace',
1068
+ allPinned: 'Everything here is pinned. Unpin a chat to show it in recents.',
1069
+ shiftClickHint: 'Shift-click a chat to pin',
1070
+ noWorkspace: 'No workspace',
1071
+ newSessionIn: label => `New session in ${label}`,
1072
+ reorderWorkspace: label => `Reorder workspace ${label}`,
1073
+ showMoreIn: (count, label) => `Show ${count} more in ${label}`,
1074
+ loading: 'Loading…',
1075
+ loadMore: 'Load more',
1076
+ loadCount: step => `Load ${step} more`,
1077
+ row: {
1078
+ pin: 'Pin',
1079
+ unpin: 'Unpin',
1080
+ copyId: 'Copy ID',
1081
+ export: 'Export',
1082
+ rename: 'Rename',
1083
+ archive: 'Archive',
1084
+ copyIdFailed: 'Could not copy session ID',
1085
+ actionsFor: title => `Actions for ${title}`,
1086
+ sessionActions: 'Session actions',
1087
+ sessionRunning: 'Session running',
1088
+ needsInput: 'Needs your input',
1089
+ waitingForAnswer: 'Waiting for your answer',
1090
+ renamed: 'Renamed',
1091
+ renameFailed: 'Rename failed',
1092
+ renameTitle: 'Rename session',
1093
+ renameDesc: 'Give this chat a memorable title. Leave empty to clear.',
1094
+ untitledPlaceholder: 'Untitled session',
1095
+ ageNow: 'now',
1096
+ ageDay: 'd',
1097
+ ageHour: 'h',
1098
+ ageMin: 'm'
1099
+ }
1100
+ },
1101
+
1102
+ composer: {
1103
+ message: 'Message',
1104
+ wakingProfile: profile => `Waking up ${profile}…`,
1105
+ placeholderStarting: 'Starting NasTech...',
1106
+ placeholderReconnecting: 'Reconnecting to NasTech…',
1107
+ placeholderFollowUp: 'Send follow-up',
1108
+ newSessionPlaceholders: [
1109
+ 'What are we building?',
1110
+ 'Give NasTech a task',
1111
+ "What's on your mind?",
1112
+ 'Describe what you need',
1113
+ 'What should we tackle?',
1114
+ 'Ask anything',
1115
+ 'Start with a goal'
1116
+ ],
1117
+ followUpPlaceholders: [
1118
+ 'Send a follow-up',
1119
+ 'Add more context',
1120
+ 'Refine the request',
1121
+ "What's next?",
1122
+ 'Keep it going',
1123
+ 'Push it further',
1124
+ 'Adjust or continue'
1125
+ ],
1126
+ startVoice: 'Start voice conversation',
1127
+ queueMessage: 'Queue message',
1128
+ steer: 'Steer the current run (⌘⏎)',
1129
+ stop: 'Stop',
1130
+ send: 'Send',
1131
+ speaking: 'Speaking',
1132
+ transcribing: 'Transcribing',
1133
+ thinking: 'Thinking',
1134
+ muted: 'Muted',
1135
+ listening: 'Listening',
1136
+ muteMic: 'Mute microphone',
1137
+ unmuteMic: 'Unmute microphone',
1138
+ stopListening: 'Stop listening and send',
1139
+ stopShort: 'Stop',
1140
+ endConversation: 'End voice conversation',
1141
+ endShort: 'End',
1142
+ stopDictation: 'Stop dictation',
1143
+ transcribingDictation: 'Transcribing dictation',
1144
+ voiceDictation: 'Voice dictation',
1145
+ lookupLoading: 'Looking up…',
1146
+ lookupNoMatches: 'No matches.',
1147
+ lookupTry: 'Try',
1148
+ lookupOr: 'or',
1149
+ commonCommands: 'Common commands',
1150
+ hotkeys: 'Hotkeys',
1151
+ helpFooter: 'opens the full panel · backspace dismisses',
1152
+ commandDescs: {
1153
+ '/help': 'full list of commands + hotkeys',
1154
+ '/clear': 'start a new session',
1155
+ '/resume': 'resume a prior session',
1156
+ '/details': 'control transcript detail level',
1157
+ '/copy': 'copy selection or last assistant message',
1158
+ '/quit': 'exit nastech'
1159
+ },
1160
+ hotkeyDescs: {
1161
+ '@': 'reference files, folders, urls, git',
1162
+ '/': 'slash command palette',
1163
+ '?': 'this quick help (delete to dismiss)',
1164
+ Enter: 'send · Shift+Enter for newline',
1165
+ 'Cmd/Ctrl+Shift+K': 'send next queued turn',
1166
+ 'Cmd/Ctrl+/': 'all keyboard shortcuts',
1167
+ Esc: 'close popover · cancel run',
1168
+ '↑ / ↓': 'cycle popover / history'
1169
+ },
1170
+ attachUrlTitle: 'Attach a URL',
1171
+ attachUrlDesc: 'NasTech will fetch the page and include it as context for this turn.',
1172
+ urlPlaceholder: 'https://example.com/post',
1173
+ urlHintPre: 'Include the full URL, e.g. ',
1174
+ attach: 'Attach',
1175
+ queued: count => `${count} Queued`,
1176
+ attachmentOnly: 'Attachment-only turn',
1177
+ emptyTurn: 'Empty turn',
1178
+ attachments: count => `${count} attachment${count === 1 ? '' : 's'}`,
1179
+ editingInComposer: 'Editing in composer',
1180
+ editingQueuedInComposer: 'Editing queued turn in composer',
1181
+ editQueued: 'Edit queued turn',
1182
+ sendQueuedNext: 'Send queued turn next',
1183
+ sendQueuedNow: 'Send queued turn now',
1184
+ deleteQueued: 'Delete queued turn',
1185
+ previewUnavailable: 'Preview unavailable',
1186
+ previewLabel: label => `Preview ${label}`,
1187
+ couldNotPreview: label => `Could not preview ${label}`,
1188
+ removeAttachment: label => `Remove ${label}`,
1189
+ dictating: 'Dictating',
1190
+ preparingAudio: 'Preparing audio',
1191
+ speakingResponse: 'Speaking response',
1192
+ readingAloud: 'Reading aloud',
1193
+ themeSuggestions: 'Desktop theme suggestions',
1194
+ noMatchingThemes: 'No matching themes.',
1195
+ themeTryPre: 'Try ',
1196
+ themeTryPost: '.',
1197
+ attachLabel: 'Attach',
1198
+ files: 'Files…',
1199
+ folder: 'Folder…',
1200
+ images: 'Images…',
1201
+ pasteImage: 'Paste image',
1202
+ url: 'URL…',
1203
+ promptSnippets: 'Prompt snippets…',
1204
+ tipPre: 'Tip: type ',
1205
+ tipPost: ' to reference files inline.',
1206
+ snippetsTitle: 'Prompt snippets',
1207
+ snippetsDesc: 'Pick a starter prompt to drop into the composer.',
1208
+ dropFiles: 'Drop files to attach',
1209
+ dropSession: 'Drop to link this chat',
1210
+ snippets: {
1211
+ codeReview: {
1212
+ label: 'Code review',
1213
+ description: 'Audit the current change for regressions, dropped edge cases, and missing tests.',
1214
+ text: 'Please review this for bugs, regressions, and missing tests.'
1215
+ },
1216
+ implementationPlan: {
1217
+ label: 'Implementation plan',
1218
+ description: 'Outline an approach before touching code so the diff stays focused.',
1219
+ text: 'Please make a concise implementation plan before changing code.'
1220
+ },
1221
+ explainThis: {
1222
+ label: 'Explain this',
1223
+ description: 'Walk through how the selected code works and link to the key files.',
1224
+ text: 'Please explain how this works and point me to the key files.'
1225
+ }
1226
+ }
1227
+ },
1228
+
1229
+ statusStack: {
1230
+ agents: 'Agents',
1231
+ background: count => `${count} Background`,
1232
+ subagents: count => `${count} Subagent${count === 1 ? '' : 's'}`,
1233
+ todos: (done, total) => `Tasks ${done}/${total}`,
1234
+ running: 'Running',
1235
+ stop: 'Stop',
1236
+ dismiss: 'Dismiss',
1237
+ exit: code => `exit ${code}`,
1238
+ },
1239
+
1240
+ updates: {
1241
+ stages: {
1242
+ idle: 'Getting ready…',
1243
+ prepare: 'Getting ready…',
1244
+ fetch: 'Downloading…',
1245
+ pull: 'Almost there…',
1246
+ pydeps: 'Finishing up…',
1247
+ restart: 'Restarting NasTech…',
1248
+ manual: 'Update from your terminal',
1249
+ error: 'Update paused'
1250
+ },
1251
+ checking: 'Looking for updates…',
1252
+ checkFailedTitle: 'Couldn’t check for updates',
1253
+ tryAgain: 'Try again',
1254
+ notAvailableTitle: 'Update not available',
1255
+ unsupportedMessage: 'This version of NasTech can’t update itself from inside the app.',
1256
+ connectionRetry: 'Check your connection and try again.',
1257
+ latestBody: 'You’re running the latest version.',
1258
+ allSetTitle: 'You’re all set',
1259
+ availableTitle: 'New update available',
1260
+ availableBody: 'A new version of NasTech is ready to install.',
1261
+ updateNow: 'Update now',
1262
+ maybeLater: 'Maybe later',
1263
+ moreChanges: count => `+ ${count} more change${count === 1 ? '' : 's'} included.`,
1264
+ manualTitle: 'Update from your terminal',
1265
+ manualBody: 'You installed NasTech from the command line, so updates run there too. Paste this into your terminal:',
1266
+ manualPickedUp: 'NasTech will pick up the new version next time you launch it.',
1267
+ copy: 'Copy',
1268
+ copied: 'Copied',
1269
+ done: 'Done',
1270
+ applyingBody: 'The NasTech updater will take over in its own window and reopen NasTech when it’s done.',
1271
+ applyingClose: 'NasTech will close to apply the update.',
1272
+ errorTitle: 'Update didn’t finish',
1273
+ errorBody: 'No worries — nothing was lost. You can try again now.',
1274
+ notNow: 'Not now'
1275
+ },
1276
+
1277
+ install: {
1278
+ stageStates: {
1279
+ pending: 'Pending',
1280
+ running: 'Installing',
1281
+ succeeded: 'Done',
1282
+ skipped: 'Skipped',
1283
+ failed: 'Failed'
1284
+ },
1285
+ oneTimeTitle: 'NasTech needs a one-time install',
1286
+ unsupportedDesc: platform =>
1287
+ `Automated first-launch install isn’t available on ${platform} yet. Open Terminal and run the command below, then relaunch this app. Subsequent launches will skip this step.`,
1288
+ installCommand: 'Install command',
1289
+ copyCommand: 'Copy command',
1290
+ viewDocs: 'View install docs',
1291
+ installTo: 'Will install to',
1292
+ retryAfterRun: 'I’ve run it -- retry',
1293
+ failedTitle: 'Installation failed',
1294
+ settingUpTitle: 'Setting up NasTech Agent',
1295
+ finishingTitle: 'Finishing up',
1296
+ failedDesc:
1297
+ 'One of the install steps failed. On Windows, this can happen if another NasTech CLI or desktop instance is running. Stop any running NasTech instances, then retry. Check the details below or the desktop log for the full transcript.',
1298
+ activeDesc:
1299
+ 'This is a one-time setup. The NasTech installer is downloading dependencies and configuring your machine. Subsequent launches will skip this step.',
1300
+ progress: (completed, total) => `${completed} of ${total} steps complete`,
1301
+ currentStage: stage => ` -- now: ${stage}`,
1302
+ fetchingManifest: 'Fetching installer manifest...',
1303
+ error: 'Error',
1304
+ hideOutput: 'Hide installer output',
1305
+ showOutput: 'Show installer output',
1306
+ lines: count => `${count} line${count === 1 ? '' : 's'}`,
1307
+ noOutput: 'No output yet.',
1308
+ cancelling: 'Cancelling...',
1309
+ cancelInstall: 'Cancel install',
1310
+ transcriptSaved: 'Full transcript saved to',
1311
+ copiedOutput: 'Copied!',
1312
+ copyOutput: 'Copy output',
1313
+ reloadRetry: 'Reload and retry'
1314
+ },
1315
+
1316
+ onboarding: {
1317
+ headerTitle: "Let's get you setup with NasTech Agent",
1318
+ headerDesc: 'Connect a model provider to start chatting. Most options take one click.',
1319
+ preparingInstall: 'NasTech is finishing install. This usually takes under a minute on first run.',
1320
+ starting: 'Starting NasTech…',
1321
+ lookingUpProviders: 'Looking up providers...',
1322
+ collapse: 'Collapse',
1323
+ otherProviders: 'Other providers',
1324
+ haveApiKey: 'I have an API key',
1325
+ chooseLater: "I'll choose a provider later",
1326
+ recommended: 'Recommended',
1327
+ connected: 'Connected',
1328
+ featuredPitch: 'One subscription, 300+ frontier models — the recommended way to run NasTech',
1329
+ openRouterPitch: 'One key, hundreds of models — a solid default',
1330
+ apiKeyOptions: {
1331
+ openrouter: {
1332
+ short: 'one key, many models',
1333
+ description: 'Hosts hundreds of models behind a single key. Good default for new installs.'
1334
+ },
1335
+ openai: { short: 'GPT-class models', description: 'Direct access to OpenAI models.' },
1336
+ gemini: { short: 'Gemini models', description: 'Direct access to Google Gemini models.' },
1337
+ xai: { short: 'Grok models', description: 'Direct access to xAI Grok models.' },
1338
+ local: {
1339
+ short: 'self-hosted',
1340
+ description: 'Point NasTech at a local or self-hosted OpenAI-compatible endpoint (vLLM, llama.cpp, Ollama, etc).'
1341
+ }
1342
+ },
1343
+ backToSignIn: 'Back to sign in',
1344
+ getKey: 'Get a key',
1345
+ replaceCurrent: 'Replace current value',
1346
+ pasteApiKey: 'Paste API key',
1347
+ couldNotSave: 'Could not save credential.',
1348
+ connecting: 'Connecting',
1349
+ update: 'Update',
1350
+ flowSubtitles: {
1351
+ pkce: 'Opens your browser to sign in, then continues here',
1352
+ device_code: 'Opens a verification page in your browser — NasTech connects automatically',
1353
+ loopback: 'Opens your browser to sign in — NasTech connects automatically',
1354
+ external: 'Sign in once in your terminal, then come back to chat'
1355
+ },
1356
+ startingSignIn: provider => `Starting sign-in for ${provider}...`,
1357
+ verifyingCode: provider => `Verifying your code with ${provider}...`,
1358
+ connectedProvider: provider => `${provider} connected`,
1359
+ connectedPicking: provider => `${provider} connected. Picking a default model...`,
1360
+ signInFailed: 'Sign-in failed. Try again.',
1361
+ pickDifferentProvider: 'Pick a different provider',
1362
+ signInWith: provider => `Sign in with ${provider}`,
1363
+ openedBrowser: provider => `We opened ${provider} in your browser.`,
1364
+ authorizeThere: 'Authorize NasTech there.',
1365
+ copyAuthCode: 'Copy the authorization code and paste it below.',
1366
+ pasteAuthCode: 'Paste authorization code',
1367
+ reopenAuthPage: 'Re-open authorization page',
1368
+ autoBrowser: provider =>
1369
+ `We opened ${provider} in your browser. Authorize NasTech there and you'll be connected automatically — nothing to copy or paste.`,
1370
+ reopenSignInPage: 'Re-open sign-in page',
1371
+ waitingAuthorize: 'Waiting for you to authorize...',
1372
+ externalPending: provider =>
1373
+ `${provider} signs in through its own CLI. Run this command in a terminal, then come back and pick "I've signed in":`,
1374
+ signedIn: "I've signed in",
1375
+ deviceCodeOpened: provider => `We opened ${provider} in your browser. Enter this code there:`,
1376
+ reopenVerification: 'Re-open verification page',
1377
+ copy: 'Copy',
1378
+ defaultModel: 'Default model',
1379
+ freeTier: 'Free tier',
1380
+ pro: 'Pro',
1381
+ free: 'Free',
1382
+ price: (input, output) => `${input} in / ${output} out per Mtok`,
1383
+ change: 'Change',
1384
+ startChatting: 'Begin',
1385
+ docs: provider => `${provider} docs`
1386
+ },
1387
+
1388
+ modelPicker: {
1389
+ title: 'Switch model',
1390
+ current: 'current:',
1391
+ unknown: '(unknown)',
1392
+ search: 'Filter providers and models...',
1393
+ noModels: 'No models found.',
1394
+ persistGlobalSession: 'Persist globally (otherwise this session only)',
1395
+ persistGlobal: 'Persist globally',
1396
+ addProvider: 'Add provider',
1397
+ loadFailed: 'Could not load models',
1398
+ noAuthenticatedProviders: 'No authenticated providers.',
1399
+ pro: 'Pro',
1400
+ proNeedsSubscription: 'Pro models need a paid NasTech Portal subscription.',
1401
+ free: 'Free',
1402
+ freeTier: 'Free tier',
1403
+ priceTitle: 'Input / Output price per million tokens'
1404
+ },
1405
+
1406
+ modelVisibility: {
1407
+ title: 'Models',
1408
+ search: 'Search models',
1409
+ noAuthenticatedProviders: 'No authenticated providers.',
1410
+ addProvider: 'Add provider…'
1411
+ },
1412
+
1413
+ shell: {
1414
+ windowControls: 'Window controls',
1415
+ paneControls: 'Pane controls',
1416
+ appControls: 'App controls',
1417
+ modelMenu: {
1418
+ search: 'Search models',
1419
+ noModels: 'No models found',
1420
+ editModels: 'Edit Models…',
1421
+ fast: 'Fast',
1422
+ medium: 'Med'
1423
+ },
1424
+ modelOptions: {
1425
+ noOptions: 'No options for this model',
1426
+ options: 'Options',
1427
+ thinking: 'Thinking',
1428
+ fast: 'Fast',
1429
+ effort: 'Effort',
1430
+ minimal: 'Minimal',
1431
+ low: 'Low',
1432
+ medium: 'Medium',
1433
+ high: 'High',
1434
+ max: 'Max',
1435
+ updateFailed: 'Model option update failed',
1436
+ fastFailed: 'Fast mode update failed'
1437
+ },
1438
+ gatewayMenu: {
1439
+ gateway: 'Gateway',
1440
+ connected: 'Connected',
1441
+ connecting: 'Connecting',
1442
+ offline: 'Offline',
1443
+ inferenceReady: 'Inference ready',
1444
+ inferenceNotReady: 'Inference not ready',
1445
+ checkingInference: 'Checking inference',
1446
+ disconnected: 'Disconnected',
1447
+ openSystem: 'Open system panel',
1448
+ connection: label => `Connection: ${label}`,
1449
+ recentActivity: 'Recent activity',
1450
+ viewAllLogs: 'View all logs →',
1451
+ messagingPlatforms: 'Messaging platforms'
1452
+ },
1453
+ statusbar: {
1454
+ unknown: 'unknown',
1455
+ restart: 'restart',
1456
+ update: 'update',
1457
+ updateInProgress: 'Update in progress',
1458
+ commitsBehind: (count, branch) => `${count} commit${count === 1 ? '' : 's'} behind ${branch}`,
1459
+ desktopVersion: version => `NasTech Desktop v${version}`,
1460
+ commit: sha => `commit ${sha}`,
1461
+ branch: branch => `branch ${branch}`,
1462
+ closeCommandCenter: 'Close Command Center',
1463
+ openCommandCenter: 'Open Command Center',
1464
+ gateway: 'Gateway',
1465
+ gatewayReady: 'ready',
1466
+ gatewayNeedsSetup: 'needs setup',
1467
+ gatewayChecking: 'checking',
1468
+ gatewayConnecting: 'connecting',
1469
+ gatewayOffline: 'offline',
1470
+ gatewayTitle: 'NasTech inference gateway status',
1471
+ agents: 'Agents',
1472
+ closeAgents: 'Close agents',
1473
+ openAgents: 'Open agents',
1474
+ subagents: count => `${count} subagent${count === 1 ? '' : 's'}`,
1475
+ failed: count => `${count} failed`,
1476
+ running: count => `${count} running`,
1477
+ cron: 'Cron',
1478
+ openCron: 'Open cron jobs',
1479
+ turnRunning: 'Running',
1480
+ currentTurnElapsed: 'Current turn elapsed',
1481
+ contextUsage: 'Context usage',
1482
+ session: 'Session',
1483
+ runtimeSessionElapsed: 'Runtime session elapsed',
1484
+ yoloOn: 'YOLO on — auto-approving dangerous commands. Click to turn off.',
1485
+ yoloOff: 'YOLO off — click to auto-approve dangerous commands.',
1486
+ modelNone: 'none',
1487
+ noModel: 'no model',
1488
+ switchModel: 'Switch model',
1489
+ openModelPicker: 'Open model picker',
1490
+ modelTitle: (provider, model) => `Model · ${provider}: ${model}`,
1491
+ providerModelTitle: (provider, model) => `${provider} · ${model}`
1492
+ }
1493
+ },
1494
+
1495
+ rightSidebar: {
1496
+ aria: 'Right sidebar',
1497
+ panelsAria: 'Right sidebar panels',
1498
+ files: 'File system',
1499
+ terminal: 'Terminal',
1500
+ noFolderSelected: 'No folder selected',
1501
+ changeCwdTitle: 'Change working directory',
1502
+ folderTip: cwd => `${cwd} — click to change folder`,
1503
+ openFolder: 'Open folder',
1504
+ refreshTree: 'Refresh tree',
1505
+ collapseAll: 'Collapse all folders',
1506
+ previewUnavailable: 'Preview unavailable',
1507
+ couldNotPreview: path => `Could not preview ${path}`,
1508
+ noProjectTitle: 'No project',
1509
+ noProjectBody: 'Set a working directory from the status bar to browse files.',
1510
+ unreadableTitle: 'Unreadable',
1511
+ unreadableBody: error => `Could not read this folder (${error}).`,
1512
+ emptyTitle: 'Empty',
1513
+ emptyBody: 'This folder is empty.',
1514
+ treeErrorTitle: 'Tree error',
1515
+ treeErrorBody: 'The file tree hit an error rendering this folder.',
1516
+ tryAgain: 'Try again',
1517
+ loadingTree: 'Loading file tree',
1518
+ loadingFiles: 'Loading files',
1519
+ terminalFocus: 'Focus terminal view',
1520
+ terminalSplit: 'Return to split view',
1521
+ addToChat: 'Add to chat',
1522
+ remotePickerTitle: 'Choose remote folder'
1523
+ },
1524
+
1525
+ preview: {
1526
+ tab: 'Preview',
1527
+ closeTab: label => `Close ${label}`,
1528
+ closePane: 'Close preview pane',
1529
+ loading: 'Loading preview',
1530
+ unavailable: 'Preview unavailable',
1531
+ opening: 'Opening...',
1532
+ hide: 'Hide',
1533
+ openPreview: 'Open preview',
1534
+ sourceLineTitle: 'Click to select · shift-click to extend · drag to composer',
1535
+ source: 'SOURCE',
1536
+ renderedPreview: 'PREVIEW',
1537
+ unknownSize: 'unknown size',
1538
+ binaryTitle: 'This looks like a binary file',
1539
+ binaryBody: label => `Previewing ${label} may show unreadable text.`,
1540
+ largeTitle: 'This file is large',
1541
+ largeBody: (label, size) => `${label} is ${size}. NasTech will only show the first 512 KB.`,
1542
+ previewAnyway: 'Preview anyway',
1543
+ truncated: 'Showing first 512 KB.',
1544
+ noInlineTitle: 'No inline preview',
1545
+ noInlineBody: mimeType => `${mimeType || 'This file type'} can still be attached as context.`,
1546
+ console: {
1547
+ deselect: 'Deselect entry',
1548
+ select: 'Select entry',
1549
+ copyFailed: 'Could not copy console output',
1550
+ copyEntry: 'Copy this entry',
1551
+ sendEntry: 'Send this entry to chat',
1552
+ messages: count => `${count} console messages`,
1553
+ resize: 'Resize preview console',
1554
+ title: 'Preview Console',
1555
+ selected: count => `${count} selected`,
1556
+ sendToChat: 'Send to chat',
1557
+ copySelected: 'Copy selected to clipboard',
1558
+ copyAll: 'Copy all to clipboard',
1559
+ copy: 'Copy',
1560
+ clear: 'Clear',
1561
+ empty: 'No console messages yet.',
1562
+ promptHeader: 'Preview console:',
1563
+ sentTitle: 'Sent to chat',
1564
+ sentMessage: count => `${count} log entr${count === 1 ? 'y' : 'ies'} added to composer`
1565
+ },
1566
+ web: {
1567
+ appFailedToBoot: 'Preview app failed to boot',
1568
+ serverNotFound: 'Server not found',
1569
+ failedToLoad: 'Preview failed to load',
1570
+ tryAgain: 'Try again',
1571
+ restarting: 'NasTech is restarting...',
1572
+ askRestart: 'Ask NasTech to restart the server',
1573
+ lookingRestart: taskId => `NasTech is looking for a preview server to restart (${taskId})`,
1574
+ restartingTitle: 'Restarting preview server',
1575
+ restartingMessage: 'NasTech is working in the background. Watch the preview console for progress.',
1576
+ startRestartFailed: message => `Could not start server restart: ${message}`,
1577
+ restartFailed: 'Server restart failed',
1578
+ hideConsole: 'Hide preview console',
1579
+ showConsole: 'Show preview console',
1580
+ hideDevTools: 'Hide preview DevTools',
1581
+ openDevTools: 'Open preview DevTools',
1582
+ finishedRestarting: message => `NasTech finished restarting the preview server${message ? `: ${message}` : ''}`,
1583
+ failedRestarting: message => `Server restart failed: ${message}`,
1584
+ unknownError: 'unknown error',
1585
+ restartedTitle: 'Preview server restarted',
1586
+ reloadingNow: 'Reloading the preview now.',
1587
+ restartFailedTitle: 'Preview restart failed',
1588
+ restartFailedMessage: 'NasTech could not restart the server.',
1589
+ stillWorking:
1590
+ 'NasTech is still working, but no restart result has arrived yet. The server command may be running in the foreground.',
1591
+ workspaceReloading: 'Workspace changed, reloading preview',
1592
+ fileChanged: url => `File changed, reloading preview: ${url}`,
1593
+ filesChanged: (count, url) => `${count} file changes, reloading preview: ${url}`,
1594
+ watchFailed: message => `Could not watch preview file: ${message}`,
1595
+ moduleMimeDescription:
1596
+ 'Module scripts are being served with the wrong MIME type. This usually means a static file server is serving a Vite/React app instead of the project dev server.',
1597
+ loadFailedConsole: (code, message) => `Load failed${code ? ` (${code})` : ''}: ${message}`,
1598
+ unreachableDescription: 'The preview page could not be reached.',
1599
+ openTarget: url => `Open ${url}`,
1600
+ fallbackTitle: 'Preview'
1601
+ }
1602
+ },
1603
+
1604
+ assistant: {
1605
+ thread: {
1606
+ loadingSession: 'Loading session',
1607
+ loadingResponse: 'NasTech is loading a response',
1608
+ thinking: 'Thinking',
1609
+ today: time => `Today, ${time}`,
1610
+ yesterday: time => `Yesterday, ${time}`,
1611
+ copy: 'Copy',
1612
+ refresh: 'Refresh',
1613
+ moreActions: 'More actions',
1614
+ branchNewChat: 'Branch in new chat',
1615
+ readAloudFailed: 'Read aloud failed',
1616
+ preparingAudio: 'Preparing audio...',
1617
+ stopReading: 'Stop reading',
1618
+ readAloud: 'Read aloud',
1619
+ editMessage: 'Edit message',
1620
+ stop: 'Stop',
1621
+ editableCheckpoint: 'Editable checkpoint',
1622
+ restorePrevious: 'Restore previous checkpoint',
1623
+ restoreCheckpoint: 'Restore checkpoint',
1624
+ restoreNext: 'Restore next checkpoint',
1625
+ goForward: 'Go forward',
1626
+ sendEdited: 'Send edited message',
1627
+ scrollToBottom: 'Scroll to bottom'
1628
+ },
1629
+ approval: {
1630
+ gatewayDisconnected: 'NasTech gateway is not connected',
1631
+ sendFailed: 'Could not send approval response',
1632
+ run: 'Run',
1633
+ moreOptions: 'More approval options',
1634
+ allowSession: 'Allow this session',
1635
+ alwaysAllowMenu: 'Always allow…',
1636
+ jumpToApproval: 'Approval needed',
1637
+ reject: 'Reject',
1638
+ alwaysTitle: 'Always allow this command?',
1639
+ alwaysDescription: pattern =>
1640
+ `This adds the “${pattern}” pattern to your permanent allowlist (~/.nastech/config.yaml). NasTech won’t ask again for commands like this — in this session or any future one.`,
1641
+ alwaysAllow: 'Always allow'
1642
+ },
1643
+ clarify: {
1644
+ notReady: 'Clarify request is not ready yet',
1645
+ gatewayDisconnected: 'NasTech gateway is not connected',
1646
+ sendFailed: 'Could not send clarify response',
1647
+ loadingQuestion: 'Loading question…',
1648
+ other: 'Other (type your answer)',
1649
+ placeholder: 'Type your answer…',
1650
+ shortcut: '⌘/Ctrl + Enter to send',
1651
+ back: 'Back',
1652
+ skip: 'Skip',
1653
+ send: 'Send'
1654
+ },
1655
+ tool: {
1656
+ code: 'Code',
1657
+ copyCode: 'Copy code',
1658
+ renderingImage: 'Rendering image',
1659
+ copyOutput: 'Copy output',
1660
+ copyCommand: 'Copy command',
1661
+ copyContent: 'Copy content',
1662
+ copyUrl: 'Copy URL',
1663
+ copyResults: 'Copy results',
1664
+ copyQuery: 'Copy query',
1665
+ copyFile: 'Copy file',
1666
+ copyPath: 'Copy path',
1667
+ outputAlt: 'Tool output',
1668
+ rawResponse: 'Raw response',
1669
+ copyActivity: 'Copy activity',
1670
+ recoveredOne: 'Recovered after 1 failed step',
1671
+ recoveredMany: count => `Recovered after ${count} failed steps`,
1672
+ failedOne: '1 step failed',
1673
+ failedMany: count => `${count} steps failed`,
1674
+ statusRunning: 'Running',
1675
+ statusError: 'Error',
1676
+ statusRecovered: 'Recovered',
1677
+ statusDone: 'Done'
1678
+ }
1679
+ },
1680
+
1681
+ prompts: {
1682
+ gatewayDisconnected: 'NasTech gateway is not connected',
1683
+ sudoSendFailed: 'Could not send sudo password',
1684
+ secretSendFailed: 'Could not send secret',
1685
+ sudoTitle: 'Administrator password',
1686
+ sudoDesc: 'NasTech needs your sudo password to run a privileged command. It is sent only to your local agent.',
1687
+ sudoPlaceholder: 'sudo password',
1688
+ secretTitle: 'Secret required',
1689
+ secretDesc: 'NasTech needs a credential to continue.',
1690
+ secretPlaceholder: 'secret value'
1691
+ },
1692
+
1693
+ desktop: {
1694
+ audioReadFailed: 'Could not read recorded audio',
1695
+ sessionUnavailable: 'Session unavailable',
1696
+ createSessionFailed: 'Could not create a new session',
1697
+ promptFailed: 'Prompt failed',
1698
+ providerCredentialRequired: 'Add a provider credential before sending your first message.',
1699
+ emptySlashCommand: 'empty slash command',
1700
+ desktopCommands: 'Desktop commands',
1701
+ skillCommandsAvailable: count => `${count} skill commands available.`,
1702
+ warningLine: message => `warning: ${message}`,
1703
+ yoloArmed: 'YOLO armed for this chat',
1704
+ yoloOff: 'YOLO off',
1705
+ yoloSystem: active => `YOLO ${active ? 'on' : 'off'} for this session`,
1706
+ yoloTitle: 'YOLO',
1707
+ yoloToggleFailed: 'Could not toggle YOLO',
1708
+ profileStatus: current =>
1709
+ `Profile: ${current}. Use /profile <name> or the "New session" picker to start a chat in another profile.`,
1710
+ unknownProfile: 'Unknown profile',
1711
+ noProfileNamed: (target, available) => `No profile named "${target}". Available: ${available}`,
1712
+ newChatsProfile: name => `New chats will use profile ${name}.`,
1713
+ setProfileFailed: 'Failed to set profile',
1714
+ sttDisabled: 'Speech-to-text is disabled in settings.',
1715
+ stopFailed: 'Stop failed',
1716
+ regenerateFailed: 'Regenerate failed',
1717
+ editFailed: 'Edit failed',
1718
+ resumeFailed: 'Resume failed',
1719
+ nothingToBranch: 'Nothing to branch',
1720
+ branchNeedsChat: 'Start or resume a chat before branching.',
1721
+ sessionBusy: 'Session busy',
1722
+ branchStopCurrent: 'Stop the current turn before branching this chat.',
1723
+ branchNoText: 'This message has no text to branch from.',
1724
+ branchTitle: 'Branch',
1725
+ branchFailed: 'Branch failed',
1726
+ deleteFailed: 'Delete failed',
1727
+ archived: 'Archived',
1728
+ archiveFailed: 'Archive failed',
1729
+ cwdChangeFailed: 'Working directory change failed',
1730
+ cwdStagedTitle: 'Working directory staged',
1731
+ cwdStagedMessage: 'Restart the desktop backend to apply cwd changes to this active session.',
1732
+ modelSwitchFailed: 'Model switch failed',
1733
+ sessionExported: 'Session exported',
1734
+ sessionExportFailed: 'Could not export session',
1735
+ imageSaved: 'Image saved',
1736
+ downloadStarted: 'Download started',
1737
+ restartToUseSaveImage: 'Restart NasTech Desktop to use Save Image.',
1738
+ restartToSaveImages: 'Restart NasTech Desktop to save images',
1739
+ imageDownloadFailed: 'Image download failed',
1740
+ openImage: 'Open image',
1741
+ downloadImage: 'Download image',
1742
+ savingImage: 'Saving image',
1743
+ imagePreviewFailed: 'Image preview failed',
1744
+ imageAttach: 'Image attach',
1745
+ imageWriteFailed: 'Failed to write image to disk.',
1746
+ imageAttachFailed: 'Image attach failed',
1747
+ attachImages: 'Attach images',
1748
+ clipboard: 'Clipboard',
1749
+ noClipboardImage: 'No image found in clipboard',
1750
+ clipboardPasteFailed: 'Clipboard paste failed',
1751
+ dropFiles: 'Drop files'
1752
+ },
1753
+
1754
+ errors: {
1755
+ genericFailure: 'Something went wrong',
1756
+ boundaryTitle: 'Something broke in the interface',
1757
+ boundaryDesc: 'The view hit an unexpected error. Your chats and settings are safe.',
1758
+ reloadWindow: 'Reload window',
1759
+ openLogs: 'Open logs'
1760
+ },
1761
+
1762
+ ui: {
1763
+ search: {
1764
+ clear: 'Clear search'
1765
+ },
1766
+ pagination: {
1767
+ label: 'pagination',
1768
+ previous: 'Prev',
1769
+ previousAria: 'Go to previous page',
1770
+ next: 'Next',
1771
+ nextAria: 'Go to next page'
1772
+ },
1773
+ sidebar: {
1774
+ title: 'Sidebar',
1775
+ description: 'Displays the mobile sidebar.',
1776
+ toggle: 'Toggle Sidebar'
1777
+ }
1778
+ }
1779
+ }