project-compass 2.9.0 → 2.9.2
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/package.json +1 -1
- package/src/cli.js +46 -21
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -9,7 +9,6 @@ import {discoverProjects, SCHEMA_GUIDE, checkBinary} from './projectDetection.js
|
|
|
9
9
|
import {CONFIG_PATH, ensureConfigDir} from './configPaths.js';
|
|
10
10
|
|
|
11
11
|
const create = React.createElement;
|
|
12
|
-
const DEFAULT_CONFIG = {customCommands: {}};
|
|
13
12
|
const ART_CHARS = ['▁', '▃', '▄', '▅', '▇'];
|
|
14
13
|
const ART_COLORS = ['magenta', 'blue', 'cyan', 'yellow', 'red'];
|
|
15
14
|
const OUTPUT_WINDOW_SIZE = 8;
|
|
@@ -38,18 +37,17 @@ function loadConfig() {
|
|
|
38
37
|
const payload = fs.readFileSync(CONFIG_PATH, 'utf-8');
|
|
39
38
|
const parsed = JSON.parse(payload || '{}');
|
|
40
39
|
return {
|
|
41
|
-
|
|
40
|
+
customCommands: {},
|
|
41
|
+
showArtBoard: true,
|
|
42
|
+
showHelpCards: false,
|
|
43
|
+
showStructureGuide: false,
|
|
42
44
|
...parsed,
|
|
43
|
-
customCommands: {
|
|
44
|
-
...DEFAULT_CONFIG.customCommands,
|
|
45
|
-
...(parsed.customCommands || {})
|
|
46
|
-
}
|
|
47
45
|
};
|
|
48
46
|
}
|
|
49
47
|
} catch (error) {
|
|
50
48
|
console.error(`Ignoring corrupt config: ${error.message}`);
|
|
51
49
|
}
|
|
52
|
-
return {
|
|
50
|
+
return {customCommands: {}, showArtBoard: true, showHelpCards: false, showStructureGuide: false};
|
|
53
51
|
}
|
|
54
52
|
|
|
55
53
|
function useScanner(rootPath) {
|
|
@@ -179,10 +177,7 @@ function Compass({rootPath, initialView = 'navigator'}) {
|
|
|
179
177
|
const [renameInput, setRenameInput] = useState('');
|
|
180
178
|
const [renameCursor, setRenameCursor] = useState(0);
|
|
181
179
|
const [quitConfirm, setQuitConfirm] = useState(false);
|
|
182
|
-
const [showArtBoard, setShowArtBoard] = useState(true);
|
|
183
180
|
const [config, setConfig] = useState(() => loadConfig());
|
|
184
|
-
const [showHelpCards, setShowHelpCards] = useState(false);
|
|
185
|
-
const [showStructureGuide, setShowStructureGuide] = useState(false);
|
|
186
181
|
const [stdinBuffer, setStdinBuffer] = useState('');
|
|
187
182
|
const [stdinCursor, setStdinCursor] = useState(0);
|
|
188
183
|
const [showHelp, setShowHelp] = useState(false);
|
|
@@ -215,6 +210,13 @@ function Compass({rootPath, initialView = 'navigator'}) {
|
|
|
215
210
|
return map;
|
|
216
211
|
}, [detailedIndexed]);
|
|
217
212
|
|
|
213
|
+
const killAllTasks = useCallback(() => {
|
|
214
|
+
runningProcessMap.current.forEach((proc) => {
|
|
215
|
+
try { proc.kill('SIGINT'); } catch { /* ignore */ }
|
|
216
|
+
});
|
|
217
|
+
runningProcessMap.current.clear();
|
|
218
|
+
}, []);
|
|
219
|
+
|
|
218
220
|
const runProjectCommand = useCallback(async (commandMeta, targetProject = selectedProject) => {
|
|
219
221
|
const project = targetProject || selectedProject;
|
|
220
222
|
if (!project) return;
|
|
@@ -249,7 +251,7 @@ function Compass({rootPath, initialView = 'navigator'}) {
|
|
|
249
251
|
setTasks(prev => prev.map(t => t.id === taskId ? {...t, status: 'finished'} : t));
|
|
250
252
|
addLogToTask(taskId, kleur.green(`✓ ${commandLabel} finished`));
|
|
251
253
|
} catch (error) {
|
|
252
|
-
if (error.isCanceled) {
|
|
254
|
+
if (error.isCanceled || error.killed) {
|
|
253
255
|
setTasks(prev => prev.map(t => t.id === taskId ? {...t, status: 'killed'} : t));
|
|
254
256
|
addLogToTask(taskId, kleur.yellow(`! Task killed by user`));
|
|
255
257
|
} else {
|
|
@@ -284,8 +286,8 @@ function Compass({rootPath, initialView = 'navigator'}) {
|
|
|
284
286
|
|
|
285
287
|
useInput((input, key) => {
|
|
286
288
|
if (quitConfirm) {
|
|
287
|
-
if (input?.toLowerCase() === 'y') exit();
|
|
288
|
-
if (input?.toLowerCase() === 'n' || key.escape) setQuitConfirm(false);
|
|
289
|
+
if (input?.toLowerCase() === 'y') { killAllTasks(); exit(); return; }
|
|
290
|
+
if (input?.toLowerCase() === 'n' || key.escape) { setQuitConfirm(false); return; }
|
|
289
291
|
return;
|
|
290
292
|
}
|
|
291
293
|
|
|
@@ -352,13 +354,34 @@ function Compass({rootPath, initialView = 'navigator'}) {
|
|
|
352
354
|
const normalizedInput = input?.toLowerCase();
|
|
353
355
|
const shiftCombo = (char) => key.shift && normalizedInput === char;
|
|
354
356
|
|
|
355
|
-
if (shiftCombo('h')) {
|
|
356
|
-
|
|
357
|
+
if (shiftCombo('h')) {
|
|
358
|
+
setConfig(prev => {
|
|
359
|
+
const next = {...prev, showHelpCards: !prev.showHelpCards};
|
|
360
|
+
saveConfig(next);
|
|
361
|
+
return next;
|
|
362
|
+
});
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
if (shiftCombo('s')) {
|
|
366
|
+
setConfig(prev => {
|
|
367
|
+
const next = {...prev, showStructureGuide: !prev.showStructureGuide};
|
|
368
|
+
saveConfig(next);
|
|
369
|
+
return next;
|
|
370
|
+
});
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
357
373
|
if (shiftCombo('a')) { setMainView((prev) => (prev === 'navigator' ? 'studio' : 'navigator')); return; }
|
|
358
374
|
if (shiftCombo('x')) { setTasks(prev => prev.map(t => t.id === activeTaskId ? {...t, logs: []} : t)); setLogOffset(0); return; }
|
|
359
375
|
if (shiftCombo('e')) { exportLogs(); return; }
|
|
360
376
|
if (shiftCombo('d')) { setActiveTaskId(null); return; }
|
|
361
|
-
if (shiftCombo('b')) {
|
|
377
|
+
if (shiftCombo('b')) {
|
|
378
|
+
setConfig(prev => {
|
|
379
|
+
const next = {...prev, showArtBoard: !prev.showArtBoard};
|
|
380
|
+
saveConfig(next);
|
|
381
|
+
return next;
|
|
382
|
+
});
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
362
385
|
|
|
363
386
|
if (shiftCombo('t')) {
|
|
364
387
|
setMainView((prev) => {
|
|
@@ -537,7 +560,7 @@ function Compass({rootPath, initialView = 'navigator'}) {
|
|
|
537
560
|
create(Text, {dimColor: true}, tile.subtext)
|
|
538
561
|
));
|
|
539
562
|
|
|
540
|
-
const artBoard = showArtBoard ? create(Box, {flexDirection: 'column', marginTop: 1, borderStyle: 'round', borderColor: 'gray', padding: 1},
|
|
563
|
+
const artBoard = config.showArtBoard ? create(Box, {flexDirection: 'column', marginTop: 1, borderStyle: 'round', borderColor: 'gray', padding: 1},
|
|
541
564
|
create(Box, {flexDirection: 'row', justifyContent: 'space-between'}, create(Text, {color: 'magenta', bold: true}, 'Art-coded build atlas'), create(Text, {dimColor: true}, 'press ? for overlay help')),
|
|
542
565
|
create(Box, {flexDirection: 'row', marginTop: 1}, ...ART_CHARS.map((char, i) => create(Text, {key: i, color: ART_COLORS[i % ART_COLORS.length]}, char.repeat(2)))),
|
|
543
566
|
create(Box, {flexDirection: 'row', marginTop: 1}, ...artTileNodes)
|
|
@@ -552,10 +575,10 @@ function Compass({rootPath, initialView = 'navigator'}) {
|
|
|
552
575
|
const helpCards = [
|
|
553
576
|
{label: 'Navigation', color: 'magenta', body: ['↑ / ↓ move focus, Enter: details', 'Shift+↑ / ↓ scroll output', 'Shift+H toggle help cards', 'Shift+D detach from task']},
|
|
554
577
|
{label: 'Commands', color: 'cyan', body: ['B / T / R build/test/run', '1-9 run detail commands', 'Shift+L rerun last command', 'Shift+X clear / Shift+E export']},
|
|
555
|
-
{label: 'Orbit & Studio', color: 'yellow', body: ['Shift+T task manager', 'Shift+A studio / Shift+B art', 'Shift+
|
|
578
|
+
{label: 'Orbit & Studio', color: 'yellow', body: ['Shift+T task manager', 'Shift+A studio / Shift+B art board', 'Shift+S structure / Shift+Q quit']}
|
|
556
579
|
];
|
|
557
580
|
|
|
558
|
-
const toggleHint = showHelpCards ? 'Shift+H hide help' : 'Shift+H show help';
|
|
581
|
+
const toggleHint = config.showHelpCards ? 'Shift+H hide help' : 'Shift+H show help';
|
|
559
582
|
return create(Box, {flexDirection: 'column', padding: 1},
|
|
560
583
|
create(Box, {justifyContent: 'space-between'},
|
|
561
584
|
create(Box, {flexDirection: 'column'}, create(Text, {color: 'magenta', bold: true}, 'Project Compass'), create(Text, {dimColor: true}, `${projectCountLabel} detected in ${rootPath}`)),
|
|
@@ -572,8 +595,8 @@ function Compass({rootPath, initialView = 'navigator'}) {
|
|
|
572
595
|
create(Box, {marginTop: 1, flexDirection: 'row', justifyContent: 'space-between'}, create(Text, {dimColor: true}, running ? 'Type to feed stdin; Enter: submit, Ctrl+C: abort.' : 'Run a command or press Shift+T to switch tasks.'), create(Text, {dimColor: true}, `${toggleHint}, Shift+S: Structure Guide`)),
|
|
573
596
|
create(Box, {marginTop: 1, flexDirection: 'row', borderStyle: 'round', borderColor: running ? 'green' : 'gray', paddingX: 1}, create(Text, {bold: true, color: running ? 'green' : 'white'}, running ? ' Stdin buffer ' : ' Input ready '), create(Box, {marginLeft: 1}, create(CursorText, {value: stdinBuffer || (running ? '' : 'Start a command to feed stdin'), cursorIndex: stdinCursor, active: running})))
|
|
574
597
|
),
|
|
575
|
-
showHelpCards && create(Box, {marginTop: 1, flexDirection: 'row', justifyContent: 'space-between', flexWrap: 'wrap'}, ...helpCards.map((card, idx) => create(Box, {key: card.label, flexGrow: 1, flexBasis: 0, minWidth: HELP_CARD_MIN_WIDTH, marginRight: idx < 2 ? 1 : 0, marginBottom: 1, borderStyle: 'round', borderColor: card.color, padding: 1, flexDirection: 'column'}, create(Text, {color: card.color, bold: true, marginBottom: 1}, card.label), ...card.body.map((line, lidx) => create(Text, {key: lidx, dimColor: card.color === 'yellow'}, line))))),
|
|
576
|
-
showStructureGuide && create(Box, {flexDirection: 'column', borderStyle: 'round', borderColor: 'blue', marginTop: 1, padding: 1}, create(Text, {color: 'cyan', bold: true}, 'Structure guide · press Shift+S to hide'), ...SCHEMA_GUIDE.map(e => create(Text, {key: e.type, dimColor: true}, `• ${e.icon} ${e.label}: ${e.files.join(', ')}`))),
|
|
598
|
+
config.showHelpCards && create(Box, {marginTop: 1, flexDirection: 'row', justifyContent: 'space-between', flexWrap: 'wrap'}, ...helpCards.map((card, idx) => create(Box, {key: card.label, flexGrow: 1, flexBasis: 0, minWidth: HELP_CARD_MIN_WIDTH, marginRight: idx < 2 ? 1 : 0, marginBottom: 1, borderStyle: 'round', borderColor: card.color, padding: 1, flexDirection: 'column'}, create(Text, {color: card.color, bold: true, marginBottom: 1}, card.label), ...card.body.map((line, lidx) => create(Text, {key: lidx, dimColor: card.color === 'yellow'}, line))))),
|
|
599
|
+
config.showStructureGuide && create(Box, {flexDirection: 'column', borderStyle: 'round', borderColor: 'blue', marginTop: 1, padding: 1}, create(Text, {color: 'cyan', bold: true}, 'Structure guide · press Shift+S to hide'), ...SCHEMA_GUIDE.map(e => create(Text, {key: e.type, dimColor: true}, `• ${e.icon} ${e.label}: ${e.files.join(', ')}`))),
|
|
577
600
|
showHelp && create(Box, {flexDirection: 'column', borderStyle: 'double', borderColor: 'cyan', marginTop: 1, padding: 1}, create(Text, {color: 'cyan', bold: true}, 'Help overlay'), create(Text, null, 'Shift+↑/↓ scrolls logs; Shift+X clears; Shift+E exports; Shift+A Studio; Shift+T Tasks; Shift+D Detach; Shift+B Toggle Art.'))
|
|
578
601
|
);
|
|
579
602
|
}
|
|
@@ -612,6 +635,8 @@ async function main() {
|
|
|
612
635
|
console.log(' Shift+T Open Orbit Task Manager (Manage background processes)');
|
|
613
636
|
console.log(' Shift+D Detach from active task (Keep it running in background)');
|
|
614
637
|
console.log(' Shift+B Toggle Art Board visibility');
|
|
638
|
+
console.log(' Shift+H Toggle Help Cards visibility');
|
|
639
|
+
console.log(' Shift+S Toggle Structure Guide visibility');
|
|
615
640
|
console.log(' Shift+X Clear active task output log');
|
|
616
641
|
console.log(' Shift+E Export current logs to a .txt file');
|
|
617
642
|
console.log(' Shift+↑ / ↓ Scroll the output logs');
|