startall 0.0.22 → 0.0.23

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 (3) hide show
  1. package/README.md +2 -0
  2. package/index.js +83 -0
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -43,6 +43,7 @@ Traditional solutions fall short:
43
43
  - Per-process visibility toggles (`Space` or `1-9`)
44
44
  - Per-pane filters (different views in each pane)
45
45
  - **Custom pane naming**: Label panes for easier identification (`n`)
46
+ - **Column view**: Instant one-pane-per-script layout with `=` key (toggle back to restore your layout)
46
47
  - **Persistent layouts**: Your pane configuration is saved between sessions
47
48
  - **Process-specific views**: Show/hide specific processes in each pane
48
49
  - **Colored output**: Each process gets unique color-coded output
@@ -122,6 +123,7 @@ That's it! The TUI will:
122
123
  - `\` - Open command palette
123
124
  - `|` - Split pane vertically (left/right)
124
125
  - `_` - Split pane horizontally (top/bottom)
126
+ - `=` - Toggle column view (one column per script, auto-generated)
125
127
  - `x` - Close current pane (if >1 pane exists)
126
128
  - `Tab` - Next pane
127
129
  - `Shift+Tab` - Previous pane
package/index.js CHANGED
@@ -606,6 +606,10 @@ class ProcessManager {
606
606
  this.paneLineCount = new Map(); // Track how many lines we've rendered per pane
607
607
  this.uiJustRebuilt = false; // Flag to skip redundant render after buildRunningUI
608
608
 
609
+ // Column view state (one pane per script, side by side)
610
+ this.isColumnView = false; // Whether column view is active
611
+ this.savedPaneRoot = null; // Saved pane tree to restore when toggling back
612
+
609
613
  // Copy mode state (select text to copy)
610
614
  this.isCopyMode = false; // Whether in copy/select mode
611
615
  this.copyModeCursor = 0; // Current cursor line index within visible lines
@@ -842,14 +846,17 @@ class ProcessManager {
842
846
  this.buildRunningUI();
843
847
  } else if (keyName === '|') {
844
848
  // Quick vertical split
849
+ this.exitColumnViewMode();
845
850
  this.splitCurrentPane('vertical');
846
851
  this.buildRunningUI();
847
852
  } else if (keyName === '_') {
848
853
  // Quick horizontal split
854
+ this.exitColumnViewMode();
849
855
  this.splitCurrentPane('horizontal');
850
856
  this.buildRunningUI();
851
857
  } else if (keyName === 'x' && getAllPaneIds(this.paneRoot).length > 1) {
852
858
  // Close current pane (only if more than one)
859
+ this.exitColumnViewMode();
853
860
  this.closeCurrentPane();
854
861
  this.buildRunningUI();
855
862
  } else if (keyName === 'space') {
@@ -985,6 +992,9 @@ class ProcessManager {
985
992
  } else if (keyName === 'y') {
986
993
  // Enter copy mode (select text to copy)
987
994
  this.enterCopyMode();
995
+ } else if (keyName === '=') {
996
+ // Toggle column view (one pane per script)
997
+ this.toggleColumnView();
988
998
  } else if (keyName === 'g' && IS_GIT_REPO) {
989
999
  // Open git modal (commit & push)
990
1000
  this.openGitModal();
@@ -1674,6 +1684,67 @@ class ProcessManager {
1674
1684
  }
1675
1685
  }
1676
1686
 
1687
+ // Generate a column view pane tree: one pane per running script, side by side
1688
+ generateColumnViewPaneTree() {
1689
+ // Get the scripts that are currently selected/running
1690
+ const runningScripts = this.scripts.filter(s => {
1691
+ const proc = this.processes.get(s.name);
1692
+ return proc && (proc.status === 'running' || proc.status === 'crashed' || proc.status === 'exited');
1693
+ });
1694
+
1695
+ if (runningScripts.length === 0) {
1696
+ return createPane([]);
1697
+ }
1698
+
1699
+ if (runningScripts.length === 1) {
1700
+ return createPane([runningScripts[0].name]);
1701
+ }
1702
+
1703
+ // Create a vertical split with one pane per script
1704
+ const panes = runningScripts.map(s => {
1705
+ const pane = createPane([s.name]);
1706
+ pane.name = s.displayName;
1707
+ return pane;
1708
+ });
1709
+
1710
+ return createSplit('vertical', panes);
1711
+ }
1712
+
1713
+ // Toggle between column view (one pane per script) and the normal saved layout
1714
+ toggleColumnView() {
1715
+ if (this.isColumnView) {
1716
+ // Restore the saved pane tree
1717
+ if (this.savedPaneRoot) {
1718
+ this.paneRoot = this.savedPaneRoot;
1719
+ this.savedPaneRoot = null;
1720
+ } else {
1721
+ this.paneRoot = createPane([]);
1722
+ }
1723
+ this.isColumnView = false;
1724
+ } else {
1725
+ // Save current pane tree and switch to column view
1726
+ this.savedPaneRoot = this.paneRoot;
1727
+ this.paneRoot = this.generateColumnViewPaneTree();
1728
+ this.isColumnView = true;
1729
+ }
1730
+
1731
+ // Focus the first pane in the new tree
1732
+ const allPanes = getAllPaneIds(this.paneRoot);
1733
+ if (allPanes.length > 0) {
1734
+ this.focusedPaneId = allPanes[0];
1735
+ }
1736
+
1737
+ this.buildRunningUI();
1738
+ }
1739
+
1740
+ // Exit column view mode without restoring saved layout (e.g. user manually split/closed a pane)
1741
+ exitColumnViewMode() {
1742
+ if (this.isColumnView) {
1743
+ this.isColumnView = false;
1744
+ this.savedPaneRoot = null;
1745
+ }
1746
+ }
1747
+
1677
1748
  // Move the currently selected process to the focused pane
1678
1749
  moveProcessToCurrentPane() {
1679
1750
  const scriptName = this.scripts[this.selectedIndex]?.name;
@@ -1760,6 +1831,8 @@ class ProcessManager {
1760
1831
 
1761
1832
  // Save the current pane layout to config (debounced to avoid excessive disk writes)
1762
1833
  savePaneLayout() {
1834
+ // Don't save the auto-generated column view layout - it's transient
1835
+ if (this.isColumnView) return;
1763
1836
  this.config.paneLayout = serializePaneTree(this.paneRoot);
1764
1837
  debouncedSaveConfig(this.config);
1765
1838
  }
@@ -4176,6 +4249,15 @@ class ProcessManager {
4176
4249
  });
4177
4250
  leftSide.add(statusIndicator);
4178
4251
 
4252
+ // Column view indicator
4253
+ if (this.isColumnView) {
4254
+ const columnIndicator = new TextRenderable(this.renderer, {
4255
+ id: 'column-view-indicator',
4256
+ content: t`${fg(COLORS.cyan)('COLUMNS')}`,
4257
+ });
4258
+ leftSide.add(columnIndicator);
4259
+ }
4260
+
4179
4261
  // Git branch indicator
4180
4262
  if (IS_GIT_REPO) {
4181
4263
  const branch = this.gitBranch || getGitBranch();
@@ -4286,6 +4368,7 @@ class ProcessManager {
4286
4368
  // Pane & navigation
4287
4369
  [
4288
4370
  { key: '\\', desc: 'panes', color: COLORS.cyan },
4371
+ { key: '=', desc: this.isColumnView ? 'merged' : 'columns', color: COLORS.cyan },
4289
4372
  { key: '1-9', desc: 'toggle', color: COLORS.success },
4290
4373
  ],
4291
4374
  // Process control
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "startall",
3
- "version": "0.0.22",
3
+ "version": "0.0.23",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "bin": {