startall 0.0.21 → 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.
- package/README.md +2 -0
- package/index.js +94 -0
- 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
|
|
@@ -660,6 +664,16 @@ class ProcessManager {
|
|
|
660
664
|
return;
|
|
661
665
|
}
|
|
662
666
|
|
|
667
|
+
// Handle Ctrl+L - clear screen buffer and redraw
|
|
668
|
+
if (key.ctrl && key.name === 'l') {
|
|
669
|
+
if (this.phase === 'running') {
|
|
670
|
+
this.outputLines = [];
|
|
671
|
+
this.totalLinesReceived = 0;
|
|
672
|
+
this.buildRunningUI();
|
|
673
|
+
}
|
|
674
|
+
return;
|
|
675
|
+
}
|
|
676
|
+
|
|
663
677
|
this.handleInput(key.name, key);
|
|
664
678
|
this.render();
|
|
665
679
|
});
|
|
@@ -832,14 +846,17 @@ class ProcessManager {
|
|
|
832
846
|
this.buildRunningUI();
|
|
833
847
|
} else if (keyName === '|') {
|
|
834
848
|
// Quick vertical split
|
|
849
|
+
this.exitColumnViewMode();
|
|
835
850
|
this.splitCurrentPane('vertical');
|
|
836
851
|
this.buildRunningUI();
|
|
837
852
|
} else if (keyName === '_') {
|
|
838
853
|
// Quick horizontal split
|
|
854
|
+
this.exitColumnViewMode();
|
|
839
855
|
this.splitCurrentPane('horizontal');
|
|
840
856
|
this.buildRunningUI();
|
|
841
857
|
} else if (keyName === 'x' && getAllPaneIds(this.paneRoot).length > 1) {
|
|
842
858
|
// Close current pane (only if more than one)
|
|
859
|
+
this.exitColumnViewMode();
|
|
843
860
|
this.closeCurrentPane();
|
|
844
861
|
this.buildRunningUI();
|
|
845
862
|
} else if (keyName === 'space') {
|
|
@@ -975,6 +992,9 @@ class ProcessManager {
|
|
|
975
992
|
} else if (keyName === 'y') {
|
|
976
993
|
// Enter copy mode (select text to copy)
|
|
977
994
|
this.enterCopyMode();
|
|
995
|
+
} else if (keyName === '=') {
|
|
996
|
+
// Toggle column view (one pane per script)
|
|
997
|
+
this.toggleColumnView();
|
|
978
998
|
} else if (keyName === 'g' && IS_GIT_REPO) {
|
|
979
999
|
// Open git modal (commit & push)
|
|
980
1000
|
this.openGitModal();
|
|
@@ -1664,6 +1684,67 @@ class ProcessManager {
|
|
|
1664
1684
|
}
|
|
1665
1685
|
}
|
|
1666
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
|
+
|
|
1667
1748
|
// Move the currently selected process to the focused pane
|
|
1668
1749
|
moveProcessToCurrentPane() {
|
|
1669
1750
|
const scriptName = this.scripts[this.selectedIndex]?.name;
|
|
@@ -1750,6 +1831,8 @@ class ProcessManager {
|
|
|
1750
1831
|
|
|
1751
1832
|
// Save the current pane layout to config (debounced to avoid excessive disk writes)
|
|
1752
1833
|
savePaneLayout() {
|
|
1834
|
+
// Don't save the auto-generated column view layout - it's transient
|
|
1835
|
+
if (this.isColumnView) return;
|
|
1753
1836
|
this.config.paneLayout = serializePaneTree(this.paneRoot);
|
|
1754
1837
|
debouncedSaveConfig(this.config);
|
|
1755
1838
|
}
|
|
@@ -4166,6 +4249,15 @@ class ProcessManager {
|
|
|
4166
4249
|
});
|
|
4167
4250
|
leftSide.add(statusIndicator);
|
|
4168
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
|
+
|
|
4169
4261
|
// Git branch indicator
|
|
4170
4262
|
if (IS_GIT_REPO) {
|
|
4171
4263
|
const branch = this.gitBranch || getGitBranch();
|
|
@@ -4276,6 +4368,7 @@ class ProcessManager {
|
|
|
4276
4368
|
// Pane & navigation
|
|
4277
4369
|
[
|
|
4278
4370
|
{ key: '\\', desc: 'panes', color: COLORS.cyan },
|
|
4371
|
+
{ key: '=', desc: this.isColumnView ? 'merged' : 'columns', color: COLORS.cyan },
|
|
4279
4372
|
{ key: '1-9', desc: 'toggle', color: COLORS.success },
|
|
4280
4373
|
],
|
|
4281
4374
|
// Process control
|
|
@@ -4290,6 +4383,7 @@ class ProcessManager {
|
|
|
4290
4383
|
{ key: '/', desc: 'filter', color: COLORS.cyan },
|
|
4291
4384
|
{ key: 'c', desc: 'color', color: COLORS.magenta },
|
|
4292
4385
|
{ key: 'y', desc: 'copy', color: COLORS.accent },
|
|
4386
|
+
{ key: '^L', desc: 'clear', color: COLORS.cyan },
|
|
4293
4387
|
],
|
|
4294
4388
|
// Misc
|
|
4295
4389
|
[
|