@mindstudio-ai/local-model-tunnel 0.1.9 → 0.3.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 (170) hide show
  1. package/README.md +30 -115
  2. package/dist/chunk-PTK4SJQK.js +1768 -0
  3. package/dist/chunk-PTK4SJQK.js.map +1 -0
  4. package/dist/cli.d.ts +0 -2
  5. package/dist/cli.js +8 -517
  6. package/dist/cli.js.map +1 -1
  7. package/dist/index.d.ts +24 -5
  8. package/dist/index.js +6 -13
  9. package/dist/index.js.map +1 -1
  10. package/dist/tui-56JFPKBP.js +1561 -0
  11. package/dist/tui-56JFPKBP.js.map +1 -0
  12. package/package.json +11 -4
  13. package/dist/api.d.ts +0 -88
  14. package/dist/api.d.ts.map +0 -1
  15. package/dist/api.js +0 -168
  16. package/dist/api.js.map +0 -1
  17. package/dist/cli.d.ts.map +0 -1
  18. package/dist/config.d.ts +0 -27
  19. package/dist/config.d.ts.map +0 -1
  20. package/dist/config.js +0 -109
  21. package/dist/config.js.map +0 -1
  22. package/dist/helpers.d.ts +0 -4
  23. package/dist/helpers.d.ts.map +0 -1
  24. package/dist/helpers.js +0 -33
  25. package/dist/helpers.js.map +0 -1
  26. package/dist/index.d.ts.map +0 -1
  27. package/dist/ollama.d.ts +0 -11
  28. package/dist/ollama.d.ts.map +0 -1
  29. package/dist/ollama.js +0 -36
  30. package/dist/ollama.js.map +0 -1
  31. package/dist/providers/comfyui.d.ts +0 -29
  32. package/dist/providers/comfyui.d.ts.map +0 -1
  33. package/dist/providers/comfyui.js +0 -359
  34. package/dist/providers/comfyui.js.map +0 -1
  35. package/dist/providers/index.d.ts +0 -63
  36. package/dist/providers/index.d.ts.map +0 -1
  37. package/dist/providers/index.js +0 -126
  38. package/dist/providers/index.js.map +0 -1
  39. package/dist/providers/lmstudio.d.ts +0 -11
  40. package/dist/providers/lmstudio.d.ts.map +0 -1
  41. package/dist/providers/lmstudio.js +0 -106
  42. package/dist/providers/lmstudio.js.map +0 -1
  43. package/dist/providers/ollama.d.ts +0 -11
  44. package/dist/providers/ollama.d.ts.map +0 -1
  45. package/dist/providers/ollama.js +0 -59
  46. package/dist/providers/ollama.js.map +0 -1
  47. package/dist/providers/stable-diffusion.d.ts +0 -41
  48. package/dist/providers/stable-diffusion.d.ts.map +0 -1
  49. package/dist/providers/stable-diffusion.js +0 -283
  50. package/dist/providers/stable-diffusion.js.map +0 -1
  51. package/dist/providers/types.d.ts +0 -196
  52. package/dist/providers/types.d.ts.map +0 -1
  53. package/dist/providers/types.js +0 -19
  54. package/dist/providers/types.js.map +0 -1
  55. package/dist/quickstart/QuickstartScreen.d.ts +0 -5
  56. package/dist/quickstart/QuickstartScreen.d.ts.map +0 -1
  57. package/dist/quickstart/QuickstartScreen.js +0 -616
  58. package/dist/quickstart/QuickstartScreen.js.map +0 -1
  59. package/dist/quickstart/detect.d.ts +0 -22
  60. package/dist/quickstart/detect.d.ts.map +0 -1
  61. package/dist/quickstart/detect.js +0 -243
  62. package/dist/quickstart/detect.js.map +0 -1
  63. package/dist/quickstart/index.d.ts +0 -4
  64. package/dist/quickstart/index.d.ts.map +0 -1
  65. package/dist/quickstart/index.js +0 -245
  66. package/dist/quickstart/index.js.map +0 -1
  67. package/dist/quickstart/installers.d.ts +0 -109
  68. package/dist/quickstart/installers.d.ts.map +0 -1
  69. package/dist/quickstart/installers.js +0 -1296
  70. package/dist/quickstart/installers.js.map +0 -1
  71. package/dist/runner.d.ts +0 -19
  72. package/dist/runner.d.ts.map +0 -1
  73. package/dist/runner.js +0 -314
  74. package/dist/runner.js.map +0 -1
  75. package/dist/tui/App.d.ts +0 -7
  76. package/dist/tui/App.d.ts.map +0 -1
  77. package/dist/tui/App.js +0 -53
  78. package/dist/tui/App.js.map +0 -1
  79. package/dist/tui/TunnelRunner.d.ts +0 -19
  80. package/dist/tui/TunnelRunner.d.ts.map +0 -1
  81. package/dist/tui/TunnelRunner.js +0 -228
  82. package/dist/tui/TunnelRunner.js.map +0 -1
  83. package/dist/tui/components/Header.d.ts +0 -9
  84. package/dist/tui/components/Header.d.ts.map +0 -1
  85. package/dist/tui/components/Header.js +0 -21
  86. package/dist/tui/components/Header.js.map +0 -1
  87. package/dist/tui/components/ModelsPanel.d.ts +0 -7
  88. package/dist/tui/components/ModelsPanel.d.ts.map +0 -1
  89. package/dist/tui/components/ModelsPanel.js +0 -28
  90. package/dist/tui/components/ModelsPanel.js.map +0 -1
  91. package/dist/tui/components/ProvidersPanel.d.ts +0 -7
  92. package/dist/tui/components/ProvidersPanel.d.ts.map +0 -1
  93. package/dist/tui/components/ProvidersPanel.js +0 -6
  94. package/dist/tui/components/ProvidersPanel.js.map +0 -1
  95. package/dist/tui/components/RequestLog.d.ts +0 -8
  96. package/dist/tui/components/RequestLog.d.ts.map +0 -1
  97. package/dist/tui/components/RequestLog.js +0 -60
  98. package/dist/tui/components/RequestLog.js.map +0 -1
  99. package/dist/tui/components/StatusBar.d.ts +0 -10
  100. package/dist/tui/components/StatusBar.d.ts.map +0 -1
  101. package/dist/tui/components/StatusBar.js +0 -7
  102. package/dist/tui/components/StatusBar.js.map +0 -1
  103. package/dist/tui/components/index.d.ts +0 -6
  104. package/dist/tui/components/index.d.ts.map +0 -1
  105. package/dist/tui/components/index.js +0 -6
  106. package/dist/tui/components/index.js.map +0 -1
  107. package/dist/tui/events.d.ts +0 -35
  108. package/dist/tui/events.d.ts.map +0 -1
  109. package/dist/tui/events.js +0 -26
  110. package/dist/tui/events.js.map +0 -1
  111. package/dist/tui/hooks/index.d.ts +0 -5
  112. package/dist/tui/hooks/index.d.ts.map +0 -1
  113. package/dist/tui/hooks/index.js +0 -5
  114. package/dist/tui/hooks/index.js.map +0 -1
  115. package/dist/tui/hooks/useConnection.d.ts +0 -10
  116. package/dist/tui/hooks/useConnection.d.ts.map +0 -1
  117. package/dist/tui/hooks/useConnection.js +0 -42
  118. package/dist/tui/hooks/useConnection.js.map +0 -1
  119. package/dist/tui/hooks/useModels.d.ts +0 -9
  120. package/dist/tui/hooks/useModels.d.ts.map +0 -1
  121. package/dist/tui/hooks/useModels.js +0 -28
  122. package/dist/tui/hooks/useModels.js.map +0 -1
  123. package/dist/tui/hooks/useProviders.d.ts +0 -9
  124. package/dist/tui/hooks/useProviders.d.ts.map +0 -1
  125. package/dist/tui/hooks/useProviders.js +0 -30
  126. package/dist/tui/hooks/useProviders.js.map +0 -1
  127. package/dist/tui/hooks/useRequests.d.ts +0 -9
  128. package/dist/tui/hooks/useRequests.d.ts.map +0 -1
  129. package/dist/tui/hooks/useRequests.js +0 -60
  130. package/dist/tui/hooks/useRequests.js.map +0 -1
  131. package/dist/tui/index.d.ts +0 -2
  132. package/dist/tui/index.d.ts.map +0 -1
  133. package/dist/tui/index.js +0 -19
  134. package/dist/tui/index.js.map +0 -1
  135. package/dist/tui/screens/ConfigScreen.d.ts +0 -2
  136. package/dist/tui/screens/ConfigScreen.d.ts.map +0 -1
  137. package/dist/tui/screens/ConfigScreen.js +0 -18
  138. package/dist/tui/screens/ConfigScreen.js.map +0 -1
  139. package/dist/tui/screens/HomeScreen.d.ts +0 -2
  140. package/dist/tui/screens/HomeScreen.d.ts.map +0 -1
  141. package/dist/tui/screens/HomeScreen.js +0 -156
  142. package/dist/tui/screens/HomeScreen.js.map +0 -1
  143. package/dist/tui/screens/ModelsScreen.d.ts +0 -2
  144. package/dist/tui/screens/ModelsScreen.d.ts.map +0 -1
  145. package/dist/tui/screens/ModelsScreen.js +0 -59
  146. package/dist/tui/screens/ModelsScreen.js.map +0 -1
  147. package/dist/tui/screens/StatusScreen.d.ts +0 -2
  148. package/dist/tui/screens/StatusScreen.d.ts.map +0 -1
  149. package/dist/tui/screens/StatusScreen.js +0 -53
  150. package/dist/tui/screens/StatusScreen.js.map +0 -1
  151. package/dist/tui/screens/index.d.ts +0 -9
  152. package/dist/tui/screens/index.d.ts.map +0 -1
  153. package/dist/tui/screens/index.js +0 -38
  154. package/dist/tui/screens/index.js.map +0 -1
  155. package/dist/tui/types.d.ts +0 -30
  156. package/dist/tui/types.d.ts.map +0 -1
  157. package/dist/tui/types.js +0 -2
  158. package/dist/tui/types.js.map +0 -1
  159. package/dist/workflows/index.d.ts +0 -47
  160. package/dist/workflows/index.d.ts.map +0 -1
  161. package/dist/workflows/index.js +0 -95
  162. package/dist/workflows/index.js.map +0 -1
  163. package/dist/workflows/ltx-video.d.ts +0 -45
  164. package/dist/workflows/ltx-video.d.ts.map +0 -1
  165. package/dist/workflows/ltx-video.js +0 -114
  166. package/dist/workflows/ltx-video.js.map +0 -1
  167. package/dist/workflows/wan2.1.d.ts +0 -44
  168. package/dist/workflows/wan2.1.d.ts.map +0 -1
  169. package/dist/workflows/wan2.1.js +0 -119
  170. package/dist/workflows/wan2.1.js.map +0 -1
