@appkit/llamacpp-cli 1.9.0 → 1.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/README.md +171 -42
  3. package/dist/cli.js +75 -10
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/completion.d.ts +9 -0
  6. package/dist/commands/completion.d.ts.map +1 -0
  7. package/dist/commands/completion.js +83 -0
  8. package/dist/commands/completion.js.map +1 -0
  9. package/dist/commands/monitor.js +1 -1
  10. package/dist/commands/monitor.js.map +1 -1
  11. package/dist/commands/ps.d.ts +1 -3
  12. package/dist/commands/ps.d.ts.map +1 -1
  13. package/dist/commands/ps.js +36 -115
  14. package/dist/commands/ps.js.map +1 -1
  15. package/dist/commands/router/config.d.ts +1 -0
  16. package/dist/commands/router/config.d.ts.map +1 -1
  17. package/dist/commands/router/config.js +7 -2
  18. package/dist/commands/router/config.js.map +1 -1
  19. package/dist/commands/router/logs.d.ts +12 -0
  20. package/dist/commands/router/logs.d.ts.map +1 -0
  21. package/dist/commands/router/logs.js +238 -0
  22. package/dist/commands/router/logs.js.map +1 -0
  23. package/dist/commands/tui.d.ts +2 -0
  24. package/dist/commands/tui.d.ts.map +1 -0
  25. package/dist/commands/tui.js +27 -0
  26. package/dist/commands/tui.js.map +1 -0
  27. package/dist/lib/completion.d.ts +5 -0
  28. package/dist/lib/completion.d.ts.map +1 -0
  29. package/dist/lib/completion.js +195 -0
  30. package/dist/lib/completion.js.map +1 -0
  31. package/dist/lib/model-downloader.d.ts +5 -1
  32. package/dist/lib/model-downloader.d.ts.map +1 -1
  33. package/dist/lib/model-downloader.js +53 -20
  34. package/dist/lib/model-downloader.js.map +1 -1
  35. package/dist/lib/router-logger.d.ts +61 -0
  36. package/dist/lib/router-logger.d.ts.map +1 -0
  37. package/dist/lib/router-logger.js +200 -0
  38. package/dist/lib/router-logger.js.map +1 -0
  39. package/dist/lib/router-manager.d.ts.map +1 -1
  40. package/dist/lib/router-manager.js +1 -0
  41. package/dist/lib/router-manager.js.map +1 -1
  42. package/dist/lib/router-server.d.ts +9 -0
  43. package/dist/lib/router-server.d.ts.map +1 -1
  44. package/dist/lib/router-server.js +169 -57
  45. package/dist/lib/router-server.js.map +1 -1
  46. package/dist/tui/ConfigApp.d.ts +7 -0
  47. package/dist/tui/ConfigApp.d.ts.map +1 -0
  48. package/dist/tui/ConfigApp.js +1002 -0
  49. package/dist/tui/ConfigApp.js.map +1 -0
  50. package/dist/tui/HistoricalMonitorApp.d.ts.map +1 -1
  51. package/dist/tui/HistoricalMonitorApp.js +85 -49
  52. package/dist/tui/HistoricalMonitorApp.js.map +1 -1
  53. package/dist/tui/ModelsApp.d.ts +7 -0
  54. package/dist/tui/ModelsApp.d.ts.map +1 -0
  55. package/dist/tui/ModelsApp.js +362 -0
  56. package/dist/tui/ModelsApp.js.map +1 -0
  57. package/dist/tui/MultiServerMonitorApp.d.ts +6 -1
  58. package/dist/tui/MultiServerMonitorApp.d.ts.map +1 -1
  59. package/dist/tui/MultiServerMonitorApp.js +1038 -122
  60. package/dist/tui/MultiServerMonitorApp.js.map +1 -1
  61. package/dist/tui/RootNavigator.d.ts +7 -0
  62. package/dist/tui/RootNavigator.d.ts.map +1 -0
  63. package/dist/tui/RootNavigator.js +55 -0
  64. package/dist/tui/RootNavigator.js.map +1 -0
  65. package/dist/tui/SearchApp.d.ts +6 -0
  66. package/dist/tui/SearchApp.d.ts.map +1 -0
  67. package/dist/tui/SearchApp.js +451 -0
  68. package/dist/tui/SearchApp.js.map +1 -0
  69. package/dist/tui/SplashScreen.d.ts +16 -0
  70. package/dist/tui/SplashScreen.d.ts.map +1 -0
  71. package/dist/tui/SplashScreen.js +129 -0
  72. package/dist/tui/SplashScreen.js.map +1 -0
  73. package/dist/types/router-config.d.ts +1 -0
  74. package/dist/types/router-config.d.ts.map +1 -1
  75. package/dist/utils/log-parser.d.ts +14 -1
  76. package/dist/utils/log-parser.d.ts.map +1 -1
  77. package/dist/utils/log-parser.js +57 -26
  78. package/dist/utils/log-parser.js.map +1 -1
  79. package/package.json +1 -1
  80. package/src/cli.ts +41 -10
  81. package/src/commands/monitor.ts +1 -1
  82. package/src/commands/ps.ts +44 -133
  83. package/src/commands/router/config.ts +9 -2
  84. package/src/commands/router/logs.ts +256 -0
  85. package/src/commands/tui.ts +25 -0
  86. package/src/lib/model-downloader.ts +57 -20
  87. package/src/lib/router-logger.ts +201 -0
  88. package/src/lib/router-manager.ts +1 -0
  89. package/src/lib/router-server.ts +193 -62
  90. package/src/tui/ConfigApp.ts +1085 -0
  91. package/src/tui/HistoricalMonitorApp.ts +88 -49
  92. package/src/tui/ModelsApp.ts +368 -0
  93. package/src/tui/MultiServerMonitorApp.ts +1163 -122
  94. package/src/tui/RootNavigator.ts +74 -0
  95. package/src/tui/SearchApp.ts +511 -0
  96. package/src/tui/SplashScreen.ts +149 -0
  97. package/src/types/router-config.ts +1 -0
  98. package/src/utils/log-parser.ts +61 -25
