@covibes/zeroshot 5.3.0 → 5.4.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 (119) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +8 -385
  3. package/cli/index.js +108 -4615
  4. package/package.json +16 -125
  5. package/CHANGELOG.md +0 -537
  6. package/cli/commands/providers.js +0 -150
  7. package/cli/lib/first-run.js +0 -211
  8. package/cli/lib/update-checker.js +0 -281
  9. package/cli/message-formatter-utils.js +0 -75
  10. package/cli/message-formatters-normal.js +0 -253
  11. package/cli/message-formatters-watch.js +0 -181
  12. package/cluster-templates/base-templates/debug-workflow.json +0 -375
  13. package/cluster-templates/base-templates/full-workflow.json +0 -697
  14. package/cluster-templates/base-templates/single-worker.json +0 -63
  15. package/cluster-templates/base-templates/worker-validator.json +0 -152
  16. package/cluster-templates/conductor-bootstrap.json +0 -124
  17. package/docker/zeroshot-cluster/Dockerfile +0 -152
  18. package/docker/zeroshot-cluster/pre-baked-deps.json +0 -28
  19. package/lib/completion.js +0 -174
  20. package/lib/docker-config.js +0 -212
  21. package/lib/id-detector.js +0 -53
  22. package/lib/provider-detection.js +0 -59
  23. package/lib/provider-names.js +0 -56
  24. package/lib/settings.js +0 -405
  25. package/lib/stream-json-parser.js +0 -10
  26. package/scripts/fix-node-pty-permissions.js +0 -75
  27. package/scripts/record-demo.sh +0 -279
  28. package/scripts/test-install.sh +0 -40
  29. package/scripts/validate-templates.js +0 -100
  30. package/src/agent/agent-config.js +0 -193
  31. package/src/agent/agent-context-builder.js +0 -335
  32. package/src/agent/agent-hook-executor.js +0 -402
  33. package/src/agent/agent-lifecycle.js +0 -683
  34. package/src/agent/agent-stuck-detector.js +0 -256
  35. package/src/agent/agent-task-executor.js +0 -1431
  36. package/src/agent/agent-trigger-evaluator.js +0 -67
  37. package/src/agent/output-extraction.js +0 -200
  38. package/src/agent/output-reformatter.js +0 -175
  39. package/src/agent/schema-utils.js +0 -111
  40. package/src/agent-wrapper.js +0 -570
  41. package/src/agents/git-pusher-agent.json +0 -20
  42. package/src/attach/attach-client.js +0 -438
  43. package/src/attach/attach-server.js +0 -543
  44. package/src/attach/index.js +0 -35
  45. package/src/attach/protocol.js +0 -220
  46. package/src/attach/ring-buffer.js +0 -121
  47. package/src/attach/socket-discovery.js +0 -267
  48. package/src/claude-task-runner.js +0 -523
  49. package/src/config-router.js +0 -80
  50. package/src/config-validator.js +0 -1660
  51. package/src/copy-worker.js +0 -43
  52. package/src/github.js +0 -139
  53. package/src/isolation-manager.js +0 -1381
  54. package/src/ledger.js +0 -614
  55. package/src/logic-engine.js +0 -223
  56. package/src/message-bus-bridge.js +0 -139
  57. package/src/message-bus.js +0 -249
  58. package/src/name-generator.js +0 -232
  59. package/src/orchestrator.js +0 -2519
  60. package/src/preflight.js +0 -485
  61. package/src/process-metrics.js +0 -566
  62. package/src/providers/anthropic/cli-builder.js +0 -45
  63. package/src/providers/anthropic/index.js +0 -134
  64. package/src/providers/anthropic/models.js +0 -23
  65. package/src/providers/anthropic/output-parser.js +0 -159
  66. package/src/providers/base-provider.js +0 -181
  67. package/src/providers/capabilities.js +0 -51
  68. package/src/providers/google/cli-builder.js +0 -55
  69. package/src/providers/google/index.js +0 -116
  70. package/src/providers/google/models.js +0 -24
  71. package/src/providers/google/output-parser.js +0 -92
  72. package/src/providers/index.js +0 -75
  73. package/src/providers/openai/cli-builder.js +0 -122
  74. package/src/providers/openai/index.js +0 -135
  75. package/src/providers/openai/models.js +0 -21
  76. package/src/providers/openai/output-parser.js +0 -129
  77. package/src/schemas/sub-cluster.js +0 -156
  78. package/src/status-footer.js +0 -980
  79. package/src/sub-cluster-wrapper.js +0 -560
  80. package/src/task-runner.js +0 -30
  81. package/src/template-resolver.js +0 -369
  82. package/src/tui/CHANGES.txt +0 -133
  83. package/src/tui/LAYOUT.md +0 -261
  84. package/src/tui/README.txt +0 -192
  85. package/src/tui/TWO-LEVEL-NAVIGATION.md +0 -186
  86. package/src/tui/data-poller.js +0 -325
  87. package/src/tui/demo.js +0 -208
  88. package/src/tui/formatters.js +0 -128
  89. package/src/tui/index.js +0 -193
  90. package/src/tui/keybindings.js +0 -383
  91. package/src/tui/layout.js +0 -334
  92. package/src/tui/renderer.js +0 -194
  93. package/task-lib/attachable-watcher.js +0 -272
  94. package/task-lib/claude-recovery.js +0 -119
  95. package/task-lib/commands/clean.js +0 -50
  96. package/task-lib/commands/get-log-path.js +0 -23
  97. package/task-lib/commands/kill.js +0 -32
  98. package/task-lib/commands/list.js +0 -105
  99. package/task-lib/commands/logs.js +0 -411
  100. package/task-lib/commands/resume.js +0 -42
  101. package/task-lib/commands/run.js +0 -57
  102. package/task-lib/commands/schedule.js +0 -105
  103. package/task-lib/commands/scheduler-cmd.js +0 -96
  104. package/task-lib/commands/schedules.js +0 -98
  105. package/task-lib/commands/status.js +0 -44
  106. package/task-lib/commands/unschedule.js +0 -16
  107. package/task-lib/completion.js +0 -9
  108. package/task-lib/config.js +0 -10
  109. package/task-lib/name-generator.js +0 -230
  110. package/task-lib/package.json +0 -3
  111. package/task-lib/runner.js +0 -144
  112. package/task-lib/scheduler.js +0 -252
  113. package/task-lib/store.js +0 -230
  114. package/task-lib/tui/formatters.js +0 -166
  115. package/task-lib/tui/index.js +0 -197
  116. package/task-lib/tui/layout.js +0 -111
  117. package/task-lib/tui/renderer.js +0 -119
  118. package/task-lib/tui.js +0 -384
  119. package/task-lib/watcher.js +0 -188
