@neurocode-ai/desktop 1.18.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (253) hide show
  1. package/AGENTS.md +4 -0
  2. package/README.md +19 -0
  3. package/electron-builder.config.test.ts +48 -0
  4. package/electron-builder.config.ts +146 -0
  5. package/electron.vite.config.ts +106 -0
  6. package/icons/README.md +14 -0
  7. package/icons/beta/128x128.png +0 -0
  8. package/icons/beta/128x128@2x.png +0 -0
  9. package/icons/beta/32x32.png +0 -0
  10. package/icons/beta/64x64.png +0 -0
  11. package/icons/beta/Square107x107Logo.png +0 -0
  12. package/icons/beta/Square142x142Logo.png +0 -0
  13. package/icons/beta/Square150x150Logo.png +0 -0
  14. package/icons/beta/Square284x284Logo.png +0 -0
  15. package/icons/beta/Square30x30Logo.png +0 -0
  16. package/icons/beta/Square310x310Logo.png +0 -0
  17. package/icons/beta/Square44x44Logo.png +0 -0
  18. package/icons/beta/Square71x71Logo.png +0 -0
  19. package/icons/beta/Square89x89Logo.png +0 -0
  20. package/icons/beta/StoreLogo.png +0 -0
  21. package/icons/beta/android/mipmap-anydpi-v26/ic_launcher.xml +5 -0
  22. package/icons/beta/android/mipmap-hdpi/ic_launcher.png +0 -0
  23. package/icons/beta/android/mipmap-hdpi/ic_launcher_foreground.png +0 -0
  24. package/icons/beta/android/mipmap-hdpi/ic_launcher_round.png +0 -0
  25. package/icons/beta/android/mipmap-mdpi/ic_launcher.png +0 -0
  26. package/icons/beta/android/mipmap-mdpi/ic_launcher_foreground.png +0 -0
  27. package/icons/beta/android/mipmap-mdpi/ic_launcher_round.png +0 -0
  28. package/icons/beta/android/mipmap-xhdpi/ic_launcher.png +0 -0
  29. package/icons/beta/android/mipmap-xhdpi/ic_launcher_foreground.png +0 -0
  30. package/icons/beta/android/mipmap-xhdpi/ic_launcher_round.png +0 -0
  31. package/icons/beta/android/mipmap-xxhdpi/ic_launcher.png +0 -0
  32. package/icons/beta/android/mipmap-xxhdpi/ic_launcher_foreground.png +0 -0
  33. package/icons/beta/android/mipmap-xxhdpi/ic_launcher_round.png +0 -0
  34. package/icons/beta/android/mipmap-xxxhdpi/ic_launcher.png +0 -0
  35. package/icons/beta/android/mipmap-xxxhdpi/ic_launcher_foreground.png +0 -0
  36. package/icons/beta/android/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
  37. package/icons/beta/android/values/ic_launcher_background.xml +4 -0
  38. package/icons/beta/dock.png +0 -0
  39. package/icons/beta/icon.icns +0 -0
  40. package/icons/beta/icon.ico +0 -0
  41. package/icons/beta/icon.png +0 -0
  42. package/icons/beta/ios/AppIcon-20x20@1x.png +0 -0
  43. package/icons/beta/ios/AppIcon-20x20@2x-1.png +0 -0
  44. package/icons/beta/ios/AppIcon-20x20@2x.png +0 -0
  45. package/icons/beta/ios/AppIcon-20x20@3x.png +0 -0
  46. package/icons/beta/ios/AppIcon-29x29@1x.png +0 -0
  47. package/icons/beta/ios/AppIcon-29x29@2x-1.png +0 -0
  48. package/icons/beta/ios/AppIcon-29x29@2x.png +0 -0
  49. package/icons/beta/ios/AppIcon-29x29@3x.png +0 -0
  50. package/icons/beta/ios/AppIcon-40x40@1x.png +0 -0
  51. package/icons/beta/ios/AppIcon-40x40@2x-1.png +0 -0
  52. package/icons/beta/ios/AppIcon-40x40@2x.png +0 -0
  53. package/icons/beta/ios/AppIcon-40x40@3x.png +0 -0
  54. package/icons/beta/ios/AppIcon-512@2x.png +0 -0
  55. package/icons/beta/ios/AppIcon-60x60@2x.png +0 -0
  56. package/icons/beta/ios/AppIcon-60x60@3x.png +0 -0
  57. package/icons/beta/ios/AppIcon-76x76@1x.png +0 -0
  58. package/icons/beta/ios/AppIcon-76x76@2x.png +0 -0
  59. package/icons/beta/ios/AppIcon-83.5x83.5@2x.png +0 -0
  60. package/icons/dev/128x128.png +0 -0
  61. package/icons/dev/128x128@2x.png +0 -0
  62. package/icons/dev/32x32.png +0 -0
  63. package/icons/dev/64x64.png +0 -0
  64. package/icons/dev/Square107x107Logo.png +0 -0
  65. package/icons/dev/Square142x142Logo.png +0 -0
  66. package/icons/dev/Square150x150Logo.png +0 -0
  67. package/icons/dev/Square284x284Logo.png +0 -0
  68. package/icons/dev/Square30x30Logo.png +0 -0
  69. package/icons/dev/Square310x310Logo.png +0 -0
  70. package/icons/dev/Square44x44Logo.png +0 -0
  71. package/icons/dev/Square71x71Logo.png +0 -0
  72. package/icons/dev/Square89x89Logo.png +0 -0
  73. package/icons/dev/StoreLogo.png +0 -0
  74. package/icons/dev/android/mipmap-anydpi-v26/ic_launcher.xml +5 -0
  75. package/icons/dev/android/mipmap-hdpi/ic_launcher.png +0 -0
  76. package/icons/dev/android/mipmap-hdpi/ic_launcher_foreground.png +0 -0
  77. package/icons/dev/android/mipmap-hdpi/ic_launcher_round.png +0 -0
  78. package/icons/dev/android/mipmap-mdpi/ic_launcher.png +0 -0
  79. package/icons/dev/android/mipmap-mdpi/ic_launcher_foreground.png +0 -0
  80. package/icons/dev/android/mipmap-mdpi/ic_launcher_round.png +0 -0
  81. package/icons/dev/android/mipmap-xhdpi/ic_launcher.png +0 -0
  82. package/icons/dev/android/mipmap-xhdpi/ic_launcher_foreground.png +0 -0
  83. package/icons/dev/android/mipmap-xhdpi/ic_launcher_round.png +0 -0
  84. package/icons/dev/android/mipmap-xxhdpi/ic_launcher.png +0 -0
  85. package/icons/dev/android/mipmap-xxhdpi/ic_launcher_foreground.png +0 -0
  86. package/icons/dev/android/mipmap-xxhdpi/ic_launcher_round.png +0 -0
  87. package/icons/dev/android/mipmap-xxxhdpi/ic_launcher.png +0 -0
  88. package/icons/dev/android/mipmap-xxxhdpi/ic_launcher_foreground.png +0 -0
  89. package/icons/dev/android/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
  90. package/icons/dev/android/values/ic_launcher_background.xml +4 -0
  91. package/icons/dev/dock.png +0 -0
  92. package/icons/dev/icon.icns +0 -0
  93. package/icons/dev/icon.ico +0 -0
  94. package/icons/dev/icon.png +0 -0
  95. package/icons/dev/ios/AppIcon-20x20@1x.png +0 -0
  96. package/icons/dev/ios/AppIcon-20x20@2x-1.png +0 -0
  97. package/icons/dev/ios/AppIcon-20x20@2x.png +0 -0
  98. package/icons/dev/ios/AppIcon-20x20@3x.png +0 -0
  99. package/icons/dev/ios/AppIcon-29x29@1x.png +0 -0
  100. package/icons/dev/ios/AppIcon-29x29@2x-1.png +0 -0
  101. package/icons/dev/ios/AppIcon-29x29@2x.png +0 -0
  102. package/icons/dev/ios/AppIcon-29x29@3x.png +0 -0
  103. package/icons/dev/ios/AppIcon-40x40@1x.png +0 -0
  104. package/icons/dev/ios/AppIcon-40x40@2x-1.png +0 -0
  105. package/icons/dev/ios/AppIcon-40x40@2x.png +0 -0
  106. package/icons/dev/ios/AppIcon-40x40@3x.png +0 -0
  107. package/icons/dev/ios/AppIcon-512@2x.png +0 -0
  108. package/icons/dev/ios/AppIcon-60x60@2x.png +0 -0
  109. package/icons/dev/ios/AppIcon-60x60@3x.png +0 -0
  110. package/icons/dev/ios/AppIcon-76x76@1x.png +0 -0
  111. package/icons/dev/ios/AppIcon-76x76@2x.png +0 -0
  112. package/icons/dev/ios/AppIcon-83.5x83.5@2x.png +0 -0
  113. package/icons/prod/128x128.png +0 -0
  114. package/icons/prod/128x128@2x.png +0 -0
  115. package/icons/prod/32x32.png +0 -0
  116. package/icons/prod/64x64.png +0 -0
  117. package/icons/prod/Square107x107Logo.png +0 -0
  118. package/icons/prod/Square142x142Logo.png +0 -0
  119. package/icons/prod/Square150x150Logo.png +0 -0
  120. package/icons/prod/Square284x284Logo.png +0 -0
  121. package/icons/prod/Square30x30Logo.png +0 -0
  122. package/icons/prod/Square310x310Logo.png +0 -0
  123. package/icons/prod/Square44x44Logo.png +0 -0
  124. package/icons/prod/Square71x71Logo.png +0 -0
  125. package/icons/prod/Square89x89Logo.png +0 -0
  126. package/icons/prod/StoreLogo.png +0 -0
  127. package/icons/prod/android/mipmap-anydpi-v26/ic_launcher.xml +5 -0
  128. package/icons/prod/android/mipmap-hdpi/ic_launcher.png +0 -0
  129. package/icons/prod/android/mipmap-hdpi/ic_launcher_foreground.png +0 -0
  130. package/icons/prod/android/mipmap-hdpi/ic_launcher_round.png +0 -0
  131. package/icons/prod/android/mipmap-mdpi/ic_launcher.png +0 -0
  132. package/icons/prod/android/mipmap-mdpi/ic_launcher_foreground.png +0 -0
  133. package/icons/prod/android/mipmap-mdpi/ic_launcher_round.png +0 -0
  134. package/icons/prod/android/mipmap-xhdpi/ic_launcher.png +0 -0
  135. package/icons/prod/android/mipmap-xhdpi/ic_launcher_foreground.png +0 -0
  136. package/icons/prod/android/mipmap-xhdpi/ic_launcher_round.png +0 -0
  137. package/icons/prod/android/mipmap-xxhdpi/ic_launcher.png +0 -0
  138. package/icons/prod/android/mipmap-xxhdpi/ic_launcher_foreground.png +0 -0
  139. package/icons/prod/android/mipmap-xxhdpi/ic_launcher_round.png +0 -0
  140. package/icons/prod/android/mipmap-xxxhdpi/ic_launcher.png +0 -0
  141. package/icons/prod/android/mipmap-xxxhdpi/ic_launcher_foreground.png +0 -0
  142. package/icons/prod/android/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
  143. package/icons/prod/android/values/ic_launcher_background.xml +4 -0
  144. package/icons/prod/dock.png +0 -0
  145. package/icons/prod/icon.icns +0 -0
  146. package/icons/prod/icon.ico +0 -0
  147. package/icons/prod/icon.png +0 -0
  148. package/icons/prod/ios/AppIcon-20x20@1x.png +0 -0
  149. package/icons/prod/ios/AppIcon-20x20@2x-1.png +0 -0
  150. package/icons/prod/ios/AppIcon-20x20@2x.png +0 -0
  151. package/icons/prod/ios/AppIcon-20x20@3x.png +0 -0
  152. package/icons/prod/ios/AppIcon-29x29@1x.png +0 -0
  153. package/icons/prod/ios/AppIcon-29x29@2x-1.png +0 -0
  154. package/icons/prod/ios/AppIcon-29x29@2x.png +0 -0
  155. package/icons/prod/ios/AppIcon-29x29@3x.png +0 -0
  156. package/icons/prod/ios/AppIcon-40x40@1x.png +0 -0
  157. package/icons/prod/ios/AppIcon-40x40@2x-1.png +0 -0
  158. package/icons/prod/ios/AppIcon-40x40@2x.png +0 -0
  159. package/icons/prod/ios/AppIcon-40x40@3x.png +0 -0
  160. package/icons/prod/ios/AppIcon-512@2x.png +0 -0
  161. package/icons/prod/ios/AppIcon-60x60@2x.png +0 -0
  162. package/icons/prod/ios/AppIcon-60x60@3x.png +0 -0
  163. package/icons/prod/ios/AppIcon-76x76@1x.png +0 -0
  164. package/icons/prod/ios/AppIcon-76x76@2x.png +0 -0
  165. package/icons/prod/ios/AppIcon-83.5x83.5@2x.png +0 -0
  166. package/package.json +75 -0
  167. package/resources/entitlements.plist +18 -0
  168. package/resources/linux/opencode-desktop.desktop +10 -0
  169. package/scripts/copy-bundles.ts +12 -0
  170. package/scripts/copy-icons.ts +12 -0
  171. package/scripts/copy-metainfo.ts +47 -0
  172. package/scripts/finalize-latest-json.ts +219 -0
  173. package/scripts/finalize-latest-yml.ts +124 -0
  174. package/scripts/prebuild.ts +10 -0
  175. package/scripts/predev.ts +5 -0
  176. package/scripts/prepare.ts +9 -0
  177. package/scripts/utils.ts +77 -0
  178. package/src/main/apps.ts +136 -0
  179. package/src/main/attachment-picker.test.ts +87 -0
  180. package/src/main/attachment-picker.ts +56 -0
  181. package/src/main/constants.ts +7 -0
  182. package/src/main/debug.ts +95 -0
  183. package/src/main/desktop-menu-actions.ts +84 -0
  184. package/src/main/env.d.ts +19 -0
  185. package/src/main/index.test.ts +37 -0
  186. package/src/main/index.ts +399 -0
  187. package/src/main/initialization.ts +6 -0
  188. package/src/main/install-state.test.ts +19 -0
  189. package/src/main/install-state.ts +8 -0
  190. package/src/main/ipc.ts +274 -0
  191. package/src/main/logging.ts +205 -0
  192. package/src/main/markdown.ts +16 -0
  193. package/src/main/menu.ts +67 -0
  194. package/src/main/migrate.ts +91 -0
  195. package/src/main/onboarding.ts +45 -0
  196. package/src/main/server.ts +238 -0
  197. package/src/main/shell-env.test.ts +50 -0
  198. package/src/main/shell-env.ts +101 -0
  199. package/src/main/sidecar.ts +157 -0
  200. package/src/main/store-cleanup.test.ts +93 -0
  201. package/src/main/store-cleanup.ts +94 -0
  202. package/src/main/store-keys.ts +7 -0
  203. package/src/main/store.ts +35 -0
  204. package/src/main/unresponsive.ts +70 -0
  205. package/src/main/updater-controller.test.ts +111 -0
  206. package/src/main/updater-controller.ts +97 -0
  207. package/src/main/updater-subscriptions.test.ts +16 -0
  208. package/src/main/updater-subscriptions.ts +20 -0
  209. package/src/main/updater.ts +85 -0
  210. package/src/main/window-registry.test.ts +91 -0
  211. package/src/main/window-registry.ts +47 -0
  212. package/src/main/window-state.ts +29 -0
  213. package/src/main/windows.ts +496 -0
  214. package/src/main/wsl/ipc.ts +103 -0
  215. package/src/main/wsl/policy.ts +33 -0
  216. package/src/main/wsl/runtime.ts +400 -0
  217. package/src/main/wsl/servers.test.ts +231 -0
  218. package/src/main/wsl/servers.ts +521 -0
  219. package/src/main/wsl/sidecar.ts +129 -0
  220. package/src/main/wsl/startup.ts +31 -0
  221. package/src/preload/index.ts +128 -0
  222. package/src/preload/types.ts +109 -0
  223. package/src/renderer/cli.ts +12 -0
  224. package/src/renderer/env.d.ts +10 -0
  225. package/src/renderer/html.test.ts +62 -0
  226. package/src/renderer/i18n/ar.ts +26 -0
  227. package/src/renderer/i18n/br.ts +27 -0
  228. package/src/renderer/i18n/bs.ts +28 -0
  229. package/src/renderer/i18n/da.ts +28 -0
  230. package/src/renderer/i18n/de.ts +28 -0
  231. package/src/renderer/i18n/en.ts +27 -0
  232. package/src/renderer/i18n/es.ts +27 -0
  233. package/src/renderer/i18n/fr.ts +28 -0
  234. package/src/renderer/i18n/index.ts +194 -0
  235. package/src/renderer/i18n/ja.ts +28 -0
  236. package/src/renderer/i18n/ko.ts +27 -0
  237. package/src/renderer/i18n/no.ts +28 -0
  238. package/src/renderer/i18n/pl.ts +28 -0
  239. package/src/renderer/i18n/ru.ts +27 -0
  240. package/src/renderer/i18n/uk.ts +28 -0
  241. package/src/renderer/i18n/zh.ts +26 -0
  242. package/src/renderer/i18n/zht.ts +26 -0
  243. package/src/renderer/index.html +21 -0
  244. package/src/renderer/index.tsx +464 -0
  245. package/src/renderer/initialization.test.ts +73 -0
  246. package/src/renderer/initialization.ts +22 -0
  247. package/src/renderer/onboarding.tsx +53 -0
  248. package/src/renderer/styles.css +0 -0
  249. package/src/renderer/webview-zoom.ts +138 -0
  250. package/src/renderer/wsl/connections.test.ts +43 -0
  251. package/src/renderer/wsl/connections.ts +28 -0
  252. package/sst-env.d.ts +10 -0
  253. package/tsconfig.json +23 -0
