@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.
- package/README.md +294 -168
- package/dist/cli.js +35 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/launch/claude.d.ts +6 -0
- package/dist/commands/launch/claude.d.ts.map +1 -0
- package/dist/commands/launch/claude.js +277 -0
- package/dist/commands/launch/claude.js.map +1 -0
- package/dist/lib/integration-checker.d.ts +26 -0
- package/dist/lib/integration-checker.d.ts.map +1 -0
- package/dist/lib/integration-checker.js +77 -0
- package/dist/lib/integration-checker.js.map +1 -0
- package/dist/lib/router-manager.d.ts +4 -0
- package/dist/lib/router-manager.d.ts.map +1 -1
- package/dist/lib/router-manager.js +10 -0
- package/dist/lib/router-manager.js.map +1 -1
- package/dist/lib/router-server.d.ts +13 -0
- package/dist/lib/router-server.d.ts.map +1 -1
- package/dist/lib/router-server.js +267 -7
- package/dist/lib/router-server.js.map +1 -1
- package/dist/types/integration-config.d.ts +28 -0
- package/dist/types/integration-config.d.ts.map +1 -0
- package/dist/types/integration-config.js +3 -0
- package/dist/types/integration-config.js.map +1 -0
- package/package.json +10 -2
- package/web/dist/assets/index-Bin89Lwr.css +1 -0
- package/web/dist/assets/index-CVmonw3T.js +17 -0
- package/web/{index.html → dist/index.html} +2 -1
- package/.versionrc.json +0 -16
- package/CHANGELOG.md +0 -213
- package/docs/images/.gitkeep +0 -1
- package/docs/images/web-ui-servers.png +0 -0
- package/src/cli.ts +0 -523
- package/src/commands/admin/config.ts +0 -121
- package/src/commands/admin/logs.ts +0 -91
- package/src/commands/admin/restart.ts +0 -26
- package/src/commands/admin/start.ts +0 -27
- package/src/commands/admin/status.ts +0 -84
- package/src/commands/admin/stop.ts +0 -16
- package/src/commands/config-global.ts +0 -38
- package/src/commands/config.ts +0 -323
- package/src/commands/create.ts +0 -183
- package/src/commands/delete.ts +0 -74
- package/src/commands/list.ts +0 -37
- package/src/commands/logs-all.ts +0 -251
- package/src/commands/logs.ts +0 -345
- package/src/commands/monitor.ts +0 -110
- package/src/commands/ps.ts +0 -84
- package/src/commands/pull.ts +0 -44
- package/src/commands/rm.ts +0 -107
- package/src/commands/router/config.ts +0 -116
- package/src/commands/router/logs.ts +0 -256
- package/src/commands/router/restart.ts +0 -36
- package/src/commands/router/start.ts +0 -60
- package/src/commands/router/status.ts +0 -119
- package/src/commands/router/stop.ts +0 -33
- package/src/commands/run.ts +0 -233
- package/src/commands/search.ts +0 -107
- package/src/commands/server-show.ts +0 -161
- package/src/commands/show.ts +0 -207
- package/src/commands/start.ts +0 -101
- package/src/commands/stop.ts +0 -39
- package/src/commands/tui.ts +0 -25
- package/src/lib/admin-manager.ts +0 -435
- package/src/lib/admin-server.ts +0 -1243
- package/src/lib/config-generator.ts +0 -130
- package/src/lib/download-job-manager.ts +0 -213
- package/src/lib/history-manager.ts +0 -172
- package/src/lib/launchctl-manager.ts +0 -225
- package/src/lib/metrics-aggregator.ts +0 -257
- package/src/lib/model-downloader.ts +0 -328
- package/src/lib/model-scanner.ts +0 -157
- package/src/lib/model-search.ts +0 -114
- package/src/lib/models-dir-setup.ts +0 -46
- package/src/lib/port-manager.ts +0 -80
- package/src/lib/router-logger.ts +0 -201
- package/src/lib/router-manager.ts +0 -414
- package/src/lib/router-server.ts +0 -538
- package/src/lib/state-manager.ts +0 -206
- package/src/lib/status-checker.ts +0 -113
- package/src/lib/system-collector.ts +0 -315
- package/src/tui/ConfigApp.ts +0 -1085
- package/src/tui/HistoricalMonitorApp.ts +0 -587
- package/src/tui/ModelsApp.ts +0 -368
- package/src/tui/MonitorApp.ts +0 -386
- package/src/tui/MultiServerMonitorApp.ts +0 -1833
- package/src/tui/RootNavigator.ts +0 -74
- package/src/tui/SearchApp.ts +0 -511
- package/src/tui/SplashScreen.ts +0 -149
- package/src/types/admin-config.ts +0 -25
- package/src/types/global-config.ts +0 -26
- package/src/types/history-types.ts +0 -39
- package/src/types/model-info.ts +0 -8
- package/src/types/monitor-types.ts +0 -162
- package/src/types/router-config.ts +0 -25
- package/src/types/server-config.ts +0 -46
- package/src/utils/downsample-utils.ts +0 -128
- package/src/utils/file-utils.ts +0 -146
- package/src/utils/format-utils.ts +0 -98
- package/src/utils/log-parser.ts +0 -284
- package/src/utils/log-utils.ts +0 -178
- package/src/utils/process-utils.ts +0 -316
- package/src/utils/prompt-utils.ts +0 -47
- package/test-load.sh +0 -100
- package/tsconfig.json +0 -20
- package/web/eslint.config.js +0 -23
- package/web/llamacpp-web-dist.tar.gz +0 -0
- package/web/package-lock.json +0 -4017
- package/web/package.json +0 -38
- package/web/postcss.config.js +0 -6
- package/web/src/App.css +0 -42
- package/web/src/App.tsx +0 -86
- package/web/src/assets/react.svg +0 -1
- package/web/src/components/ApiKeyPrompt.tsx +0 -71
- package/web/src/components/CreateServerModal.tsx +0 -372
- package/web/src/components/DownloadProgress.tsx +0 -123
- package/web/src/components/Nav.tsx +0 -89
- package/web/src/components/RouterConfigModal.tsx +0 -240
- package/web/src/components/SearchModal.tsx +0 -306
- package/web/src/components/ServerConfigModal.tsx +0 -291
- package/web/src/hooks/useApi.ts +0 -259
- package/web/src/index.css +0 -42
- package/web/src/lib/api.ts +0 -226
- package/web/src/main.tsx +0 -10
- package/web/src/pages/Dashboard.tsx +0 -103
- package/web/src/pages/Models.tsx +0 -258
- package/web/src/pages/Router.tsx +0 -270
- package/web/src/pages/RouterLogs.tsx +0 -201
- package/web/src/pages/ServerLogs.tsx +0 -553
- package/web/src/pages/Servers.tsx +0 -358
- package/web/src/types/api.ts +0 -140
- package/web/tailwind.config.js +0 -31
- package/web/tsconfig.app.json +0 -28
- package/web/tsconfig.json +0 -7
- package/web/tsconfig.node.json +0 -26
- package/web/vite.config.ts +0 -25
- /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
|
-
}
|