@@ -4,6 +4,13 @@
4
4
  export declare class LogParser {
5
5
  private buffer;
6
6
  private isBuffering;
7
+ /**
8
+ * Check if line is a request status line (contains method/endpoint/status, no JSON)
9
+ * Handles both old and new formats:
10
+ * - Old: log_server_r: request: POST /v1/chat/completions 127.0.0.1 200
11
+ * - New: log_server_r: done request: POST /v1/messages 172.16.0.114 200
12
+ */
13
+ private isRequestStatusLine;
7
14
  /**
8
15
  * Process log lines and output compact format
9
16
  */
@@ -15,11 +22,14 @@ export declare class LogParser {
15
22
  flush(callback: (compactLine: string) => void): void;
16
23
  /**
17
24
  * Parse simple single-line format (non-verbose mode)
18
- * Format: srv log_server_r: request: POST /v1/chat/completions 127.0.0.1 200
25
+ * Handles both old and new formats:
26
+ * - Old: srv log_server_r: request: POST /v1/chat/completions 127.0.0.1 200
27
+ * - New: srv log_server_r: done request: POST /v1/messages 172.16.0.114 200
19
28
  */
20
29
  private parseSimpleFormat;
21
30
  /**
22
31
  * Consolidate buffered request/response lines into single line
32
+ * Handles both old and new llama.cpp log formats
23
33
  */
24
34
  private consolidateRequest;
25
35
  /**
@@ -32,6 +42,9 @@ export declare class LogParser {
32
42
  private extractJson;
33
43
  /**
34
44
  * Extract first user message from request JSON
45
+ * Handles both string content and array content formats:
46
+ * - String: {"role":"user","content":"Hello"}
47
+ * - Array: {"role":"user","content":[{"type":"text","text":"Hello"}]}
35
48
  */
36
49
  private extractUserMessage;
37
50
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"log-parser.d.ts","sourceRoot":"","sources":["../../src/utils/log-parser.ts"],"names":[],"mappings":"AAAA;;GAEG;AAcH,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,WAAW,CAAS;IAE5B;;OAEG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAsCxE;;;OAGG;IACH,KAAK,CAAC,QAAQ,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAcpD;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAezB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAiD1B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAWxB;;OAEG;IACH,OAAO,CAAC,WAAW;IAYnB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAU1B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAoB3B;;OAEG;IACH,OAAO,CAAC,iBAAiB;CAa1B;AAGD,eAAO,MAAM,SAAS,WAAkB,CAAC"}
1
+ {"version":3,"file":"log-parser.d.ts","sourceRoot":"","sources":["../../src/utils/log-parser.ts"],"names":[],"mappings":"AAAA;;GAEG;AAcH,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,WAAW,CAAS;IAE5B;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;IAQ3B;;OAEG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAsCxE;;;OAGG;IACH,KAAK,CAAC,QAAQ,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAcpD;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB;IAgBzB;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAsD1B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAWxB;;OAEG;IACH,OAAO,CAAC,WAAW;IAYnB;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAoB1B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAoB3B;;OAEG;IACH,OAAO,CAAC,iBAAiB;CAa1B;AAGD,eAAO,MAAM,SAAS,WAAkB,CAAC"}
@@ -9,13 +9,24 @@ class LogParser {
9
9
  this.buffer = [];
10
10
  this.isBuffering = false;
11
11
  }
12
+ /**
13
+ * Check if line is a request status line (contains method/endpoint/status, no JSON)
14
+ * Handles both old and new formats:
15
+ * - Old: log_server_r: request: POST /v1/chat/completions 127.0.0.1 200
16
+ * - New: log_server_r: done request: POST /v1/messages 172.16.0.114 200
17
+ */
18
+ isRequestStatusLine(line) {
19
+ return ((line.includes('log_server_r: request:') || line.includes('log_server_r: done request:')) &&
20
+ !line.includes('{') &&
21
+ /(?:done )?request: (POST|GET|PUT|DELETE)/.test(line));
22
+ }
12
23
  /**
13
24
  * Process log lines and output compact format
14
25
  */
15
26
  processLine(line, callback) {
16
- // Check if this is a simple single-line format (no JSON, non-verbose mode)
17
- // Format: srv log_server_r: request: POST /v1/chat/completions 127.0.0.1 200
18
- if (line.includes('log_server_r: request:') && !line.includes('{')) {
27
+ // Check if this is a request status line (no JSON, has method/endpoint/status)
28
+ // Handles both old format (request:) and new format (done request:)
29
+ if (this.isRequestStatusLine(line)) {
19
30
  // Check if this is the start of verbose format (status line before JSON)
20
31
  // or a simple single-line log
21
32
  if (this.isBuffering) {
@@ -65,12 +76,15 @@ class LogParser {
65
76
  }
66
77
  /**
67
78
  * Parse simple single-line format (non-verbose mode)
68
- * Format: srv log_server_r: request: POST /v1/chat/completions 127.0.0.1 200
79
+ * Handles both old and new formats:
80
+ * - Old: srv log_server_r: request: POST /v1/chat/completions 127.0.0.1 200
81
+ * - New: srv log_server_r: done request: POST /v1/messages 172.16.0.114 200
69
82
  */
70
83
  parseSimpleFormat(line) {
71
84
  try {
72
85
  const timestamp = this.extractTimestamp(line);
73
- const requestMatch = line.match(/request: (POST|GET|PUT|DELETE) ([^\s]+) ([^\s]+) (\d+)/);
86
+ // Match both "request:" and "done request:" formats
87
+ const requestMatch = line.match(/(?:done )?request: (POST|GET|PUT|DELETE) ([^\s]+) ([^\s]+) (\d+)/);
74
88
  if (!requestMatch)
75
89
  return null;
76
90
  const [, method, endpoint, ip, status] = requestMatch;
@@ -83,36 +97,41 @@ class LogParser {
83
97
  }
84
98
  /**
85
99
  * Consolidate buffered request/response lines into single line
100
+ * Handles both old and new llama.cpp log formats
86
101
  */
87
102
  consolidateRequest(lines) {
88
103
  try {
89
104
  // Parse first line: timestamp and request info
105
+ // Match both "request:" and "done request:" formats
90
106
  const firstLine = lines[0];
91
107
  const timestamp = this.extractTimestamp(firstLine);
92
- const requestMatch = firstLine.match(/request: (POST|GET|PUT|DELETE) (\/[^\s]+) ([^\s]+) (\d+)/);
108
+ const requestMatch = firstLine.match(/(?:done )?request: (POST|GET|PUT|DELETE) (\/[^\s]+) ([^\s]+) (\d+)/);
93
109
  if (!requestMatch)
94
110
  return null;
95
111
  const [, method, endpoint, ip, status] = requestMatch;
96
- // Parse request JSON (second line)
112
+ // Parse request JSON (line with JSON body)
97
113
  const requestLine = lines.find((l) => l.includes('log_server_r: request:') && l.includes('{'));
98
- if (!requestLine)
99
- return null;
100
- const requestJson = this.extractJson(requestLine);
101
- if (!requestJson)
102
- return null;
103
- const userMessage = this.extractUserMessage(requestJson);
104
- // Parse response JSON (last line)
114
+ let userMessage = '';
115
+ if (requestLine) {
116
+ const requestJson = this.extractJson(requestLine);
117
+ if (requestJson) {
118
+ userMessage = this.extractUserMessage(requestJson);
119
+ }
120
+ }
121
+ // Parse response JSON (may be empty in new format)
105
122
  const responseLine = lines.find((l) => l.includes('log_server_r: response:'));
106
- if (!responseLine)
107
- return null;
108
- const responseJson = this.extractJson(responseLine);
109
- if (!responseJson)
110
- return null;
111
- const tokensIn = responseJson.usage?.prompt_tokens || 0;
112
- const tokensOut = responseJson.usage?.completion_tokens || 0;
113
- // Extract response time from verbose timings
114
- const responseTimeMs = this.extractResponseTime(responseJson);
115
- // Format compact line
123
+ let tokensIn = 0;
124
+ let tokensOut = 0;
125
+ let responseTimeMs = 0;
126
+ if (responseLine) {
127
+ const responseJson = this.extractJson(responseLine);
128
+ if (responseJson) {
129
+ tokensIn = responseJson.usage?.prompt_tokens || 0;
130
+ tokensOut = responseJson.usage?.completion_tokens || 0;
131
+ responseTimeMs = this.extractResponseTime(responseJson);
132
+ }
133
+ }
134
+ // Format compact line (works even without response data)
116
135
  return this.formatCompactLine({
117
136
  timestamp,
118
137
  method,
@@ -159,14 +178,26 @@ class LogParser {
159
178
  }
160
179
  /**
161
180
  * Extract first user message from request JSON
181
+ * Handles both string content and array content formats:
182
+ * - String: {"role":"user","content":"Hello"}
183
+ * - Array: {"role":"user","content":[{"type":"text","text":"Hello"}]}
162
184
  */
163
185
  extractUserMessage(requestJson) {
164
186
  const messages = requestJson.messages || [];
165
187
  const userMsg = messages.find((m) => m.role === 'user');
166
188
  if (!userMsg || !userMsg.content)
167
189
  return '';
168
- // Truncate to first 50 characters
169
- const content = userMsg.content.replace(/\n/g, ' ').replace(/\s+/g, ' ').trim();
190
+ let content;
191
+ // Handle array format (e.g., Claude/Anthropic API style)
192
+ if (Array.isArray(userMsg.content)) {
193
+ const textPart = userMsg.content.find((p) => p.type === 'text');
194
+ content = textPart?.text || '';
195
+ }
196
+ else {
197
+ content = userMsg.content;
198
+ }
199
+ // Clean and truncate to first 50 characters
200
+ content = content.replace(/\n/g, ' ').replace(/\s+/g, ' ').trim();
170
201
  return content.length > 50 ? content.substring(0, 47) + '...' : content;
171
202
  }
172
203
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"log-parser.js","sourceRoot":"","sources":["../../src/utils/log-parser.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"log-parser.js","sourceRoot":"","sources":["../../src/utils/log-parser.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@appkit/llamacpp-cli",
3
- "version": "1.9.0",
3
+ "version": "1.10.1",
4
4
  "description": "CLI tool to manage local llama.cpp servers on macOS",
5
5
  "main": "dist/cli.js",
6
6
  "bin": {
package/src/cli.ts CHANGED
@@ -24,6 +24,7 @@ import { routerStopCommand } from './commands/router/stop';
24
24
  import { routerStatusCommand } from './commands/router/status';
25
25
  import { routerRestartCommand } from './commands/router/restart';
26
26
  import { routerConfigCommand } from './commands/router/config';
27
+ import { routerLogsCommand } from './commands/router/logs';
27
28
  import packageJson from '../package.json';
28
29
 
29
30
  const program = new Command();
@@ -31,7 +32,17 @@ const program = new Command();
31
32
  program
32
33
  .name('llamacpp')
33
34
  .description('CLI tool to manage local llama.cpp servers on macOS')
34
- .version(packageJson.version, '-v, --version', 'Output the version number');
35
+ .version(packageJson.version, '-v, --version', 'Output the version number')
36
+ .action(async () => {
37
+ // Default action: launch TUI when no command provided
38
+ try {
39
+ const { tuiCommand } = await import('./commands/tui');
40
+ await tuiCommand();
41
+ } catch (error) {
42
+ console.error(chalk.red('❌ Error:'), (error as Error).message);
43
+ process.exit(1);
44
+ }
45
+ });
35
46
 
36
47
  // List models
37
48
  program
@@ -46,14 +57,13 @@ program
46
57
  }
47
58
  });
48
59
 
49
- // List running servers
60
+ // List servers (static table)
50
61
  program
51
- .command('ps [identifier]')
52
- .description('Interactive server monitoring dashboard')
53
- .option('--table', 'Show static table instead of TUI (for scripting)')
54
- .action(async (identifier?: string, options?: { table?: boolean }) => {
62
+ .command('ps')
63
+ .description('List all servers with status (static table)')
64
+ .action(async () => {
55
65
  try {
56
- await psCommand(identifier, options);
66
+ await psCommand();
57
67
  } catch (error) {
58
68
  console.error(chalk.red('❌ Error:'), (error as Error).message);
59
69
  process.exit(1);
@@ -298,14 +308,14 @@ server
298
308
  }
299
309
  });
300
310
 
301
- // Monitor server (deprecated - redirects to ps)
311
+ // Monitor server (deprecated - redirects to TUI)
302
312
  server
303
313
  .command('monitor [identifier]')
304
- .description('Monitor server with real-time metrics TUI (deprecated: use "llamacpp ps" instead)')
314
+ .description('Monitor server with real-time metrics TUI (deprecated: use "llamacpp" instead)')
305
315
  .action(async (identifier?: string) => {
306
316
  try {
307
317
  console.log(chalk.yellow('⚠️ The "monitor" command is deprecated and will be removed in a future version.'));
308
- console.log(chalk.dim(' Please use "llamacpp ps" instead for the same functionality.\n'));
318
+ console.log(chalk.dim(' Please use "llamacpp" instead for the same functionality.\n'));
309
319
  await monitorCommand(identifier);
310
320
  } catch (error) {
311
321
  console.error(chalk.red('❌ Error:'), (error as Error).message);
@@ -378,6 +388,7 @@ router
378
388
  .option('-h, --host <address>', 'Update bind address')
379
389
  .option('--timeout <ms>', 'Update request timeout (milliseconds)', parseInt)
380
390
  .option('--health-interval <ms>', 'Update health check interval (milliseconds)', parseInt)
391
+ .option('-v, --verbose [boolean]', 'Enable/disable verbose logging to file (true/false)', (val) => val === 'true' || val === '1')
381
392
  .option('-r, --restart', 'Automatically restart router if running')
382
393
  .action(async (options) => {
383
394
  try {
@@ -388,5 +399,25 @@ router
388
399
  }
389
400
  });
390
401
 
402
+ // Router logs
403
+ router
404
+ .command('logs')
405
+ .description('View router logs')
406
+ .option('-f, --follow', 'Follow logs in real-time (like tail -f)')
407
+ .option('-n, --lines <number>', 'Number of lines to show (default: 50)', parseInt)
408
+ .option('--stderr', 'Show system logs (stderr) instead of activity logs (stdout)')
409
+ .option('-v, --verbose', 'Show verbose JSON log file (if enabled)')
410
+ .option('--clear', 'Clear the log file')
411
+ .option('--rotate', 'Rotate the log file with timestamp')
412
+ .option('--clear-all', 'Clear all router logs (activity, system, verbose)')
413
+ .action(async (options) => {
414
+ try {
415
+ await routerLogsCommand(options);
416
+ } catch (error) {
417
+ console.error(chalk.red('❌ Error:'), (error as Error).message);
418
+ process.exit(1);
419
+ }
420
+ });
421
+
391
422
  // Parse arguments
392
423
  program.parse();
@@ -31,7 +31,7 @@ export async function monitorCommand(identifier?: string): Promise<void> {
31
31
  screen.destroy();
32
32
  throw new Error(
33
33
  `Server not found: ${identifier}\n\n` +
34
- `Use: llamacpp ps\n` +
34
+ `Use: llamacpp ps (to list servers)\n` +
35
35
  `Or create a new server: llamacpp server create <model>`
36
36
  );
37
37
  }
@@ -1,14 +1,32 @@
1
1
  import chalk from 'chalk';
2
2
  import Table from 'cli-table3';
3
- import blessed from 'blessed';
4
- import { stateManager } from '../lib/state-manager';
5
- import { statusChecker } from '../lib/status-checker';
6
- import { formatUptime, formatBytes } from '../utils/format-utils';
7
- import { getProcessMemory } from '../utils/process-utils';
8
- import { createMultiServerMonitorUI } from '../tui/MultiServerMonitorApp.js';
3
+ import { stateManager } from '../lib/state-manager.js';
4
+ import { statusChecker } from '../lib/status-checker.js';
5
+ import { formatUptime, formatBytes } from '../utils/format-utils.js';
6
+ import { getProcessMemory } from '../utils/process-utils.js';
9
7
  import { ServerConfig } from '../types/server-config.js';
10
8
 
11
- async function showStaticTable(): Promise<void> {
9
+ const STATUS_CONFIG = {
10
+ running: { text: '✅ RUNNING', color: chalk.green },
11
+ crashed: { text: '❌ CRASHED', color: chalk.red },
12
+ stopped: { text: '⚠️ STOPPED', color: chalk.yellow },
13
+ } as const;
14
+
15
+ async function getServerMemory(server: ServerConfig): Promise<string> {
16
+ if (server.status !== 'running' || !server.pid) {
17
+ return '-';
18
+ }
19
+
20
+ const cpuMemoryBytes = await getProcessMemory(server.pid);
21
+ if (cpuMemoryBytes === null) {
22
+ return '-';
23
+ }
24
+
25
+ const metalMemoryBytes = server.metalMemoryMB ? server.metalMemoryMB * 1024 * 1024 : 0;
26
+ return formatBytes(cpuMemoryBytes + metalMemoryBytes);
27
+ }
28
+
29
+ export async function psCommand(): Promise<void> {
12
30
  const servers = await stateManager.getAllServers();
13
31
 
14
32
  if (servers.length === 0) {
@@ -17,60 +35,31 @@ async function showStaticTable(): Promise<void> {
17
35
  return;
18
36
  }
19
37
 
20
- // Update all server statuses
21
38
  console.log(chalk.dim('Checking server statuses...\n'));
22
- const updated = await statusChecker.updateAllServerStatuses();
39
+ const serversWithStatus = await statusChecker.updateAllServerStatuses();
23
40
 
24
41
  const table = new Table({
25
42
  head: ['SERVER ID', 'MODEL', 'PORT', 'STATUS', 'PID', 'MEMORY', 'UPTIME'],
26
43
  });
27
44
 
28
- let runningCount = 0;
29
- let stoppedCount = 0;
30
- let crashedCount = 0;
31
-
32
- for (const server of updated) {
33
- let statusText: string;
34
- let statusColor: (text: string) => string;
35
-
36
- switch (server.status) {
37
- case 'running':
38
- statusText = '✅ RUNNING';
39
- statusColor = chalk.green;
40
- runningCount++;
41
- break;
42
- case 'crashed':
43
- statusText = '❌ CRASHED';
44
- statusColor = chalk.red;
45
- crashedCount++;
46
- break;
47
- default:
48
- statusText = '⚠️ STOPPED';
49
- statusColor = chalk.yellow;
50
- stoppedCount++;
51
- }
52
-
53
- const uptime =
54
- server.status === 'running' && server.lastStarted
55
- ? formatUptime(server.lastStarted)
56
- : '-';
57
-
58
- // Get memory usage for running servers (CPU + Metal GPU memory)
59
- let memoryText = '-';
60
- if (server.status === 'running' && server.pid) {
61
- const cpuMemoryBytes = await getProcessMemory(server.pid);
62
- if (cpuMemoryBytes !== null) {
63
- const metalMemoryBytes = server.metalMemoryMB ? server.metalMemoryMB * 1024 * 1024 : 0;
64
- const totalMemoryBytes = cpuMemoryBytes + metalMemoryBytes;
65
- memoryText = formatBytes(totalMemoryBytes);
66
- }
67
- }
45
+ const counts = { running: 0, stopped: 0, crashed: 0 };
46
+
47
+ for (const server of serversWithStatus) {
48
+ const status = server.status || 'stopped';
49
+ const config = STATUS_CONFIG[status] || STATUS_CONFIG.stopped;
50
+ counts[status]++;
51
+
52
+ const uptime = server.status === 'running' && server.lastStarted
53
+ ? formatUptime(server.lastStarted)
54
+ : '-';
55
+
56
+ const memoryText = await getServerMemory(server);
68
57
 
69
58
  table.push([
70
59
  server.id,
71
60
  server.modelName,
72
61
  server.port.toString(),
73
- statusColor(statusText),
62
+ config.color(config.text),
74
63
  server.pid?.toString() || '-',
75
64
  memoryText,
76
65
  uptime,
@@ -80,94 +69,16 @@ async function showStaticTable(): Promise<void> {
80
69
  console.log(table.toString());
81
70
 
82
71
  const summary = [
83
- chalk.green(`${runningCount} running`),
84
- chalk.yellow(`${stoppedCount} stopped`),
72
+ chalk.green(`${counts.running} running`),
73
+ chalk.yellow(`${counts.stopped} stopped`),
85
74
  ];
86
- if (crashedCount > 0) {
87
- summary.push(chalk.red(`${crashedCount} crashed`));
75
+ if (counts.crashed > 0) {
76
+ summary.push(chalk.red(`${counts.crashed} crashed`));
88
77
  }
89
78
 
90
79
  console.log(chalk.dim(`\nTotal: ${servers.length} servers (${summary.join(', ')})`));
91
80
 
92
- if (crashedCount > 0) {
81
+ if (counts.crashed > 0) {
93
82
  console.log(chalk.red('\n⚠️ Some servers have crashed. Check logs with: llamacpp server logs <id> --errors'));
94
83
  }
95
84
  }
96
-
97
- export async function psCommand(identifier?: string, options?: { table?: boolean }): Promise<void> {
98
- // If --table flag is set, show static table (backward compatibility)
99
- if (options?.table) {
100
- await showStaticTable();
101
- return;
102
- }
103
-
104
- // Get all servers and update their statuses
105
- const servers = await stateManager.getAllServers();
106
-
107
- if (servers.length === 0) {
108
- console.log(chalk.yellow('No servers configured.'));
109
- console.log(chalk.dim('\nCreate a server: llamacpp server create <model-filename>'));
110
- return;
111
- }
112
-
113
- // Update all server statuses
114
- const updated = await statusChecker.updateAllServerStatuses();
115
-
116
- // If identifier is provided, find the server and jump to detail view
117
- if (identifier) {
118
- const server = await findServer(identifier, updated);
119
- if (!server) {
120
- console.log(chalk.red(`❌ Server not found: ${identifier}`));
121
- console.log(chalk.dim('\nAvailable servers:'));
122
- updated.forEach((s: ServerConfig) => {
123
- console.log(chalk.dim(` - ${s.id} (port ${s.port})`));
124
- });
125
- process.exit(1);
126
- }
127
-
128
- // Find the server index for direct jump
129
- const serverIndex = updated.findIndex(s => s.id === server.id);
130
-
131
- // Launch multi-server TUI with direct jump to detail view
132
- const screen = blessed.screen({
133
- smartCSR: true,
134
- title: 'llama.cpp Multi-Server Monitor',
135
- fullUnicode: true,
136
- });
137
-
138
- await createMultiServerMonitorUI(screen, updated, true, serverIndex); // fromPs = true, directJumpIndex
139
- return;
140
- }
141
-
142
- // No identifier - launch multi-server TUI
143
- const runningServers = updated.filter((s: ServerConfig) => s.status === 'running');
144
-
145
- // Launch multi-server TUI (shows all servers, not just running ones)
146
- const screen = blessed.screen({
147
- smartCSR: true,
148
- title: 'llama.cpp Multi-Server Monitor',
149
- fullUnicode: true,
150
- });
151
-
152
- await createMultiServerMonitorUI(screen, updated, true); // fromPs = true
153
- }
154
-
155
- // Helper function to find server by identifier
156
- async function findServer(identifier: string, servers: ServerConfig[]): Promise<ServerConfig | null> {
157
- // Try by port
158
- const port = parseInt(identifier);
159
- if (!isNaN(port)) {
160
- const server = servers.find(s => s.port === port);
161
- if (server) return server;
162
- }
163
-
164
- // Try by exact ID
165
- const byId = servers.find(s => s.id === identifier);
166
- if (byId) return byId;
167
-
168
- // Try by partial model name
169
- const byModel = servers.find(s => s.modelName.toLowerCase().includes(identifier.toLowerCase()));
170
- if (byModel) return byModel;
171
-
172
- return null;
173
- }
@@ -6,6 +6,7 @@ interface ConfigOptions {
6
6
  host?: string;
7
7
  timeout?: number;
8
8
  healthInterval?: number;
9
+ verbose?: boolean;
9
10
  restart?: boolean;
10
11
  }
11
12
 
@@ -18,9 +19,9 @@ export async function routerConfigCommand(options: ConfigOptions): Promise<void>
18
19
  }
19
20
 
20
21
  // Check if any options were provided
21
- const hasOptions = options.port || options.host || options.timeout || options.healthInterval;
22
+ const hasOptions = options.port || options.host || options.timeout || options.healthInterval || options.verbose !== undefined;
22
23
  if (!hasOptions) {
23
- throw new Error('No configuration options provided. Use --port, --host, --timeout, or --health-interval');
24
+ throw new Error('No configuration options provided. Use --port, --host, --timeout, --health-interval, or --verbose');
24
25
  }
25
26
 
26
27
  const isRunning = config.status === 'running';
@@ -55,6 +56,12 @@ export async function routerConfigCommand(options: ConfigOptions): Promise<void>
55
56
  updates.healthCheckInterval = options.healthInterval;
56
57
  }
57
58
 
59
+ if (options.verbose !== undefined) {
60
+ const verboseStr = (val: boolean) => val ? 'enabled' : 'disabled';
61
+ changes.push(`Verbose Logging: ${verboseStr(config.verbose)} → ${verboseStr(options.verbose)}`);
62
+ updates.verbose = options.verbose;
63
+ }
64
+
58
65
  // Display changes
59
66
  console.log(chalk.blue('📝 Configuration changes:'));
60
67
  console.log();