numux 1.9.0 → 1.10.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 +45 -0
- package/dist/numux.js +124 -31
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -98,6 +98,22 @@ numux completions fish | source
|
|
|
98
98
|
numux completions fish > ~/.config/fish/completions/numux.fish
|
|
99
99
|
```
|
|
100
100
|
|
|
101
|
+
### Workspaces
|
|
102
|
+
|
|
103
|
+
Run a `package.json` script across all workspaces in a monorepo:
|
|
104
|
+
|
|
105
|
+
```sh
|
|
106
|
+
numux -w dev
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Reads the `workspaces` field from your root `package.json`, finds which workspaces have the given script, and spawns `<pm> run <script>` in each. The package manager is auto-detected from `packageManager` field or lockfiles.
|
|
110
|
+
|
|
111
|
+
Composes with other flags:
|
|
112
|
+
|
|
113
|
+
```sh
|
|
114
|
+
numux -w dev -n redis="redis-server" --colors
|
|
115
|
+
```
|
|
116
|
+
|
|
101
117
|
### Ad-hoc commands
|
|
102
118
|
|
|
103
119
|
```sh
|
|
@@ -108,10 +124,39 @@ numux "bun dev:api" "bun dev:web"
|
|
|
108
124
|
numux -n api="bun dev:api" -n web="bun dev:web"
|
|
109
125
|
```
|
|
110
126
|
|
|
127
|
+
### Script patterns
|
|
128
|
+
|
|
129
|
+
Run multiple package.json scripts matching a glob pattern:
|
|
130
|
+
|
|
131
|
+
```sh
|
|
132
|
+
numux 'dev:*' # all scripts matching dev:*
|
|
133
|
+
numux 'npm:*:dev' # explicit npm: prefix (same behavior)
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Extra arguments after the pattern are forwarded to each matched command:
|
|
137
|
+
|
|
138
|
+
```sh
|
|
139
|
+
numux 'lint:* --fix' # → bun run lint:js --fix, bun run lint:ts --fix
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
In a config file, use the pattern as the process name:
|
|
143
|
+
|
|
144
|
+
```ts
|
|
145
|
+
export default defineConfig({
|
|
146
|
+
processes: {
|
|
147
|
+
'dev:*': { color: ['green', 'cyan'] },
|
|
148
|
+
'lint:* --fix': {},
|
|
149
|
+
},
|
|
150
|
+
})
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Template properties (color, env, dependsOn, etc.) are inherited by all matched processes. Colors given as an array are distributed round-robin.
|
|
154
|
+
|
|
111
155
|
### Options
|
|
112
156
|
|
|
113
157
|
| Flag | Description |
|
|
114
158
|
|------|-------------|
|
|
159
|
+
| `-w, --workspace <script>` | Run a script across all workspaces |
|
|
115
160
|
| `-c, --config <path>` | Explicit config file path |
|
|
116
161
|
| `-n, --name <name=cmd>` | Add a named process (repeatable) |
|
|
117
162
|
| `-p, --prefix` | Prefixed output mode (no TUI, for CI/scripts) |
|
package/dist/numux.js
CHANGED
|
@@ -22,7 +22,7 @@ var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports,
|
|
|
22
22
|
var require_package = __commonJS((exports, module) => {
|
|
23
23
|
module.exports = {
|
|
24
24
|
name: "numux",
|
|
25
|
-
version: "1.
|
|
25
|
+
version: "1.10.0",
|
|
26
26
|
description: "Terminal multiplexer with dependency orchestration",
|
|
27
27
|
type: "module",
|
|
28
28
|
license: "MIT",
|
|
@@ -75,8 +75,8 @@ var require_package = __commonJS((exports, module) => {
|
|
|
75
75
|
});
|
|
76
76
|
|
|
77
77
|
// src/index.ts
|
|
78
|
-
import { existsSync as
|
|
79
|
-
import { resolve as
|
|
78
|
+
import { existsSync as existsSync5, writeFileSync } from "fs";
|
|
79
|
+
import { resolve as resolve8 } from "path";
|
|
80
80
|
|
|
81
81
|
// src/cli.ts
|
|
82
82
|
function parseArgs(argv) {
|
|
@@ -122,6 +122,8 @@ function parseArgs(argv) {
|
|
|
122
122
|
result.timestamps = true;
|
|
123
123
|
} else if (arg === "--no-restart") {
|
|
124
124
|
result.noRestart = true;
|
|
125
|
+
} else if (arg === "-w" || arg === "--workspace") {
|
|
126
|
+
result.workspace = consumeValue(arg);
|
|
125
127
|
} else if (arg === "--no-watch") {
|
|
126
128
|
result.noWatch = true;
|
|
127
129
|
} else if (arg === "--colors") {
|
|
@@ -274,7 +276,7 @@ _numux() {
|
|
|
274
276
|
return ;;
|
|
275
277
|
--only|--exclude)
|
|
276
278
|
return ;;
|
|
277
|
-
-n|--name)
|
|
279
|
+
-n|--name|-w|--workspace)
|
|
278
280
|
return ;;
|
|
279
281
|
completions)
|
|
280
282
|
COMPREPLY=( $(compgen -W "bash zsh fish" -- "$cur") )
|
|
@@ -282,7 +284,7 @@ _numux() {
|
|
|
282
284
|
esac
|
|
283
285
|
|
|
284
286
|
if [[ "$cur" == -* ]]; then
|
|
285
|
-
COMPREPLY=( $(compgen -W "-h --help -v --version -c --color --colors --config -n --name -p --prefix --only --exclude --kill-others --no-restart --no-watch -t --timestamps --log-dir --debug" -- "$cur") )
|
|
287
|
+
COMPREPLY=( $(compgen -W "-h --help -v --version -w --workspace -c --color --colors --config -n --name -p --prefix --only --exclude --kill-others --no-restart --no-watch -t --timestamps --log-dir --debug" -- "$cur") )
|
|
286
288
|
else
|
|
287
289
|
local subcmds="init validate exec completions"
|
|
288
290
|
COMPREPLY=( $(compgen -W "$subcmds" -- "$cur") )
|
|
@@ -306,6 +308,7 @@ _numux() {
|
|
|
306
308
|
_arguments -s \\
|
|
307
309
|
'(-h --help)'{-h,--help}'[Show help]' \\
|
|
308
310
|
'(-v --version)'{-v,--version}'[Show version]' \\
|
|
311
|
+
'(-w --workspace)'{-w,--workspace}'[Run script across all workspaces]:script' \\
|
|
309
312
|
'(-c --color)'{-c,--color}'[Comma-separated colors for processes]' \\
|
|
310
313
|
'--colors[Auto-assign colors based on process name]' \\
|
|
311
314
|
'--config[Config file path]:file:_files' \\
|
|
@@ -352,6 +355,7 @@ complete -c numux -s v -l version -d 'Show version'
|
|
|
352
355
|
complete -c numux -s c -l color -r -d 'Comma-separated colors for processes'
|
|
353
356
|
complete -c numux -l colors -d 'Auto-assign colors based on process name'
|
|
354
357
|
complete -c numux -l config -rF -d 'Config file path'
|
|
358
|
+
complete -c numux -s w -l workspace -r -d 'Run script across all workspaces'
|
|
355
359
|
complete -c numux -s n -l name -r -d 'Named process (name=command)'
|
|
356
360
|
complete -c numux -s p -l prefix -d 'Prefixed output mode'
|
|
357
361
|
complete -c numux -l only -r -d 'Only run these processes'
|
|
@@ -390,6 +394,12 @@ function detectPackageManager(pkgJson, cwd) {
|
|
|
390
394
|
function isGlobPattern(name) {
|
|
391
395
|
return /[*?[]/.test(name);
|
|
392
396
|
}
|
|
397
|
+
function splitPatternArgs(raw) {
|
|
398
|
+
const i = raw.indexOf(" ");
|
|
399
|
+
if (i === -1)
|
|
400
|
+
return { glob: raw, extraArgs: "" };
|
|
401
|
+
return { glob: raw.slice(0, i), extraArgs: raw.slice(i) };
|
|
402
|
+
}
|
|
393
403
|
function expandScriptPatterns(config, cwd) {
|
|
394
404
|
const entries = Object.entries(config.processes);
|
|
395
405
|
const hasWildcard = entries.some(([name]) => name.startsWith("npm:") || isGlobPattern(name));
|
|
@@ -413,15 +423,16 @@ function expandScriptPatterns(config, cwd) {
|
|
|
413
423
|
expanded[name] = value;
|
|
414
424
|
continue;
|
|
415
425
|
}
|
|
416
|
-
const
|
|
426
|
+
const rawPattern = name.startsWith("npm:") ? name.slice(4) : name;
|
|
427
|
+
const { glob: globPattern, extraArgs } = splitPatternArgs(rawPattern);
|
|
417
428
|
const template = value ?? {};
|
|
418
429
|
if (template.command) {
|
|
419
430
|
throw new Error(`"${name}": wildcard processes cannot have a "command" field (commands come from package.json scripts)`);
|
|
420
431
|
}
|
|
421
|
-
const glob = new Bun.Glob(
|
|
432
|
+
const glob = new Bun.Glob(globPattern);
|
|
422
433
|
const matches = scriptNames.filter((s) => glob.match(s));
|
|
423
434
|
if (matches.length === 0) {
|
|
424
|
-
throw new Error(`"${name}": no scripts matched pattern "${
|
|
435
|
+
throw new Error(`"${name}": no scripts matched pattern "${globPattern}". Available scripts: ${scriptNames.join(", ")}`);
|
|
425
436
|
}
|
|
426
437
|
const colors = Array.isArray(template.color) ? template.color : undefined;
|
|
427
438
|
const singleColor = typeof template.color === "string" ? template.color : undefined;
|
|
@@ -434,7 +445,7 @@ function expandScriptPatterns(config, cwd) {
|
|
|
434
445
|
const { color: _color, ...rest } = template;
|
|
435
446
|
expanded[scriptName] = {
|
|
436
447
|
...rest,
|
|
437
|
-
command: `${pm} run ${scriptName}`,
|
|
448
|
+
command: `${pm} run ${scriptName}${extraArgs}`,
|
|
438
449
|
...color ? { color } : {}
|
|
439
450
|
};
|
|
440
451
|
}
|
|
@@ -847,8 +858,71 @@ function validateStopSignal(value) {
|
|
|
847
858
|
return;
|
|
848
859
|
}
|
|
849
860
|
|
|
861
|
+
// src/config/workspaces.ts
|
|
862
|
+
import { existsSync as existsSync4, readFileSync as readFileSync2 } from "fs";
|
|
863
|
+
import { basename, resolve as resolve4 } from "path";
|
|
864
|
+
function resolveWorkspaceProcesses(script, cwd) {
|
|
865
|
+
const pkgPath = resolve4(cwd, "package.json");
|
|
866
|
+
if (!existsSync4(pkgPath)) {
|
|
867
|
+
throw new Error(`No package.json found in ${cwd}`);
|
|
868
|
+
}
|
|
869
|
+
const pkgJson = JSON.parse(readFileSync2(pkgPath, "utf-8"));
|
|
870
|
+
const pm = detectPackageManager(pkgJson, cwd);
|
|
871
|
+
const raw = pkgJson.workspaces;
|
|
872
|
+
let patterns;
|
|
873
|
+
if (Array.isArray(raw)) {
|
|
874
|
+
patterns = raw;
|
|
875
|
+
} else if (raw && typeof raw === "object" && Array.isArray(raw.packages)) {
|
|
876
|
+
patterns = raw.packages;
|
|
877
|
+
} else {
|
|
878
|
+
throw new Error('No "workspaces" field found in package.json');
|
|
879
|
+
}
|
|
880
|
+
const dirs = [];
|
|
881
|
+
for (const pattern of patterns) {
|
|
882
|
+
const glob = new Bun.Glob(pattern);
|
|
883
|
+
for (const match of glob.scanSync({ cwd, onlyFiles: false })) {
|
|
884
|
+
const abs = resolve4(cwd, match);
|
|
885
|
+
const wsPkgPath = resolve4(abs, "package.json");
|
|
886
|
+
if (existsSync4(wsPkgPath)) {
|
|
887
|
+
dirs.push(abs);
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
const processes = {};
|
|
892
|
+
const usedNames = new Set;
|
|
893
|
+
for (const dir of dirs) {
|
|
894
|
+
const wsPkgPath = resolve4(dir, "package.json");
|
|
895
|
+
const wsPkg = JSON.parse(readFileSync2(wsPkgPath, "utf-8"));
|
|
896
|
+
const scripts = wsPkg.scripts;
|
|
897
|
+
if (!scripts?.[script])
|
|
898
|
+
continue;
|
|
899
|
+
let name;
|
|
900
|
+
if (typeof wsPkg.name === "string" && wsPkg.name) {
|
|
901
|
+
name = wsPkg.name.replace(/^@[^/]+\//, "");
|
|
902
|
+
} else {
|
|
903
|
+
name = basename(dir);
|
|
904
|
+
}
|
|
905
|
+
if (usedNames.has(name)) {
|
|
906
|
+
let suffix = 1;
|
|
907
|
+
while (usedNames.has(`${name}-${suffix}`))
|
|
908
|
+
suffix++;
|
|
909
|
+
name = `${name}-${suffix}`;
|
|
910
|
+
}
|
|
911
|
+
usedNames.add(name);
|
|
912
|
+
processes[name] = {
|
|
913
|
+
command: `${pm} run ${script}`,
|
|
914
|
+
cwd: dir,
|
|
915
|
+
persistent: true
|
|
916
|
+
};
|
|
917
|
+
}
|
|
918
|
+
if (Object.keys(processes).length === 0) {
|
|
919
|
+
throw new Error(`No workspaces have a "${script}" script`);
|
|
920
|
+
}
|
|
921
|
+
return processes;
|
|
922
|
+
}
|
|
923
|
+
|
|
850
924
|
// src/process/manager.ts
|
|
851
|
-
import { resolve as
|
|
925
|
+
import { resolve as resolve7 } from "path";
|
|
852
926
|
|
|
853
927
|
// src/utils/watcher.ts
|
|
854
928
|
import { watch } from "fs";
|
|
@@ -896,11 +970,11 @@ class FileWatcher {
|
|
|
896
970
|
}
|
|
897
971
|
|
|
898
972
|
// src/process/runner.ts
|
|
899
|
-
import { resolve as
|
|
973
|
+
import { resolve as resolve6 } from "path";
|
|
900
974
|
|
|
901
975
|
// src/utils/env-file.ts
|
|
902
|
-
import { readFileSync as
|
|
903
|
-
import { resolve as
|
|
976
|
+
import { readFileSync as readFileSync3 } from "fs";
|
|
977
|
+
import { resolve as resolve5 } from "path";
|
|
904
978
|
function parseEnvFile(content) {
|
|
905
979
|
const vars = {};
|
|
906
980
|
for (const line of content.split(/\r?\n/)) {
|
|
@@ -928,10 +1002,10 @@ function loadEnvFiles(envFile, cwd) {
|
|
|
928
1002
|
const files = Array.isArray(envFile) ? envFile : [envFile];
|
|
929
1003
|
const merged = {};
|
|
930
1004
|
for (const file of files) {
|
|
931
|
-
const path =
|
|
1005
|
+
const path = resolve5(cwd, file);
|
|
932
1006
|
let content;
|
|
933
1007
|
try {
|
|
934
|
-
content =
|
|
1008
|
+
content = readFileSync3(path, "utf-8");
|
|
935
1009
|
} catch (err) {
|
|
936
1010
|
const code = err.code;
|
|
937
1011
|
if (code === "ENOENT") {
|
|
@@ -1046,7 +1120,7 @@ class ProcessRunner {
|
|
|
1046
1120
|
this.stopping = false;
|
|
1047
1121
|
log(`[${this.name}] Starting (gen ${gen}): ${this.config.command}`);
|
|
1048
1122
|
this.handler.onStatus("starting");
|
|
1049
|
-
const cwd = this.config.cwd ?
|
|
1123
|
+
const cwd = this.config.cwd ? resolve6(this.config.cwd) : process.cwd();
|
|
1050
1124
|
try {
|
|
1051
1125
|
const envFromFile = this.config.envFile ? loadEnvFiles(this.config.envFile, cwd) : {};
|
|
1052
1126
|
const noColor = "NO_COLOR" in process.env;
|
|
@@ -1308,12 +1382,12 @@ class ProcessManager {
|
|
|
1308
1382
|
this.updateStatus(name, "skipped");
|
|
1309
1383
|
continue;
|
|
1310
1384
|
}
|
|
1311
|
-
const { promise, resolve:
|
|
1385
|
+
const { promise, resolve: resolve8 } = Promise.withResolvers();
|
|
1312
1386
|
readyPromises.push(promise);
|
|
1313
|
-
this.pendingReadyResolvers.set(name,
|
|
1387
|
+
this.pendingReadyResolvers.set(name, resolve8);
|
|
1314
1388
|
this.createRunner(name, () => {
|
|
1315
1389
|
this.pendingReadyResolvers.delete(name);
|
|
1316
|
-
|
|
1390
|
+
resolve8();
|
|
1317
1391
|
});
|
|
1318
1392
|
this.startProcess(name, cols, rows);
|
|
1319
1393
|
}
|
|
@@ -1421,7 +1495,7 @@ class ProcessManager {
|
|
|
1421
1495
|
if (!this.fileWatcher)
|
|
1422
1496
|
this.fileWatcher = new FileWatcher;
|
|
1423
1497
|
const patterns = Array.isArray(proc.watch) ? proc.watch : [proc.watch];
|
|
1424
|
-
const cwd = proc.cwd ?
|
|
1498
|
+
const cwd = proc.cwd ? resolve7(proc.cwd) : process.cwd();
|
|
1425
1499
|
this.fileWatcher.watch(name, patterns, cwd, (changedFile) => {
|
|
1426
1500
|
const state = this.states.get(name);
|
|
1427
1501
|
if (!state)
|
|
@@ -1527,8 +1601,8 @@ class ProcessManager {
|
|
|
1527
1601
|
clearTimeout(timer);
|
|
1528
1602
|
}
|
|
1529
1603
|
this.restartTimers.clear();
|
|
1530
|
-
for (const
|
|
1531
|
-
|
|
1604
|
+
for (const resolve8 of this.pendingReadyResolvers.values()) {
|
|
1605
|
+
resolve8();
|
|
1532
1606
|
}
|
|
1533
1607
|
this.pendingReadyResolvers.clear();
|
|
1534
1608
|
const reversed = [...this.tiers].reverse();
|
|
@@ -2352,7 +2426,6 @@ class PrefixDisplay {
|
|
|
2352
2426
|
noColor;
|
|
2353
2427
|
decoders = new Map;
|
|
2354
2428
|
buffers = new Map;
|
|
2355
|
-
maxNameLen;
|
|
2356
2429
|
logWriter;
|
|
2357
2430
|
killOthers;
|
|
2358
2431
|
timestamps;
|
|
@@ -2364,7 +2437,6 @@ class PrefixDisplay {
|
|
|
2364
2437
|
this.timestamps = options.timestamps ?? false;
|
|
2365
2438
|
this.noColor = "NO_COLOR" in process.env;
|
|
2366
2439
|
const names = manager.getProcessNames();
|
|
2367
|
-
this.maxNameLen = Math.max(...names.map((n) => n.length));
|
|
2368
2440
|
this.colors = buildProcessColorMap(names, config);
|
|
2369
2441
|
for (const name of names) {
|
|
2370
2442
|
this.decoders.set(name, new TextDecoder("utf-8", { fatal: false }));
|
|
@@ -2438,15 +2510,14 @@ class PrefixDisplay {
|
|
|
2438
2510
|
return `${h}:${m}:${s}`;
|
|
2439
2511
|
}
|
|
2440
2512
|
printLine(name, line) {
|
|
2441
|
-
const padded = name.padEnd(this.maxNameLen);
|
|
2442
2513
|
const ts = this.timestamps ? `${DIM}[${this.formatTimestamp()}]${RESET} ` : "";
|
|
2443
2514
|
const tsPlain = this.timestamps ? `[${this.formatTimestamp()}] ` : "";
|
|
2444
2515
|
if (this.noColor) {
|
|
2445
|
-
process.stdout.write(`${tsPlain}[${
|
|
2516
|
+
process.stdout.write(`${tsPlain}[${name}] ${stripAnsi(line)}
|
|
2446
2517
|
`);
|
|
2447
2518
|
} else {
|
|
2448
2519
|
const color = this.colors.get(name) ?? "";
|
|
2449
|
-
process.stdout.write(`${ts}${color}[${
|
|
2520
|
+
process.stdout.write(`${ts}${color}[${name}]${RESET} ${line}
|
|
2450
2521
|
`);
|
|
2451
2522
|
}
|
|
2452
2523
|
}
|
|
@@ -2600,12 +2671,14 @@ Usage:
|
|
|
2600
2671
|
numux Run processes from config file
|
|
2601
2672
|
numux <cmd1> <cmd2> ... Run ad-hoc commands in parallel
|
|
2602
2673
|
numux -n name1=cmd1 -n name2=cmd2 Named ad-hoc commands
|
|
2674
|
+
numux -w <script> Run a script across all workspaces
|
|
2603
2675
|
numux init Create a starter config file
|
|
2604
2676
|
numux validate Validate config and show process graph
|
|
2605
2677
|
numux exec <name> [--] <cmd> Run a command in a process's environment
|
|
2606
2678
|
numux completions <shell> Generate shell completions (bash, zsh, fish)
|
|
2607
2679
|
|
|
2608
2680
|
Options:
|
|
2681
|
+
-w, --workspace <script> Run a package.json script across all workspaces
|
|
2609
2682
|
-n, --name <name=command> Add a named process
|
|
2610
2683
|
-c, --color <colors> Comma-separated colors (hex or names: black, red, green, yellow, blue, magenta, cyan, white, gray, orange, purple)
|
|
2611
2684
|
--colors Auto-assign colors to processes based on their name
|
|
@@ -2658,8 +2731,8 @@ async function main() {
|
|
|
2658
2731
|
process.exit(0);
|
|
2659
2732
|
}
|
|
2660
2733
|
if (parsed.init) {
|
|
2661
|
-
const target =
|
|
2662
|
-
if (
|
|
2734
|
+
const target = resolve8("numux.config.ts");
|
|
2735
|
+
if (existsSync5(target)) {
|
|
2663
2736
|
console.error(`Already exists: ${target}`);
|
|
2664
2737
|
process.exit(1);
|
|
2665
2738
|
}
|
|
@@ -2717,7 +2790,7 @@ async function main() {
|
|
|
2717
2790
|
const names = Object.keys(config2.processes);
|
|
2718
2791
|
throw new Error(`Unknown process "${parsed.execName}". Available: ${names.join(", ")}`);
|
|
2719
2792
|
}
|
|
2720
|
-
const cwd = proc.cwd ?
|
|
2793
|
+
const cwd = proc.cwd ? resolve8(proc.cwd) : process.cwd();
|
|
2721
2794
|
const envFromFile = proc.envFile ? loadEnvFiles(proc.envFile, cwd) : {};
|
|
2722
2795
|
const env = {
|
|
2723
2796
|
...process.env,
|
|
@@ -2738,7 +2811,7 @@ async function main() {
|
|
|
2738
2811
|
}
|
|
2739
2812
|
let config;
|
|
2740
2813
|
const warnings = [];
|
|
2741
|
-
if (parsed.commands.length > 0 || parsed.named.length > 0) {
|
|
2814
|
+
if (parsed.commands.length > 0 || parsed.named.length > 0 || parsed.workspace) {
|
|
2742
2815
|
const isScriptPattern = (c) => c.startsWith("npm:") || /[*?[]/.test(c);
|
|
2743
2816
|
const hasNpmPatterns = parsed.commands.some(isScriptPattern);
|
|
2744
2817
|
if (hasNpmPatterns) {
|
|
@@ -2769,6 +2842,21 @@ async function main() {
|
|
|
2769
2842
|
colors: parsed.colors
|
|
2770
2843
|
});
|
|
2771
2844
|
}
|
|
2845
|
+
if (parsed.workspace) {
|
|
2846
|
+
const wsProcesses = resolveWorkspaceProcesses(parsed.workspace, process.cwd());
|
|
2847
|
+
for (const [name, proc] of Object.entries(wsProcesses)) {
|
|
2848
|
+
let finalName = name;
|
|
2849
|
+
if (config.processes[finalName]) {
|
|
2850
|
+
let suffix = 1;
|
|
2851
|
+
while (config.processes[`${finalName}-${suffix}`])
|
|
2852
|
+
suffix++;
|
|
2853
|
+
finalName = `${finalName}-${suffix}`;
|
|
2854
|
+
}
|
|
2855
|
+
if (parsed.noRestart)
|
|
2856
|
+
proc.maxRestarts = 0;
|
|
2857
|
+
config.processes[finalName] = proc;
|
|
2858
|
+
}
|
|
2859
|
+
}
|
|
2772
2860
|
} else {
|
|
2773
2861
|
const raw = expandScriptPatterns(await loadConfig(parsed.configPath));
|
|
2774
2862
|
config = validateConfig(raw, warnings);
|
|
@@ -2800,6 +2888,11 @@ async function main() {
|
|
|
2800
2888
|
}
|
|
2801
2889
|
printWarnings(warnings);
|
|
2802
2890
|
if (parsed.prefix) {
|
|
2891
|
+
if (!parsed.noRestart) {
|
|
2892
|
+
for (const proc of Object.values(config.processes)) {
|
|
2893
|
+
proc.maxRestarts ??= 0;
|
|
2894
|
+
}
|
|
2895
|
+
}
|
|
2803
2896
|
const display = new PrefixDisplay(manager, config, {
|
|
2804
2897
|
logWriter,
|
|
2805
2898
|
killOthers: parsed.killOthers,
|