@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
package/src/cli.ts DELETED
@@ -1,523 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { Command } from 'commander';
4
- import chalk from 'chalk';
5
- import { listCommand } from './commands/list';
6
- import { psCommand } from './commands/ps';
7
- import { createCommand } from './commands/create';
8
- import { startCommand } from './commands/start';
9
- import { runCommand } from './commands/run';
10
- import { stopCommand } from './commands/stop';
11
- import { deleteCommand } from './commands/delete';
12
- import { pullCommand } from './commands/pull';
13
- import { rmCommand } from './commands/rm';
14
- import { logsCommand } from './commands/logs';
15
- import { logsAllCommand } from './commands/logs-all';
16
- import { searchCommand } from './commands/search';
17
- import { showCommand } from './commands/show';
18
- import { serverShowCommand } from './commands/server-show';
19
- import { serverConfigCommand } from './commands/config';
20
- import { configGlobalCommand } from './commands/config-global';
21
- import { monitorCommand } from './commands/monitor';
22
- import { routerStartCommand } from './commands/router/start';
23
- import { routerStopCommand } from './commands/router/stop';
24
- import { routerStatusCommand } from './commands/router/status';
25
- import { routerRestartCommand } from './commands/router/restart';
26
- import { routerConfigCommand } from './commands/router/config';
27
- import { routerLogsCommand } from './commands/router/logs';
28
- import { adminStartCommand } from './commands/admin/start';
29
- import { adminStopCommand } from './commands/admin/stop';
30
- import { adminStatusCommand } from './commands/admin/status';
31
- import { adminRestartCommand } from './commands/admin/restart';
32
- import { adminConfigCommand } from './commands/admin/config';
33
- import { adminLogsCommand } from './commands/admin/logs';
34
- import packageJson from '../package.json';
35
-
36
- const program = new Command();
37
-
38
- program
39
- .name('llamacpp')
40
- .description('CLI tool to manage local llama.cpp servers on macOS')
41
- .version(packageJson.version, '-v, --version', 'Output the version number')
42
- .action(async () => {
43
- // Default action: launch TUI when no command provided
44
- try {
45
- const { tuiCommand } = await import('./commands/tui');
46
- await tuiCommand();
47
- } catch (error) {
48
- console.error(chalk.red('❌ Error:'), (error as Error).message);
49
- process.exit(1);
50
- }
51
- });
52
-
53
- // List models
54
- program
55
- .command('ls')
56
- .description('List available GGUF models')
57
- .action(async () => {
58
- try {
59
- await listCommand();
60
- } catch (error) {
61
- console.error(chalk.red('❌ Error:'), (error as Error).message);
62
- process.exit(1);
63
- }
64
- });
65
-
66
- // List servers (static table)
67
- program
68
- .command('ps')
69
- .description('List all servers with status (static table)')
70
- .action(async () => {
71
- try {
72
- await psCommand();
73
- } catch (error) {
74
- console.error(chalk.red('❌ Error:'), (error as Error).message);
75
- process.exit(1);
76
- }
77
- });
78
-
79
- // View all server logs
80
- program
81
- .command('logs')
82
- .description('View log sizes for all servers (with batch operations)')
83
- .option('--clear', 'Clear current logs for all servers')
84
- .option('--clear-archived', 'Delete only archived logs for all servers')
85
- .option('--clear-all', 'Clear current + delete archived logs for all servers')
86
- .option('--rotate', 'Rotate logs for all servers with timestamps')
87
- .action(async (options) => {
88
- try {
89
- await logsAllCommand(options);
90
- } catch (error) {
91
- console.error(chalk.red('❌ Error:'), (error as Error).message);
92
- process.exit(1);
93
- }
94
- });
95
-
96
- // Search for models
97
- program
98
- .command('search')
99
- .description('Search Hugging Face for GGUF models')
100
- .argument('<query>', 'Search query (e.g., "llama 3b" or "qwen")')
101
- .option('-l, --limit <number>', 'Max results to show (default: 20)', parseInt)
102
- .option('--files [number]', 'Show available files for result number (e.g., --files 1)', (val) => {
103
- return val ? parseInt(val) : true;
104
- })
105
- .action(async (query: string, options) => {
106
- try {
107
- await searchCommand(query, options);
108
- } catch (error) {
109
- console.error(chalk.red('❌ Error:'), (error as Error).message);
110
- process.exit(1);
111
- }
112
- });
113
-
114
- // Show model details
115
- program
116
- .command('show')
117
- .description('Show details about a model or file')
118
- .argument('<identifier>', 'HuggingFace repo/file (e.g., owner/repo or owner/repo/file.gguf)')
119
- .option('-f, --file <filename>', 'Specific GGUF file to show details for')
120
- .action(async (identifier: string, options) => {
121
- try {
122
- await showCommand(identifier, options);
123
- } catch (error) {
124
- console.error(chalk.red('❌ Error:'), (error as Error).message);
125
- process.exit(1);
126
- }
127
- });
128
-
129
- // Download a model
130
- program
131
- .command('pull')
132
- .description('Download a GGUF model from Hugging Face')
133
- .argument('<identifier>', 'HuggingFace repo/file (e.g., owner/repo/file.gguf or owner/repo)')
134
- .option('-f, --file <filename>', 'Specific GGUF file (alternative to path in identifier)')
135
- .action(async (identifier: string, options) => {
136
- try {
137
- await pullCommand(identifier, options);
138
- } catch (error) {
139
- console.error(chalk.red('❌ Error:'), (error as Error).message);
140
- process.exit(1);
141
- }
142
- });
143
-
144
- // Delete a model
145
- program
146
- .command('rm')
147
- .description('Delete a model file (and any associated servers)')
148
- .argument('<model>', 'Model filename or partial name')
149
- .action(async (model: string) => {
150
- try {
151
- await rmCommand(model);
152
- } catch (error) {
153
- console.error(chalk.red('❌ Error:'), (error as Error).message);
154
- process.exit(1);
155
- }
156
- });
157
-
158
- // Global configuration
159
- program
160
- .command('config')
161
- .description('View or change global configuration')
162
- .option('--models-dir <path>', 'Set models directory path')
163
- .action(async (options) => {
164
- try {
165
- await configGlobalCommand(options);
166
- } catch (error) {
167
- console.error(chalk.red('❌ Error:'), (error as Error).message);
168
- process.exit(1);
169
- }
170
- });
171
-
172
- // Server management commands
173
- const server = program
174
- .command('server')
175
- .description('Manage llama-server instances');
176
-
177
- // Create a new server
178
- server
179
- .command('create')
180
- .description('Create and start a new llama-server instance')
181
- .argument('<model>', 'Model filename or path')
182
- .option('-p, --port <number>', 'Port number (default: auto-assign)', parseInt)
183
- .option('-h, --host <address>', 'Bind address (default: 127.0.0.1, use 0.0.0.0 for remote access)')
184
- .option('-t, --threads <number>', 'Thread count (default: auto)', parseInt)
185
- .option('-c, --ctx-size <number>', 'Context size (default: auto)', parseInt)
186
- .option('-g, --gpu-layers <number>', 'GPU layers (default: 60)', parseInt)
187
- .option('-v, --verbose', 'Enable verbose HTTP logging (detailed request/response info)')
188
- .option('-f, --flags <flags>', 'Additional llama-server flags (comma-separated, e.g., "--pooling,mean")')
189
- .action(async (model: string, options) => {
190
- try {
191
- await createCommand(model, options);
192
- } catch (error) {
193
- console.error(chalk.red('❌ Error:'), (error as Error).message);
194
- process.exit(1);
195
- }
196
- });
197
-
198
- // Show server details
199
- server
200
- .command('show')
201
- .description('Show server configuration details')
202
- .argument('<identifier>', 'Server identifier: port (9000), server ID (llama-3-2-3b), or partial model name')
203
- .action(async (identifier: string) => {
204
- try {
205
- await serverShowCommand(identifier);
206
- } catch (error) {
207
- console.error(chalk.red('❌ Error:'), (error as Error).message);
208
- process.exit(1);
209
- }
210
- });
211
-
212
- // Update server configuration
213
- server
214
- .command('config')
215
- .description('Update server configuration parameters')
216
- .argument('<identifier>', 'Server identifier: port (9000), server ID (llama-3-2-3b), or partial model name')
217
- .option('-m, --model <filename>', 'Update model (filename or path)')
218
- .option('-h, --host <address>', 'Update bind address (127.0.0.1 for localhost, 0.0.0.0 for remote access)')
219
- .option('-t, --threads <number>', 'Update thread count', parseInt)
220
- .option('-c, --ctx-size <number>', 'Update context size', parseInt)
221
- .option('-g, --gpu-layers <number>', 'Update GPU layers', parseInt)
222
- .option('-v, --verbose', 'Enable verbose logging')
223
- .option('--no-verbose', 'Disable verbose logging')
224
- .option('-f, --flags <flags>', 'Update custom llama-server flags (comma-separated, empty string to clear)')
225
- .option('-r, --restart', 'Automatically restart server if running')
226
- .action(async (identifier: string, options) => {
227
- try {
228
- await serverConfigCommand(identifier, options);
229
- } catch (error) {
230
- console.error(chalk.red('❌ Error:'), (error as Error).message);
231
- process.exit(1);
232
- }
233
- });
234
-
235
- // Start an existing server
236
- server
237
- .command('start')
238
- .description('Start an existing stopped server')
239
- .argument('<identifier>', 'Server identifier: port (9000), server ID (llama-3-2-3b), or partial model name')
240
- .action(async (identifier: string) => {
241
- try {
242
- await startCommand(identifier);
243
- } catch (error) {
244
- console.error(chalk.red('❌ Error:'), (error as Error).message);
245
- process.exit(1);
246
- }
247
- });
248
-
249
- // Run interactive chat with a model
250
- server
251
- .command('run')
252
- .description('Run an interactive chat session with a model')
253
- .argument('<model>', 'Model identifier: port (9000), server ID (llama-3-2-3b), partial name, or model filename')
254
- .option('-m, --message <text>', 'Send a single message and exit (non-interactive mode)')
255
- .action(async (model: string, options) => {
256
- try {
257
- await runCommand(model, options);
258
- } catch (error) {
259
- console.error(chalk.red('❌ Error:'), (error as Error).message);
260
- process.exit(1);
261
- }
262
- });
263
-
264
- // Stop a server
265
- server
266
- .command('stop')
267
- .description('Stop a running server')
268
- .argument('<identifier>', 'Server identifier: port (9000), server ID (llama-3-2-3b), or partial model name')
269
- .action(async (identifier: string) => {
270
- try {
271
- await stopCommand(identifier);
272
- } catch (error) {
273
- console.error(chalk.red('❌ Error:'), (error as Error).message);
274
- process.exit(1);
275
- }
276
- });
277
-
278
- // Delete a server
279
- server
280
- .command('rm')
281
- .description('Remove a server configuration and launchctl service (preserves model file)')
282
- .argument('<identifier>', 'Server identifier: port (9000), server ID (llama-3-2-3b), or partial model name')
283
- .action(async (identifier: string) => {
284
- try {
285
- await deleteCommand(identifier);
286
- } catch (error) {
287
- console.error(chalk.red('❌ Error:'), (error as Error).message);
288
- process.exit(1);
289
- }
290
- });
291
-
292
- // View logs
293
- server
294
- .command('logs')
295
- .description('View server logs (default: compact one-line per request)')
296
- .argument('<identifier>', 'Server identifier: port (9000), server ID (llama-3-2-3b), or partial model name')
297
- .option('-f, --follow', 'Follow log output in real-time')
298
- .option('-n, --lines <number>', 'Number of lines to show (default: 50)', parseInt)
299
- .option('--http', 'Show full HTTP JSON request/response logs')
300
- .option('--errors', 'Show only error messages')
301
- .option('--verbose', 'Show all messages including debug internals')
302
- .option('--filter <pattern>', 'Custom grep pattern for filtering')
303
- .option('--stdout', 'Show stdout instead of stderr (rarely needed)')
304
- .option('--clear', 'Clear (truncate) log file to zero bytes')
305
- .option('--clear-archived', 'Delete only archived logs (preserves current logs)')
306
- .option('--clear-all', 'Clear current logs AND delete all archived logs')
307
- .option('--rotate', 'Rotate log file with timestamp (preserves old logs)')
308
- .option('--include-health', 'Include health check requests (/health, /slots, /props) - filtered by default')
309
- .action(async (identifier: string, options) => {
310
- try {
311
- await logsCommand(identifier, options);
312
- } catch (error) {
313
- console.error(chalk.red('❌ Error:'), (error as Error).message);
314
- process.exit(1);
315
- }
316
- });
317
-
318
- // Monitor server (deprecated - redirects to TUI)
319
- server
320
- .command('monitor [identifier]')
321
- .description('Monitor server with real-time metrics TUI (deprecated: use "llamacpp" instead)')
322
- .action(async (identifier?: string) => {
323
- try {
324
- console.log(chalk.yellow('⚠️ The "monitor" command is deprecated and will be removed in a future version.'));
325
- console.log(chalk.dim(' Please use "llamacpp" instead for the same functionality.\n'));
326
- await monitorCommand(identifier);
327
- } catch (error) {
328
- console.error(chalk.red('❌ Error:'), (error as Error).message);
329
- process.exit(1);
330
- }
331
- });
332
-
333
- // Router management commands
334
- const router = program
335
- .command('router')
336
- .description('Manage the unified router endpoint');
337
-
338
- // Start router
339
- router
340
- .command('start')
341
- .description('Start the router service')
342
- .action(async () => {
343
- try {
344
- await routerStartCommand();
345
- } catch (error) {
346
- console.error(chalk.red('❌ Error:'), (error as Error).message);
347
- process.exit(1);
348
- }
349
- });
350
-
351
- // Stop router
352
- router
353
- .command('stop')
354
- .description('Stop the router service')
355
- .action(async () => {
356
- try {
357
- await routerStopCommand();
358
- } catch (error) {
359
- console.error(chalk.red('❌ Error:'), (error as Error).message);
360
- process.exit(1);
361
- }
362
- });
363
-
364
- // Show router status
365
- router
366
- .command('status')
367
- .description('Show router status and configuration')
368
- .action(async () => {
369
- try {
370
- await routerStatusCommand();
371
- } catch (error) {
372
- console.error(chalk.red('❌ Error:'), (error as Error).message);
373
- process.exit(1);
374
- }
375
- });
376
-
377
- // Restart router
378
- router
379
- .command('restart')
380
- .description('Restart the router service')
381
- .action(async () => {
382
- try {
383
- await routerRestartCommand();
384
- } catch (error) {
385
- console.error(chalk.red('❌ Error:'), (error as Error).message);
386
- process.exit(1);
387
- }
388
- });
389
-
390
- // Configure router
391
- router
392
- .command('config')
393
- .description('Update router configuration')
394
- .option('-p, --port <number>', 'Update port number', parseInt)
395
- .option('-h, --host <address>', 'Update bind address')
396
- .option('--timeout <ms>', 'Update request timeout (milliseconds)', parseInt)
397
- .option('--health-interval <ms>', 'Update health check interval (milliseconds)', parseInt)
398
- .option('-v, --verbose [boolean]', 'Enable/disable verbose logging to file (true/false)', (val) => val === 'true' || val === '1')
399
- .option('-r, --restart', 'Automatically restart router if running')
400
- .action(async (options) => {
401
- try {
402
- await routerConfigCommand(options);
403
- } catch (error) {
404
- console.error(chalk.red('❌ Error:'), (error as Error).message);
405
- process.exit(1);
406
- }
407
- });
408
-
409
- // Router logs
410
- router
411
- .command('logs')
412
- .description('View router logs')
413
- .option('-f, --follow', 'Follow logs in real-time (like tail -f)')
414
- .option('-n, --lines <number>', 'Number of lines to show (default: 50)', parseInt)
415
- .option('--stderr', 'Show system logs (stderr) instead of activity logs (stdout)')
416
- .option('-v, --verbose', 'Show verbose JSON log file (if enabled)')
417
- .option('--clear', 'Clear the log file')
418
- .option('--rotate', 'Rotate the log file with timestamp')
419
- .option('--clear-all', 'Clear all router logs (activity, system, verbose)')
420
- .action(async (options) => {
421
- try {
422
- await routerLogsCommand(options);
423
- } catch (error) {
424
- console.error(chalk.red('❌ Error:'), (error as Error).message);
425
- process.exit(1);
426
- }
427
- });
428
-
429
- // Admin management commands
430
- const admin = program
431
- .command('admin')
432
- .description('Manage the admin REST API service');
433
-
434
- // Start admin
435
- admin
436
- .command('start')
437
- .description('Start the admin service')
438
- .action(async () => {
439
- try {
440
- await adminStartCommand();
441
- } catch (error) {
442
- console.error(chalk.red('❌ Error:'), (error as Error).message);
443
- process.exit(1);
444
- }
445
- });
446
-
447
- // Stop admin
448
- admin
449
- .command('stop')
450
- .description('Stop the admin service')
451
- .action(async () => {
452
- try {
453
- await adminStopCommand();
454
- } catch (error) {
455
- console.error(chalk.red('❌ Error:'), (error as Error).message);
456
- process.exit(1);
457
- }
458
- });
459
-
460
- // Show admin status
461
- admin
462
- .command('status')
463
- .description('Show admin service status and configuration')
464
- .action(async () => {
465
- try {
466
- await adminStatusCommand();
467
- } catch (error) {
468
- console.error(chalk.red('❌ Error:'), (error as Error).message);
469
- process.exit(1);
470
- }
471
- });
472
-
473
- // Restart admin
474
- admin
475
- .command('restart')
476
- .description('Restart the admin service')
477
- .action(async () => {
478
- try {
479
- await adminRestartCommand();
480
- } catch (error) {
481
- console.error(chalk.red('❌ Error:'), (error as Error).message);
482
- process.exit(1);
483
- }
484
- });
485
-
486
- // Configure admin
487
- admin
488
- .command('config')
489
- .description('Update admin service configuration')
490
- .option('-p, --port <number>', 'Update port number', parseInt)
491
- .option('-h, --host <address>', 'Update bind address')
492
- .option('--regenerate-key', 'Generate a new API key')
493
- .option('-v, --verbose [boolean]', 'Enable/disable verbose logging', (val) => val === 'true' || val === '1')
494
- .option('-r, --restart', 'Automatically restart admin service if running')
495
- .action(async (options) => {
496
- try {
497
- await adminConfigCommand(options);
498
- } catch (error) {
499
- console.error(chalk.red('❌ Error:'), (error as Error).message);
500
- process.exit(1);
501
- }
502
- });
503
-
504
- // Admin logs
505
- admin
506
- .command('logs')
507
- .description('View admin service logs')
508
- .option('-f, --follow', 'Follow logs in real-time (like tail -f)')
509
- .option('-n, --lines <number>', 'Number of lines to show (default: 100)', parseInt)
510
- .option('--stdout', 'Show activity logs (stdout)')
511
- .option('--stderr', 'Show system logs (stderr)')
512
- .option('--clear', 'Clear the log files')
513
- .action(async (options) => {
514
- try {
515
- await adminLogsCommand(options);
516
- } catch (error) {
517
- console.error(chalk.red('❌ Error:'), (error as Error).message);
518
- process.exit(1);
519
- }
520
- });
521
-
522
- // Parse arguments
523
- program.parse();
@@ -1,121 +0,0 @@
1
- import chalk from 'chalk';
2
- import { adminManager } from '../../lib/admin-manager';
3
-
4
- interface ConfigOptions {
5
- port?: number;
6
- host?: string;
7
- regenerateKey?: boolean;
8
- verbose?: boolean;
9
- restart?: boolean;
10
- }
11
-
12
- export async function adminConfigCommand(options: ConfigOptions): Promise<void> {
13
- try {
14
- const result = await adminManager.getStatus();
15
-
16
- if (!result) {
17
- console.error(chalk.red('✗ Admin service is not configured'));
18
- console.log(chalk.gray('\nRun: llamacpp admin start'));
19
- process.exit(1);
20
- }
21
-
22
- const { config, status } = result;
23
-
24
- // Check if any options were provided
25
- const hasChanges = options.port || options.host || options.regenerateKey !== undefined || options.verbose !== undefined;
26
- if (!hasChanges) {
27
- console.error(chalk.red('✗ No configuration options provided'));
28
- console.log(chalk.gray('\nAvailable options:'));
29
- console.log(chalk.gray(' --port <port> Change port'));
30
- console.log(chalk.gray(' --host <host> Change host'));
31
- console.log(chalk.gray(' --regenerate-key Generate new API key'));
32
- console.log(chalk.gray(' --verbose Enable verbose logging'));
33
- console.log(chalk.gray(' --restart Restart after config change'));
34
- process.exit(1);
35
- }
36
-
37
- // Display what will change
38
- console.log(chalk.bold('Configuration Changes:'));
39
- console.log();
40
-
41
- const updates: Partial<typeof config> = {};
42
-
43
- if (options.port !== undefined) {
44
- console.log(chalk.bold(' Port: '), chalk.gray(config.port.toString()), chalk.gray('→'), chalk.cyan(options.port.toString()));
45
- updates.port = options.port;
46
- }
47
-
48
- if (options.host !== undefined) {
49
- console.log(chalk.bold(' Host: '), chalk.gray(config.host), chalk.gray('→'), chalk.cyan(options.host));
50
- updates.host = options.host;
51
-
52
- // Warn if binding to non-localhost
53
- if (options.host !== '127.0.0.1' && options.host !== 'localhost') {
54
- console.log();
55
- console.log(chalk.yellow(' ⚠ Warning: Binding to non-localhost address exposes admin API to network'));
56
- console.log(chalk.yellow(' ⚠ Ensure your firewall is properly configured'));
57
- }
58
- }
59
-
60
- if (options.verbose !== undefined) {
61
- console.log(chalk.bold(' Verbose: '), chalk.gray(config.verbose ? 'enabled' : 'disabled'), chalk.gray('→'), chalk.cyan(options.verbose ? 'enabled' : 'disabled'));
62
- updates.verbose = options.verbose;
63
- }
64
-
65
- let newApiKey: string | undefined;
66
- if (options.regenerateKey) {
67
- newApiKey = await adminManager.regenerateApiKey();
68
- console.log(chalk.bold(' API Key: '), chalk.gray('*********************'), chalk.gray('→'), chalk.yellow(newApiKey));
69
- }
70
-
71
- console.log();
72
-
73
- // Check if restart is needed
74
- const isRunning = status.isRunning;
75
- const needsRestart = isRunning && (options.port !== undefined || options.host !== undefined);
76
-
77
- if (needsRestart && !options.restart) {
78
- console.log(chalk.yellow('⚠ Admin service is running. Changes require restart.'));
79
- console.log(chalk.gray(' Add --restart flag to restart automatically\n'));
80
- }
81
-
82
- // Apply changes
83
- if (Object.keys(updates).length > 0) {
84
- await adminManager.updateConfig(updates);
85
- }
86
-
87
- // Restart if requested and needed
88
- if (options.restart && needsRestart) {
89
- console.log(chalk.blue('🔄 Restarting admin service...\n'));
90
-
91
- // Regenerate plist with new config
92
- const updatedConfig = await adminManager.loadConfig();
93
- if (updatedConfig) {
94
- await adminManager.createPlist(updatedConfig);
95
- }
96
-
97
- await adminManager.restart();
98
-
99
- console.log(chalk.green('✓ Admin service restarted successfully'));
100
- } else {
101
- console.log(chalk.green('✓ Configuration updated'));
102
-
103
- if (needsRestart && !options.restart) {
104
- console.log(chalk.gray('\nRestart with: llamacpp admin restart'));
105
- }
106
- }
107
-
108
- console.log();
109
-
110
- // Show new API key prominently if regenerated
111
- if (newApiKey) {
112
- console.log(chalk.bold('New API Key:'), chalk.yellow(newApiKey));
113
- console.log(chalk.gray('Store this key securely - it cannot be retrieved later'));
114
- console.log();
115
- }
116
- } catch (error) {
117
- console.error(chalk.red('✗ Failed to update admin configuration'));
118
- console.error(chalk.gray((error as Error).message));
119
- process.exit(1);
120
- }
121
- }