@appkit/llamacpp-cli 1.12.0 → 1.13.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 (136) hide show
  1. package/README.md +294 -168
  2. package/dist/cli.js +35 -0
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/launch/claude.d.ts +6 -0
  5. package/dist/commands/launch/claude.d.ts.map +1 -0
  6. package/dist/commands/launch/claude.js +277 -0
  7. package/dist/commands/launch/claude.js.map +1 -0
  8. package/dist/lib/integration-checker.d.ts +26 -0
  9. package/dist/lib/integration-checker.d.ts.map +1 -0
  10. package/dist/lib/integration-checker.js +77 -0
  11. package/dist/lib/integration-checker.js.map +1 -0
  12. package/dist/lib/router-manager.d.ts +4 -0
  13. package/dist/lib/router-manager.d.ts.map +1 -1
  14. package/dist/lib/router-manager.js +10 -0
  15. package/dist/lib/router-manager.js.map +1 -1
  16. package/dist/lib/router-server.d.ts +13 -0
  17. package/dist/lib/router-server.d.ts.map +1 -1
  18. package/dist/lib/router-server.js +267 -7
  19. package/dist/lib/router-server.js.map +1 -1
  20. package/dist/types/integration-config.d.ts +28 -0
  21. package/dist/types/integration-config.d.ts.map +1 -0
  22. package/dist/types/integration-config.js +3 -0
  23. package/dist/types/integration-config.js.map +1 -0
  24. package/package.json +10 -2
  25. package/web/dist/assets/index-Bin89Lwr.css +1 -0
  26. package/web/dist/assets/index-CVmonw3T.js +17 -0
  27. package/web/{index.html → dist/index.html} +2 -1
  28. package/.versionrc.json +0 -16
  29. package/CHANGELOG.md +0 -213
  30. package/docs/images/.gitkeep +0 -1
  31. package/docs/images/web-ui-servers.png +0 -0
  32. package/src/cli.ts +0 -523
  33. package/src/commands/admin/config.ts +0 -121
  34. package/src/commands/admin/logs.ts +0 -91
  35. package/src/commands/admin/restart.ts +0 -26
  36. package/src/commands/admin/start.ts +0 -27
  37. package/src/commands/admin/status.ts +0 -84
  38. package/src/commands/admin/stop.ts +0 -16
  39. package/src/commands/config-global.ts +0 -38
  40. package/src/commands/config.ts +0 -323
  41. package/src/commands/create.ts +0 -183
  42. package/src/commands/delete.ts +0 -74
  43. package/src/commands/list.ts +0 -37
  44. package/src/commands/logs-all.ts +0 -251
  45. package/src/commands/logs.ts +0 -345
  46. package/src/commands/monitor.ts +0 -110
  47. package/src/commands/ps.ts +0 -84
  48. package/src/commands/pull.ts +0 -44
  49. package/src/commands/rm.ts +0 -107
  50. package/src/commands/router/config.ts +0 -116
  51. package/src/commands/router/logs.ts +0 -256
  52. package/src/commands/router/restart.ts +0 -36
  53. package/src/commands/router/start.ts +0 -60
  54. package/src/commands/router/status.ts +0 -119
  55. package/src/commands/router/stop.ts +0 -33
  56. package/src/commands/run.ts +0 -233
  57. package/src/commands/search.ts +0 -107
  58. package/src/commands/server-show.ts +0 -161
  59. package/src/commands/show.ts +0 -207
  60. package/src/commands/start.ts +0 -101
  61. package/src/commands/stop.ts +0 -39
  62. package/src/commands/tui.ts +0 -25
  63. package/src/lib/admin-manager.ts +0 -435
  64. package/src/lib/admin-server.ts +0 -1243
  65. package/src/lib/config-generator.ts +0 -130
  66. package/src/lib/download-job-manager.ts +0 -213
  67. package/src/lib/history-manager.ts +0 -172
  68. package/src/lib/launchctl-manager.ts +0 -225
  69. package/src/lib/metrics-aggregator.ts +0 -257
  70. package/src/lib/model-downloader.ts +0 -328
  71. package/src/lib/model-scanner.ts +0 -157
  72. package/src/lib/model-search.ts +0 -114
  73. package/src/lib/models-dir-setup.ts +0 -46
  74. package/src/lib/port-manager.ts +0 -80
  75. package/src/lib/router-logger.ts +0 -201
  76. package/src/lib/router-manager.ts +0 -414
  77. package/src/lib/router-server.ts +0 -538
  78. package/src/lib/state-manager.ts +0 -206
  79. package/src/lib/status-checker.ts +0 -113
  80. package/src/lib/system-collector.ts +0 -315
  81. package/src/tui/ConfigApp.ts +0 -1085
  82. package/src/tui/HistoricalMonitorApp.ts +0 -587
  83. package/src/tui/ModelsApp.ts +0 -368
  84. package/src/tui/MonitorApp.ts +0 -386
  85. package/src/tui/MultiServerMonitorApp.ts +0 -1833
  86. package/src/tui/RootNavigator.ts +0 -74
  87. package/src/tui/SearchApp.ts +0 -511
  88. package/src/tui/SplashScreen.ts +0 -149
  89. package/src/types/admin-config.ts +0 -25
  90. package/src/types/global-config.ts +0 -26
  91. package/src/types/history-types.ts +0 -39
  92. package/src/types/model-info.ts +0 -8
  93. package/src/types/monitor-types.ts +0 -162
  94. package/src/types/router-config.ts +0 -25
  95. package/src/types/server-config.ts +0 -46
  96. package/src/utils/downsample-utils.ts +0 -128
  97. package/src/utils/file-utils.ts +0 -146
  98. package/src/utils/format-utils.ts +0 -98
  99. package/src/utils/log-parser.ts +0 -284
  100. package/src/utils/log-utils.ts +0 -178
  101. package/src/utils/process-utils.ts +0 -316
  102. package/src/utils/prompt-utils.ts +0 -47
  103. package/test-load.sh +0 -100
  104. package/tsconfig.json +0 -20
  105. package/web/eslint.config.js +0 -23
  106. package/web/llamacpp-web-dist.tar.gz +0 -0
  107. package/web/package-lock.json +0 -4017
  108. package/web/package.json +0 -38
  109. package/web/postcss.config.js +0 -6
  110. package/web/src/App.css +0 -42
  111. package/web/src/App.tsx +0 -86
  112. package/web/src/assets/react.svg +0 -1
  113. package/web/src/components/ApiKeyPrompt.tsx +0 -71
  114. package/web/src/components/CreateServerModal.tsx +0 -372
  115. package/web/src/components/DownloadProgress.tsx +0 -123
  116. package/web/src/components/Nav.tsx +0 -89
  117. package/web/src/components/RouterConfigModal.tsx +0 -240
  118. package/web/src/components/SearchModal.tsx +0 -306
  119. package/web/src/components/ServerConfigModal.tsx +0 -291
  120. package/web/src/hooks/useApi.ts +0 -259
  121. package/web/src/index.css +0 -42
  122. package/web/src/lib/api.ts +0 -226
  123. package/web/src/main.tsx +0 -10
  124. package/web/src/pages/Dashboard.tsx +0 -103
  125. package/web/src/pages/Models.tsx +0 -258
  126. package/web/src/pages/Router.tsx +0 -270
  127. package/web/src/pages/RouterLogs.tsx +0 -201
  128. package/web/src/pages/ServerLogs.tsx +0 -553
  129. package/web/src/pages/Servers.tsx +0 -358
  130. package/web/src/types/api.ts +0 -140
  131. package/web/tailwind.config.js +0 -31
  132. package/web/tsconfig.app.json +0 -28
  133. package/web/tsconfig.json +0 -7
  134. package/web/tsconfig.node.json +0 -26
  135. package/web/vite.config.ts +0 -25
  136. /package/web/{public → dist}/vite.svg +0 -0
