numux 2.16.0 → 2.16.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.
package/README.md CHANGED
@@ -212,7 +212,7 @@ export default defineConfig({
212
212
  <!-- generated:options -->
213
213
  | Flag | Description |
214
214
  |------|-------------|
215
- | `-s,` `--sort` `<config|alphabetical|topological>` | Tab display order |
215
+ | `-s,` `--sort` `<config|alphabetical|topological|status>` | Tab display order |
216
216
  | `-w,` `--workspace` `<script>` | Run a package.json script across all workspaces |
217
217
  | `-n,` `--name` `<name=command>` | Add a named process |
218
218
  | `-c,` `--color` `<colors>` | Comma-separated colors (hex or names: black, red, green, yellow, blue, magenta, cyan, white, gray, orange, purple) |
@@ -277,7 +277,7 @@ Top-level options apply to all processes (process-level settings override):
277
277
  | `stopSignal` | `'SIGTERM' \| 'SIGINT' \| 'SIGHUP'` | Global stop signal, inherited by all processes |
278
278
  | `errorMatcher` | `boolean \| string` | Global error matcher, inherited by all processes. `true` = detect ANSI red output, string = regex |
279
279
  | `watch` | `string \| string[]` | Global watch patterns, inherited by processes without their own watch |
280
- | `sort` | `'config' \| 'alphabetical' \| 'topological'` | Tab display order. `'config'` preserves definition order (package.json script order for wildcards), `'alphabetical'` sorts by process name, `'topological'` sorts by dependency tiers. |
280
+ | `sort` | `'config' \| 'alphabetical' \| 'topological' \| 'status'` | Tab display order. `'config'` preserves definition order (package.json script order for wildcards), `'alphabetical'` sorts by process name, `'topological'` sorts by dependency tiers, `'status'` uses config order but moves finished/stopped/failed/skipped tabs to the bottom. |
281
281
  | `prefix` | `boolean` | Use prefixed output mode instead of TUI (for CI/scripts) |
282
282
  | `timestamps` | `boolean \| string` | Add timestamps to output lines. `true` uses default `HH:mm:ss.SSS` format, or pass a format string (e.g. `"HH:mm:ss"`) |
283
283
  | `killOthers` | `boolean` | Kill all processes when any one exits (regardless of exit code) |
package/dist/man/numux.1 CHANGED
@@ -1,4 +1,4 @@
1
- .TH "NUMUX" "1" "May 2026" "2.16.0" "numux manual"
1
+ .TH "NUMUX" "1" "May 2026" "2.16.1" "numux manual"
2
2
  .SH "NAME"
3
3
  \fBnumux\fR
4
4
  .P
@@ -486,9 +486,9 @@ _
486
486
  T{
487
487
  \fBsort\fP
488
488
  T}|T{
489
- \fB&#39;config&#39; | &#39;alphabetical&#39; | &#39;topological&#39;\fP
489
+ \fB&#39;config&#39; | &#39;alphabetical&#39; | &#39;topological&#39; | &#39;status&#39;\fP
490
490
  T}|T{
491
- Tab display order\. \fB&#39;config&#39;\fP preserves definition order (package\.json script order for wildcards), \fB&#39;alphabetical&#39;\fP sorts by process name, \fB&#39;topological&#39;\fP sorts by dependency tiers\.
491
+ Tab display order\. \fB&#39;config&#39;\fP preserves definition order (package\.json script order for wildcards), \fB&#39;alphabetical&#39;\fP sorts by process name, \fB&#39;topological&#39;\fP sorts by dependency tiers, \fB&#39;status&#39;\fP uses config order but moves finished/stopped/failed/skipped tabs to the bottom\.
492
492
  T}
493
493
  _
494
494
  T{
package/dist/numux.js CHANGED
@@ -230,7 +230,7 @@ export default defineConfig({
230
230
  options: { title: "Options", body: `<!-- generated:options -->
231
231
  | Flag | Description |
232
232
  |------|-------------|
233
- | \`-s,\` \`--sort\` \`<config|alphabetical|topological>\` | Tab display order |
233
+ | \`-s,\` \`--sort\` \`<config|alphabetical|topological|status>\` | Tab display order |
234
234
  | \`-w,\` \`--workspace\` \`<script>\` | Run a package.json script across all workspaces |
235
235
  | \`-n,\` \`--name\` \`<name=command>\` | Add a named process |
236
236
  | \`-c,\` \`--color\` \`<colors>\` | Comma-separated colors (hex or names: black, red, green, yellow, blue, magenta, cyan, white, gray, orange, purple) |
@@ -283,7 +283,7 @@ numux logs api | tail -f # Follow process log output
283
283
  | \`stopSignal\` | \`'SIGTERM' \\| 'SIGINT' \\| 'SIGHUP'\` | Global stop signal, inherited by all processes |
284
284
  | \`errorMatcher\` | \`boolean \\| string\` | Global error matcher, inherited by all processes. \`true\` = detect ANSI red output, string = regex |
285
285
  | \`watch\` | \`string \\| string[]\` | Global watch patterns, inherited by processes without their own watch |
286
- | \`sort\` | \`'config' \\| 'alphabetical' \\| 'topological'\` | Tab display order. \`'config'\` preserves definition order (package.json script order for wildcards), \`'alphabetical'\` sorts by process name, \`'topological'\` sorts by dependency tiers. |
286
+ | \`sort\` | \`'config' \\| 'alphabetical' \\| 'topological' \\| 'status'\` | Tab display order. \`'config'\` preserves definition order (package.json script order for wildcards), \`'alphabetical'\` sorts by process name, \`'topological'\` sorts by dependency tiers, \`'status'\` uses config order but moves finished/stopped/failed/skipped tabs to the bottom. |
287
287
  | \`prefix\` | \`boolean\` | Use prefixed output mode instead of TUI (for CI/scripts) |
288
288
  | \`timestamps\` | \`boolean \\| string\` | Add timestamps to output lines. \`true\` uses default \`HH:mm:ss.SSS\` format, or pass a format string (e.g. \`"HH:mm:ss"\`) |
289
289
  | \`killOthers\` | \`boolean\` | Kill all processes when any one exits (regardless of exit code) |
@@ -548,7 +548,7 @@ var init_help = __esm(() => {
548
548
  var require_package = __commonJS((exports, module) => {
549
549
  module.exports = {
550
550
  name: "numux",
551
- version: "2.16.0",
551
+ version: "2.16.1",
552
552
  description: "Terminal multiplexer with dependency orchestration",
553
553
  type: "module",
554
554
  license: "MIT",
@@ -738,7 +738,7 @@ var FLAGS = [
738
738
  short: "-s",
739
739
  key: "sort",
740
740
  description: "Tab display order",
741
- valueName: "<config|alphabetical|topological>",
741
+ valueName: "<config|alphabetical|topological|status>",
742
742
  completionHint: "none"
743
743
  },
744
744
  {
@@ -1912,7 +1912,7 @@ function validateErrorMatcher(name, value) {
1912
1912
  }
1913
1913
  return;
1914
1914
  }
1915
- var VALID_SORT_VALUES = new Set(["config", "alphabetical", "topological"]);
1915
+ var VALID_SORT_VALUES = new Set(["config", "alphabetical", "topological", "status"]);
1916
1916
  function validateSort(value) {
1917
1917
  if (typeof value === "string") {
1918
1918
  if (!VALID_SORT_VALUES.has(value)) {
@@ -4102,6 +4102,11 @@ var STATUS_ICON_HEX = {
4102
4102
  skipped: "#888888"
4103
4103
  };
4104
4104
  var TERMINAL_STATUSES = new Set(["finished", "stopped", "failed", "skipped"]);
4105
+ function getDisplayOrder(originalNames, statuses) {
4106
+ const active = originalNames.filter((n) => !TERMINAL_STATUSES.has(statuses.get(n)));
4107
+ const terminal = originalNames.filter((n) => TERMINAL_STATUSES.has(statuses.get(n)));
4108
+ return [...active, ...terminal];
4109
+ }
4105
4110
  function formatTab(name, status) {
4106
4111
  return `${STATUS_ICONS[status]} ${name}`;
4107
4112
  }
@@ -4115,11 +4120,6 @@ function formatDescription(status, exitCode, restartCount) {
4115
4120
  }
4116
4121
  return desc;
4117
4122
  }
4118
- function getDisplayOrder(originalNames, statuses) {
4119
- const active = originalNames.filter((n) => !TERMINAL_STATUSES.has(statuses.get(n)));
4120
- const terminal = originalNames.filter((n) => TERMINAL_STATUSES.has(statuses.get(n)));
4121
- return [...active, ...terminal];
4122
- }
4123
4123
  function resolveOptionColors(names, statuses, processColors, inputWaiting, erroredProcesses, searchMatchProcesses) {
4124
4124
  return names.map((name) => {
4125
4125
  const status = statuses.get(name);
@@ -4209,12 +4209,14 @@ class TabBar {
4209
4209
  statuses;
4210
4210
  baseDescriptions;
4211
4211
  processColors;
4212
+ reorderByStatus;
4212
4213
  inputWaiting = new Set;
4213
4214
  erroredProcesses = new Set;
4214
4215
  searchMatchCounts = new Map;
4215
- constructor(renderer, names, colors) {
4216
+ constructor(renderer, names, colors, reorderByStatus = false) {
4216
4217
  this.originalNames = names;
4217
4218
  this.names = [...names];
4219
+ this.reorderByStatus = reorderByStatus;
4218
4220
  this.statuses = new Map(names.map((n) => [n, "pending"]));
4219
4221
  this.baseDescriptions = new Map(names.map((n) => [n, "pending"]));
4220
4222
  this.processColors = colors ?? new Map;
@@ -4284,17 +4286,19 @@ class TabBar {
4284
4286
  return this.names.length;
4285
4287
  }
4286
4288
  refreshOptions() {
4287
- const currentIdx = this.renderable.getSelectedIndex();
4288
- const currentName = this.names[currentIdx];
4289
- this.names = getDisplayOrder(this.originalNames, this.statuses);
4289
+ if (this.reorderByStatus) {
4290
+ const currentIdx = this.renderable.getSelectedIndex();
4291
+ const currentName = this.names[currentIdx];
4292
+ this.names = getDisplayOrder(this.originalNames, this.statuses);
4293
+ const newIdx = this.names.indexOf(currentName);
4294
+ if (newIdx >= 0 && newIdx !== currentIdx) {
4295
+ this.renderable.setSelectedIndex(newIdx);
4296
+ }
4297
+ }
4290
4298
  this.renderable.options = this.names.map((n) => ({
4291
4299
  name: formatTab(n, this.statuses.get(n)),
4292
4300
  description: this.getDescription(n)
4293
4301
  }));
4294
- const newIdx = this.names.indexOf(currentName);
4295
- if (newIdx >= 0 && newIdx !== currentIdx) {
4296
- this.renderable.setSelectedIndex(newIdx);
4297
- }
4298
4302
  this.updateOptionColors();
4299
4303
  }
4300
4304
  getDescription(name) {
@@ -4372,7 +4376,7 @@ class App {
4372
4376
  border: false
4373
4377
  });
4374
4378
  const processHexColors = buildProcessHexColorMap(this.names, this.config);
4375
- this.tabBar = new TabBar(this.renderer, this.names, processHexColors);
4379
+ this.tabBar = new TabBar(this.renderer, this.names, processHexColors, this.config.sort === "status");
4376
4380
  const contentRow = new BoxRenderable3(this.renderer, {
4377
4381
  id: "content-row",
4378
4382
  flexDirection: "row",
package/dist/types.d.ts CHANGED
@@ -93,7 +93,8 @@ export interface NumuxConfig<K extends string = string> {
93
93
  watch?: string | string[];
94
94
  /**
95
95
  * Tab display order. `'config'` preserves definition order (package.json script order for wildcards),
96
- * `'alphabetical'` sorts by process name, `'topological'` sorts by dependency tiers.
96
+ * `'alphabetical'` sorts by process name, `'topological'` sorts by dependency tiers,
97
+ * `'status'` uses config order but moves finished/stopped/failed/skipped tabs to the bottom.
97
98
  * @default 'config'
98
99
  */
99
100
  sort?: SortOrder;
@@ -123,7 +124,7 @@ export interface NumuxConfig<K extends string = string> {
123
124
  logDir?: string;
124
125
  processes: Record<K, NumuxProcessConfig<K> | NumuxScriptPattern<K> | string | true>;
125
126
  }
126
- export type SortOrder = 'config' | 'alphabetical' | 'topological';
127
+ export type SortOrder = 'config' | 'alphabetical' | 'topological' | 'status';
127
128
  /** Process config after validation — dependsOn is always normalized to an array */
128
129
  export interface ResolvedProcessConfig extends Omit<NumuxProcessConfig, 'dependsOn' | 'workspaces'> {
129
130
  dependsOn?: string[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "numux",
3
- "version": "2.16.0",
3
+ "version": "2.16.1",
4
4
  "description": "Terminal multiplexer with dependency orchestration",
5
5
  "type": "module",
6
6
  "license": "MIT",