project-compass 2.6.0 → 2.7.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.
- package/package.json +1 -1
- package/src/cli.js +69 -16
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -142,9 +142,9 @@ function Studio() {
|
|
|
142
142
|
{flexDirection: 'column'},
|
|
143
143
|
...runtimes.map(r => create(
|
|
144
144
|
Box,
|
|
145
|
-
{key: r.name, marginBottom:
|
|
146
|
-
create(Text, {width:
|
|
147
|
-
create(Text, {dimColor: r.status !== 'ok'}, r.version)
|
|
145
|
+
{key: r.name, marginBottom: 0},
|
|
146
|
+
create(Text, {width: 20, color: r.status === 'ok' ? 'green' : 'red'}, `${r.status === 'ok' ? '✓' : '✗'} ${r.name}`),
|
|
147
|
+
create(Text, {dimColor: r.status !== 'ok'}, `: ${r.version}`)
|
|
148
148
|
)),
|
|
149
149
|
create(Text, {marginTop: 1, color: 'yellow'}, '🛠️ Interactive Project Creator coming soon in v3.0'),
|
|
150
150
|
create(Text, {dimColor: true}, 'Press Shift+A to return to Navigator.')
|
|
@@ -152,6 +152,20 @@ function Studio() {
|
|
|
152
152
|
);
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
+
function CursorText({value, cursorIndex, active = true}) {
|
|
156
|
+
const before = value.slice(0, cursorIndex);
|
|
157
|
+
const charAt = value[cursorIndex] || ' ';
|
|
158
|
+
const after = value.slice(cursorIndex + 1);
|
|
159
|
+
|
|
160
|
+
return create(
|
|
161
|
+
Text,
|
|
162
|
+
null,
|
|
163
|
+
before,
|
|
164
|
+
active ? create(Text, {backgroundColor: 'white', color: 'black'}, charAt) : charAt,
|
|
165
|
+
after
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
|
|
155
169
|
function Compass({rootPath, initialView = 'navigator'}) {
|
|
156
170
|
const {exit} = useApp();
|
|
157
171
|
const {projects, loading, error} = useScanner(rootPath);
|
|
@@ -164,10 +178,12 @@ function Compass({rootPath, initialView = 'navigator'}) {
|
|
|
164
178
|
const [lastAction, setLastAction] = useState(null);
|
|
165
179
|
const [customMode, setCustomMode] = useState(false);
|
|
166
180
|
const [customInput, setCustomInput] = useState('');
|
|
181
|
+
const [customCursor, setCustomCursor] = useState(0);
|
|
167
182
|
const [config, setConfig] = useState(() => loadConfig());
|
|
168
183
|
const [showHelpCards, setShowHelpCards] = useState(false);
|
|
169
184
|
const [showStructureGuide, setShowStructureGuide] = useState(false);
|
|
170
185
|
const [stdinBuffer, setStdinBuffer] = useState('');
|
|
186
|
+
const [stdinCursor, setStdinCursor] = useState(0);
|
|
171
187
|
const [showHelp, setShowHelp] = useState(false);
|
|
172
188
|
const [recentRuns, setRecentRuns] = useState([]);
|
|
173
189
|
const selectedProject = projects[selectedIndex] || null;
|
|
@@ -241,6 +257,7 @@ function Compass({rootPath, initialView = 'navigator'}) {
|
|
|
241
257
|
} finally {
|
|
242
258
|
setRunning(false);
|
|
243
259
|
setStdinBuffer('');
|
|
260
|
+
setStdinCursor(0);
|
|
244
261
|
runningProcessRef.current = null;
|
|
245
262
|
}
|
|
246
263
|
}, [addLog, running, selectedProject]);
|
|
@@ -276,6 +293,7 @@ function Compass({rootPath, initialView = 'navigator'}) {
|
|
|
276
293
|
addLog(kleur.gray('Canceled custom command (empty).'));
|
|
277
294
|
setCustomMode(false);
|
|
278
295
|
setCustomInput('');
|
|
296
|
+
setCustomCursor(0);
|
|
279
297
|
return;
|
|
280
298
|
}
|
|
281
299
|
const [labelPart, commandPart] = raw.split('|');
|
|
@@ -284,12 +302,14 @@ function Compass({rootPath, initialView = 'navigator'}) {
|
|
|
284
302
|
addLog(kleur.red('Custom command needs at least one token.'));
|
|
285
303
|
setCustomMode(false);
|
|
286
304
|
setCustomInput('');
|
|
305
|
+
setCustomCursor(0);
|
|
287
306
|
return;
|
|
288
307
|
}
|
|
289
308
|
const label = commandPart ? labelPart.trim() : `Custom ${selectedProject.name}`;
|
|
290
309
|
handleAddCustomCommand(label || 'Custom', commandTokens);
|
|
291
310
|
setCustomMode(false);
|
|
292
311
|
setCustomInput('');
|
|
312
|
+
setCustomCursor(0);
|
|
293
313
|
}, [customInput, selectedProject, handleAddCustomCommand, addLog]);
|
|
294
314
|
|
|
295
315
|
const exportLogs = useCallback(() => {
|
|
@@ -314,14 +334,27 @@ function Compass({rootPath, initialView = 'navigator'}) {
|
|
|
314
334
|
if (key.escape) {
|
|
315
335
|
setCustomMode(false);
|
|
316
336
|
setCustomInput('');
|
|
337
|
+
setCustomCursor(0);
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
if (key.backspace || key.delete) {
|
|
341
|
+
if (customCursor > 0) {
|
|
342
|
+
setCustomInput((prev) => prev.slice(0, customCursor - 1) + prev.slice(customCursor));
|
|
343
|
+
setCustomCursor(c => Math.max(0, c - 1));
|
|
344
|
+
}
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
if (key.leftArrow) {
|
|
348
|
+
setCustomCursor(c => Math.max(0, c - 1));
|
|
317
349
|
return;
|
|
318
350
|
}
|
|
319
|
-
if (key.
|
|
320
|
-
|
|
351
|
+
if (key.rightArrow) {
|
|
352
|
+
setCustomCursor(c => Math.min(customInput.length, c + 1));
|
|
321
353
|
return;
|
|
322
354
|
}
|
|
323
355
|
if (input) {
|
|
324
|
-
setCustomInput((prev) => prev + input);
|
|
356
|
+
setCustomInput((prev) => prev.slice(0, customCursor) + input + prev.slice(customCursor));
|
|
357
|
+
setCustomCursor(c => c + input.length);
|
|
325
358
|
}
|
|
326
359
|
return;
|
|
327
360
|
}
|
|
@@ -363,31 +396,43 @@ function Compass({rootPath, initialView = 'navigator'}) {
|
|
|
363
396
|
if (key.ctrl && input === 'c') {
|
|
364
397
|
runningProcessRef.current.kill('SIGINT');
|
|
365
398
|
setStdinBuffer('');
|
|
399
|
+
setStdinCursor(0);
|
|
366
400
|
return;
|
|
367
401
|
}
|
|
368
402
|
if (key.return) {
|
|
369
|
-
runningProcessRef.current.stdin?.write('\n');
|
|
403
|
+
runningProcessRef.current.stdin?.write(stdinBuffer + '\n');
|
|
370
404
|
setStdinBuffer('');
|
|
405
|
+
setStdinCursor(0);
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
if (key.backspace || key.delete) {
|
|
409
|
+
if (stdinCursor > 0) {
|
|
410
|
+
setStdinBuffer(prev => prev.slice(0, stdinCursor - 1) + prev.slice(stdinCursor));
|
|
411
|
+
setStdinCursor(c => Math.max(0, c - 1));
|
|
412
|
+
}
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
if (key.leftArrow) {
|
|
416
|
+
setStdinCursor(c => Math.max(0, c - 1));
|
|
371
417
|
return;
|
|
372
418
|
}
|
|
373
|
-
if (key.
|
|
374
|
-
|
|
375
|
-
setStdinBuffer((prev) => prev.slice(0, -1));
|
|
419
|
+
if (key.rightArrow) {
|
|
420
|
+
setStdinCursor(c => Math.min(stdinBuffer.length, c + 1));
|
|
376
421
|
return;
|
|
377
422
|
}
|
|
378
423
|
if (input) {
|
|
379
|
-
|
|
380
|
-
|
|
424
|
+
setStdinBuffer(prev => prev.slice(0, stdinCursor) + input + prev.slice(stdinCursor));
|
|
425
|
+
setStdinCursor(c => c + input.length);
|
|
381
426
|
}
|
|
382
427
|
return;
|
|
383
428
|
}
|
|
384
429
|
|
|
385
430
|
if (key.shift && key.upArrow) {
|
|
386
|
-
scrollLogs(1);
|
|
431
|
+
scrollLogs(-1);
|
|
387
432
|
return;
|
|
388
433
|
}
|
|
389
434
|
if (key.shift && key.downArrow) {
|
|
390
|
-
scrollLogs(
|
|
435
|
+
scrollLogs(1);
|
|
391
436
|
return;
|
|
392
437
|
}
|
|
393
438
|
|
|
@@ -422,6 +467,7 @@ function Compass({rootPath, initialView = 'navigator'}) {
|
|
|
422
467
|
if (shiftCombo('c') && viewMode === 'detail' && selectedProject) {
|
|
423
468
|
setCustomMode(true);
|
|
424
469
|
setCustomInput('');
|
|
470
|
+
setCustomCursor(0);
|
|
425
471
|
return;
|
|
426
472
|
}
|
|
427
473
|
const actionKey = normalizedInput && ACTION_MAP[normalizedInput];
|
|
@@ -529,7 +575,14 @@ function Compass({rootPath, initialView = 'navigator'}) {
|
|
|
529
575
|
}
|
|
530
576
|
|
|
531
577
|
if (customMode) {
|
|
532
|
-
detailContent.push(
|
|
578
|
+
detailContent.push(
|
|
579
|
+
create(
|
|
580
|
+
Box,
|
|
581
|
+
{key: 'custom-input-box', flexDirection: 'row'},
|
|
582
|
+
create(Text, {color: 'cyan'}, 'Type label|cmd (Enter: save, Esc: cancel): '),
|
|
583
|
+
create(CursorText, {value: customInput, cursorIndex: customCursor})
|
|
584
|
+
)
|
|
585
|
+
);
|
|
533
586
|
}
|
|
534
587
|
|
|
535
588
|
const artTileNodes = useMemo(() => {
|
|
@@ -818,7 +871,7 @@ function Compass({rootPath, initialView = 'navigator'}) {
|
|
|
818
871
|
paddingX: 1
|
|
819
872
|
},
|
|
820
873
|
create(Text, {bold: true, color: running ? 'green' : 'white'}, running ? ' Stdin buffer ' : ' Input ready '),
|
|
821
|
-
create(
|
|
874
|
+
create(Box, {marginLeft: 1}, create(CursorText, {value: stdinBuffer || (running ? '' : 'Start a command to feed stdin'), cursorIndex: stdinCursor, active: running}))
|
|
822
875
|
)
|
|
823
876
|
),
|
|
824
877
|
helpSection,
|