@appkit/llamacpp-cli 1.11.0 → 1.12.1

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 (126) hide show
  1. package/README.md +572 -170
  2. package/dist/cli.js +99 -0
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/admin/config.d.ts +10 -0
  5. package/dist/commands/admin/config.d.ts.map +1 -0
  6. package/dist/commands/admin/config.js +100 -0
  7. package/dist/commands/admin/config.js.map +1 -0
  8. package/dist/commands/admin/logs.d.ts +10 -0
  9. package/dist/commands/admin/logs.d.ts.map +1 -0
  10. package/dist/commands/admin/logs.js +114 -0
  11. package/dist/commands/admin/logs.js.map +1 -0
  12. package/dist/commands/admin/restart.d.ts +2 -0
  13. package/dist/commands/admin/restart.d.ts.map +1 -0
  14. package/dist/commands/admin/restart.js +29 -0
  15. package/dist/commands/admin/restart.js.map +1 -0
  16. package/dist/commands/admin/start.d.ts +2 -0
  17. package/dist/commands/admin/start.d.ts.map +1 -0
  18. package/dist/commands/admin/start.js +30 -0
  19. package/dist/commands/admin/start.js.map +1 -0
  20. package/dist/commands/admin/status.d.ts +2 -0
  21. package/dist/commands/admin/status.d.ts.map +1 -0
  22. package/dist/commands/admin/status.js +82 -0
  23. package/dist/commands/admin/status.js.map +1 -0
  24. package/dist/commands/admin/stop.d.ts +2 -0
  25. package/dist/commands/admin/stop.d.ts.map +1 -0
  26. package/dist/commands/admin/stop.js +21 -0
  27. package/dist/commands/admin/stop.js.map +1 -0
  28. package/dist/commands/logs.d.ts +1 -0
  29. package/dist/commands/logs.d.ts.map +1 -1
  30. package/dist/commands/logs.js +22 -0
  31. package/dist/commands/logs.js.map +1 -1
  32. package/dist/lib/admin-manager.d.ts +111 -0
  33. package/dist/lib/admin-manager.d.ts.map +1 -0
  34. package/dist/lib/admin-manager.js +413 -0
  35. package/dist/lib/admin-manager.js.map +1 -0
  36. package/dist/lib/admin-server.d.ts +148 -0
  37. package/dist/lib/admin-server.d.ts.map +1 -0
  38. package/dist/lib/admin-server.js +1161 -0
  39. package/dist/lib/admin-server.js.map +1 -0
  40. package/dist/lib/download-job-manager.d.ts +64 -0
  41. package/dist/lib/download-job-manager.d.ts.map +1 -0
  42. package/dist/lib/download-job-manager.js +164 -0
  43. package/dist/lib/download-job-manager.js.map +1 -0
  44. package/dist/tui/MultiServerMonitorApp.js +1 -1
  45. package/dist/types/admin-config.d.ts +19 -0
  46. package/dist/types/admin-config.d.ts.map +1 -0
  47. package/dist/types/admin-config.js +3 -0
  48. package/dist/types/admin-config.js.map +1 -0
  49. package/dist/utils/log-parser.d.ts +9 -0
  50. package/dist/utils/log-parser.d.ts.map +1 -1
  51. package/dist/utils/log-parser.js +11 -0
  52. package/dist/utils/log-parser.js.map +1 -1
  53. package/package.json +10 -2
  54. package/web/README.md +429 -0
  55. package/web/dist/assets/index-Bin89Lwr.css +1 -0
  56. package/web/dist/assets/index-CVmonw3T.js +17 -0
  57. package/web/dist/index.html +14 -0
  58. package/web/dist/vite.svg +1 -0
  59. package/.versionrc.json +0 -16
  60. package/CHANGELOG.md +0 -203
  61. package/MONITORING-ACCURACY-FIX.md +0 -199
  62. package/PER-PROCESS-METRICS.md +0 -190
  63. package/docs/images/.gitkeep +0 -1
  64. package/src/cli.ts +0 -423
  65. package/src/commands/config-global.ts +0 -38
  66. package/src/commands/config.ts +0 -323
  67. package/src/commands/create.ts +0 -183
  68. package/src/commands/delete.ts +0 -74
  69. package/src/commands/list.ts +0 -37
  70. package/src/commands/logs-all.ts +0 -251
  71. package/src/commands/logs.ts +0 -321
  72. package/src/commands/monitor.ts +0 -110
  73. package/src/commands/ps.ts +0 -84
  74. package/src/commands/pull.ts +0 -44
  75. package/src/commands/rm.ts +0 -107
  76. package/src/commands/router/config.ts +0 -116
  77. package/src/commands/router/logs.ts +0 -256
  78. package/src/commands/router/restart.ts +0 -36
  79. package/src/commands/router/start.ts +0 -60
  80. package/src/commands/router/status.ts +0 -119
  81. package/src/commands/router/stop.ts +0 -33
  82. package/src/commands/run.ts +0 -233
  83. package/src/commands/search.ts +0 -107
  84. package/src/commands/server-show.ts +0 -161
  85. package/src/commands/show.ts +0 -207
  86. package/src/commands/start.ts +0 -101
  87. package/src/commands/stop.ts +0 -39
  88. package/src/commands/tui.ts +0 -25
  89. package/src/lib/config-generator.ts +0 -130
  90. package/src/lib/history-manager.ts +0 -172
  91. package/src/lib/launchctl-manager.ts +0 -225
  92. package/src/lib/metrics-aggregator.ts +0 -257
  93. package/src/lib/model-downloader.ts +0 -328
  94. package/src/lib/model-scanner.ts +0 -157
  95. package/src/lib/model-search.ts +0 -114
  96. package/src/lib/models-dir-setup.ts +0 -46
  97. package/src/lib/port-manager.ts +0 -80
  98. package/src/lib/router-logger.ts +0 -201
  99. package/src/lib/router-manager.ts +0 -414
  100. package/src/lib/router-server.ts +0 -538
  101. package/src/lib/state-manager.ts +0 -206
  102. package/src/lib/status-checker.ts +0 -113
  103. package/src/lib/system-collector.ts +0 -315
  104. package/src/tui/ConfigApp.ts +0 -1085
  105. package/src/tui/HistoricalMonitorApp.ts +0 -587
  106. package/src/tui/ModelsApp.ts +0 -368
  107. package/src/tui/MonitorApp.ts +0 -386
  108. package/src/tui/MultiServerMonitorApp.ts +0 -1833
  109. package/src/tui/RootNavigator.ts +0 -74
  110. package/src/tui/SearchApp.ts +0 -511
  111. package/src/tui/SplashScreen.ts +0 -149
  112. package/src/types/global-config.ts +0 -26
  113. package/src/types/history-types.ts +0 -39
  114. package/src/types/model-info.ts +0 -8
  115. package/src/types/monitor-types.ts +0 -162
  116. package/src/types/router-config.ts +0 -25
  117. package/src/types/server-config.ts +0 -46
  118. package/src/utils/downsample-utils.ts +0 -128
  119. package/src/utils/file-utils.ts +0 -146
  120. package/src/utils/format-utils.ts +0 -98
  121. package/src/utils/log-parser.ts +0 -271
  122. package/src/utils/log-utils.ts +0 -178
  123. package/src/utils/process-utils.ts +0 -316
  124. package/src/utils/prompt-utils.ts +0 -47
  125. package/test-load.sh +0 -100
  126. package/tsconfig.json +0 -20
@@ -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
- }