numux 1.20.0 → 1.22.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 +7 -0
- package/dist/numux.js +48 -8
- package/dist/types.d.ts +24 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -164,6 +164,7 @@ Template properties (color, env, dependsOn, etc.) are inherited by all matched p
|
|
|
164
164
|
| `--exclude <a,b,...>` | Exclude these processes |
|
|
165
165
|
| `--kill-others` | Kill all processes when any exits |
|
|
166
166
|
| `--no-restart` | Disable auto-restart for crashed processes |
|
|
167
|
+
| `-s, --sort <mode>` | Tab display order: `config` (default), `alphabetical`, `topological` |
|
|
167
168
|
| `--no-watch` | Disable file watching even if config has `watch` patterns |
|
|
168
169
|
| `-t, --timestamps` | Add `[HH:MM:SS]` timestamps to prefixed output |
|
|
169
170
|
| `--log-dir <path>` | Write per-process output to `<path>/<name>.log` |
|
|
@@ -193,6 +194,12 @@ Top-level options apply to all processes (process-level settings override):
|
|
|
193
194
|
| `env` | `Record<string, string>` | Environment variables merged into all processes (process `env` overrides per key) |
|
|
194
195
|
| `envFile` | `string \| string[] \| false` | `.env` file(s) for all processes (process `envFile` replaces if set; `false` disables) |
|
|
195
196
|
| `showCommand` | `boolean` | Print the command being run as the first line of output (default: `true`) |
|
|
197
|
+
| `maxRestarts` | `number` | Restart limit for all processes (default: `Infinity`) |
|
|
198
|
+
| `readyTimeout` | `number` | Ready timeout in ms for all processes |
|
|
199
|
+
| `stopSignal` | `'SIGTERM' \| 'SIGINT' \| 'SIGHUP'` | Stop signal for all processes (default: `'SIGTERM'`) |
|
|
200
|
+
| `errorMatcher` | `boolean \| string` | Error detection for all processes (`true` = ANSI red, string = regex) |
|
|
201
|
+
| `watch` | `string \| string[]` | Watch patterns for all processes (process `watch` replaces if set) |
|
|
202
|
+
| `sort` | `'config' \| 'alphabetical' \| 'topological'` | Tab display order (default: `'config'` — definition order) |
|
|
196
203
|
|
|
197
204
|
```ts
|
|
198
205
|
export default defineConfig({
|
package/dist/numux.js
CHANGED
|
@@ -36,7 +36,7 @@ var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports,
|
|
|
36
36
|
var require_package = __commonJS((exports, module) => {
|
|
37
37
|
module.exports = {
|
|
38
38
|
name: "numux",
|
|
39
|
-
version: "1.
|
|
39
|
+
version: "1.22.0",
|
|
40
40
|
description: "Terminal multiplexer with dependency orchestration",
|
|
41
41
|
type: "module",
|
|
42
42
|
license: "MIT",
|
|
@@ -95,6 +95,15 @@ import { resolve as resolve8 } from "path";
|
|
|
95
95
|
// src/cli-flags.ts
|
|
96
96
|
var commaSplit = (raw) => raw.split(",").map((s) => s.trim()).filter(Boolean);
|
|
97
97
|
var FLAGS = [
|
|
98
|
+
{
|
|
99
|
+
type: "value",
|
|
100
|
+
long: "--sort",
|
|
101
|
+
short: "-s",
|
|
102
|
+
key: "sort",
|
|
103
|
+
description: "Tab display order",
|
|
104
|
+
valueName: "<config|alphabetical|topological>",
|
|
105
|
+
completionHint: "none"
|
|
106
|
+
},
|
|
98
107
|
{
|
|
99
108
|
type: "value",
|
|
100
109
|
long: "--workspace",
|
|
@@ -1035,6 +1044,11 @@ function validateConfig(raw, warnings) {
|
|
|
1035
1044
|
const globalCwd = typeof config.cwd === "string" ? config.cwd : undefined;
|
|
1036
1045
|
const globalShowCommand = typeof config.showCommand === "boolean" ? config.showCommand : undefined;
|
|
1037
1046
|
const globalEnvFile = validateEnvFile(config.envFile);
|
|
1047
|
+
const globalMaxRestarts = typeof config.maxRestarts === "number" && config.maxRestarts >= 0 ? config.maxRestarts : undefined;
|
|
1048
|
+
const globalReadyTimeout = typeof config.readyTimeout === "number" && config.readyTimeout > 0 ? config.readyTimeout : undefined;
|
|
1049
|
+
const globalStopSignal = validateStopSignal(config.stopSignal);
|
|
1050
|
+
const globalErrorMatcher = validateErrorMatcher("(global)", config.errorMatcher);
|
|
1051
|
+
const globalWatch = validateStringOrStringArray(config.watch);
|
|
1038
1052
|
let globalEnv;
|
|
1039
1053
|
if (config.env && typeof config.env === "object") {
|
|
1040
1054
|
for (const [k, v] of Object.entries(config.env)) {
|
|
@@ -1044,6 +1058,7 @@ function validateConfig(raw, warnings) {
|
|
|
1044
1058
|
}
|
|
1045
1059
|
globalEnv = config.env;
|
|
1046
1060
|
}
|
|
1061
|
+
const sort = validateSort(config.sort);
|
|
1047
1062
|
const validated = {};
|
|
1048
1063
|
for (const name of names) {
|
|
1049
1064
|
let proc = processes[name];
|
|
@@ -1115,6 +1130,11 @@ function validateConfig(raw, warnings) {
|
|
|
1115
1130
|
const processEnvFile = validateEnvFile(p.envFile);
|
|
1116
1131
|
const showCommand = typeof p.showCommand === "boolean" ? p.showCommand : globalShowCommand ?? true;
|
|
1117
1132
|
const platform = validatePlatform(name, p.platform);
|
|
1133
|
+
const processMaxRestarts = typeof p.maxRestarts === "number" && p.maxRestarts >= 0 ? p.maxRestarts : undefined;
|
|
1134
|
+
const processReadyTimeout = typeof p.readyTimeout === "number" && p.readyTimeout > 0 ? p.readyTimeout : undefined;
|
|
1135
|
+
const processStopSignal = validateStopSignal(p.stopSignal);
|
|
1136
|
+
const processErrorMatcher = validateErrorMatcher(name, p.errorMatcher);
|
|
1137
|
+
const processWatch = validateStringOrStringArray(p.watch);
|
|
1118
1138
|
validated[name] = {
|
|
1119
1139
|
command: p.command,
|
|
1120
1140
|
cwd: processCwd ?? globalCwd,
|
|
@@ -1123,20 +1143,20 @@ function validateConfig(raw, warnings) {
|
|
|
1123
1143
|
dependsOn: Array.isArray(p.dependsOn) ? p.dependsOn : undefined,
|
|
1124
1144
|
readyPattern,
|
|
1125
1145
|
persistent,
|
|
1126
|
-
maxRestarts:
|
|
1127
|
-
readyTimeout:
|
|
1146
|
+
maxRestarts: processMaxRestarts ?? globalMaxRestarts,
|
|
1147
|
+
readyTimeout: processReadyTimeout ?? globalReadyTimeout,
|
|
1128
1148
|
delay: typeof p.delay === "number" && p.delay > 0 ? p.delay : undefined,
|
|
1129
1149
|
condition: typeof p.condition === "string" && p.condition.trim() ? p.condition.trim() : undefined,
|
|
1130
1150
|
platform,
|
|
1131
|
-
stopSignal:
|
|
1151
|
+
stopSignal: processStopSignal ?? globalStopSignal,
|
|
1132
1152
|
color: typeof p.color === "string" ? p.color : Array.isArray(p.color) ? p.color : undefined,
|
|
1133
|
-
watch:
|
|
1153
|
+
watch: processWatch ?? globalWatch,
|
|
1134
1154
|
interactive: typeof p.interactive === "boolean" ? p.interactive : false,
|
|
1135
|
-
errorMatcher:
|
|
1155
|
+
errorMatcher: processErrorMatcher ?? globalErrorMatcher,
|
|
1136
1156
|
showCommand
|
|
1137
1157
|
};
|
|
1138
1158
|
}
|
|
1139
|
-
return { processes: validated };
|
|
1159
|
+
return { ...sort ? { sort } : {}, processes: validated };
|
|
1140
1160
|
}
|
|
1141
1161
|
function validateStringOrStringArray(value) {
|
|
1142
1162
|
if (typeof value === "string")
|
|
@@ -1166,6 +1186,16 @@ function validateErrorMatcher(name, value) {
|
|
|
1166
1186
|
}
|
|
1167
1187
|
return;
|
|
1168
1188
|
}
|
|
1189
|
+
var VALID_SORT_VALUES = new Set(["config", "alphabetical", "topological"]);
|
|
1190
|
+
function validateSort(value) {
|
|
1191
|
+
if (typeof value === "string") {
|
|
1192
|
+
if (!VALID_SORT_VALUES.has(value)) {
|
|
1193
|
+
throw new Error(`sort must be one of: ${[...VALID_SORT_VALUES].join(", ")}. Got "${value}"`);
|
|
1194
|
+
}
|
|
1195
|
+
return value;
|
|
1196
|
+
}
|
|
1197
|
+
return;
|
|
1198
|
+
}
|
|
1169
1199
|
var VALID_PLATFORMS = new Set(["aix", "darwin", "freebsd", "linux", "openbsd", "sunos", "win32"]);
|
|
1170
1200
|
function validatePlatform(name, value) {
|
|
1171
1201
|
const arr = validateStringOrStringArray(value);
|
|
@@ -1733,7 +1763,14 @@ class ProcessManager {
|
|
|
1733
1763
|
return [...this.states.values()];
|
|
1734
1764
|
}
|
|
1735
1765
|
getProcessNames() {
|
|
1736
|
-
|
|
1766
|
+
switch (this.config.sort) {
|
|
1767
|
+
case "alphabetical":
|
|
1768
|
+
return Object.keys(this.config.processes).sort();
|
|
1769
|
+
case "topological":
|
|
1770
|
+
return this.tiers.flat();
|
|
1771
|
+
default:
|
|
1772
|
+
return Object.keys(this.config.processes);
|
|
1773
|
+
}
|
|
1737
1774
|
}
|
|
1738
1775
|
async startAll(cols, rows) {
|
|
1739
1776
|
log("Starting all processes");
|
|
@@ -3469,6 +3506,9 @@ async function main() {
|
|
|
3469
3506
|
}
|
|
3470
3507
|
}
|
|
3471
3508
|
}
|
|
3509
|
+
if (parsed.sort) {
|
|
3510
|
+
config.sort = parsed.sort;
|
|
3511
|
+
}
|
|
3472
3512
|
if (parsed.envFile !== undefined) {
|
|
3473
3513
|
for (const proc of Object.values(config.processes)) {
|
|
3474
3514
|
proc.envFile = parsed.envFile;
|
package/dist/types.d.ts
CHANGED
|
@@ -72,14 +72,38 @@ export interface NumuxConfig<K extends string = string> {
|
|
|
72
72
|
* @default true
|
|
73
73
|
*/
|
|
74
74
|
showCommand?: boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Global restart limit, inherited by all processes
|
|
77
|
+
* @default Infinity
|
|
78
|
+
*/
|
|
79
|
+
maxRestarts?: number;
|
|
80
|
+
/** Global ready timeout (ms), inherited by all processes */
|
|
81
|
+
readyTimeout?: number;
|
|
82
|
+
/**
|
|
83
|
+
* Global stop signal, inherited by all processes
|
|
84
|
+
* @default 'SIGTERM'
|
|
85
|
+
*/
|
|
86
|
+
stopSignal?: 'SIGTERM' | 'SIGINT' | 'SIGHUP';
|
|
87
|
+
/** Global error matcher, inherited by all processes. `true` = detect ANSI red output, string = regex */
|
|
88
|
+
errorMatcher?: boolean | string;
|
|
89
|
+
/** Global watch patterns, inherited by processes without their own watch */
|
|
90
|
+
watch?: string | string[];
|
|
91
|
+
/**
|
|
92
|
+
* Tab display order. `'config'` preserves definition order (package.json script order for wildcards),
|
|
93
|
+
* `'alphabetical'` sorts by process name, `'topological'` sorts by dependency tiers.
|
|
94
|
+
* @default 'config'
|
|
95
|
+
*/
|
|
96
|
+
sort?: SortOrder;
|
|
75
97
|
processes: Record<K, NumuxProcessConfig<K> | NumuxScriptPattern<K> | string>;
|
|
76
98
|
}
|
|
99
|
+
export type SortOrder = 'config' | 'alphabetical' | 'topological';
|
|
77
100
|
/** Process config after validation — dependsOn is always normalized to an array */
|
|
78
101
|
export interface ResolvedProcessConfig extends Omit<NumuxProcessConfig, 'dependsOn'> {
|
|
79
102
|
dependsOn?: string[];
|
|
80
103
|
}
|
|
81
104
|
/** Validated config with all shorthand expanded to full objects */
|
|
82
105
|
export interface ResolvedNumuxConfig {
|
|
106
|
+
sort?: SortOrder;
|
|
83
107
|
processes: Record<string, ResolvedProcessConfig>;
|
|
84
108
|
}
|
|
85
109
|
export type ProcessStatus = 'pending' | 'starting' | 'ready' | 'running' | 'stopping' | 'stopped' | 'finished' | 'failed' | 'skipped';
|