@@ -1,368 +0,0 @@
1
- import blessed from 'blessed';
2
- import { modelScanner } from '../lib/model-scanner.js';
3
- import { stateManager } from '../lib/state-manager.js';
4
- import { launchctlManager } from '../lib/launchctl-manager.js';
5
- import { ModelInfo } from '../types/model-info.js';
6
- import { ServerConfig } from '../types/server-config.js';
7
- import { formatBytes, formatDateShort } from '../utils/format-utils.js';
8
- import * as fs from 'fs/promises';
9
- import { createSearchUI } from './SearchApp.js';
10
-
11
- /**
12
- * Models management TUI
13
- * Display installed models and allow deletion
14
- */
15
- export async function createModelsUI(
16
- screen: blessed.Widgets.Screen,
17
- onBack: () => void,
18
- onSearch: () => void
19
- ): Promise<void> {
20
- let models: ModelInfo[] = [];
21
- let selectedIndex = 0;
22
- let isLoading = false;
23
-
24
- // Create content box
25
- const contentBox = blessed.box({
26
- top: 0,
27
- left: 0,
28
- width: '100%',
29
- height: '100%',
30
- tags: true,
31
- scrollable: true,
32
- alwaysScroll: true,
33
- keys: true,
34
- vi: true,
35
- mouse: true,
36
- scrollbar: {
37
- ch: '█',
38
- style: {
39
- fg: 'blue',
40
- },
41
- },
42
- });
43
- screen.append(contentBox);
44
-
45
- // Render models view
46
- async function render() {
47
- const termWidth = (screen.width as number) || 80;
48
- const divider = '─'.repeat(termWidth - 2);
49
- let content = '';
50
-
51
- // Header
52
- content += '{bold}{blue-fg}═══ Models Management{/blue-fg}{/bold}\n\n';
53
-
54
- if (isLoading) {
55
- content += '{cyan-fg}⏳ Loading models...{/cyan-fg}\n';
56
- contentBox.setContent(content);
57
- screen.render();
58
- return;
59
- }
60
-
61
- if (models.length === 0) {
62
- content += '{yellow-fg}No models found{/yellow-fg}\n\n';
63
- content += '{dim}Models directory: ' + await stateManager.getModelsDirectory() + '{/dim}\n';
64
- content += '{dim}Download models: Press [S] to search HuggingFace{/dim}\n';
65
- content += '\n' + divider + '\n';
66
- content += `{gray-fg}[S]earch [ESC] Back [Q]uit{/gray-fg}`;
67
- contentBox.setContent(content);
68
- screen.render();
69
- return;
70
- }
71
-
72
- // System info
73
- const totalSize = models.reduce((sum, m) => sum + m.size, 0);
74
- content += `{bold}Total: ${models.length} models{/bold} - ${formatBytes(totalSize)}\n`;
75
- content += divider + '\n';
76
-
77
- // Get all servers to check dependencies
78
- const allServers = await stateManager.getAllServers();
79
-
80
- // Table header
81
- content += '{bold} │ Model File │ Size │ Modified │ Servers{/bold}\n';
82
- content += divider + '\n';
83
-
84
- // Model rows
85
- for (let i = 0; i < models.length; i++) {
86
- const model = models[i];
87
- const isSelected = i === selectedIndex;
88
-
89
- // Count servers using this model
90
- const serversUsingModel = allServers.filter(s => s.modelPath === model.path);
91
- const serverCount = serversUsingModel.length;
92
-
93
- // Selection indicator
94
- const indicator = isSelected ? '►' : ' ';
95
-
96
- // Model filename (truncate if too long)
97
- const maxFilenameLen = 46;
98
- let filename = model.filename;
99
- if (filename.length > maxFilenameLen) {
100
- filename = filename.substring(0, maxFilenameLen - 3) + '...';
101
- }
102
- filename = filename.padEnd(maxFilenameLen);
103
-
104
- // Size
105
- const size = model.sizeFormatted.padStart(11);
106
-
107
- // Modified date
108
- const modified = formatDateShort(model.modified).padStart(11);
109
-
110
- // Servers count with color coding
111
- let serversText = '';
112
- let serversTextPlain = '';
113
- if (serverCount === 0) {
114
- serversText = '{green-fg}0 servers{/green-fg}';
115
- serversTextPlain = '0 servers';
116
- } else {
117
- const runningCount = serversUsingModel.filter(s => s.status === 'running').length;
118
- if (runningCount > 0) {
119
- serversText = `{yellow-fg}${serverCount} (${runningCount} running){/yellow-fg}`;
120
- serversTextPlain = `${serverCount} (${runningCount} running)`;
121
- } else {
122
- serversText = `{gray-fg}${serverCount} stopped{/gray-fg}`;
123
- serversTextPlain = `${serverCount} stopped`;
124
- }
125
- }
126
-
127
- // Build row content
128
- let rowContent = '';
129
- if (isSelected) {
130
- // Selected row: cyan background with bright white text
131
- rowContent = `{cyan-bg}{15-fg}${indicator} │ ${filename} │ ${size} │ ${modified} │ ${serversTextPlain}{/15-fg}{/cyan-bg}`;
132
- } else {
133
- // Normal row: with colored server text
134
- rowContent = `${indicator} │ ${filename} │ ${size} │ ${modified} │ ${serversText}`;
135
- }
136
-
137
- content += rowContent + '\n';
138
- }
139
-
140
- // Footer
141
- content += '\n' + divider + '\n';
142
- content += '{gray-fg}[↑/↓] Navigate [D]elete [S]earch [R]efresh [ESC] Back [Q]uit{/gray-fg}';
143
-
144
- contentBox.setContent(content);
145
- screen.render();
146
- }
147
-
148
- // Load models
149
- async function loadModels() {
150
- isLoading = true;
151
- await render();
152
-
153
- models = await modelScanner.scanModels();
154
- selectedIndex = Math.min(selectedIndex, Math.max(0, models.length - 1));
155
-
156
- isLoading = false;
157
- await render();
158
- }
159
-
160
- // Delete selected model
161
- async function deleteModel() {
162
- if (models.length === 0) return;
163
-
164
- const model = models[selectedIndex];
165
- const allServers = await stateManager.getAllServers();
166
- const serversUsingModel = allServers.filter(s => s.modelPath === model.path);
167
-
168
- // Show confirmation dialog
169
- const confirmBox = blessed.message({
170
- parent: screen,
171
- top: 'center',
172
- left: 'center',
173
- width: '60%',
174
- height: 'shrink',
175
- border: { type: 'line' },
176
- style: {
177
- border: { fg: 'red' },
178
- fg: 'white',
179
- },
180
- tags: true,
181
- });
182
-
183
- let confirmText = `{bold}Delete model: ${model.filename}?{/bold}\n\n`;
184
- confirmText += `Size: ${model.sizeFormatted}\n\n`;
185
-
186
- if (serversUsingModel.length > 0) {
187
- confirmText += `{yellow-fg}⚠️ This model has ${serversUsingModel.length} server(s) configured:{/yellow-fg}\n`;
188
- for (const server of serversUsingModel) {
189
- const statusColor = server.status === 'running' ? 'green-fg' : 'gray-fg';
190
- confirmText += ` - ${server.id} ({${statusColor}}${server.status}{/${statusColor}})\n`;
191
- }
192
- confirmText += `\n{yellow-fg}These servers will be deleted before removing the model.{/yellow-fg}\n\n`;
193
- }
194
-
195
- confirmText += `Type 'yes' to confirm:\n\n\n\n`; // Extra lines for input box space
196
-
197
- // Create input box for confirmation
198
- const inputBox = blessed.textbox({
199
- parent: confirmBox,
200
- bottom: 1,
201
- left: 2,
202
- right: 2,
203
- height: 3,
204
- inputOnFocus: true,
205
- border: { type: 'line' },
206
- style: {
207
- border: { fg: 'cyan' },
208
- focus: { border: { fg: 'green' } },
209
- },
210
- });
211
-
212
- confirmBox.setContent(confirmText);
213
- screen.append(confirmBox);
214
- confirmBox.focus();
215
- inputBox.focus();
216
- screen.render();
217
-
218
- inputBox.on('submit', async (value: string) => {
219
- screen.remove(confirmBox);
220
-
221
- if (value.toLowerCase() !== 'yes') {
222
- await render();
223
- return;
224
- }
225
-
226
- // Show deleting message
227
- isLoading = true;
228
- contentBox.setContent('{cyan-fg}⏳ Deleting model...{/cyan-fg}');
229
- screen.render();
230
-
231
- try {
232
- // Delete all servers using this model
233
- for (const server of serversUsingModel) {
234
- // Unload service (stops and removes from launchd)
235
- try {
236
- await launchctlManager.unloadService(server.plistPath);
237
- if (server.status === 'running') {
238
- await launchctlManager.waitForServiceStop(server.label, 5000);
239
- }
240
- } catch (error) {
241
- // Continue even if unload fails
242
- }
243
-
244
- // Delete plist
245
- await launchctlManager.deletePlist(server.plistPath);
246
-
247
- // Delete server config
248
- await stateManager.deleteServerConfig(server.id);
249
- }
250
-
251
- // Delete model file
252
- await fs.unlink(model.path);
253
-
254
- // Reload models
255
- await loadModels();
256
- } catch (error) {
257
- // Show error
258
- const errorBox = blessed.message({
259
- parent: screen,
260
- top: 'center',
261
- left: 'center',
262
- width: '60%',
263
- height: 'shrink',
264
- border: { type: 'line' },
265
- style: {
266
- border: { fg: 'red' },
267
- fg: 'red',
268
- },
269
- tags: true,
270
- });
271
-
272
- const errorMsg = error instanceof Error ? error.message : 'Unknown error';
273
- errorBox.display(`{bold}Delete failed{/bold}\n\n${errorMsg}\n\nPress any key to continue`, () => {
274
- screen.remove(errorBox);
275
- isLoading = false;
276
- render();
277
- });
278
- }
279
- });
280
-
281
- inputBox.on('cancel', () => {
282
- screen.remove(confirmBox);
283
- render();
284
- });
285
-
286
- inputBox.key(['escape'], () => {
287
- screen.remove(confirmBox);
288
- render();
289
- });
290
- }
291
-
292
- // Store key handler references for cleanup
293
- const keyHandlers = {
294
- up: () => {
295
- if (models.length === 0) return;
296
- selectedIndex = Math.max(0, selectedIndex - 1);
297
- render();
298
- },
299
- down: () => {
300
- if (models.length === 0) return;
301
- selectedIndex = Math.min(models.length - 1, selectedIndex + 1);
302
- render();
303
- },
304
- delete: () => {
305
- deleteModel();
306
- },
307
- search: async () => {
308
- // Cleanup current handlers before switching views
309
- cleanup();
310
-
311
- // Open search view
312
- await createSearchUI(screen, async () => {
313
- // onBack callback - return to models view
314
- // Re-register handlers
315
- registerHandlers();
316
- screen.append(contentBox);
317
- await loadModels();
318
- });
319
- },
320
- refresh: () => {
321
- loadModels();
322
- },
323
- escape: async () => {
324
- cleanup();
325
- await onBack();
326
- },
327
- quit: () => {
328
- screen.destroy();
329
- process.exit(0);
330
- },
331
- };
332
-
333
- // Cleanup function to unregister all handlers
334
- function cleanup() {
335
- screen.unkey('up', keyHandlers.up);
336
- screen.unkey('k', keyHandlers.up);
337
- screen.unkey('down', keyHandlers.down);
338
- screen.unkey('j', keyHandlers.down);
339
- screen.unkey('d', keyHandlers.delete);
340
- screen.unkey('D', keyHandlers.delete);
341
- screen.unkey('s', keyHandlers.search);
342
- screen.unkey('S', keyHandlers.search);
343
- screen.unkey('r', keyHandlers.refresh);
344
- screen.unkey('R', keyHandlers.refresh);
345
- screen.unkey('escape', keyHandlers.escape);
346
- screen.unkey('q', keyHandlers.quit);
347
- screen.unkey('Q', keyHandlers.quit);
348
- screen.unkey('C-c', keyHandlers.quit);
349
- screen.remove(contentBox);
350
- }
351
-
352
- // Register key handlers
353
- function registerHandlers() {
354
- screen.key(['up', 'k'], keyHandlers.up);
355
- screen.key(['down', 'j'], keyHandlers.down);
356
- screen.key(['d', 'D'], keyHandlers.delete);
357
- screen.key(['s', 'S'], keyHandlers.search);
358
- screen.key(['r', 'R'], keyHandlers.refresh);
359
- screen.key(['escape'], keyHandlers.escape);
360
- screen.key(['q', 'Q', 'C-c'], keyHandlers.quit);
361
- }
362
-
363
- // Register initial handlers
364
- registerHandlers();
365
-
366
- // Initial load
367
- await loadModels();
368
- }