@@ -0,0 +1,138 @@
1
+ // Copyright 2019-2024 Tauri Programme within The Commons Conservancy
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ // SPDX-License-Identifier: MIT
4
+
5
+ import { createSignal } from "solid-js"
6
+
7
+ const OS_NAME = (() => {
8
+ if (navigator.userAgent.includes("Mac")) return "macos"
9
+ if (navigator.userAgent.includes("Windows")) return "windows"
10
+ if (navigator.userAgent.includes("Linux")) return "linux"
11
+ return "unknown"
12
+ })()
13
+
14
+ const [webviewZoom, setWebviewZoom] = createSignal(1)
15
+ let requestedZoom = 1
16
+ let pinchZoomEnabled = false
17
+ let wheelPinch = undefined as
18
+ | {
19
+ active: boolean
20
+ startZoom: number
21
+ totalDelta: number
22
+ timeout: ReturnType<typeof setTimeout> | undefined
23
+ }
24
+ | undefined
25
+
26
+ const MAX_ZOOM_LEVEL = 10
27
+ const MIN_ZOOM_LEVEL = 0.2
28
+ const WHEEL_PINCH_THRESHOLD = 20
29
+ const WHEEL_PINCH_STEP = 0.2
30
+ const WHEEL_PINCH_END_DELAY = 160
31
+
32
+ const clamp = (value: number) => Math.min(Math.max(value, MIN_ZOOM_LEVEL), MAX_ZOOM_LEVEL)
33
+
34
+ const applyZoom = (next: number) => {
35
+ requestedZoom = next
36
+ void window.api
37
+ .setZoomFactor(next)
38
+ .then(() => {
39
+ if (requestedZoom !== next) return
40
+ setWebviewZoom(next)
41
+ })
42
+ .catch(() => {
43
+ if (requestedZoom !== next) return
44
+ requestedZoom = webviewZoom()
45
+ })
46
+ }
47
+
48
+ window.api.onZoomFactorChanged((factor) => {
49
+ requestedZoom = clamp(factor)
50
+ setWebviewZoom(requestedZoom)
51
+ })
52
+
53
+ void window.api.getPinchZoomEnabled().then((enabled) => {
54
+ pinchZoomEnabled = enabled
55
+ })
56
+
57
+ window.api.onPinchZoomEnabledChanged((enabled) => {
58
+ pinchZoomEnabled = enabled
59
+ resetWheelPinch()
60
+ })
61
+
62
+ const setPinchZoomEnabled = (enabled: boolean) => {
63
+ pinchZoomEnabled = enabled
64
+ resetWheelPinch()
65
+ return window.api.setPinchZoomEnabled(enabled)
66
+ }
67
+
68
+ const resetZoom = () => applyZoom(1)
69
+ const zoomIn = () => applyZoom(clamp(requestedZoom + 0.2))
70
+ const zoomOut = () => applyZoom(clamp(requestedZoom - 0.2))
71
+
72
+ const resetWheelPinch = () => {
73
+ clearTimeout(wheelPinch?.timeout)
74
+ wheelPinch = undefined
75
+ }
76
+
77
+ const normalizeWheelDelta = (event: WheelEvent) => {
78
+ if (event.deltaMode === WheelEvent.DOM_DELTA_LINE) return event.deltaY * 16
79
+ if (event.deltaMode === WheelEvent.DOM_DELTA_PAGE) return event.deltaY * window.innerHeight
80
+ return event.deltaY
81
+ }
82
+
83
+ const updateWheelPinch = (event: WheelEvent) => {
84
+ wheelPinch ??= {
85
+ active: false,
86
+ startZoom: requestedZoom,
87
+ totalDelta: 0,
88
+ timeout: undefined,
89
+ }
90
+
91
+ clearTimeout(wheelPinch.timeout)
92
+ wheelPinch.timeout = setTimeout(resetWheelPinch, WHEEL_PINCH_END_DELAY)
93
+ wheelPinch.totalDelta += normalizeWheelDelta(event)
94
+
95
+ if (!wheelPinch.active && Math.abs(wheelPinch.totalDelta) < WHEEL_PINCH_THRESHOLD) return
96
+ if (!wheelPinch.active) {
97
+ wheelPinch.active = true
98
+ wheelPinch.startZoom = requestedZoom
99
+ wheelPinch.totalDelta = 0
100
+ return
101
+ }
102
+
103
+ wheelPinch.active = true
104
+ applyZoom(clamp(wheelPinch.startZoom - (wheelPinch.totalDelta / WHEEL_PINCH_THRESHOLD) * WHEEL_PINCH_STEP))
105
+ }
106
+
107
+ window.addEventListener(
108
+ "wheel",
109
+ (event) => {
110
+ if (!pinchZoomEnabled) return
111
+ if (!event.ctrlKey) return
112
+
113
+ event.preventDefault()
114
+ updateWheelPinch(event)
115
+ },
116
+ { passive: false },
117
+ )
118
+
119
+ window.addEventListener("keydown", (event) => {
120
+ if (!(OS_NAME === "macos" ? event.metaKey : event.ctrlKey)) return
121
+
122
+ if (event.key === "-") {
123
+ event.preventDefault()
124
+ zoomOut()
125
+ return
126
+ }
127
+ if (event.key === "=" || event.key === "+") {
128
+ event.preventDefault()
129
+ zoomIn()
130
+ return
131
+ }
132
+ if (event.key === "0") {
133
+ event.preventDefault()
134
+ resetZoom()
135
+ }
136
+ })
137
+
138
+ export { webviewZoom, resetZoom, setPinchZoomEnabled, zoomIn, zoomOut }
@@ -0,0 +1,43 @@
1
+ import { describe, expect, test } from "bun:test"
2
+ import type { WslServersState } from "@neurocode-ai/app/wsl/types"
3
+ import { availableStartupServer, readyWslConnections } from "./connections"
4
+
5
+ const state = (kind: "starting" | "ready" | "failed" | "stopped"): WslServersState => ({
6
+ runtime: null,
7
+ installed: [],
8
+ online: [],
9
+ distroProbes: {},
10
+ neurocodeChecks: {},
11
+ pendingRestart: false,
12
+ job: null,
13
+ servers: [
14
+ {
15
+ config: { id: "wsl:Debian", distro: "Debian" },
16
+ runtime: runtime(kind),
17
+ },
18
+ ],
19
+ })
20
+
21
+ function runtime(kind: "starting" | "ready" | "failed" | "stopped") {
22
+ if (kind === "ready") return { kind, url: "http://127.0.0.1:4096", username: "neurocode", password: "secret" }
23
+ if (kind === "failed") return { kind, message: "boom" }
24
+ return { kind }
25
+ }
26
+
27
+ describe("WSL desktop connections", () => {
28
+ test("publishes a WSL server only after it reports ready", () => {
29
+ expect(readyWslConnections(state("starting"))).toEqual([])
30
+ expect(readyWslConnections(state("failed"))).toEqual([])
31
+ expect(readyWslConnections(state("stopped"))).toEqual([])
32
+ expect(readyWslConnections(state("ready"))).toEqual([
33
+ expect.objectContaining({ displayName: "Debian", label: "WSL" }),
34
+ ])
35
+ })
36
+
37
+ test("does not block desktop startup on a configured WSL default", () => {
38
+ const key = "wsl:Debian"
39
+ expect(availableStartupServer(key, undefined)).toBe("sidecar")
40
+ expect(availableStartupServer(key, state("starting"))).toBe("sidecar")
41
+ expect(availableStartupServer(key, state("ready"))).toBe(key)
42
+ })
43
+ })
@@ -0,0 +1,28 @@
1
+ import type { WslServersState } from "@neurocode-ai/app/wsl/types"
2
+
3
+ export function readyWslConnections(state?: WslServersState) {
4
+ return (state?.servers ?? []).flatMap((item) => {
5
+ if (item.runtime.kind !== "ready") return []
6
+ return [
7
+ {
8
+ displayName: item.config.distro,
9
+ label: "WSL",
10
+ type: "sidecar" as const,
11
+ variant: "wsl" as const,
12
+ distro: item.config.distro,
13
+ http: {
14
+ url: item.runtime.url,
15
+ username: item.runtime.username ?? undefined,
16
+ password: item.runtime.password ?? undefined,
17
+ },
18
+ },
19
+ ]
20
+ })
21
+ }
22
+
23
+ export function availableStartupServer(defaultServer: string | null | undefined, state?: WslServersState) {
24
+ const key = defaultServer ?? "sidecar"
25
+ if (!key.startsWith("wsl:")) return key
26
+ if (state?.servers.some((item) => item.config.id === key && item.runtime.kind === "ready")) return key
27
+ return "sidecar"
28
+ }
package/sst-env.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ /* This file is auto-generated by SST. Do not edit. */
2
+ /* tslint:disable */
3
+ /* eslint-disable */
4
+ /* deno-fmt-ignore-file */
5
+ /* biome-ignore-all lint: auto-generated */
6
+
7
+ /// <reference path="../../sst-env.d.ts" />
8
+
9
+ import "sst"
10
+ export {}
package/tsconfig.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ESNext",
4
+ "module": "ESNext",
5
+ "skipLibCheck": true,
6
+ "moduleResolution": "bundler",
7
+ "allowSyntheticDefaultImports": true,
8
+ "esModuleInterop": true,
9
+ "jsx": "preserve",
10
+ "jsxImportSource": "solid-js",
11
+ "allowJs": true,
12
+ "resolveJsonModule": true,
13
+ "strict": true,
14
+ "isolatedModules": true,
15
+ "noEmit": true,
16
+ "emitDeclarationOnly": false,
17
+ "outDir": "node_modules/.ts-dist",
18
+ "types": ["vite/client", "node", "electron"]
19
+ },
20
+ "references": [{ "path": "../app" }],
21
+ "include": ["src", "package.json"],
22
+ "exclude": ["src/**/*.test.ts"]
23
+ }