@litmers/cursorflow-orchestrator 0.1.20 → 0.1.26

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 (224) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/commands/cursorflow-clean.md +19 -0
  3. package/commands/cursorflow-runs.md +59 -0
  4. package/commands/cursorflow-stop.md +55 -0
  5. package/dist/cli/clean.js +171 -0
  6. package/dist/cli/clean.js.map +1 -1
  7. package/dist/cli/index.js +7 -0
  8. package/dist/cli/index.js.map +1 -1
  9. package/dist/cli/init.js +1 -1
  10. package/dist/cli/init.js.map +1 -1
  11. package/dist/cli/logs.js +83 -42
  12. package/dist/cli/logs.js.map +1 -1
  13. package/dist/cli/monitor.d.ts +7 -0
  14. package/dist/cli/monitor.js +1007 -189
  15. package/dist/cli/monitor.js.map +1 -1
  16. package/dist/cli/prepare.js +4 -3
  17. package/dist/cli/prepare.js.map +1 -1
  18. package/dist/cli/resume.js +188 -236
  19. package/dist/cli/resume.js.map +1 -1
  20. package/dist/cli/run.js +8 -3
  21. package/dist/cli/run.js.map +1 -1
  22. package/dist/cli/runs.d.ts +5 -0
  23. package/dist/cli/runs.js +214 -0
  24. package/dist/cli/runs.js.map +1 -0
  25. package/dist/cli/setup-commands.js +0 -0
  26. package/dist/cli/signal.js +1 -1
  27. package/dist/cli/signal.js.map +1 -1
  28. package/dist/cli/stop.d.ts +5 -0
  29. package/dist/cli/stop.js +215 -0
  30. package/dist/cli/stop.js.map +1 -0
  31. package/dist/cli/tasks.d.ts +10 -0
  32. package/dist/cli/tasks.js +165 -0
  33. package/dist/cli/tasks.js.map +1 -0
  34. package/dist/core/auto-recovery.d.ts +212 -0
  35. package/dist/core/auto-recovery.js +737 -0
  36. package/dist/core/auto-recovery.js.map +1 -0
  37. package/dist/core/failure-policy.d.ts +156 -0
  38. package/dist/core/failure-policy.js +488 -0
  39. package/dist/core/failure-policy.js.map +1 -0
  40. package/dist/core/orchestrator.d.ts +15 -2
  41. package/dist/core/orchestrator.js +392 -15
  42. package/dist/core/orchestrator.js.map +1 -1
  43. package/dist/core/reviewer.d.ts +2 -0
  44. package/dist/core/reviewer.js +2 -0
  45. package/dist/core/reviewer.js.map +1 -1
  46. package/dist/core/runner.d.ts +33 -10
  47. package/dist/core/runner.js +321 -146
  48. package/dist/core/runner.js.map +1 -1
  49. package/dist/services/logging/buffer.d.ts +67 -0
  50. package/dist/services/logging/buffer.js +309 -0
  51. package/dist/services/logging/buffer.js.map +1 -0
  52. package/dist/services/logging/console.d.ts +89 -0
  53. package/dist/services/logging/console.js +169 -0
  54. package/dist/services/logging/console.js.map +1 -0
  55. package/dist/services/logging/file-writer.d.ts +71 -0
  56. package/dist/services/logging/file-writer.js +516 -0
  57. package/dist/services/logging/file-writer.js.map +1 -0
  58. package/dist/services/logging/formatter.d.ts +39 -0
  59. package/dist/services/logging/formatter.js +227 -0
  60. package/dist/services/logging/formatter.js.map +1 -0
  61. package/dist/services/logging/index.d.ts +11 -0
  62. package/dist/services/logging/index.js +30 -0
  63. package/dist/services/logging/index.js.map +1 -0
  64. package/dist/services/logging/parser.d.ts +31 -0
  65. package/dist/services/logging/parser.js +222 -0
  66. package/dist/services/logging/parser.js.map +1 -0
  67. package/dist/services/process/index.d.ts +59 -0
  68. package/dist/services/process/index.js +257 -0
  69. package/dist/services/process/index.js.map +1 -0
  70. package/dist/types/agent.d.ts +20 -0
  71. package/dist/types/agent.js +6 -0
  72. package/dist/types/agent.js.map +1 -0
  73. package/dist/types/config.d.ts +65 -0
  74. package/dist/types/config.js +6 -0
  75. package/dist/types/config.js.map +1 -0
  76. package/dist/types/events.d.ts +125 -0
  77. package/dist/types/events.js +6 -0
  78. package/dist/types/events.js.map +1 -0
  79. package/dist/types/index.d.ts +12 -0
  80. package/dist/types/index.js +37 -0
  81. package/dist/types/index.js.map +1 -0
  82. package/dist/types/lane.d.ts +43 -0
  83. package/dist/types/lane.js +6 -0
  84. package/dist/types/lane.js.map +1 -0
  85. package/dist/types/logging.d.ts +71 -0
  86. package/dist/types/logging.js +16 -0
  87. package/dist/types/logging.js.map +1 -0
  88. package/dist/types/review.d.ts +17 -0
  89. package/dist/types/review.js +6 -0
  90. package/dist/types/review.js.map +1 -0
  91. package/dist/types/run.d.ts +32 -0
  92. package/dist/types/run.js +6 -0
  93. package/dist/types/run.js.map +1 -0
  94. package/dist/types/task.d.ts +71 -0
  95. package/dist/types/task.js +6 -0
  96. package/dist/types/task.js.map +1 -0
  97. package/dist/ui/components.d.ts +134 -0
  98. package/dist/ui/components.js +389 -0
  99. package/dist/ui/components.js.map +1 -0
  100. package/dist/ui/log-viewer.d.ts +49 -0
  101. package/dist/ui/log-viewer.js +449 -0
  102. package/dist/ui/log-viewer.js.map +1 -0
  103. package/dist/utils/checkpoint.d.ts +87 -0
  104. package/dist/utils/checkpoint.js +317 -0
  105. package/dist/utils/checkpoint.js.map +1 -0
  106. package/dist/utils/config.d.ts +4 -0
  107. package/dist/utils/config.js +11 -2
  108. package/dist/utils/config.js.map +1 -1
  109. package/dist/utils/cursor-agent.js.map +1 -1
  110. package/dist/utils/dependency.d.ts +74 -0
  111. package/dist/utils/dependency.js +420 -0
  112. package/dist/utils/dependency.js.map +1 -0
  113. package/dist/utils/doctor.js +10 -5
  114. package/dist/utils/doctor.js.map +1 -1
  115. package/dist/utils/enhanced-logger.d.ts +10 -33
  116. package/dist/utils/enhanced-logger.js +94 -9
  117. package/dist/utils/enhanced-logger.js.map +1 -1
  118. package/dist/utils/git.d.ts +121 -0
  119. package/dist/utils/git.js +322 -2
  120. package/dist/utils/git.js.map +1 -1
  121. package/dist/utils/health.d.ts +91 -0
  122. package/dist/utils/health.js +556 -0
  123. package/dist/utils/health.js.map +1 -0
  124. package/dist/utils/lock.d.ts +95 -0
  125. package/dist/utils/lock.js +332 -0
  126. package/dist/utils/lock.js.map +1 -0
  127. package/dist/utils/log-buffer.d.ts +17 -0
  128. package/dist/utils/log-buffer.js +14 -0
  129. package/dist/utils/log-buffer.js.map +1 -0
  130. package/dist/utils/log-constants.d.ts +23 -0
  131. package/dist/utils/log-constants.js +28 -0
  132. package/dist/utils/log-constants.js.map +1 -0
  133. package/dist/utils/log-formatter.d.ts +9 -0
  134. package/dist/utils/log-formatter.js +113 -70
  135. package/dist/utils/log-formatter.js.map +1 -1
  136. package/dist/utils/log-service.d.ts +19 -0
  137. package/dist/utils/log-service.js +47 -0
  138. package/dist/utils/log-service.js.map +1 -0
  139. package/dist/utils/logger.d.ts +46 -27
  140. package/dist/utils/logger.js +82 -60
  141. package/dist/utils/logger.js.map +1 -1
  142. package/dist/utils/process-manager.d.ts +21 -0
  143. package/dist/utils/process-manager.js +138 -0
  144. package/dist/utils/process-manager.js.map +1 -0
  145. package/dist/utils/retry.d.ts +121 -0
  146. package/dist/utils/retry.js +374 -0
  147. package/dist/utils/retry.js.map +1 -0
  148. package/dist/utils/run-service.d.ts +88 -0
  149. package/dist/utils/run-service.js +412 -0
  150. package/dist/utils/run-service.js.map +1 -0
  151. package/dist/utils/state.d.ts +58 -2
  152. package/dist/utils/state.js +306 -3
  153. package/dist/utils/state.js.map +1 -1
  154. package/dist/utils/task-service.d.ts +82 -0
  155. package/dist/utils/task-service.js +348 -0
  156. package/dist/utils/task-service.js.map +1 -0
  157. package/dist/utils/types.d.ts +2 -272
  158. package/dist/utils/types.js +16 -0
  159. package/dist/utils/types.js.map +1 -1
  160. package/package.json +38 -23
  161. package/scripts/ai-security-check.js +0 -1
  162. package/scripts/local-security-gate.sh +0 -0
  163. package/scripts/monitor-lanes.sh +94 -0
  164. package/scripts/patches/test-cursor-agent.js +0 -1
  165. package/scripts/release.sh +0 -0
  166. package/scripts/setup-security.sh +0 -0
  167. package/scripts/stream-logs.sh +72 -0
  168. package/scripts/verify-and-fix.sh +0 -0
  169. package/src/cli/clean.ts +180 -0
  170. package/src/cli/index.ts +7 -0
  171. package/src/cli/init.ts +1 -1
  172. package/src/cli/logs.ts +79 -42
  173. package/src/cli/monitor.ts +1815 -899
  174. package/src/cli/prepare.ts +4 -3
  175. package/src/cli/resume.ts +220 -277
  176. package/src/cli/run.ts +9 -3
  177. package/src/cli/runs.ts +212 -0
  178. package/src/cli/setup-commands.ts +0 -0
  179. package/src/cli/signal.ts +1 -1
  180. package/src/cli/stop.ts +209 -0
  181. package/src/cli/tasks.ts +154 -0
  182. package/src/core/auto-recovery.ts +909 -0
  183. package/src/core/failure-policy.ts +592 -0
  184. package/src/core/orchestrator.ts +1131 -675
  185. package/src/core/reviewer.ts +4 -0
  186. package/src/core/runner.ts +388 -162
  187. package/src/services/logging/buffer.ts +326 -0
  188. package/src/services/logging/console.ts +193 -0
  189. package/src/services/logging/file-writer.ts +526 -0
  190. package/src/services/logging/formatter.ts +268 -0
  191. package/src/services/logging/index.ts +16 -0
  192. package/src/services/logging/parser.ts +232 -0
  193. package/src/services/process/index.ts +261 -0
  194. package/src/types/agent.ts +24 -0
  195. package/src/types/config.ts +79 -0
  196. package/src/types/events.ts +156 -0
  197. package/src/types/index.ts +29 -0
  198. package/src/types/lane.ts +56 -0
  199. package/src/types/logging.ts +96 -0
  200. package/src/types/review.ts +20 -0
  201. package/src/types/run.ts +37 -0
  202. package/src/types/task.ts +79 -0
  203. package/src/ui/components.ts +430 -0
  204. package/src/ui/log-viewer.ts +485 -0
  205. package/src/utils/checkpoint.ts +374 -0
  206. package/src/utils/config.ts +11 -2
  207. package/src/utils/cursor-agent.ts +1 -1
  208. package/src/utils/dependency.ts +482 -0
  209. package/src/utils/doctor.ts +11 -5
  210. package/src/utils/enhanced-logger.ts +108 -49
  211. package/src/utils/git.ts +374 -2
  212. package/src/utils/health.ts +596 -0
  213. package/src/utils/lock.ts +346 -0
  214. package/src/utils/log-buffer.ts +28 -0
  215. package/src/utils/log-constants.ts +26 -0
  216. package/src/utils/log-formatter.ts +120 -37
  217. package/src/utils/log-service.ts +49 -0
  218. package/src/utils/logger.ts +100 -51
  219. package/src/utils/process-manager.ts +100 -0
  220. package/src/utils/retry.ts +413 -0
  221. package/src/utils/run-service.ts +433 -0
  222. package/src/utils/state.ts +369 -3
  223. package/src/utils/task-service.ts +370 -0
  224. package/src/utils/types.ts +2 -315
