startall 0.0.19 → 0.0.20
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/index.js +159 -66
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
|
-
import { createCliRenderer, TextRenderable, BoxRenderable, ScrollBoxRenderable, t, fg } from '@opentui/core';
|
|
3
|
+
import { createCliRenderer, TextRenderable, BoxRenderable, ScrollBoxRenderable, ASCIIFontRenderable, t, fg, bold, dim, RGBA } from '@opentui/core';
|
|
4
4
|
import { spawn, execSync, spawnSync } from 'child_process';
|
|
5
5
|
import { readFileSync, writeFileSync, writeSync, existsSync } from 'fs';
|
|
6
6
|
import { join } from 'path';
|
|
@@ -1956,7 +1956,7 @@ class ProcessManager {
|
|
|
1956
1956
|
width: '100%',
|
|
1957
1957
|
height: '100%',
|
|
1958
1958
|
backgroundColor: COLORS.bg,
|
|
1959
|
-
padding:
|
|
1959
|
+
padding: 2,
|
|
1960
1960
|
});
|
|
1961
1961
|
|
|
1962
1962
|
// Header bar with title
|
|
@@ -1964,6 +1964,7 @@ class ProcessManager {
|
|
|
1964
1964
|
id: 'header-bar',
|
|
1965
1965
|
flexDirection: 'row',
|
|
1966
1966
|
justifyContent: 'space-between',
|
|
1967
|
+
alignItems: 'center',
|
|
1967
1968
|
width: '100%',
|
|
1968
1969
|
border: ['bottom'],
|
|
1969
1970
|
borderStyle: 'single',
|
|
@@ -1974,13 +1975,13 @@ class ProcessManager {
|
|
|
1974
1975
|
|
|
1975
1976
|
const titleText = new TextRenderable(this.renderer, {
|
|
1976
1977
|
id: 'title',
|
|
1977
|
-
content: t`${fg(COLORS.accent)('
|
|
1978
|
+
content: t`${bold(fg(COLORS.accent)('Settings'))}`,
|
|
1978
1979
|
});
|
|
1979
1980
|
headerBar.add(titleText);
|
|
1980
1981
|
|
|
1981
1982
|
const versionText = new TextRenderable(this.renderer, {
|
|
1982
1983
|
id: 'version',
|
|
1983
|
-
content: t`${fg(COLORS.textDim)(APP_VERSION)}`,
|
|
1984
|
+
content: t`${fg(COLORS.textDim)('startall')} ${fg(COLORS.textDim)('·')} ${fg(COLORS.textDim)(APP_VERSION)}`,
|
|
1984
1985
|
});
|
|
1985
1986
|
headerBar.add(versionText);
|
|
1986
1987
|
|
|
@@ -2121,40 +2122,42 @@ class ProcessManager {
|
|
|
2121
2122
|
id: 'footer-bar',
|
|
2122
2123
|
flexDirection: 'row',
|
|
2123
2124
|
width: '100%',
|
|
2125
|
+
backgroundColor: COLORS.bgLight,
|
|
2124
2126
|
border: ['top'],
|
|
2125
2127
|
borderStyle: 'single',
|
|
2126
2128
|
borderColor: COLORS.border,
|
|
2127
|
-
|
|
2129
|
+
paddingLeft: 2,
|
|
2130
|
+
paddingRight: 2,
|
|
2128
2131
|
marginTop: 1,
|
|
2129
|
-
gap:
|
|
2132
|
+
gap: 3,
|
|
2130
2133
|
});
|
|
2131
2134
|
|
|
2132
2135
|
let shortcuts;
|
|
2133
2136
|
if (this.isAddingPattern) {
|
|
2134
2137
|
shortcuts = [
|
|
2135
|
-
{ key: 'enter', desc: 'save' },
|
|
2136
|
-
{ key: 'esc', desc: 'cancel' },
|
|
2138
|
+
{ key: 'enter', desc: 'save', color: COLORS.success },
|
|
2139
|
+
{ key: 'esc', desc: 'cancel', color: COLORS.error },
|
|
2137
2140
|
];
|
|
2138
2141
|
} else if (this.isAssigningShortcut) {
|
|
2139
2142
|
shortcuts = [
|
|
2140
|
-
{ key: 'any key', desc: 'assign' },
|
|
2141
|
-
{ key: 'esc', desc: 'cancel' },
|
|
2143
|
+
{ key: 'any key', desc: 'assign', color: COLORS.warning },
|
|
2144
|
+
{ key: 'esc', desc: 'cancel', color: COLORS.error },
|
|
2142
2145
|
];
|
|
2143
2146
|
} else {
|
|
2144
2147
|
shortcuts = [
|
|
2145
|
-
{ key: 'tab', desc: 'section' },
|
|
2146
|
-
{ key: 'space', desc: this.settingsSection === 'shortcuts' ? 'assign' : 'toggle' },
|
|
2147
|
-
{ key: 'i', desc: 'add ignore' },
|
|
2148
|
-
{ key: 'n', desc: 'add include' },
|
|
2149
|
-
{ key: 'd', desc: 'delete' },
|
|
2150
|
-
{ key: 'esc', desc: 'back' },
|
|
2148
|
+
{ key: 'tab', desc: 'section', color: COLORS.cyan },
|
|
2149
|
+
{ key: 'space', desc: this.settingsSection === 'shortcuts' ? 'assign' : 'toggle', color: COLORS.success },
|
|
2150
|
+
{ key: 'i', desc: 'add ignore', color: COLORS.error },
|
|
2151
|
+
{ key: 'n', desc: 'add include', color: COLORS.success },
|
|
2152
|
+
{ key: 'd', desc: 'delete', color: COLORS.error },
|
|
2153
|
+
{ key: 'esc', desc: 'back', color: COLORS.textDim },
|
|
2151
2154
|
];
|
|
2152
2155
|
}
|
|
2153
2156
|
|
|
2154
|
-
shortcuts.forEach(({ key, desc }) => {
|
|
2157
|
+
shortcuts.forEach(({ key, desc, color }) => {
|
|
2155
2158
|
const shortcut = new TextRenderable(this.renderer, {
|
|
2156
2159
|
id: `shortcut-${key}`,
|
|
2157
|
-
content: t`${fg(COLORS.
|
|
2160
|
+
content: t`${fg(color || COLORS.accent)(key)} ${fg(COLORS.textDim)(desc)}`,
|
|
2158
2161
|
});
|
|
2159
2162
|
footerBar.add(shortcut);
|
|
2160
2163
|
});
|
|
@@ -2424,17 +2427,49 @@ class ProcessManager {
|
|
|
2424
2427
|
backgroundColor: COLORS.bg,
|
|
2425
2428
|
});
|
|
2426
2429
|
|
|
2427
|
-
//
|
|
2430
|
+
// Content area (centered vertically, with padding)
|
|
2431
|
+
const contentArea = new BoxRenderable(this.renderer, {
|
|
2432
|
+
id: 'content-area',
|
|
2433
|
+
flexDirection: 'column',
|
|
2434
|
+
flexGrow: 1,
|
|
2435
|
+
padding: 2,
|
|
2436
|
+
paddingBottom: 0,
|
|
2437
|
+
gap: 1,
|
|
2438
|
+
});
|
|
2439
|
+
|
|
2440
|
+
// ASCII art title banner
|
|
2441
|
+
const asciiTitle = new ASCIIFontRenderable(this.renderer, {
|
|
2442
|
+
id: 'ascii-title',
|
|
2443
|
+
text: 'startall',
|
|
2444
|
+
font: 'tiny',
|
|
2445
|
+
color: RGBA.fromHex(COLORS.accent),
|
|
2446
|
+
});
|
|
2447
|
+
contentArea.add(asciiTitle);
|
|
2448
|
+
|
|
2449
|
+
// Subtitle with version
|
|
2450
|
+
const subtitle = new TextRenderable(this.renderer, {
|
|
2451
|
+
id: 'subtitle',
|
|
2452
|
+
content: t`${dim(fg(COLORS.textDim)(`${APP_VERSION} Process Manager`))}`,
|
|
2453
|
+
});
|
|
2454
|
+
contentArea.add(subtitle);
|
|
2455
|
+
|
|
2456
|
+
// Scripts panel in a bordered box
|
|
2428
2457
|
const scriptsPanel = new BoxRenderable(this.renderer, {
|
|
2429
2458
|
id: 'scripts-panel',
|
|
2430
2459
|
flexDirection: 'column',
|
|
2431
2460
|
flexGrow: 1,
|
|
2432
|
-
|
|
2433
|
-
|
|
2461
|
+
border: true,
|
|
2462
|
+
borderStyle: 'rounded',
|
|
2463
|
+
borderColor: COLORS.border,
|
|
2464
|
+
title: ' Select Scripts ',
|
|
2465
|
+
titleAlignment: 'left',
|
|
2466
|
+
padding: 1,
|
|
2467
|
+
marginTop: 1,
|
|
2434
2468
|
});
|
|
2435
2469
|
|
|
2436
2470
|
// Track Y positions for mouse clicks
|
|
2437
|
-
|
|
2471
|
+
// ASCII title is ~3 lines, subtitle 1 line, margins/padding ~5 lines, border top 1 line
|
|
2472
|
+
let currentY = 10; // approximate start of scripts inside bordered box
|
|
2438
2473
|
this.scriptLinePositions = [];
|
|
2439
2474
|
|
|
2440
2475
|
this.scriptLines = this.scripts.map((script, index) => {
|
|
@@ -2450,17 +2485,21 @@ class ProcessManager {
|
|
|
2450
2485
|
const numberLabel = index < 9 ? ` ${index + 1}` : ' ';
|
|
2451
2486
|
|
|
2452
2487
|
// Build checkbox with colored brackets and checkmark
|
|
2488
|
+
const checkIcon = isSelected ? '✓' : ' ';
|
|
2489
|
+
const pointer = isFocused ? fg(COLORS.accent)('❯ ') : ' ';
|
|
2490
|
+
|
|
2453
2491
|
let content;
|
|
2454
2492
|
if (isSelected) {
|
|
2455
|
-
content = t`${fg(numberColor)(numberLabel)} ${fg(bracketColor)('[')}${fg(COLORS.
|
|
2493
|
+
content = t`${pointer}${fg(numberColor)(numberLabel)} ${fg(bracketColor)('[')}${fg(COLORS.success)(checkIcon)}${fg(bracketColor)(']')} ${fg(nameColor)(script.displayName)}`;
|
|
2456
2494
|
} else {
|
|
2457
|
-
content = t`${fg(numberColor)(numberLabel)} ${fg(bracketColor)('[ ]')} ${fg(nameColor)(script.displayName)}`;
|
|
2495
|
+
content = t`${pointer}${fg(numberColor)(numberLabel)} ${fg(bracketColor)('[ ]')} ${fg(nameColor)(script.displayName)}`;
|
|
2458
2496
|
}
|
|
2459
2497
|
|
|
2460
2498
|
const lineContainer = new BoxRenderable(this.renderer, {
|
|
2461
2499
|
id: `script-box-${index}`,
|
|
2462
2500
|
backgroundColor: bgColor,
|
|
2463
2501
|
paddingLeft: 1,
|
|
2502
|
+
paddingRight: 1,
|
|
2464
2503
|
width: '100%',
|
|
2465
2504
|
});
|
|
2466
2505
|
|
|
@@ -2475,7 +2514,8 @@ class ProcessManager {
|
|
|
2475
2514
|
return lineContainer;
|
|
2476
2515
|
});
|
|
2477
2516
|
|
|
2478
|
-
|
|
2517
|
+
contentArea.add(scriptsPanel);
|
|
2518
|
+
this.selectionContainer.add(contentArea);
|
|
2479
2519
|
|
|
2480
2520
|
// Footer bar with title, countdown, and shortcuts
|
|
2481
2521
|
const footerBar = new BoxRenderable(this.renderer, {
|
|
@@ -2484,11 +2524,14 @@ class ProcessManager {
|
|
|
2484
2524
|
justifyContent: 'space-between',
|
|
2485
2525
|
width: '100%',
|
|
2486
2526
|
backgroundColor: COLORS.bgLight,
|
|
2487
|
-
paddingLeft:
|
|
2488
|
-
paddingRight:
|
|
2527
|
+
paddingLeft: 2,
|
|
2528
|
+
paddingRight: 2,
|
|
2529
|
+
border: ['top'],
|
|
2530
|
+
borderStyle: 'single',
|
|
2531
|
+
borderColor: COLORS.border,
|
|
2489
2532
|
});
|
|
2490
2533
|
|
|
2491
|
-
// Left side:
|
|
2534
|
+
// Left side: countdown timer
|
|
2492
2535
|
const leftSide = new BoxRenderable(this.renderer, {
|
|
2493
2536
|
id: 'footer-left',
|
|
2494
2537
|
flexDirection: 'row',
|
|
@@ -2497,7 +2540,7 @@ class ProcessManager {
|
|
|
2497
2540
|
|
|
2498
2541
|
const titleText = new TextRenderable(this.renderer, {
|
|
2499
2542
|
id: 'title',
|
|
2500
|
-
content: t`${fg(COLORS.accent)('startall')} ${fg(COLORS.warning)(this.countdown
|
|
2543
|
+
content: t`${fg(COLORS.accent)('startall')} ${fg(COLORS.textDim)('·')} ${fg(COLORS.warning)(`${this.countdown}s`)}`,
|
|
2501
2544
|
});
|
|
2502
2545
|
leftSide.add(titleText);
|
|
2503
2546
|
this.headerText = titleText; // Save reference for countdown updates
|
|
@@ -2513,23 +2556,23 @@ class ProcessManager {
|
|
|
2513
2556
|
|
|
2514
2557
|
footerBar.add(leftSide);
|
|
2515
2558
|
|
|
2516
|
-
// Right side: shortcuts
|
|
2559
|
+
// Right side: shortcuts with visual badges
|
|
2517
2560
|
const rightSide = new BoxRenderable(this.renderer, {
|
|
2518
2561
|
id: 'footer-right',
|
|
2519
2562
|
flexDirection: 'row',
|
|
2520
|
-
gap:
|
|
2563
|
+
gap: 3,
|
|
2521
2564
|
});
|
|
2522
2565
|
|
|
2523
2566
|
const shortcuts = [
|
|
2524
|
-
{ key: '
|
|
2525
|
-
{ key: '
|
|
2526
|
-
{ key: 'o', desc: '
|
|
2567
|
+
{ key: 'space', desc: 'select', color: COLORS.success },
|
|
2568
|
+
{ key: 'enter', desc: 'start', color: COLORS.accent },
|
|
2569
|
+
{ key: 'o', desc: 'settings', color: COLORS.magenta },
|
|
2527
2570
|
];
|
|
2528
2571
|
|
|
2529
2572
|
shortcuts.forEach(({ key, desc, color }) => {
|
|
2530
2573
|
const shortcut = new TextRenderable(this.renderer, {
|
|
2531
2574
|
id: `shortcut-${key}`,
|
|
2532
|
-
content: t`${fg(color)(key)}${fg(COLORS.textDim)(
|
|
2575
|
+
content: t`${fg(color)(key)} ${fg(COLORS.textDim)(desc)}`,
|
|
2533
2576
|
});
|
|
2534
2577
|
rightSide.add(shortcut);
|
|
2535
2578
|
});
|
|
@@ -3207,11 +3250,20 @@ class ProcessManager {
|
|
|
3207
3250
|
});
|
|
3208
3251
|
|
|
3209
3252
|
// Footer hint
|
|
3253
|
+
const hintBar = new BoxRenderable(this.renderer, {
|
|
3254
|
+
id: 'menu-hint-bar',
|
|
3255
|
+
border: ['top'],
|
|
3256
|
+
borderStyle: 'single',
|
|
3257
|
+
borderColor: COLORS.border,
|
|
3258
|
+
paddingTop: 1,
|
|
3259
|
+
marginTop: 1,
|
|
3260
|
+
});
|
|
3210
3261
|
const hint = new TextRenderable(this.renderer, {
|
|
3211
3262
|
id: 'menu-hint',
|
|
3212
|
-
content: t`${fg(COLORS.textDim)('
|
|
3263
|
+
content: t`${fg(COLORS.accent)('enter')} ${fg(COLORS.textDim)('select')} ${fg(COLORS.accent)('esc')} ${fg(COLORS.textDim)('close')}`,
|
|
3213
3264
|
});
|
|
3214
|
-
|
|
3265
|
+
hintBar.add(hint);
|
|
3266
|
+
overlay.add(hintBar);
|
|
3215
3267
|
|
|
3216
3268
|
parent.add(overlay);
|
|
3217
3269
|
}
|
|
@@ -3455,7 +3507,12 @@ class ProcessManager {
|
|
|
3455
3507
|
flexDirection: 'row',
|
|
3456
3508
|
width: '100%',
|
|
3457
3509
|
backgroundColor: COLORS.bgLight,
|
|
3458
|
-
paddingLeft:
|
|
3510
|
+
paddingLeft: 2,
|
|
3511
|
+
paddingRight: 2,
|
|
3512
|
+
gap: 1,
|
|
3513
|
+
border: ['bottom'],
|
|
3514
|
+
borderStyle: 'single',
|
|
3515
|
+
borderColor: COLORS.border,
|
|
3459
3516
|
});
|
|
3460
3517
|
this.processBarContainer = processBar; // Save reference for light updates
|
|
3461
3518
|
|
|
@@ -3513,15 +3570,18 @@ class ProcessManager {
|
|
|
3513
3570
|
|
|
3514
3571
|
mainContainer.add(paneArea);
|
|
3515
3572
|
|
|
3516
|
-
// Footer bar -
|
|
3573
|
+
// Footer bar - polished with top border
|
|
3517
3574
|
const footerBar = new BoxRenderable(this.renderer, {
|
|
3518
3575
|
id: 'footer-bar',
|
|
3519
3576
|
flexDirection: 'row',
|
|
3520
3577
|
width: '100%',
|
|
3521
3578
|
backgroundColor: COLORS.bgLight,
|
|
3522
|
-
paddingLeft:
|
|
3523
|
-
paddingRight:
|
|
3579
|
+
paddingLeft: 2,
|
|
3580
|
+
paddingRight: 2,
|
|
3524
3581
|
justifyContent: 'space-between',
|
|
3582
|
+
border: ['top'],
|
|
3583
|
+
borderStyle: 'single',
|
|
3584
|
+
borderColor: COLORS.border,
|
|
3525
3585
|
});
|
|
3526
3586
|
|
|
3527
3587
|
// Left side: status indicator and filter
|
|
@@ -3632,47 +3692,80 @@ class ProcessManager {
|
|
|
3632
3692
|
gap: 2,
|
|
3633
3693
|
});
|
|
3634
3694
|
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
|
|
3695
|
+
// Shortcut groups separated by dimmed pipe characters
|
|
3696
|
+
const shortcutGroups = [
|
|
3697
|
+
// Pane & navigation
|
|
3698
|
+
[
|
|
3699
|
+
{ key: '\\', desc: 'panes', color: COLORS.cyan },
|
|
3700
|
+
{ key: '1-9', desc: 'toggle', color: COLORS.success },
|
|
3701
|
+
],
|
|
3702
|
+
// Process control
|
|
3703
|
+
[
|
|
3704
|
+
{ key: 's', desc: 'stop', color: COLORS.error },
|
|
3705
|
+
{ key: 'r', desc: 'restart', color: COLORS.success },
|
|
3706
|
+
{ key: 'e', desc: 'execute', color: COLORS.warning },
|
|
3707
|
+
],
|
|
3708
|
+
// View & edit
|
|
3709
|
+
[
|
|
3710
|
+
{ key: 'p', desc: 'pause', color: COLORS.warning },
|
|
3711
|
+
{ key: '/', desc: 'filter', color: COLORS.cyan },
|
|
3712
|
+
{ key: 'c', desc: 'color', color: COLORS.magenta },
|
|
3713
|
+
{ key: 'y', desc: 'copy', color: COLORS.accent },
|
|
3714
|
+
],
|
|
3715
|
+
// Misc
|
|
3716
|
+
[
|
|
3717
|
+
{ key: 'i', desc: 'input', color: COLORS.success },
|
|
3718
|
+
{ key: 'n', desc: 'name', color: COLORS.accent },
|
|
3719
|
+
{ key: 'o', desc: 'cfg', color: COLORS.magenta },
|
|
3720
|
+
{ key: 'q', desc: 'quit', color: COLORS.error },
|
|
3721
|
+
],
|
|
3649
3722
|
];
|
|
3650
3723
|
|
|
3651
|
-
// Add configured quick command shortcuts
|
|
3724
|
+
// Add configured quick command shortcuts to the first group
|
|
3652
3725
|
const configShortcuts = this.config.shortcuts || {};
|
|
3726
|
+
const customGroup = [];
|
|
3653
3727
|
for (const [key, scriptName] of Object.entries(configShortcuts)) {
|
|
3654
|
-
|
|
3655
|
-
if (Object.keys(configShortcuts).length <= 3 || shortcuts.length < 15) {
|
|
3728
|
+
if (customGroup.length < 3) {
|
|
3656
3729
|
const script = this.allScripts.find(s => s.name === scriptName);
|
|
3657
3730
|
if (script) {
|
|
3658
3731
|
const shortDesc = script.displayName.length > 8 ? script.displayName.substring(0, 6) + '..' : script.displayName;
|
|
3659
|
-
|
|
3732
|
+
customGroup.push({ key, desc: shortDesc, color: this.processColors.get(script.name) || COLORS.text });
|
|
3660
3733
|
}
|
|
3661
3734
|
}
|
|
3662
3735
|
}
|
|
3736
|
+
if (customGroup.length > 0) {
|
|
3737
|
+
shortcutGroups.splice(1, 0, customGroup);
|
|
3738
|
+
}
|
|
3663
3739
|
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
|
|
3740
|
+
shortcutGroups.forEach((group, groupIdx) => {
|
|
3741
|
+
// Add separator between groups
|
|
3742
|
+
if (groupIdx > 0) {
|
|
3743
|
+
const sep = new TextRenderable(this.renderer, {
|
|
3744
|
+
id: `shortcut-sep-${groupIdx}`,
|
|
3745
|
+
content: t`${fg(COLORS.border)('│')}`,
|
|
3746
|
+
});
|
|
3747
|
+
rightSide.add(sep);
|
|
3748
|
+
}
|
|
3749
|
+
|
|
3750
|
+
group.forEach(({ key, desc, color }) => {
|
|
3751
|
+
const shortcut = new TextRenderable(this.renderer, {
|
|
3752
|
+
id: `shortcut-${key}`,
|
|
3753
|
+
content: t`${fg(color)(key)} ${fg(COLORS.textDim)(desc)}`,
|
|
3754
|
+
});
|
|
3755
|
+
rightSide.add(shortcut);
|
|
3668
3756
|
});
|
|
3669
|
-
rightSide.add(shortcut);
|
|
3670
3757
|
});
|
|
3671
3758
|
|
|
3672
|
-
// Title and version on far right
|
|
3759
|
+
// Title and version on far right, separated
|
|
3760
|
+
const titleSep = new TextRenderable(this.renderer, {
|
|
3761
|
+
id: 'footer-title-sep',
|
|
3762
|
+
content: t`${fg(COLORS.border)('│')}`,
|
|
3763
|
+
});
|
|
3764
|
+
rightSide.add(titleSep);
|
|
3765
|
+
|
|
3673
3766
|
const titleText = new TextRenderable(this.renderer, {
|
|
3674
3767
|
id: 'footer-title',
|
|
3675
|
-
content: t`${fg(COLORS.accent)('
|
|
3768
|
+
content: t`${fg(COLORS.accent)('startall')} ${fg(COLORS.textDim)(APP_VERSION)}`,
|
|
3676
3769
|
});
|
|
3677
3770
|
rightSide.add(titleText);
|
|
3678
3771
|
|