project-compass 2.9.0 → 2.9.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/cli.js +22 -13
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "project-compass",
3
- "version": "2.9.0",
3
+ "version": "2.9.1",
4
4
  "description": "Ink-based project explorer that detects local repos and lets you build/test/run them without memorizing commands.",
5
5
  "main": "src/cli.js",
6
6
  "type": "module",
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,15 @@ function loadConfig() {
38
37
  const payload = fs.readFileSync(CONFIG_PATH, 'utf-8');
39
38
  const parsed = JSON.parse(payload || '{}');
40
39
  return {
41
- ...DEFAULT_CONFIG,
40
+ customCommands: {},
41
+ showArtBoard: true,
42
42
  ...parsed,
43
- customCommands: {
44
- ...DEFAULT_CONFIG.customCommands,
45
- ...(parsed.customCommands || {})
46
- }
47
43
  };
48
44
  }
49
45
  } catch (error) {
50
46
  console.error(`Ignoring corrupt config: ${error.message}`);
51
47
  }
52
- return {...DEFAULT_CONFIG};
48
+ return {customCommands: {}, showArtBoard: true};
53
49
  }
54
50
 
55
51
  function useScanner(rootPath) {
@@ -179,7 +175,6 @@ function Compass({rootPath, initialView = 'navigator'}) {
179
175
  const [renameInput, setRenameInput] = useState('');
180
176
  const [renameCursor, setRenameCursor] = useState(0);
181
177
  const [quitConfirm, setQuitConfirm] = useState(false);
182
- const [showArtBoard, setShowArtBoard] = useState(true);
183
178
  const [config, setConfig] = useState(() => loadConfig());
184
179
  const [showHelpCards, setShowHelpCards] = useState(false);
185
180
  const [showStructureGuide, setShowStructureGuide] = 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
 
@@ -358,7 +360,14 @@ function Compass({rootPath, initialView = 'navigator'}) {
358
360
  if (shiftCombo('x')) { setTasks(prev => prev.map(t => t.id === activeTaskId ? {...t, logs: []} : t)); setLogOffset(0); return; }
359
361
  if (shiftCombo('e')) { exportLogs(); return; }
360
362
  if (shiftCombo('d')) { setActiveTaskId(null); return; }
361
- if (shiftCombo('b')) { setShowArtBoard(prev => !prev); return; }
363
+ if (shiftCombo('b')) {
364
+ setConfig(prev => {
365
+ const next = {...prev, showArtBoard: !prev.showArtBoard};
366
+ saveConfig(next);
367
+ return next;
368
+ });
369
+ return;
370
+ }
362
371
 
363
372
  if (shiftCombo('t')) {
364
373
  setMainView((prev) => {
@@ -537,7 +546,7 @@ function Compass({rootPath, initialView = 'navigator'}) {
537
546
  create(Text, {dimColor: true}, tile.subtext)
538
547
  ));
539
548
 
540
- const artBoard = showArtBoard ? create(Box, {flexDirection: 'column', marginTop: 1, borderStyle: 'round', borderColor: 'gray', padding: 1},
549
+ const artBoard = config.showArtBoard ? create(Box, {flexDirection: 'column', marginTop: 1, borderStyle: 'round', borderColor: 'gray', padding: 1},
541
550
  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
551
  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
552
  create(Box, {flexDirection: 'row', marginTop: 1}, ...artTileNodes)