@@ -1,25 +1,14 @@
1
1
  /**
2
2
  * Logging utilities for CursorFlow
3
+ *
4
+ * 통일된 로그 형식: [HH:MM:SS] emoji TYPE message
5
+ * 컨텍스트 포함 시: [HH:MM:SS] [context] emoji TYPE message
3
6
  */
4
7
 
5
- export enum LogLevel {
6
- error = 0,
7
- warn = 1,
8
- info = 2,
9
- debug = 3,
10
- }
8
+ import { COLORS, LogLevel } from './log-constants';
9
+ import { formatMessageForConsole } from './log-formatter';
11
10
 
12
- export const COLORS = {
13
- reset: '\x1b[0m',
14
- red: '\x1b[31m',
15
- yellow: '\x1b[33m',
16
- green: '\x1b[32m',
17
- blue: '\x1b[34m',
18
- cyan: '\x1b[36m',
19
- magenta: '\x1b[35m',
20
- gray: '\x1b[90m',
21
- bold: '\x1b[1m',
22
- };
11
+ export { COLORS, LogLevel };
23
12
 
24
13
  let currentLogLevel: number = LogLevel.info;
25
14
 
@@ -35,67 +24,119 @@ export function setLogLevel(level: string | number): void {
35
24
  }
36
25
 
