@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/commands/create.ts
DELETED
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import * as path from 'path';
|
|
3
|
-
import * as fs from 'fs';
|
|
4
|
-
import { modelScanner } from '../lib/model-scanner';
|
|
5
|
-
import { stateManager } from '../lib/state-manager';
|
|
6
|
-
import { configGenerator, ServerOptions } from '../lib/config-generator';
|
|
7
|
-
import { portManager } from '../lib/port-manager';
|
|
8
|
-
import { launchctlManager } from '../lib/launchctl-manager';
|
|
9
|
-
import { statusChecker } from '../lib/status-checker';
|
|
10
|
-
import { commandExists } from '../utils/process-utils';
|
|
11
|
-
import { formatBytes } from '../utils/format-utils';
|
|
12
|
-
import { ensureDir, parseMetalMemoryFromLog } from '../utils/file-utils';
|
|
13
|
-
import { ensureModelsDirectory } from '../lib/models-dir-setup';
|
|
14
|
-
|
|
15
|
-
interface CreateOptions {
|
|
16
|
-
port?: number;
|
|
17
|
-
host?: string;
|
|
18
|
-
threads?: number;
|
|
19
|
-
ctxSize?: number;
|
|
20
|
-
gpuLayers?: number;
|
|
21
|
-
verbose?: boolean;
|
|
22
|
-
flags?: string;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export async function createCommand(model: string, options: CreateOptions): Promise<void> {
|
|
26
|
-
// Initialize state manager
|
|
27
|
-
await stateManager.initialize();
|
|
28
|
-
|
|
29
|
-
// 1. Check if llama-server exists
|
|
30
|
-
if (!(await commandExists('llama-server'))) {
|
|
31
|
-
throw new Error('llama-server not found. Install with: brew install llama.cpp');
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// 2. Ensure models directory exists if model is not an absolute path
|
|
35
|
-
if (!path.isAbsolute(model)) {
|
|
36
|
-
const modelsDir = await stateManager.getModelsDirectory();
|
|
37
|
-
if (!fs.existsSync(modelsDir)) {
|
|
38
|
-
await ensureModelsDirectory();
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// 3. Resolve model path
|
|
43
|
-
const modelPath = await modelScanner.resolveModelPath(model);
|
|
44
|
-
if (!modelPath) {
|
|
45
|
-
throw new Error(`Model not found: ${model}\n\nRun: llamacpp ls`);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const modelName = path.basename(modelPath);
|
|
49
|
-
|
|
50
|
-
// 4. Check if server already exists for this model
|
|
51
|
-
const existingServer = await stateManager.serverExistsForModel(modelPath);
|
|
52
|
-
if (existingServer) {
|
|
53
|
-
throw new Error(`Server already exists for ${modelName}\n\nUse: llamacpp server start ${modelName}`);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// 5. Get model size
|
|
57
|
-
const modelSize = await modelScanner.getModelSize(modelName);
|
|
58
|
-
if (!modelSize) {
|
|
59
|
-
throw new Error(`Failed to read model file: ${modelPath}`);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// 6. Determine port
|
|
63
|
-
let port: number;
|
|
64
|
-
if (options.port) {
|
|
65
|
-
portManager.validatePort(options.port);
|
|
66
|
-
const available = await portManager.isPortAvailable(options.port);
|
|
67
|
-
if (!available) {
|
|
68
|
-
throw new Error(`Port ${options.port} is already in use`);
|
|
69
|
-
}
|
|
70
|
-
port = options.port;
|
|
71
|
-
} else {
|
|
72
|
-
port = await portManager.findAvailablePort();
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// 7. Generate server configuration
|
|
76
|
-
console.log(chalk.blue(`🚀 Creating server for ${modelName}\n`));
|
|
77
|
-
|
|
78
|
-
// Parse custom flags if provided
|
|
79
|
-
let customFlags: string[] | undefined;
|
|
80
|
-
if (options.flags) {
|
|
81
|
-
customFlags = options.flags.split(',').map(f => f.trim()).filter(f => f.length > 0);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const serverOptions: ServerOptions = {
|
|
85
|
-
port: options.port,
|
|
86
|
-
host: options.host,
|
|
87
|
-
threads: options.threads,
|
|
88
|
-
ctxSize: options.ctxSize,
|
|
89
|
-
gpuLayers: options.gpuLayers,
|
|
90
|
-
verbose: options.verbose,
|
|
91
|
-
customFlags,
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
const config = await configGenerator.generateConfig(
|
|
95
|
-
modelPath,
|
|
96
|
-
modelName,
|
|
97
|
-
modelSize,
|
|
98
|
-
port,
|
|
99
|
-
serverOptions
|
|
100
|
-
);
|
|
101
|
-
|
|
102
|
-
// Security warning for 0.0.0.0
|
|
103
|
-
if (config.host === '0.0.0.0') {
|
|
104
|
-
console.log(chalk.yellow('⚠️ WARNING: Binding to 0.0.0.0 allows remote access from any network interface.'));
|
|
105
|
-
console.log(chalk.yellow(' This exposes your server to your local network and potentially the internet.'));
|
|
106
|
-
console.log(chalk.yellow(' Use 127.0.0.1 for localhost-only access (recommended for local development).\n'));
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Display configuration
|
|
110
|
-
console.log(chalk.dim(`Model: ${modelPath}`));
|
|
111
|
-
console.log(chalk.dim(`Size: ${formatBytes(modelSize)}`));
|
|
112
|
-
console.log(chalk.dim(`Host: ${config.host}`));
|
|
113
|
-
console.log(chalk.dim(`Port: ${config.port}${options.port ? '' : ' (auto-assigned)'}`));
|
|
114
|
-
console.log(chalk.dim(`Threads: ${config.threads}`));
|
|
115
|
-
console.log(chalk.dim(`Context Size: ${config.ctxSize}`));
|
|
116
|
-
console.log(chalk.dim(`GPU Layers: ${config.gpuLayers}`));
|
|
117
|
-
console.log(chalk.dim(`Verbose Logging: ${config.verbose ? 'enabled' : 'disabled'}`));
|
|
118
|
-
if (config.customFlags && config.customFlags.length > 0) {
|
|
119
|
-
console.log(chalk.dim(`Custom Flags: ${config.customFlags.join(' ')}`));
|
|
120
|
-
}
|
|
121
|
-
console.log();
|
|
122
|
-
|
|
123
|
-
// 7. Ensure log directory exists
|
|
124
|
-
await ensureDir(path.dirname(config.stdoutPath));
|
|
125
|
-
|
|
126
|
-
// 8. Create plist file
|
|
127
|
-
console.log(chalk.dim('Creating launchctl service...'));
|
|
128
|
-
await launchctlManager.createPlist(config);
|
|
129
|
-
|
|
130
|
-
// 9. Load service
|
|
131
|
-
try {
|
|
132
|
-
await launchctlManager.loadService(config.plistPath);
|
|
133
|
-
} catch (error) {
|
|
134
|
-
// Clean up plist if load fails
|
|
135
|
-
await launchctlManager.deletePlist(config.plistPath);
|
|
136
|
-
throw new Error(`Failed to load service: ${(error as Error).message}`);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// 10. Start service
|
|
140
|
-
try {
|
|
141
|
-
await launchctlManager.startService(config.label);
|
|
142
|
-
} catch (error) {
|
|
143
|
-
// Clean up if start fails
|
|
144
|
-
await launchctlManager.unloadService(config.plistPath);
|
|
145
|
-
await launchctlManager.deletePlist(config.plistPath);
|
|
146
|
-
throw new Error(`Failed to start service: ${(error as Error).message}`);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// 11. Wait for startup
|
|
150
|
-
console.log(chalk.dim('Waiting for server to start...'));
|
|
151
|
-
const started = await launchctlManager.waitForServiceStart(config.label, 5000);
|
|
152
|
-
|
|
153
|
-
if (!started) {
|
|
154
|
-
// Clean up if startup fails
|
|
155
|
-
await launchctlManager.unloadService(config.plistPath);
|
|
156
|
-
await launchctlManager.deletePlist(config.plistPath);
|
|
157
|
-
throw new Error('Server failed to start. Check logs with: llamacpp server logs --errors');
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// 12. Update config with running status
|
|
161
|
-
let updatedConfig = await statusChecker.updateServerStatus(config);
|
|
162
|
-
|
|
163
|
-
// 13. Parse Metal (GPU) memory allocation from logs
|
|
164
|
-
// Wait a few seconds for model to start loading (large models take time)
|
|
165
|
-
console.log(chalk.dim('Detecting Metal (GPU) memory allocation...'));
|
|
166
|
-
await new Promise(resolve => setTimeout(resolve, 8000)); // 8 second delay
|
|
167
|
-
const metalMemoryMB = await parseMetalMemoryFromLog(updatedConfig.stderrPath);
|
|
168
|
-
if (metalMemoryMB) {
|
|
169
|
-
updatedConfig = { ...updatedConfig, metalMemoryMB };
|
|
170
|
-
console.log(chalk.dim(`Metal memory: ${metalMemoryMB.toFixed(0)} MB`));
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// 14. Save server config
|
|
174
|
-
await stateManager.saveServerConfig(updatedConfig);
|
|
175
|
-
|
|
176
|
-
// 15. Display success message
|
|
177
|
-
console.log();
|
|
178
|
-
console.log(chalk.green('✅ Server created and started successfully!'));
|
|
179
|
-
console.log();
|
|
180
|
-
console.log(chalk.dim(`Connect: http://${config.host}:${config.port}`));
|
|
181
|
-
console.log(chalk.dim(`View logs: llamacpp server logs ${config.id}`));
|
|
182
|
-
console.log(chalk.dim(`Stop: llamacpp server stop ${config.id}`));
|
|
183
|
-
}
|
package/src/commands/delete.ts
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import * as readline from 'readline';
|
|
3
|
-
import { stateManager } from '../lib/state-manager';
|
|
4
|
-
import { launchctlManager } from '../lib/launchctl-manager';
|
|
5
|
-
|
|
6
|
-
export async function deleteCommand(identifier: string): Promise<void> {
|
|
7
|
-
// Find server
|
|
8
|
-
const server = await stateManager.findServer(identifier);
|
|
9
|
-
if (!server) {
|
|
10
|
-
throw new Error(`Server not found: ${identifier}\n\nUse: llamacpp ps`);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
// Confirm deletion
|
|
14
|
-
console.log(chalk.yellow(`⚠️ Delete server configuration for ${server.modelName}?`));
|
|
15
|
-
console.log(chalk.dim(' This will remove the launchd service but keep the model file.'));
|
|
16
|
-
console.log();
|
|
17
|
-
|
|
18
|
-
const confirmed = await confirmDeletion();
|
|
19
|
-
if (!confirmed) {
|
|
20
|
-
console.log(chalk.dim('Cancelled'));
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
console.log();
|
|
25
|
-
console.log(chalk.blue(`🗑️ Deleting server ${server.modelName}...`));
|
|
26
|
-
|
|
27
|
-
// Unload service (stops and removes from launchd)
|
|
28
|
-
if (server.status === 'running') {
|
|
29
|
-
console.log(chalk.dim('Stopping and unloading service...'));
|
|
30
|
-
} else {
|
|
31
|
-
console.log(chalk.dim('Unloading service...'));
|
|
32
|
-
}
|
|
33
|
-
try {
|
|
34
|
-
await launchctlManager.unloadService(server.plistPath);
|
|
35
|
-
if (server.status === 'running') {
|
|
36
|
-
await launchctlManager.waitForServiceStop(server.label, 5000);
|
|
37
|
-
}
|
|
38
|
-
} catch (error) {
|
|
39
|
-
console.log(chalk.yellow('⚠️ Failed to unload service gracefully'));
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Delete plist
|
|
43
|
-
console.log(chalk.dim('Deleting plist file...'));
|
|
44
|
-
await launchctlManager.deletePlist(server.plistPath);
|
|
45
|
-
|
|
46
|
-
// Delete server config
|
|
47
|
-
console.log(chalk.dim('Deleting server configuration...'));
|
|
48
|
-
await stateManager.deleteServerConfig(server.id);
|
|
49
|
-
|
|
50
|
-
// Success
|
|
51
|
-
console.log();
|
|
52
|
-
console.log(chalk.green('✅ Server deleted'));
|
|
53
|
-
console.log(chalk.dim(` Plist removed: ${server.plistPath}`));
|
|
54
|
-
console.log(chalk.dim(` Config removed`));
|
|
55
|
-
console.log();
|
|
56
|
-
console.log(chalk.dim(` Model file preserved at: ${server.modelPath}`));
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Prompt user for confirmation
|
|
61
|
-
*/
|
|
62
|
-
function confirmDeletion(): Promise<boolean> {
|
|
63
|
-
return new Promise((resolve) => {
|
|
64
|
-
const rl = readline.createInterface({
|
|
65
|
-
input: process.stdin,
|
|
66
|
-
output: process.stdout,
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
rl.question(chalk.yellow(" Type 'yes' to confirm: "), (answer) => {
|
|
70
|
-
rl.close();
|
|
71
|
-
resolve(answer.toLowerCase() === 'yes');
|
|
72
|
-
});
|
|
73
|
-
});
|
|
74
|
-
}
|
package/src/commands/list.ts
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import Table from 'cli-table3';
|
|
3
|
-
import { modelScanner } from '../lib/model-scanner';
|
|
4
|
-
import { formatBytes, formatDateShort } from '../utils/format-utils';
|
|
5
|
-
import { stateManager } from '../lib/state-manager';
|
|
6
|
-
|
|
7
|
-
export async function listCommand(): Promise<void> {
|
|
8
|
-
const modelsDir = await stateManager.getModelsDirectory();
|
|
9
|
-
console.log(chalk.blue(`📦 Available models in ${modelsDir}\n`));
|
|
10
|
-
|
|
11
|
-
const models = await modelScanner.scanModels();
|
|
12
|
-
|
|
13
|
-
if (models.length === 0) {
|
|
14
|
-
console.log(chalk.yellow('No GGUF models found.'));
|
|
15
|
-
console.log(chalk.dim(`\nDownload models with: llamacpp pull <repo> --file <filename>`));
|
|
16
|
-
return;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const table = new Table({
|
|
20
|
-
head: ['MODEL', 'SIZE', 'MODIFIED'],
|
|
21
|
-
colWidths: [50, 12, 15],
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
for (const model of models) {
|
|
25
|
-
table.push([
|
|
26
|
-
model.filename,
|
|
27
|
-
model.sizeFormatted,
|
|
28
|
-
formatDateShort(model.modified),
|
|
29
|
-
]);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
console.log(table.toString());
|
|
33
|
-
|
|
34
|
-
const totalSize = models.reduce((sum, m) => sum + m.size, 0);
|
|
35
|
-
console.log(chalk.dim(`\nTotal: ${models.length} models (${formatBytes(totalSize)})`));
|
|
36
|
-
console.log(chalk.dim(`\nCreate a server: llamacpp server create <model-filename>`));
|
|
37
|
-
}
|
package/src/commands/logs-all.ts
DELETED
|
@@ -1,251 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import Table from 'cli-table3';
|
|
3
|
-
import { stateManager } from '../lib/state-manager';
|
|
4
|
-
import { fileExists } from '../utils/file-utils';
|
|
5
|
-
import {
|
|
6
|
-
getFileSize,
|
|
7
|
-
formatFileSize,
|
|
8
|
-
getArchivedLogInfo,
|
|
9
|
-
clearLogFile,
|
|
10
|
-
rotateLogFile,
|
|
11
|
-
deleteArchivedLogs,
|
|
12
|
-
} from '../utils/log-utils';
|
|
13
|
-
|
|
14
|
-
interface LogsAllOptions {
|
|
15
|
-
clear?: boolean;
|
|
16
|
-
clearArchived?: boolean;
|
|
17
|
-
clearAll?: boolean;
|
|
18
|
-
rotate?: boolean;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export async function logsAllCommand(options: LogsAllOptions): Promise<void> {
|
|
22
|
-
// Get all servers
|
|
23
|
-
const servers = await stateManager.getAllServers();
|
|
24
|
-
|
|
25
|
-
if (servers.length === 0) {
|
|
26
|
-
console.log(chalk.yellow('⚠️ No servers found'));
|
|
27
|
-
console.log(chalk.dim('\nCreate a server: llamacpp server create <model-filename>'));
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Handle batch operations
|
|
32
|
-
if (options.clear || options.clearArchived || options.clearAll || options.rotate) {
|
|
33
|
-
await handleBatchOperation(servers, options);
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// Show table of log information
|
|
38
|
-
await showLogsTable(servers);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
async function showLogsTable(servers: any[]): Promise<void> {
|
|
42
|
-
const table = new Table({
|
|
43
|
-
head: [
|
|
44
|
-
chalk.bold('Server ID'),
|
|
45
|
-
chalk.bold('Current Stderr'),
|
|
46
|
-
chalk.bold('Current Stdout'),
|
|
47
|
-
chalk.bold('Archived'),
|
|
48
|
-
chalk.bold('Total'),
|
|
49
|
-
],
|
|
50
|
-
colWidths: [30, 18, 18, 18, 18],
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
let totalCurrent = 0;
|
|
54
|
-
let totalArchived = 0;
|
|
55
|
-
|
|
56
|
-
for (const server of servers) {
|
|
57
|
-
// Get current log sizes
|
|
58
|
-
const stderrSize = (await fileExists(server.stderrPath))
|
|
59
|
-
? await getFileSize(server.stderrPath)
|
|
60
|
-
: 0;
|
|
61
|
-
const stdoutSize = (await fileExists(server.stdoutPath))
|
|
62
|
-
? await getFileSize(server.stdoutPath)
|
|
63
|
-
: 0;
|
|
64
|
-
|
|
65
|
-
// Get archived info
|
|
66
|
-
const archivedInfo = await getArchivedLogInfo(server.id);
|
|
67
|
-
|
|
68
|
-
const currentTotal = stderrSize + stdoutSize;
|
|
69
|
-
const total = currentTotal + archivedInfo.totalSize;
|
|
70
|
-
|
|
71
|
-
totalCurrent += currentTotal;
|
|
72
|
-
totalArchived += archivedInfo.totalSize;
|
|
73
|
-
|
|
74
|
-
table.push([
|
|
75
|
-
server.id,
|
|
76
|
-
formatFileSize(stderrSize),
|
|
77
|
-
formatFileSize(stdoutSize),
|
|
78
|
-
archivedInfo.count > 0
|
|
79
|
-
? `${formatFileSize(archivedInfo.totalSize)} (${archivedInfo.count})`
|
|
80
|
-
: formatFileSize(0),
|
|
81
|
-
formatFileSize(total),
|
|
82
|
-
]);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
console.log(chalk.bold('\nServer Logs Overview:'));
|
|
86
|
-
console.log(table.toString());
|
|
87
|
-
|
|
88
|
-
console.log(chalk.dim('\nTotals:'));
|
|
89
|
-
console.log(chalk.dim(` Current logs: ${formatFileSize(totalCurrent)}`));
|
|
90
|
-
console.log(chalk.dim(` Archived logs: ${formatFileSize(totalArchived)}`));
|
|
91
|
-
console.log(chalk.dim(` Grand total: ${formatFileSize(totalCurrent + totalArchived)}`));
|
|
92
|
-
|
|
93
|
-
console.log(chalk.dim('\nBatch operations:'));
|
|
94
|
-
console.log(chalk.dim(' llamacpp logs --clear Clear all current logs'));
|
|
95
|
-
console.log(chalk.dim(' llamacpp logs --clear-archived Delete only archived logs'));
|
|
96
|
-
console.log(chalk.dim(' llamacpp logs --clear-all Clear current + delete archives'));
|
|
97
|
-
console.log(chalk.dim(' llamacpp logs --rotate Rotate all logs with timestamps'));
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
async function handleBatchOperation(
|
|
101
|
-
servers: any[],
|
|
102
|
-
options: LogsAllOptions
|
|
103
|
-
): Promise<void> {
|
|
104
|
-
if (options.clearArchived) {
|
|
105
|
-
console.log(chalk.blue('🗑️ Deleting archived logs for all servers...'));
|
|
106
|
-
console.log();
|
|
107
|
-
|
|
108
|
-
let totalFreed = 0;
|
|
109
|
-
let totalFiles = 0;
|
|
110
|
-
let serversProcessed = 0;
|
|
111
|
-
|
|
112
|
-
for (const server of servers) {
|
|
113
|
-
const archivedInfo = await deleteArchivedLogs(server.id);
|
|
114
|
-
|
|
115
|
-
if (archivedInfo.count > 0) {
|
|
116
|
-
console.log(chalk.dim(` ${server.id}: ${formatFileSize(archivedInfo.totalSize)} (${archivedInfo.count} file${archivedInfo.count !== 1 ? 's' : ''})`));
|
|
117
|
-
totalFreed += archivedInfo.totalSize;
|
|
118
|
-
totalFiles += archivedInfo.count;
|
|
119
|
-
serversProcessed++;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
console.log();
|
|
124
|
-
if (serversProcessed === 0) {
|
|
125
|
-
console.log(chalk.yellow('⚠️ No archived logs found'));
|
|
126
|
-
console.log(chalk.dim(' Archived logs are created via --rotate or automatic rotation'));
|
|
127
|
-
} else {
|
|
128
|
-
console.log(chalk.green(`✅ Deleted archived logs for ${serversProcessed} server${serversProcessed !== 1 ? 's' : ''}`));
|
|
129
|
-
console.log(chalk.dim(` Files deleted: ${totalFiles}`));
|
|
130
|
-
console.log(chalk.dim(` Total freed: ${formatFileSize(totalFreed)}`));
|
|
131
|
-
console.log(chalk.dim(` Current logs preserved`));
|
|
132
|
-
}
|
|
133
|
-
} else if (options.clearAll) {
|
|
134
|
-
console.log(chalk.blue('🗑️ Clearing all logs (current + archived) for all servers...'));
|
|
135
|
-
console.log();
|
|
136
|
-
|
|
137
|
-
let totalFreed = 0;
|
|
138
|
-
let serversProcessed = 0;
|
|
139
|
-
|
|
140
|
-
for (const server of servers) {
|
|
141
|
-
let serverTotal = 0;
|
|
142
|
-
|
|
143
|
-
// Clear current stderr
|
|
144
|
-
if (await fileExists(server.stderrPath)) {
|
|
145
|
-
serverTotal += await getFileSize(server.stderrPath);
|
|
146
|
-
await clearLogFile(server.stderrPath);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// Clear current stdout
|
|
150
|
-
if (await fileExists(server.stdoutPath)) {
|
|
151
|
-
serverTotal += await getFileSize(server.stdoutPath);
|
|
152
|
-
await clearLogFile(server.stdoutPath);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// Delete archived logs
|
|
156
|
-
const archivedInfo = await deleteArchivedLogs(server.id);
|
|
157
|
-
serverTotal += archivedInfo.totalSize;
|
|
158
|
-
|
|
159
|
-
if (serverTotal > 0) {
|
|
160
|
-
console.log(chalk.dim(` ${server.id}: ${formatFileSize(serverTotal)}`));
|
|
161
|
-
totalFreed += serverTotal;
|
|
162
|
-
serversProcessed++;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
console.log();
|
|
167
|
-
console.log(chalk.green(`✅ Cleared all logs for ${serversProcessed} server${serversProcessed !== 1 ? 's' : ''}`));
|
|
168
|
-
console.log(chalk.dim(` Total freed: ${formatFileSize(totalFreed)}`));
|
|
169
|
-
} else if (options.clear) {
|
|
170
|
-
console.log(chalk.blue('🗑️ Clearing current logs for all servers...'));
|
|
171
|
-
console.log();
|
|
172
|
-
|
|
173
|
-
let totalFreed = 0;
|
|
174
|
-
let serversProcessed = 0;
|
|
175
|
-
|
|
176
|
-
for (const server of servers) {
|
|
177
|
-
let serverTotal = 0;
|
|
178
|
-
|
|
179
|
-
// Clear current stderr
|
|
180
|
-
if (await fileExists(server.stderrPath)) {
|
|
181
|
-
serverTotal += await getFileSize(server.stderrPath);
|
|
182
|
-
await clearLogFile(server.stderrPath);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// Clear current stdout
|
|
186
|
-
if (await fileExists(server.stdoutPath)) {
|
|
187
|
-
serverTotal += await getFileSize(server.stdoutPath);
|
|
188
|
-
await clearLogFile(server.stdoutPath);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
if (serverTotal > 0) {
|
|
192
|
-
console.log(chalk.dim(` ${server.id}: ${formatFileSize(serverTotal)}`));
|
|
193
|
-
totalFreed += serverTotal;
|
|
194
|
-
serversProcessed++;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
console.log();
|
|
199
|
-
console.log(chalk.green(`✅ Cleared current logs for ${serversProcessed} server${serversProcessed !== 1 ? 's' : ''}`));
|
|
200
|
-
console.log(chalk.dim(` Total freed: ${formatFileSize(totalFreed)}`));
|
|
201
|
-
console.log(chalk.dim(` Archived logs preserved`));
|
|
202
|
-
} else if (options.rotate) {
|
|
203
|
-
console.log(chalk.blue('🔄 Rotating logs for all servers...'));
|
|
204
|
-
console.log();
|
|
205
|
-
|
|
206
|
-
let totalRotated = 0;
|
|
207
|
-
let filesRotated = 0;
|
|
208
|
-
|
|
209
|
-
for (const server of servers) {
|
|
210
|
-
const rotatedFiles: string[] = [];
|
|
211
|
-
|
|
212
|
-
// Rotate stderr if it has content
|
|
213
|
-
if (await fileExists(server.stderrPath)) {
|
|
214
|
-
const size = await getFileSize(server.stderrPath);
|
|
215
|
-
if (size > 0) {
|
|
216
|
-
try {
|
|
217
|
-
const archivedPath = await rotateLogFile(server.stderrPath);
|
|
218
|
-
rotatedFiles.push(archivedPath);
|
|
219
|
-
totalRotated += size;
|
|
220
|
-
filesRotated++;
|
|
221
|
-
} catch {
|
|
222
|
-
// Ignore empty files
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
// Rotate stdout if it has content
|
|
228
|
-
if (await fileExists(server.stdoutPath)) {
|
|
229
|
-
const size = await getFileSize(server.stdoutPath);
|
|
230
|
-
if (size > 0) {
|
|
231
|
-
try {
|
|
232
|
-
const archivedPath = await rotateLogFile(server.stdoutPath);
|
|
233
|
-
rotatedFiles.push(archivedPath);
|
|
234
|
-
totalRotated += size;
|
|
235
|
-
filesRotated++;
|
|
236
|
-
} catch {
|
|
237
|
-
// Ignore empty files
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
if (rotatedFiles.length > 0) {
|
|
243
|
-
console.log(chalk.dim(` ${server.id}: ${rotatedFiles.length} file${rotatedFiles.length !== 1 ? 's' : ''}`));
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
console.log();
|
|
248
|
-
console.log(chalk.green(`✅ Rotated ${filesRotated} log file${filesRotated !== 1 ? 's' : ''}`));
|
|
249
|
-
console.log(chalk.dim(` Total archived: ${formatFileSize(totalRotated)}`));
|
|
250
|
-
}
|
|
251
|
-
}
|