@@ -1,566 +0,0 @@
1
- /**
2
- * ProcessMetrics - Cross-platform real-time process monitoring
3
- *
4
- * Provides:
5
- * - CPU usage (percent)
6
- * - Memory usage (MB)
7
- * - Network I/O (bytes/sec)
8
- * - Process state (running, sleeping, etc.)
9
- * - Child process aggregation
10
- *
11
- * Supports:
12
- * - Linux: /proc filesystem + ss
13
- * - macOS: ps + lsof
14
- */
15
-
16
- const { execSync } = require('child_process');
17
- const fs = require('fs');
18
-
19
- const PLATFORM = process.platform;
20
-
21
- /**
22
- * Escape a string for safe use in shell commands
23
- * Prevents shell injection when passing dynamic values to execSync with shell: true
24
- * @param {string} str - String to escape
25
- * @returns {string} Shell-escaped string
26
- */
27
- function escapeShell(str) {
28
- // Replace single quotes with escaped version and wrap in single quotes
29
- // This is the safest approach for shell escaping
30
- return `'${str.replace(/'/g, "'\\''")}'`;
31
- }
32
-
33
- /**
34
- * @typedef {Object} ProcessMetrics
35
- * @property {number} pid - Process ID
36
- * @property {boolean} exists - Whether process exists
37
- * @property {number} cpuPercent - CPU usage (0-100)
38
- * @property {number} memoryMB - Memory usage in MB
39
- * @property {string} state - Process state (R=running, S=sleeping, etc.)
40
- * @property {number} threads - Thread count
41
- * @property {Object} network - Network activity
42
- * @property {number} network.established - Established connections
43
- * @property {boolean} network.hasActivity - Has data in flight
44
- * @property {number} network.sendQueueBytes - Bytes in send queue
45
- * @property {number} network.recvQueueBytes - Bytes in receive queue
46
- * @property {number} childCount - Number of child processes
47
- * @property {number} timestamp - Measurement timestamp
48
- */
49
-
50
- /**
51
- * Get all child PIDs for a process (recursive)
52
- * @param {number} pid - Parent process ID
53
- * @returns {number[]} Array of child PIDs
54
- */
55
- function getChildPids(pid) {
56
- const children = [];
57
-
58
- try {
59
- if (PLATFORM === 'darwin') {
60
- // macOS: Use pgrep with -P flag
61
- const output = execSync(`pgrep -P ${escapeShell(String(pid))} 2>/dev/null`, {
62
- encoding: 'utf8',
63
- timeout: 2000,
64
- });
65
- const pids = output.trim().split('\n').filter(Boolean).map(Number);
66
- children.push(...pids);
67
-
68
- // Recursively get grandchildren
69
- for (const childPid of pids) {
70
- children.push(...getChildPids(childPid));
71
- }
72
- } else {
73
- // Linux: Read /proc/{pid}/task/{tid}/children
74
- const taskPath = `/proc/${pid}/task`;
75
- if (fs.existsSync(taskPath)) {
76
- const tids = fs.readdirSync(taskPath);
77
- for (const tid of tids) {
78
- const childrenPath = `/proc/${pid}/task/${tid}/children`;
79
- if (fs.existsSync(childrenPath)) {
80
- const childPids = fs.readFileSync(childrenPath, 'utf8')
81
- .trim()
82
- .split(/\s+/)
83
- .filter(Boolean)
84
- .map(Number);
85
- children.push(...childPids);
86
-
87
- // Recursively get grandchildren
88
- for (const childPid of childPids) {
89
- children.push(...getChildPids(childPid));
90
- }
91
- }
92
- }
93
- }
94
- }
95
- } catch {
96
- // Ignore errors (process may have exited)
97
- }
98
-
99
- return [...new Set(children)]; // Dedupe
100
- }
101
-
102
- /**
103
- * Get metrics for a single process (Linux)
104
- * @param {number} pid - Process ID
105
- * @returns {Object|null} Metrics or null if process doesn't exist
106
- */
107
- function getProcessMetricsLinux(pid) {
108
- try {
109
- const statPath = `/proc/${pid}/stat`;
110
- if (!fs.existsSync(statPath)) {
111
- return null;
112
- }
113
-
114
- const stat = fs.readFileSync(statPath, 'utf8');
115
- const parts = stat.split(' ');
116
-
117
- // state is field 3 (index 2)
118
- const state = parts[2];
119
-
120
- // utime (14) + stime (15) = CPU ticks
121
- const utime = parseInt(parts[13], 10);
122
- const stime = parseInt(parts[14], 10);
123
- const cpuTicks = utime + stime;
124
-
125
- // Read status for memory and threads
126
- const status = fs.readFileSync(`/proc/${pid}/status`, 'utf8');
127
- const vmRss = status.match(/VmRSS:\s+(\d+)/)?.[1] || '0';
128
- const threads = status.match(/Threads:\s+(\d+)/)?.[1] || '1';
129
-
130
- return {
131
- pid,
132
- exists: true,
133
- state,
134
- cpuTicks,
135
- memoryKB: parseInt(vmRss, 10),
136
- threads: parseInt(threads, 10),
137
- };
138
- } catch {
139
- return null;
140
- }
141
- }
142
-
143
- /**
144
- * Get metrics for a single process (macOS)
145
- * @param {number} pid - Process ID
146
- * @returns {Object|null} Metrics or null if process doesn't exist
147
- */
148
- function getProcessMetricsDarwin(pid) {
149
- try {
150
- // ps -p PID -o %cpu=,rss=,state=
151
- const output = execSync(`ps -p ${escapeShell(String(pid))} -o %cpu=,rss=,state= 2>/dev/null`, {
152
- encoding: 'utf8',
153
- timeout: 2000,
154
- });
155
-
156
- if (!output.trim()) {
157
- return null;
158
- }
159
-
160
- const parts = output.trim().split(/\s+/);
161
- const cpuPercent = parseFloat(parts[0]) || 0;
162
- const rssKB = parseInt(parts[1], 10) || 0;
163
- const state = parts[2]?.[0] || 'S'; // First char (R, S, etc.)
164
-
165
- return {
166
- pid,
167
- exists: true,
168
- state,
169
- cpuPercent, // macOS ps gives us percent directly
170
- memoryKB: rssKB,
171
- threads: 1, // ps doesn't give thread count easily
172
- };
173
- } catch {
174
- return null;
175
- }
176
- }
177
-
178
- /**
179
- * Get network state for a process (Linux)
180
- * Uses ss -tip to get extended TCP info including cumulative bytes sent/received
181
- * @param {number} pid - Process ID
182
- * @returns {Object} Network state
183
- */
184
- function getNetworkStateLinux(pid) {
185
- const result = {
186
- established: 0,
187
- hasActivity: false,
188
- sendQueueBytes: 0,
189
- recvQueueBytes: 0,
190
- bytesSent: 0, // Cumulative bytes sent across all sockets
191
- bytesReceived: 0, // Cumulative bytes received across all sockets
192
- };
193
-
194
- try {
195
- // Use ss -tip to get extended TCP info with bytes_sent/bytes_received
196
- // -t = TCP only, -i = show internal TCP info, -p = show process
197
- const output = execSync(`ss -tip 2>/dev/null | grep -A1 "pid=${escapeShell(String(pid))}," || true`, {
198
- encoding: 'utf8',
199
- timeout: 3000,
200
- });
201
-
202
- if (!output.trim()) {
203
- return result;
204
- }
205
-
206
- const lines = output.trim().split('\n');
207
-
208
- for (let i = 0; i < lines.length; i++) {
209
- const line = lines[i];
210
-
211
- // Parse socket line: State Recv-Q Send-Q Local:Port Peer:Port Process
212
- const match = line.match(/^(\S+)\s+(\d+)\s+(\d+)\s+/);
213
- if (match) {
214
- const state = match[1];
215
- const recvQ = parseInt(match[2], 10);
216
- const sendQ = parseInt(match[3], 10);
217
-
218
- if (state === 'ESTAB') {
219
- result.established++;
220
- }
221
-
222
- result.recvQueueBytes += recvQ;
223
- result.sendQueueBytes += sendQ;
224
-
225
- if (recvQ > 0 || sendQ > 0) {
226
- result.hasActivity = true;
227
- }
228
- }
229
-
230
- // Parse extended TCP info line (follows socket line)
231
- // Contains: bytes_sent:N bytes_received:N (and other metrics)
232
- const bytesSentMatch = line.match(/bytes_sent:(\d+)/);
233
- const bytesReceivedMatch = line.match(/bytes_received:(\d+)/);
234
-
235
- if (bytesSentMatch) {
236
- result.bytesSent += parseInt(bytesSentMatch[1], 10);
237
- result.hasActivity = true;
238
- }
239
- if (bytesReceivedMatch) {
240
- result.bytesReceived += parseInt(bytesReceivedMatch[1], 10);
241
- result.hasActivity = true;
242
- }
243
- }
244
- } catch {
245
- // Ignore errors
246
- }
247
-
248
- return result;
249
- }
250
-
251
- /**
252
- * Get network state for a process (macOS)
253
- * Note: macOS doesn't expose per-socket byte counts like Linux's ss -tip
254
- * We return 0 for bytesSent/bytesReceived (not available without dtrace/nettop)
255
- * @param {number} pid - Process ID
256
- * @returns {Object} Network state
257
- */
258
- function getNetworkStateDarwin(pid) {
259
- const result = {
260
- established: 0,
261
- hasActivity: false,
262
- sendQueueBytes: 0,
263
- recvQueueBytes: 0,
264
- bytesSent: 0, // Not available on macOS without root/dtrace
265
- bytesReceived: 0, // Not available on macOS without root/dtrace
266
- };
267
-
268
- try {
269
- // lsof -i -n -P for network connections
270
- const output = execSync(`lsof -i -n -P -a -p ${escapeShell(String(pid))} 2>/dev/null || true`, {
271
- encoding: 'utf8',
272
- timeout: 3000,
273
- });
274
-
275
- if (!output.trim()) {
276
- return result;
277
- }
278
-
279
- const lines = output.trim().split('\n').slice(1); // Skip header
280
-
281
- for (const line of lines) {
282
- const parts = line.split(/\s+/);
283
- // Look for ESTABLISHED connections
284
- if (parts.includes('ESTABLISHED') || parts.some(p => p.includes('->'))) {
285
- result.established++;
286
- result.hasActivity = true; // lsof doesn't show queue sizes, assume activity
287
- }
288
- }
289
- } catch {
290
- // Ignore errors
291
- }
292
-
293
- return result;
294
- }
295
-
296
- /**
297
- * Get real-time metrics for a process and its children
298
- * @param {number} pid - Process ID
299
- * @param {Object} [options] - Options
300
- * @param {number} [options.samplePeriodMs=1000] - Sample period for rate calculations (Linux only)
301
- * @returns {Promise<ProcessMetrics>}
302
- */
303
- function getProcessMetrics(pid, options = {}) {
304
- const samplePeriodMs = options.samplePeriodMs || 1000;
305
-
306
- if (PLATFORM === 'darwin') {
307
- return getProcessMetricsDarwinAggregated(pid);
308
- }
309
-
310
- return getProcessMetricsLinuxAggregated(pid, samplePeriodMs);
311
- }
312
-
313
- /**
314
- * Get aggregated metrics for process tree (Linux)
315
- * @param {number} pid - Root process ID
316
- * @param {number} samplePeriodMs - Sample period for CPU calculation
317
- * @returns {Promise<ProcessMetrics>}
318
- */
319
- async function getProcessMetricsLinuxAggregated(pid, samplePeriodMs) {
320
- // Get initial CPU sample
321
- const allPids = [pid, ...getChildPids(pid)];
322
- const t0Metrics = {};
323
-
324
- for (const p of allPids) {
325
- const m = getProcessMetricsLinux(p);
326
- if (m) t0Metrics[p] = m;
327
- }
328
-
329
- if (Object.keys(t0Metrics).length === 0) {
330
- return {
331
- pid,
332
- exists: false,
333
- cpuPercent: 0,
334
- memoryMB: 0,
335
- state: 'X',
336
- threads: 0,
337
- network: { established: 0, hasActivity: false, sendQueueBytes: 0, recvQueueBytes: 0, bytesSent: 0, bytesReceived: 0 },
338
- childCount: 0,
339
- timestamp: Date.now(),
340
- };
341
- }
342
-
343
- // Wait for sample period
344
- await new Promise(r => setTimeout(r, samplePeriodMs));
345
-
346
- // Get second CPU sample
347
- const t1Metrics = {};
348
- const currentPids = [pid, ...getChildPids(pid)];
349
-
350
- for (const p of currentPids) {
351
- const m = getProcessMetricsLinux(p);
352
- if (m) t1Metrics[p] = m;
353
- }
354
-
355
- // Calculate aggregated metrics
356
- let totalCpuTicksDelta = 0;
357
- let totalMemoryKB = 0;
358
- let totalThreads = 0;
359
- let rootState = 'S';
360
-
361
- for (const p of Object.keys(t1Metrics)) {
362
- const t1 = t1Metrics[p];
363
- const t0 = t0Metrics[p];
364
-
365
- if (t0 && t1) {
366
- totalCpuTicksDelta += t1.cpuTicks - t0.cpuTicks;
367
- }
368
-
369
- totalMemoryKB += t1.memoryKB;
370
- totalThreads += t1.threads;
371
-
372
- if (p === String(pid)) {
373
- rootState = t1.state;
374
- }
375
- }
376
-
377
- // Calculate CPU percent
378
- const clockTicks = 100; // Usually 100 on Linux
379
- const cpuSeconds = totalCpuTicksDelta / clockTicks;
380
- const sampleSeconds = samplePeriodMs / 1000;
381
- const rawCpuPercent = (cpuSeconds / sampleSeconds) * 100;
382
-
383
- // Normalize to per-core average (0-100% range)
384
- const cpuCores = require('os').cpus().length;
385
- const cpuPercent = Math.min(100, rawCpuPercent / cpuCores);
386
-
387
- // Get network state for all processes
388
- let network = { established: 0, hasActivity: false, sendQueueBytes: 0, recvQueueBytes: 0, bytesSent: 0, bytesReceived: 0 };
389
- for (const p of Object.keys(t1Metrics)) {
390
- const netState = getNetworkStateLinux(parseInt(p, 10));
391
- network.established += netState.established;
392
- network.sendQueueBytes += netState.sendQueueBytes;
393
- network.recvQueueBytes += netState.recvQueueBytes;
394
- network.bytesSent += netState.bytesSent;
395
- network.bytesReceived += netState.bytesReceived;
396
- if (netState.hasActivity) network.hasActivity = true;
397
- }
398
-
399
- return {
400
- pid,
401
- exists: true,
402
- cpuPercent: parseFloat(cpuPercent.toFixed(1)),
403
- memoryMB: parseFloat((totalMemoryKB / 1024).toFixed(1)),
404
- state: rootState,
405
- threads: totalThreads,
406
- network,
407
- childCount: Object.keys(t1Metrics).length - 1,
408
- timestamp: Date.now(),
409
- };
410
- }
411
-
412
- /**
413
- * Get aggregated metrics for process tree (macOS)
414
- * @param {number} pid - Root process ID
415
- * @returns {Promise<ProcessMetrics>}
416
- */
417
- function getProcessMetricsDarwinAggregated(pid) {
418
- const allPids = [pid, ...getChildPids(pid)];
419
- let totalCpuPercent = 0;
420
- let totalMemoryKB = 0;
421
- let totalThreads = 0;
422
- let rootState = 'S';
423
- let existsCount = 0;
424
-
425
- for (const p of allPids) {
426
- const m = getProcessMetricsDarwin(p);
427
- if (m) {
428
- existsCount++;
429
- totalCpuPercent += m.cpuPercent;
430
- totalMemoryKB += m.memoryKB;
431
- totalThreads += m.threads;
432
-
433
- if (p === pid) {
434
- rootState = m.state;
435
- }
436
- }
437
- }
438
-
439
- if (existsCount === 0) {
440
- return {
441
- pid,
442
- exists: false,
443
- cpuPercent: 0,
444
- memoryMB: 0,
445
- state: 'X',
446
- threads: 0,
447
- network: { established: 0, hasActivity: false, sendQueueBytes: 0, recvQueueBytes: 0 },
448
- childCount: 0,
449
- timestamp: Date.now(),
450
- };
451
- }
452
-
453
- // Get network state
454
- let network = { established: 0, hasActivity: false, sendQueueBytes: 0, recvQueueBytes: 0, bytesSent: 0, bytesReceived: 0 };
455
- for (const p of allPids) {
456
- const netState = getNetworkStateDarwin(p);
457
- network.established += netState.established;
458
- network.bytesSent += netState.bytesSent;
459
- network.bytesReceived += netState.bytesReceived;
460
- if (netState.hasActivity) network.hasActivity = true;
461
- }
462
-
463
- // Normalize to per-core average (0-100% range)
464
- const cpuCores = require('os').cpus().length;
465
- const normalizedCpu = Math.min(100, totalCpuPercent / cpuCores);
466
-
467
- return {
468
- pid,
469
- exists: true,
470
- cpuPercent: parseFloat(normalizedCpu.toFixed(1)),
471
- memoryMB: parseFloat((totalMemoryKB / 1024).toFixed(1)),
472
- state: rootState,
473
- threads: totalThreads,
474
- network,
475
- childCount: existsCount - 1,
476
- timestamp: Date.now(),
477
- };
478
- }
479
-
480
- /**
481
- * Format metrics for display
482
- * @param {ProcessMetrics} metrics
483
- * @returns {string} Formatted string
484
- */
485
- function formatMetrics(metrics) {
486
- if (!metrics.exists) {
487
- return '(process exited)';
488
- }
489
-
490
- const parts = [];
491
-
492
- // CPU
493
- parts.push(`CPU: ${metrics.cpuPercent}%`);
494
-
495
- // Memory
496
- parts.push(`Mem: ${metrics.memoryMB}MB`);
497
-
498
- // Network
499
- if (metrics.network.established > 0) {
500
- parts.push(`Net: ${metrics.network.established} conn`);
501
- if (metrics.network.hasActivity) {
502
- parts.push('↕');
503
- }
504
- }
505
-
506
- // Children
507
- if (metrics.childCount > 0) {
508
- parts.push(`+${metrics.childCount} child`);
509
- }
510
-
511
- return parts.join(' │ ');
512
- }
513
-
514
- /**
515
- * Get state icon for process state
516
- * @param {string} state - Process state char
517
- * @returns {string} Icon
518
- */
519
- function getStateIcon(state) {
520
- switch (state) {
521
- case 'R': return '🟢'; // Running
522
- case 'S': return '🔵'; // Sleeping
523
- case 'D': return '🟡'; // Disk wait
524
- case 'Z': return '💀'; // Zombie
525
- case 'T': return '⏸️'; // Stopped
526
- case 'X': return '❌'; // Dead
527
- default: return '⚪';
528
- }
529
- }
530
-
531
- /**
532
- * Check if platform is supported for full metrics
533
- * @returns {boolean}
534
- */
535
- function isPlatformSupported() {
536
- return PLATFORM === 'linux' || PLATFORM === 'darwin';
537
- }
538
-
539
- /**
540
- * Get platform-specific metrics provider info
541
- * @returns {Object}
542
- */
543
- function getPlatformInfo() {
544
- return {
545
- platform: PLATFORM,
546
- supported: isPlatformSupported(),
547
- cpuSource: PLATFORM === 'linux' ? '/proc/stat' : 'ps',
548
- memorySource: PLATFORM === 'linux' ? '/proc/status' : 'ps',
549
- networkSource: PLATFORM === 'linux' ? 'ss' : 'lsof',
550
- ioSupported: PLATFORM === 'linux', // I/O only on Linux
551
- };
552
- }
553
-
554
- module.exports = {
555
- getProcessMetrics,
556
- getChildPids,
557
- formatMetrics,
558
- getStateIcon,
559
- isPlatformSupported,
560
- getPlatformInfo,
561
- // Export internal functions for testing
562
- getProcessMetricsLinux,
563
- getProcessMetricsDarwin,
564
- getNetworkStateLinux,
565
- getNetworkStateDarwin,
566
- };
@@ -1,45 +0,0 @@
1
- function buildCommand(context, options = {}, commandConfig = {}) {
2
- const { modelSpec, outputFormat, jsonSchema, autoApprove, cliFeatures = {} } = options;
3
-
4
- const command = commandConfig.command || 'claude';
5
- const extraArgs = commandConfig.args || [];
6
- const args = [...extraArgs, '--print', '--input-format', 'text'];
7
-
8
- if (outputFormat && cliFeatures.supportsOutputFormat !== false) {
9
- args.push('--output-format', outputFormat);
10
- }
11
-
12
- if (outputFormat === 'stream-json') {
13
- if (cliFeatures.supportsVerbose !== false) {
14
- args.push('--verbose');
15
- }
16
- if (cliFeatures.supportsIncludePartials !== false) {
17
- args.push('--include-partial-messages');
18
- }
19
- }
20
-
21
- if (jsonSchema && outputFormat === 'json' && cliFeatures.supportsJsonSchema !== false) {
22
- const schemaString = typeof jsonSchema === 'string' ? jsonSchema : JSON.stringify(jsonSchema);
23
- args.push('--json-schema', schemaString);
24
- }
25
-
26
- if (modelSpec?.model && cliFeatures.supportsModel !== false) {
27
- args.push('--model', modelSpec.model);
28
- }
29
-
30
- if (autoApprove && cliFeatures.supportsAutoApprove !== false) {
31
- args.push('--dangerously-skip-permissions');
32
- }
33
-
34
- args.push(context);
35
-
36
- return {
37
- binary: command,
38
- args,
39
- env: {},
40
- };
41
- }
42
-
43
- module.exports = {
44
- buildCommand,
45
- };