37
26
  /**
38
- * Format message with timestamp
27
+ * Get current log level
28
+ */
29
+ export function getLogLevel(): number {
30
+ return currentLogLevel;
31
+ }
32
+
33
+ /**
34
+ * Log options interface for contextual logging
39
35
  */
40
- function formatMessage(level: string, message: string, emoji = ''): string {
41
- const timestamp = new Date().toISOString();
42
- const prefix = emoji ? `${emoji} ` : '';
43
- const lines = String(message).split('\n');
44
- return lines.map(line => `[${timestamp}] [${level.toUpperCase()}] ${prefix}${line}`).join('\n');
36
+ export interface LogOptions {
37
+ /** Context label (e.g., lane name) */
38
+ context?: string;
39
+ /** Custom emoji override */
40
+ emoji?: string;
41
+ /** Skip timestamp */
42
+ noTimestamp?: boolean;
43
+ /** Custom color */
44
+ color?: string;
45
+ /** Use box format */
46
+ box?: boolean;
45
47
  }
46
48
 
47
49
  /**
48
- * Log with color
50
+ * Internal log function that uses formatMessageForConsole
49
51
  */
50
- function logWithColor(color: string, level: keyof typeof LogLevel, message: string, emoji = ''): void {
51
- if (LogLevel[level] > currentLogLevel) {
52
+ function logInternal(
53
+ type: string,
54
+ message: string,
55
+ options: LogOptions = {}
56
+ ): void {
57
+ const level = (LogLevel as any)[type] ?? LogLevel.info;
58
+ if (level > currentLogLevel) {
52
59
  return;
53
60
  }
54
-
55
- const formatted = formatMessage(level, message, emoji);
56
- console.log(`${color}${formatted}${COLORS.reset}`);
61
+
62
+ const formatted = formatMessageForConsole({
63
+ type: type as any,
64
+ role: 'system',
65
+ content: message,
66
+ timestamp: Date.now(),
67
+ }, {
68
+ includeTimestamp: !options.noTimestamp,
69
+ context: options.context,
70
+ compact: !options.box
71
+ });
72
+
73
+ console.log(formatted);
57
74
  }
58
75
 
76
+ // ============================================================================
77
+ // Primary Logging Functions
78
+ // ============================================================================
79
+
59
80
  /**
60
81
  * Error log
61
82
  */
62
- export function error(message: string, emoji = '❌'): void {
63
- logWithColor(COLORS.red, 'error', message, emoji);
83
+ export function error(message: string, options: LogOptions | string = {}): void {
84
+ const opts = typeof options === 'string' ? { emoji: options } : options;
85
+ logInternal('error', message, opts);
64
86
  }
65
87
 
66
88
  /**
67
89
  * Warning log
68
90
  */
69
- export function warn(message: string, emoji = '⚠️'): void {
70
- logWithColor(COLORS.yellow, 'warn', message, emoji);
91
+ export function warn(message: string, options: LogOptions | string = {}): void {
92
+ const opts = typeof options === 'string' ? { emoji: options } : options;
93
+ logInternal('warn', message, opts);
71
94
  }
72
95
 
73
96
  /**
74
97
  * Info log
75
98
  */
76
- export function info(message: string, emoji = 'ℹ️'): void {
77
- logWithColor(COLORS.cyan, 'info', message, emoji);
99
+ export function info(message: string, options: LogOptions | string = {}): void {
100
+ const opts = typeof options === 'string' ? { emoji: options } : options;
101
+ logInternal('info', message, opts);
78
102
  }
79
103
 
80
104
  /**
81
105
  * Success log
82
106
  */
83
- export function success(message: string, emoji = '✅'): void {
84
- logWithColor(COLORS.green, 'info', message, emoji);
107
+ export function success(message: string, options: LogOptions | string = {}): void {
108
+ const opts = typeof options === 'string' ? { emoji: options } : options;
109
+ logInternal('success', message, opts);
85
110
  }
86
111
 
87
112
  /**
88
113
  * Debug log
89
114
  */
90
- export function debug(message: string, emoji = '🔍'): void {
91
- logWithColor(COLORS.gray, 'debug', message, emoji);
115
+ export function debug(message: string, options: LogOptions | string = {}): void {
116
+ const opts = typeof options === 'string' ? { emoji: options } : options;
117
+ logInternal('debug', message, opts);
92
118
  }
93
119
 
94
120
  /**
95
121
  * Progress log
96
122
  */
97
- export function progress(message: string, emoji = '🔄'): void {
98
- logWithColor(COLORS.blue, 'info', message, emoji);
123
+ export function progress(message: string, options: LogOptions | string = {}): void {
124
+ const opts = typeof options === 'string' ? { emoji: options } : options;
125
+ logInternal('progress', message, opts);
126
+ }
127
+
128
+ /**
129
+ * Create a context-bound logger
130
+ */
131
+ export function withContext(context: string) {
132
+ return {
133
+ error: (message: string, options?: Omit<LogOptions, 'context'>) => error(message, { ...options, context }),
134
+ warn: (message: string, options?: Omit<LogOptions, 'context'>) => warn(message, { ...options, context }),
135
+ info: (message: string, options?: Omit<LogOptions, 'context'>) => info(message, { ...options, context }),
136
+ success: (message: string, options?: Omit<LogOptions, 'context'>) => success(message, { ...options, context }),
137
+ debug: (message: string, options?: Omit<LogOptions, 'context'>) => debug(message, { ...options, context }),
138
+ progress: (message: string, options?: Omit<LogOptions, 'context'>) => progress(message, { ...options, context }),
139
+ };
99
140
  }
100
141
 
101
142
  /**
@@ -110,26 +151,29 @@ export function section(message: string): void {
110
151
  }
111
152
 
112
153
  /**
113
- * Simple log without formatting
154
+ * Raw output (direct to stdout)
114
155
  */
115
- export function log(message: string | any): void {
116
- console.log(message);
156
+ export function raw(message: string): void {
157
+ process.stdout.write(message);
117
158
  }
118
159
 
119
160
  /**
120
- * Log JSON data (pretty print in debug mode)
161
+ * Simple log without formatting
121
162
  */
122
- export function json(data: any): void {
123
- if (currentLogLevel >= LogLevel.debug) {
124
- console.log(JSON.stringify(data, null, 2));
125
- }
163
+ export function log(message: string): void {
164
+ console.log(message);
126
165
  }
127
166
 
167
+ // ============================================================================
168
+ // Spinner
169
+ // ============================================================================
170
+
128
171
  export interface Spinner {
129
172
  start(): void;
130
173
  stop(finalMessage?: string | null): void;
131
174
  succeed(message: string): void;
132
175
  fail(message: string): void;
176
+ update(message: string): void;
133
177
  }
134
178
 
135
179
  /**
@@ -139,13 +183,14 @@ export function createSpinner(message: string): Spinner {
139
183
  const frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
140
184
  let i = 0;
141
185
  let interval: NodeJS.Timeout | null = null;
186
+ let currentMessage = message;
142
187
 
143
188
  const spinner: Spinner = {
144
189
  start() {
145
- process.stdout.write(`${message} ${frames[0]}`);
190
+ process.stdout.write(`${currentMessage} ${frames[0]}`);
146
191
  interval = setInterval(() => {
147
192
  i = (i + 1) % frames.length;
148
- process.stdout.write(`\r${message} ${frames[i]}`);
193
+ process.stdout.write(`\r${currentMessage} ${frames[i]}`);
149
194
  }, 80);
150
195
  },
151
196
 
@@ -167,6 +212,10 @@ export function createSpinner(message: string): Spinner {
167
212
  fail(message: string) {
168
213
  this.stop(`${COLORS.red}✗${COLORS.reset} ${message}`);
169
214
  },
215
+
216
+ update(message: string) {
217
+ currentMessage = message;
218
+ },
170
219
  };
171
220
 
172
221
  return spinner;
@@ -0,0 +1,100 @@
1
+ import { spawnSync } from 'child_process';
2
+ import * as os from 'os';
3
+
4
+ export class ProcessManager {
5
+ /**
6
+ * Check if a process is running by its PID
7
+ */
8
+ static isProcessRunning(pid: number): boolean {
9
+ try {
10
+ // Signal 0 checks for process existence without killing it
11
+ process.kill(pid, 0);
12
+ return true;
13
+ } catch (e) {
14
+ return false;
15
+ }
16
+ }
17
+
18
+ /**
19
+ * Kill a process by its PID
20
+ * @param pid Process ID
21
+ * @param signal Signal to send (default: SIGTERM)
22
+ */
23
+ static killProcess(pid: number, signal: string = 'SIGTERM'): boolean {
24
+ try {
25
+ if (os.platform() === 'win32') {
26
+ // Windows doesn't support signals in the same way, use taskkill
27
+ const result = spawnSync('taskkill', ['/F', '/PID', String(pid)]);
28
+ return result.status === 0;
29
+ } else {
30
+ process.kill(pid, signal as NodeJS.Signals);
31
+ return true;
32
+ }
33
+ } catch (e) {
34
+ return false;
35
+ }
36
+ }
37
+
38
+ /**
39
+ * Kill a process and all its child processes
40
+ * Cross-platform implementation
41
+ */
42
+ static killProcessTree(pid: number): boolean {
43
+ try {
44
+ if (os.platform() === 'win32') {
45
+ // Windows: /T flag kills child processes too
46
+ const result = spawnSync('taskkill', ['/F', '/T', '/PID', String(pid)]);
47
+ return result.status === 0;
48
+ } else {
49
+ // Linux/macOS: Find and kill children recursively or use pkill
50
+ // A simple approach is to use pgrep to find children
51
+ const result = spawnSync('pgrep', ['-P', String(pid)], { encoding: 'utf8' });
52
+ if (result.status === 0 && result.stdout) {
53
+ const children = result.stdout.split('\n').map(s => parseInt(s.trim())).filter(n => !isNaN(n));
54
+ for (const child of children) {
55
+ this.killProcessTree(child);
56
+ }
57
+ }
58
+
59
+ // Kill the process itself
60
+ return this.killProcess(pid);
61
+ }
62
+ } catch (e) {
63
+ // Fallback to simple kill
64
+ return this.killProcess(pid);
65
+ }
66
+ }
67
+
68
+ /**
69
+ * Find cursorflow related processes using pgrep (Linux/macOS only)
70
+ */
71
+ static findCursorFlowProcesses(): number[] {
72
+ if (os.platform() === 'win32') {
73
+ // Basic Windows implementation using tasklist if needed,
74
+ // but for now focusing on core requirements
75
+ return [];
76
+ }
77
+
78
+ try {
79
+ // Find processes with 'cursorflow' in their command line,
80
+ // avoiding unrelated matches by looking for specific execution patterns
81
+ const result = spawnSync('pgrep', ['-f', 'cursorflow.*(index|runner|orchestrator)'], { encoding: 'utf8' });
82
+ if (result.status !== 0) {
83
+ // Fallback to simpler pattern
84
+ const fallback = spawnSync('pgrep', ['-f', 'cursorflow'], { encoding: 'utf8' });
85
+ if (fallback.status !== 0) return [];
86
+ return fallback.stdout
87
+ .split('\n')
88
+ .map(s => parseInt(s.trim()))
89
+ .filter(n => !isNaN(n) && n !== process.pid);
90
+ }
91
+
92
+ return result.stdout
93
+ .split('\n')
94
+ .map(s => parseInt(s.trim()))
95
+ .filter(n => !isNaN(n) && n !== process.pid);
96
+ } catch (e) {
97
+ return [];
98
+ }
99
+ }
100
+ }