@@ -1,616 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState, useEffect } from "react";
3
- import { Box, Text, useApp, useInput } from "ink";
4
- import TextInput from "ink-text-input";
5
- import Spinner from "ink-spinner";
6
- import * as path from "path";
7
- import * as os from "os";
8
- import { detectAllProviders } from "./detect.js";
9
- import { installOllama, installLMStudio, installStableDiffusion, installComfyUI, installComfyUICustomNodes, pullOllamaModel, startOllama, hasDefaultSdModel, getComfyUIModelStatus, getPythonVersion, isPythonVersionOk, } from "./installers.js";
10
- import { LogoString } from "../helpers.js";
11
- export function QuickstartScreen({ onExternalAction } = {}) {
12
- const { exit } = useApp();
13
- const [screen, setScreen] = useState("detecting");
14
- const [providers, setProviders] = useState([]);
15
- const [selectedIndex, setSelectedIndex] = useState(0);
16
- const [installProgress, setInstallProgress] = useState(null);
17
- const [logs, setLogs] = useState([]);
18
- // Track what action was completed for context-specific done screen
19
- const [completedAction, setCompletedAction] = useState(null);
20
- // Path input state for Stable Diffusion
21
- const defaultSdPath = path.join(os.homedir(), "sd-webui-forge-neo");
22
- const [sdInstallPath, setSdInstallPath] = useState(defaultSdPath);
23
- // Model download state for Ollama
24
- const [modelName, setModelName] = useState("");
25
- // Track if default SD model already exists
26
- const [sdModelExists, setSdModelExists] = useState(false);
27
- // ComfyUI state
28
- const defaultComfyPath = path.join(os.homedir(), "ComfyUI");
29
- const [comfyInstallPath, setComfyInstallPath] = useState(defaultComfyPath);
30
- const [comfyModelStatus, setComfyModelStatus] = useState([]);
31
- // Refresh provider detection and model status
32
- const refreshProviders = async () => {
33
- const detected = await detectAllProviders();
34
- setProviders(detected);
35
- const modelExists = await hasDefaultSdModel();
36
- setSdModelExists(modelExists);
37
- setComfyModelStatus(getComfyUIModelStatus());
38
- };
39
- // Navigate to a screen with a clean slate
40
- const navigateTo = (target) => {
41
- // Clear screen + scrollback buffer + reset cursor position
42
- process.stdout.write("\x1B[2J\x1B[3J\x1B[H");
43
- setInstallProgress(null);
44
- setLogs([]);
45
- setScreen(target);
46
- };
47
- // Detect providers on mount
48
- useEffect(() => {
49
- async function detect() {
50
- await refreshProviders();
51
- setScreen("menu");
52
- }
53
- detect();
54
- }, []);
55
- // Build menu items based on detected providers
56
- const menuItems = [];
57
- const ollama = providers.find((p) => p.id === "ollama");
58
- const lmstudio = providers.find((p) => p.id === "lmstudio");
59
- const sd = providers.find((p) => p.id === "stable-diffusion");
60
- // --- Text providers (Ollama, LM Studio) ---
61
- if (ollama) {
62
- if (!ollama.installed) {
63
- menuItems.push({
64
- id: "install-ollama",
65
- category: "text",
66
- label: ollama.installable
67
- ? "Install Ollama (automatic)"
68
- : "Download Ollama (opens browser)",
69
- action: async () => {
70
- navigateTo("installing");
71
- await installOllama((progress) => {
72
- setInstallProgress(progress);
73
- if (progress.message) {
74
- setLogs((prev) => [...prev.slice(-10), progress.message]);
75
- }
76
- });
77
- // After install, pull a default model
78
- setInstallProgress({ stage: "pull", message: "Pulling llama3.2..." });
79
- await pullOllamaModel("llama3.2", (progress) => {
80
- setInstallProgress(progress);
81
- if (progress.message) {
82
- setLogs((prev) => [...prev.slice(-10), progress.message]);
83
- }
84
- });
85
- setCompletedAction("install-ollama");
86
- navigateTo("done");
87
- },
88
- });
89
- }
90
- else if (!ollama.running) {
91
- menuItems.push({
92
- id: "start-ollama",
93
- category: "text",
94
- label: "Start Ollama server",
95
- action: async () => {
96
- navigateTo("installing");
97
- await startOllama((progress) => {
98
- setInstallProgress(progress);
99
- });
100
- setCompletedAction("start-ollama");
101
- navigateTo("done");
102
- },
103
- });
104
- }
105
- else {
106
- // Ollama is installed and running - offer to download models and stop
107
- menuItems.push({
108
- id: "download-model",
109
- category: "text",
110
- label: "Download Ollama Models",
111
- action: async () => {
112
- setModelName("");
113
- navigateTo("model-download");
114
- },
115
- });
116
- menuItems.push({
117
- id: "stop-ollama",
118
- category: "text",
119
- label: "Stop Ollama server",
120
- action: async () => {
121
- if (onExternalAction) {
122
- onExternalAction("stop-ollama");
123
- }
124
- exit();
125
- },
126
- });
127
- }
128
- }
129
- if (lmstudio && !lmstudio.installed) {
130
- menuItems.push({
131
- id: "install-lmstudio",
132
- category: "text",
133
- label: "Download LM Studio (opens browser)",
134
- action: async () => {
135
- navigateTo("installing");
136
- await installLMStudio((progress) => {
137
- setInstallProgress(progress);
138
- });
139
- setCompletedAction("install-lmstudio");
140
- navigateTo("done");
141
- },
142
- });
143
- }
144
- // --- Image providers (Stable Diffusion) ---
145
- if (sd) {
146
- if (sd.warning) {
147
- menuItems.push({
148
- id: "fix-python",
149
- category: "image",
150
- label: "Install Python 3.13 (required for Forge Neo)",
151
- action: async () => {
152
- if (onExternalAction) {
153
- onExternalAction("fix-python");
154
- }
155
- exit();
156
- },
157
- });
158
- }
159
- if (!sd.installed) {
160
- menuItems.push({
161
- id: "install-sd",
162
- category: "image",
163
- label: sd.installable
164
- ? "Install Stable Diffusion Forge Neo"
165
- : "Stable Diffusion (requires git & python)",
166
- disabled: !sd.installable,
167
- action: async () => {
168
- navigateTo("path-input");
169
- },
170
- });
171
- }
172
- else if (!sd.running) {
173
- menuItems.push({
174
- id: "start-sd",
175
- category: "image",
176
- label: "Start Stable Diffusion server",
177
- action: async () => {
178
- const pyInfo = await getPythonVersion();
179
- if (!pyInfo) {
180
- setInstallProgress({
181
- stage: "error",
182
- message: "Python not found",
183
- error: "Python is not installed. Forge Neo requires Python 3.13+.\nInstall from https://www.python.org/downloads/",
184
- });
185
- setCompletedAction("start-sd");
186
- navigateTo("done");
187
- return;
188
- }
189
- if (!isPythonVersionOk(pyInfo)) {
190
- setInstallProgress({
191
- stage: "error",
192
- message: `Python ${pyInfo.version} is too old`,
193
- error: `Forge Neo requires Python 3.13+. You have ${pyInfo.version}.\nUse "Install Python 3.13" from the setup menu for instructions.`,
194
- });
195
- setCompletedAction("start-sd");
196
- navigateTo("done");
197
- return;
198
- }
199
- if (onExternalAction) {
200
- onExternalAction("start-sd");
201
- }
202
- exit();
203
- },
204
- });
205
- }
206
- else {
207
- menuItems.push({
208
- id: "stop-sd",
209
- category: "image",
210
- label: "Stop Stable Diffusion server",
211
- action: async () => {
212
- if (onExternalAction) {
213
- onExternalAction("stop-sd");
214
- }
215
- exit();
216
- },
217
- });
218
- }
219
- if (sd.installed && !sdModelExists) {
220
- menuItems.push({
221
- id: "download-sd-model",
222
- category: "image",
223
- label: "Download default SDXL model (~6.5 GB)",
224
- action: async () => {
225
- if (onExternalAction) {
226
- onExternalAction("download-sd-model");
227
- }
228
- exit();
229
- },
230
- });
231
- }
232
- }
233
- // Function to start SD installation with the chosen path
234
- const startSdInstallation = async () => {
235
- navigateTo("installing");
236
- await installStableDiffusion((progress) => {
237
- setInstallProgress(progress);
238
- if (progress.message) {
239
- setLogs((prev) => [...prev.slice(-10), progress.message]);
240
- }
241
- }, sdInstallPath);
242
- setCompletedAction("install-sd");
243
- navigateTo("done");
244
- };
245
- // Function to download an Ollama model
246
- const startModelDownload = async () => {
247
- if (!modelName.trim())
248
- return;
249
- navigateTo("installing");
250
- await pullOllamaModel(modelName.trim(), (progress) => {
251
- setInstallProgress(progress);
252
- if (progress.message) {
253
- setLogs((prev) => [...prev.slice(-10), progress.message]);
254
- }
255
- });
256
- setCompletedAction("download-model");
257
- navigateTo("done");
258
- };
259
- // --- Video providers (ComfyUI) ---
260
- const comfyui = providers.find((p) => p.id === "comfyui");
261
- if (comfyui) {
262
- if (!comfyui.installed) {
263
- menuItems.push({
264
- id: "install-comfyui",
265
- category: "video",
266
- label: comfyui.installable
267
- ? "Install ComfyUI"
268
- : "ComfyUI (requires git & python)",
269
- disabled: !comfyui.installable,
270
- action: async () => {
271
- navigateTo("installing");
272
- setInstallProgress({
273
- stage: "start",
274
- message: "Installing ComfyUI...",
275
- });
276
- const success = await installComfyUI(comfyInstallPath, (progress) => {
277
- setInstallProgress(progress);
278
- if (progress.message) {
279
- setLogs((prev) => [...prev.slice(-10), progress.message]);
280
- }
281
- });
282
- if (success) {
283
- setInstallProgress({
284
- stage: "start",
285
- message: "Installing LTX-Video custom nodes...",
286
- });
287
- await installComfyUICustomNodes((progress) => {
288
- setInstallProgress(progress);
289
- if (progress.message) {
290
- setLogs((prev) => [...prev.slice(-10), progress.message]);
291
- }
292
- });
293
- }
294
- setCompletedAction("install-comfyui");
295
- navigateTo("done");
296
- },
297
- });
298
- }
299
- else if (!comfyui.running) {
300
- menuItems.push({
301
- id: "start-comfyui",
302
- category: "video",
303
- label: "Start ComfyUI server",
304
- action: async () => {
305
- if (onExternalAction) {
306
- onExternalAction("start-comfyui");
307
- }
308
- exit();
309
- },
310
- });
311
- }
312
- else {
313
- for (const model of comfyModelStatus) {
314
- if (!model.installed) {
315
- menuItems.push({
316
- id: `download-comfyui-${model.id}`,
317
- category: "video",
318
- label: `Download ${model.label} (${model.totalSize})`,
319
- action: async () => {
320
- if (onExternalAction) {
321
- onExternalAction(`download-comfyui-model:${model.id}`);
322
- }
323
- exit();
324
- },
325
- });
326
- }
327
- }
328
- menuItems.push({
329
- id: "stop-comfyui",
330
- category: "video",
331
- label: "Stop ComfyUI server",
332
- action: async () => {
333
- if (onExternalAction) {
334
- onExternalAction("stop-comfyui");
335
- }
336
- exit();
337
- },
338
- });
339
- }
340
- }
341
- // --- General ---
342
- menuItems.push({
343
- id: "model-guide",
344
- category: "general",
345
- label: "How to Add Your Own Models",
346
- action: async () => {
347
- navigateTo("model-guide");
348
- },
349
- });
350
- menuItems.push({
351
- id: "exit",
352
- category: "general",
353
- label: "Exit",
354
- action: async () => {
355
- exit();
356
- },
357
- });
358
- // Keyboard navigation
359
- useInput((input, key) => {
360
- if (screen === "menu") {
361
- if (key.upArrow) {
362
- setSelectedIndex((prev) => Math.max(0, prev - 1));
363
- }
364
- if (key.downArrow) {
365
- setSelectedIndex((prev) => Math.min(menuItems.length - 1, prev + 1));
366
- }
367
- if (key.return) {
368
- const item = menuItems[selectedIndex];
369
- if (item && !item.disabled) {
370
- item.action();
371
- }
372
- }
373
- }
374
- // Allow escape to go back from path input
375
- if (screen === "path-input" && key.escape) {
376
- navigateTo("menu");
377
- return;
378
- }
379
- // Allow escape to go back from model download
380
- if (screen === "model-download" && key.escape) {
381
- navigateTo("menu");
382
- return;
383
- }
384
- // Allow escape or Enter to go back from model guide
385
- if (screen === "model-guide" && (key.escape || key.return)) {
386
- navigateTo("menu");
387
- return;
388
- }
389
- // Allow Enter to exit from done screen (return to main menu)
390
- if (screen === "done" && key.return) {
391
- exit();
392
- return;
393
- }
394
- // Global quit (but not during input screens, done screen, or guide)
395
- if (screen !== "path-input" &&
396
- screen !== "model-download" &&
397
- screen !== "model-guide" &&
398
- screen !== "done" &&
399
- (input === "q" || key.escape)) {
400
- exit();
401
- }
402
- });
403
- // Detecting screen
404
- if (screen === "detecting") {
405
- return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Text, { color: "cyan", children: LogoString }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: "cyan", children: _jsx(Spinner, { type: "dots" }) }), _jsx(Text, { children: " Detecting installed providers..." })] })] }));
406
- }
407
- // Path input screen for Stable Diffusion
408
- if (screen === "path-input") {
409
- return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Text, { color: "cyan", children: LogoString }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { bold: true, color: "white", children: "Install Stable Diffusion Forge Neo" }) }), _jsxs(Box, { marginTop: 1, flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, paddingY: 1, children: [_jsx(Text, { children: "Installation path:" }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: "cyan", children: "> " }), _jsx(TextInput, { value: sdInstallPath, onChange: setSdInstallPath, onSubmit: () => {
410
- startSdInstallation();
411
- } })] })] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: "gray", children: "Enter: Confirm and install" }), _jsx(Text, { color: "gray", children: "Esc: Go back" })] })] }));
412
- }
413
- // Model download screen for Ollama
414
- if (screen === "model-download") {
415
- return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Text, { color: "cyan", children: LogoString }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { bold: true, color: "white", children: "Download Ollama Model" }) }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { children: "Browse available models at:" }), _jsx(Text, { color: "cyan", bold: true, children: "https://ollama.com/library" })] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: "gray", children: "Popular models:" }), _jsx(Text, { color: "gray", children: " llama3.2, mistral, codellama, phi3, gemma2" })] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, paddingY: 1, children: [_jsx(Text, { children: "Enter model name:" }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: "cyan", children: "> " }), _jsx(TextInput, { value: modelName, onChange: setModelName, placeholder: "e.g. llama3.2", onSubmit: () => {
416
- if (modelName.trim()) {
417
- startModelDownload();
418
- }
419
- } })] })] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: "gray", children: "Enter: Download model" }), _jsx(Text, { color: "gray", children: "Esc: Go back" })] })] }));
420
- }
421
- // Model guide screen
422
- if (screen === "model-guide") {
423
- return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Text, { color: "cyan", children: LogoString }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { bold: true, color: "white", children: "How to Add Your Own Models" }) }), _jsxs(Box, { marginTop: 1, flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, paddingY: 1, children: [_jsx(Text, { bold: true, children: "Text Models (Ollama)" }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Text, { color: "gray", children: ["Browse models at", " ", _jsx(Text, { color: "cyan", children: "https://ollama.com/library" })] }), _jsx(Text, { color: "gray", children: "Download via the setup menu or run:" }), _jsxs(Text, { color: "white", children: [" ollama pull ", "<model-name>"] })] })] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, paddingY: 1, children: [_jsx(Text, { bold: true, children: "Image Models (Stable Diffusion)" }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Text, { color: "gray", children: ["Download ", _jsx(Text, { color: "white", children: ".safetensors" }), " files from", " ", _jsx(Text, { color: "cyan", children: "https://civitai.com" })] }), _jsxs(Text, { color: "gray", children: ["Filter by ", _jsx(Text, { color: "white", children: "SDXL 1.0" }), " for best compatibility."] })] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: "gray", children: "Place them in:" }), _jsxs(Text, { color: "white", children: [" ", sdInstallPath, "/models/Stable-diffusion/"] })] }), _jsx(Box, { marginTop: 1, flexDirection: "column", children: _jsx(Text, { color: "gray", children: "Restart the SD server to pick up new models." }) })] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, paddingY: 1, children: [_jsx(Text, { bold: true, children: "Video Models (ComfyUI)" }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Text, { color: "gray", children: ["Download models from", " ", _jsx(Text, { color: "cyan", children: "https://huggingface.co" }), " ", "and place in the folders below."] }), _jsx(Text, { color: "gray", children: "Models marked with * can be auto-downloaded from the setup menu." })] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { bold: true, color: "white", children: "LTX-Video" }), _jsxs(Text, { color: "gray", children: [" * ltx-video-2b-v0.9.5.safetensors ", _jsx(Text, { color: "white", children: "checkpoints/" }), " ", _jsx(Text, { color: "gray", children: "(~6 GB)" })] }), _jsxs(Text, { color: "gray", children: [" * t5xxl_fp16.safetensors ", _jsx(Text, { color: "white", children: "text_encoders/" }), " ", _jsx(Text, { color: "gray", children: "(~10 GB)" })] })] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { bold: true, color: "white", children: "Wan 2.1 Text-to-Video" }), _jsxs(Text, { color: "gray", children: [" * wan2.1_t2v_1.3B_fp16.safetensors ", _jsx(Text, { color: "white", children: "diffusion_models/" }), " ", _jsx(Text, { color: "gray", children: "(~2.6 GB)" })] }), _jsxs(Text, { color: "gray", children: [" wan2.1_t2v_14B_fp16.safetensors ", _jsx(Text, { color: "white", children: "diffusion_models/" }), " ", _jsx(Text, { color: "gray", children: "(~28 GB)" })] }), _jsxs(Text, { color: "gray", children: [" * umt5_xxl_fp8_e4m3fn_scaled ", _jsx(Text, { color: "white", children: "text_encoders/" }), " ", _jsx(Text, { color: "gray", children: "(~5 GB, shared)" })] }), _jsxs(Text, { color: "gray", children: [" * wan_2.1_vae.safetensors ", _jsx(Text, { color: "white", children: "vae/" }), " ", _jsx(Text, { color: "gray", children: "(~0.3 GB, shared)" })] })] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Text, { color: "gray", children: ["All folders are relative to: ", _jsxs(Text, { color: "white", children: [comfyInstallPath, "/models/"] })] }), _jsx(Text, { color: "gray", children: "The 14B model uses the same text encoder and VAE as the 1.3B." }), _jsx(Text, { color: "gray", children: "Restart the ComfyUI server to pick up new models." })] })] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "gray", children: "Press Esc or Enter to go back" }) })] }));
424
- }
425
- // Installing screen
426
- if (screen === "installing") {
427
- return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Text, { color: "cyan", children: LogoString }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { bold: true, color: "white", children: "Loading..." }) }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [installProgress && (_jsxs(Box, { children: [!installProgress.complete && !installProgress.error && (_jsxs(Text, { color: "cyan", children: [_jsx(Spinner, { type: "dots" }), " "] })), installProgress.complete && _jsx(Text, { color: "green", children: "\u2713 " }), installProgress.error && _jsx(Text, { color: "red", children: "\u2717 " }), _jsx(Text, { children: installProgress.message })] })), installProgress?.error && (_jsxs(Text, { color: "red", children: ["Error: ", installProgress.error] }))] }), logs.length > 0 && (_jsx(Box, { marginTop: 1, flexDirection: "column", borderStyle: "round", borderColor: "gray", paddingX: 1, children: logs.slice(-5).map((log, i) => (_jsx(Text, { color: "gray", children: log }, i))) }))] }));
428
- }
429
- // Done screen - context-aware based on completed action
430
- if (screen === "done") {
431
- const getDoneMessage = () => {
432
- switch (completedAction) {
433
- case "start-ollama":
434
- return {
435
- title: "Ollama is now running!",
436
- description: "Ollama server is running in the background on port 11434.",
437
- nextSteps: [
438
- "Return to main menu to authenticate or start the tunnel.",
439
- ],
440
- note: "Ollama will keep running until you restart your computer or stop it manually.",
441
- };
442
- case "stop-ollama":
443
- return {
444
- title: "Ollama server stopped!",
445
- description: "The Ollama server has been shut down.",
446
- nextSteps: [],
447
- note: null,
448
- };
449
- case "download-model":
450
- return {
451
- title: "Model downloaded!",
452
- description: `The model "${modelName}" has been pulled successfully.`,
453
- nextSteps: [
454
- "Return to main menu to register models and start the tunnel.",
455
- ],
456
- note: null,
457
- };
458
- case "install-ollama":
459
- return {
460
- title: "Ollama installed successfully!",
461
- description: "Ollama has been installed and the llama3.2 model has been pulled.",
462
- nextSteps: [
463
- "Return to main menu to authenticate and start the tunnel.",
464
- ],
465
- note: null,
466
- };
467
- case "install-lmstudio":
468
- return {
469
- title: "LM Studio download started!",
470
- description: "The download page has been opened in your browser.",
471
- nextSteps: [
472
- "Complete the installation from the downloaded file.",
473
- "Launch LM Studio and download a model.",
474
- "Start the local server in LM Studio.",
475
- "Return to main menu to start the tunnel.",
476
- ],
477
- note: null,
478
- };
479
- case "install-sd":
480
- return {
481
- title: "Stable Diffusion Forge Neo cloned!",
482
- description: `Repository cloned to: ${sdInstallPath}`,
483
- nextSteps: [
484
- 'Use "Download default SDXL model" from the setup menu to get a model automatically.',
485
- 'Or download from https://civitai.com/models (filter by "SDXL 1.0").',
486
- "Then start the server from the setup menu.",
487
- ],
488
- note: `To add your own models, download .safetensors files from https://civitai.com and place them in:\n ${sdInstallPath}/models/Stable-diffusion/`,
489
- };
490
- case "install-comfyui":
491
- return {
492
- title: "ComfyUI installed!",
493
- description: `Installed to: ${comfyInstallPath}`,
494
- nextSteps: [
495
- "Start the ComfyUI server from the setup menu.",
496
- "Download a video model (LTX-Video or Wan 2.1) once the server is running.",
497
- "Then start the tunnel to connect to MindStudio.",
498
- ],
499
- note: [
500
- "LTX-Video custom nodes have been installed for best compatibility.",
501
- "",
502
- "To add your own video models, download .safetensors files from https://huggingface.co and place them in:",
503
- ` Checkpoints: ${comfyInstallPath}/models/checkpoints/`,
504
- ` Diffusion models: ${comfyInstallPath}/models/diffusion_models/`,
505
- ` Text encoders: ${comfyInstallPath}/models/text_encoders/`,
506
- ` VAE: ${comfyInstallPath}/models/vae/`,
507
- ].join("\n"),
508
- };
509
- case "start-sd":
510
- // If there was a pre-flight error (Python version), show it
511
- if (installProgress?.error) {
512
- return {
513
- title: installProgress.message,
514
- description: installProgress.error,
515
- nextSteps: [
516
- 'Use "Install Python 3.13" from the setup menu for instructions.',
517
- `If you recently updated Python, delete the old venv: rm -rf ${sdInstallPath}/venv`,
518
- ],
519
- note: null,
520
- };
521
- }
522
- return {
523
- title: "Stable Diffusion server stopped.",
524
- description: "The server has been shut down.",
525
- nextSteps: [
526
- "Return to main menu to start it again or start the tunnel.",
527
- ],
528
- note: null,
529
- };
530
- case "stop-sd":
531
- return {
532
- title: "Stable Diffusion server stopped!",
533
- description: "The server has been shut down.",
534
- nextSteps: ["Return to main menu to start it again if needed."],
535
- note: null,
536
- };
537
- default:
538
- return {
539
- title: "Setup complete!",
540
- description: null,
541
- nextSteps: [
542
- "Return to main menu to authenticate and start the tunnel.",
543
- ],
544
- note: null,
545
- };
546
- }
547
- };
548
- const msg = getDoneMessage();
549
- return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Text, { color: "cyan", children: LogoString }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: "green", bold: true, children: msg.title }), msg.description && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "white", children: msg.description }) })), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: "white", bold: true, children: "Next steps:" }), msg.nextSteps.map((step, i) => (_jsxs(Text, { color: "gray", children: [" ", i + 1, ". ", step] }, i)))] }), msg.note && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "yellow", children: ["Note: ", msg.note] }) })), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "cyan", children: "Press Enter to return to main menu" }) })] })] }));
550
- }
551
- // Menu screen
552
- const allInstalled = providers.every((p) => p.installed);
553
- const allRunning = providers
554
- .filter((p) => p.installed)
555
- .every((p) => p.running);
556
- return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Text, { color: "cyan", children: LogoString }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { bold: true, color: "white", children: "Quickstart Setup" }) }), _jsxs(Box, { marginTop: 1, flexDirection: "column", borderStyle: "round", borderColor: "gray", paddingX: 1, children: [_jsx(Text, { bold: true, children: "Provider Status" }), [
557
- { label: "Text", ids: ["ollama", "lmstudio"] },
558
- { label: "Image", ids: ["stable-diffusion"] },
559
- { label: "Video", ids: ["comfyui"] },
560
- ].map((group) => {
561
- const groupProviders = providers.filter((p) => group.ids.includes(p.id));
562
- if (groupProviders.length === 0)
563
- return null;
564
- return (_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: "gray", dimColor: true, children: group.label }), groupProviders.map((provider) => (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { color: provider.installed
565
- ? provider.running
566
- ? "green"
567
- : "yellow"
568
- : "red", children: provider.installed
569
- ? provider.running
570
- ? "●"
571
- : "○"
572
- : "✗" }), _jsxs(Text, { children: [" ", provider.name, " - "] }), _jsx(Text, { color: "gray", children: provider.running
573
- ? "Running"
574
- : provider.installed
575
- ? "Installed (not running)"
576
- : "Not installed" })] }), provider.warning && (_jsx(Box, { children: _jsxs(Text, { color: "yellow", children: [" \u26A0 ", provider.warning] }) }))] }, provider.id)))] }, group.label));
577
- })] }), process.platform === "darwin" && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "yellow", children: "\u26A0 macOS: Stable Diffusion and ComfyUI may have compatibility issues due to limited CUDA support. GPU acceleration requires Apple Silicon with MPS." }) })), allInstalled && allRunning && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "green", children: "\u2713 All providers are installed and running!" }) })), menuItems.length > 1 &&
578
- (() => {
579
- const categoryOrder = [
580
- "text",
581
- "image",
582
- "video",
583
- "general",
584
- ];
585
- const categoryLabels = {
586
- text: "Text Generation",
587
- image: "Image Generation",
588
- video: "Video Generation",
589
- general: "",
590
- };
591
- const categoryIcons = {
592
- text: "💬",
593
- image: "🎨",
594
- video: "🎬",
595
- general: "",
596
- };
597
- // Only show categories that have items
598
- const activeCategories = categoryOrder.filter((cat) => menuItems.some((item) => item.category === cat));
599
- // Track the global index for selection
600
- let globalIndex = 0;
601
- return (_jsx(Box, { marginTop: 1, flexDirection: "column", children: activeCategories.map((cat, catIdx) => {
602
- const items = menuItems.filter((item) => item.category === cat);
603
- const startIdx = globalIndex;
604
- globalIndex += items.length;
605
- return (_jsxs(Box, { flexDirection: "column", marginTop: catIdx > 0 ? 1 : 0, children: [cat !== "general" && (_jsxs(Text, { bold: true, color: "gray", children: [categoryIcons[cat], " ", categoryLabels[cat]] })), items.map((item, i) => {
606
- const idx = startIdx + i;
607
- return (_jsxs(Box, { children: [_jsx(Text, { color: idx === selectedIndex ? "cyan" : "white", children: idx === selectedIndex ? " ❯ " : " " }), _jsx(Text, { color: item.disabled
608
- ? "gray"
609
- : idx === selectedIndex
610
- ? "cyan"
611
- : "white", dimColor: item.disabled, children: item.label })] }, item.id));
612
- })] }, cat));
613
- }) }));
614
- })(), (sd?.installed || comfyui?.installed) && (_jsxs(Box, { marginTop: 1, flexDirection: "column", borderStyle: "round", borderColor: "gray", paddingX: 1, children: [_jsx(Text, { bold: true, color: "gray", children: "Add Your Own Models" }), sd?.installed && (_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Text, { color: "gray", children: ["Image models (.safetensors) from", " ", _jsx(Text, { color: "cyan", children: "https://civitai.com" })] }), _jsxs(Text, { color: "gray", children: [" ", "Place in:", " ", _jsxs(Text, { color: "white", children: [sdInstallPath, "/models/Stable-diffusion/"] })] })] })), comfyui?.installed && (_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Text, { color: "gray", children: ["Video models (.safetensors) from", " ", _jsx(Text, { color: "cyan", children: "https://huggingface.co" })] }), _jsxs(Text, { color: "gray", children: [" ", "Checkpoints:", " ", _jsxs(Text, { color: "white", children: [comfyInstallPath, "/models/checkpoints/"] })] }), _jsxs(Text, { color: "gray", children: [" ", "Diffusion models:", " ", _jsxs(Text, { color: "white", children: [comfyInstallPath, "/models/diffusion_models/"] })] })] }))] })), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "gray", children: "\u2191\u2193 Navigate \u2022 Enter Select \u2022 q Quit" }) })] }));
615
- }
616
- //# sourceMappingURL=QuickstartScreen.js.map