project-compass 2.6.0 → 2.7.0
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 +71 -11
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -152,6 +152,27 @@ function Studio() {
|
|
|
152
152
|
);
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
+
function CursorText({value, cursorIndex, active = true}) {
|
|
156
|
+
const [visible, setVisible] = useState(true);
|
|
157
|
+
useEffect(() => {
|
|
158
|
+
if (!active) return;
|
|
159
|
+
const interval = setInterval(() => setVisible(v => !v), 500);
|
|
160
|
+
return () => clearInterval(interval);
|
|
161
|
+
}, [active]);
|
|
162
|
+
|
|
163
|
+
const before = value.slice(0, cursorIndex);
|
|
164
|
+
const charAt = value[cursorIndex] || ' ';
|
|
165
|
+
const after = value.slice(cursorIndex + 1);
|
|
166
|
+
|
|
167
|
+
return create(
|
|
168
|
+
Text,
|
|
169
|
+
null,
|
|
170
|
+
before,
|
|
171
|
+
active && visible ? create(Text, {backgroundColor: 'white', color: 'black'}, charAt) : charAt,
|
|
172
|
+
after
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
|
|
155
176
|
function Compass({rootPath, initialView = 'navigator'}) {
|
|
156
177
|
const {exit} = useApp();
|
|
157
178
|
const {projects, loading, error} = useScanner(rootPath);
|
|
@@ -164,10 +185,12 @@ function Compass({rootPath, initialView = 'navigator'}) {
|
|
|
164
185
|
const [lastAction, setLastAction] = useState(null);
|
|
165
186
|
const [customMode, setCustomMode] = useState(false);
|
|
166
187
|
const [customInput, setCustomInput] = useState('');
|
|
188
|
+
const [customCursor, setCustomCursor] = useState(0);
|
|
167
189
|
const [config, setConfig] = useState(() => loadConfig());
|
|
168
190
|
const [showHelpCards, setShowHelpCards] = useState(false);
|
|
169
191
|
const [showStructureGuide, setShowStructureGuide] = useState(false);
|
|
170
192
|
const [stdinBuffer, setStdinBuffer] = useState('');
|
|
193
|
+
const [stdinCursor, setStdinCursor] = useState(0);
|
|
171
194
|
const [showHelp, setShowHelp] = useState(false);
|
|
172
195
|
const [recentRuns, setRecentRuns] = useState([]);
|
|
173
196
|
const selectedProject = projects[selectedIndex] || null;
|
|
@@ -241,6 +264,7 @@ function Compass({rootPath, initialView = 'navigator'}) {
|
|
|
241
264
|
} finally {
|
|
242
265
|
setRunning(false);
|
|
243
266
|
setStdinBuffer('');
|
|
267
|
+
setStdinCursor(0);
|
|
244
268
|
runningProcessRef.current = null;
|
|
245
269
|
}
|
|
246
270
|
}, [addLog, running, selectedProject]);
|
|
@@ -276,6 +300,7 @@ function Compass({rootPath, initialView = 'navigator'}) {
|
|
|
276
300
|
addLog(kleur.gray('Canceled custom command (empty).'));
|
|
277
301
|
setCustomMode(false);
|
|
278
302
|
setCustomInput('');
|
|
303
|
+
setCustomCursor(0);
|
|
279
304
|
return;
|
|
280
305
|
}
|
|
281
306
|
const [labelPart, commandPart] = raw.split('|');
|
|
@@ -284,12 +309,14 @@ function Compass({rootPath, initialView = 'navigator'}) {
|
|
|
284
309
|
addLog(kleur.red('Custom command needs at least one token.'));
|
|
285
310
|
setCustomMode(false);
|
|
286
311
|
setCustomInput('');
|
|
312
|
+
setCustomCursor(0);
|
|
287
313
|
return;
|
|
288
314
|
}
|
|
289
315
|
const label = commandPart ? labelPart.trim() : `Custom ${selectedProject.name}`;
|
|
290
316
|
handleAddCustomCommand(label || 'Custom', commandTokens);
|
|
291
317
|
setCustomMode(false);
|
|
292
318
|
setCustomInput('');
|
|
319
|
+
setCustomCursor(0);
|
|
293
320
|
}, [customInput, selectedProject, handleAddCustomCommand, addLog]);
|
|
294
321
|
|
|
295
322
|
const exportLogs = useCallback(() => {
|
|
@@ -314,14 +341,27 @@ function Compass({rootPath, initialView = 'navigator'}) {
|
|
|
314
341
|
if (key.escape) {
|
|
315
342
|
setCustomMode(false);
|
|
316
343
|
setCustomInput('');
|
|
344
|
+
setCustomCursor(0);
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
if (key.backspace || key.delete) {
|
|
348
|
+
if (customCursor > 0) {
|
|
349
|
+
setCustomInput((prev) => prev.slice(0, customCursor - 1) + prev.slice(customCursor));
|
|
350
|
+
setCustomCursor(c => Math.max(0, c - 1));
|
|
351
|
+
}
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
if (key.leftArrow) {
|
|
355
|
+
setCustomCursor(c => Math.max(0, c - 1));
|
|
317
356
|
return;
|
|
318
357
|
}
|
|
319
|
-
if (key.
|
|
320
|
-
|
|
358
|
+
if (key.rightArrow) {
|
|
359
|
+
setCustomCursor(c => Math.min(customInput.length, c + 1));
|
|
321
360
|
return;
|
|
322
361
|
}
|
|
323
362
|
if (input) {
|
|
324
|
-
setCustomInput((prev) => prev + input);
|
|
363
|
+
setCustomInput((prev) => prev.slice(0, customCursor) + input + prev.slice(customCursor));
|
|
364
|
+
setCustomCursor(c => c + input.length);
|
|
325
365
|
}
|
|
326
366
|
return;
|
|
327
367
|
}
|
|
@@ -363,21 +403,33 @@ function Compass({rootPath, initialView = 'navigator'}) {
|
|
|
363
403
|
if (key.ctrl && input === 'c') {
|
|
364
404
|
runningProcessRef.current.kill('SIGINT');
|
|
365
405
|
setStdinBuffer('');
|
|
406
|
+
setStdinCursor(0);
|
|
366
407
|
return;
|
|
367
408
|
}
|
|
368
409
|
if (key.return) {
|
|
369
|
-
runningProcessRef.current.stdin?.write('\n');
|
|
410
|
+
runningProcessRef.current.stdin?.write(stdinBuffer + '\n');
|
|
370
411
|
setStdinBuffer('');
|
|
412
|
+
setStdinCursor(0);
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
if (key.backspace || key.delete) {
|
|
416
|
+
if (stdinCursor > 0) {
|
|
417
|
+
setStdinBuffer(prev => prev.slice(0, stdinCursor - 1) + prev.slice(stdinCursor));
|
|
418
|
+
setStdinCursor(c => Math.max(0, c - 1));
|
|
419
|
+
}
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
if (key.leftArrow) {
|
|
423
|
+
setStdinCursor(c => Math.max(0, c - 1));
|
|
371
424
|
return;
|
|
372
425
|
}
|
|
373
|
-
if (key.
|
|
374
|
-
|
|
375
|
-
setStdinBuffer((prev) => prev.slice(0, -1));
|
|
426
|
+
if (key.rightArrow) {
|
|
427
|
+
setStdinCursor(c => Math.min(stdinBuffer.length, c + 1));
|
|
376
428
|
return;
|
|
377
429
|
}
|
|
378
430
|
if (input) {
|
|
379
|
-
|
|
380
|
-
|
|
431
|
+
setStdinBuffer(prev => prev.slice(0, stdinCursor) + input + prev.slice(stdinCursor));
|
|
432
|
+
setStdinCursor(c => c + input.length);
|
|
381
433
|
}
|
|
382
434
|
return;
|
|
383
435
|
}
|
|
@@ -422,6 +474,7 @@ function Compass({rootPath, initialView = 'navigator'}) {
|
|
|
422
474
|
if (shiftCombo('c') && viewMode === 'detail' && selectedProject) {
|
|
423
475
|
setCustomMode(true);
|
|
424
476
|
setCustomInput('');
|
|
477
|
+
setCustomCursor(0);
|
|
425
478
|
return;
|
|
426
479
|
}
|
|
427
480
|
const actionKey = normalizedInput && ACTION_MAP[normalizedInput];
|
|
@@ -529,7 +582,14 @@ function Compass({rootPath, initialView = 'navigator'}) {
|
|
|
529
582
|
}
|
|
530
583
|
|
|
531
584
|
if (customMode) {
|
|
532
|
-
detailContent.push(
|
|
585
|
+
detailContent.push(
|
|
586
|
+
create(
|
|
587
|
+
Box,
|
|
588
|
+
{key: 'custom-input-box', flexDirection: 'row'},
|
|
589
|
+
create(Text, {color: 'cyan'}, 'Type label|cmd (Enter: save, Esc: cancel): '),
|
|
590
|
+
create(CursorText, {value: customInput, cursorIndex: customCursor})
|
|
591
|
+
)
|
|
592
|
+
);
|
|
533
593
|
}
|
|
534
594
|
|
|
535
595
|
const artTileNodes = useMemo(() => {
|
|
@@ -818,7 +878,7 @@ function Compass({rootPath, initialView = 'navigator'}) {
|
|
|
818
878
|
paddingX: 1
|
|
819
879
|
},
|
|
820
880
|
create(Text, {bold: true, color: running ? 'green' : 'white'}, running ? ' Stdin buffer ' : ' Input ready '),
|
|
821
|
-
create(
|
|
881
|
+
create(Box, {marginLeft: 1}, create(CursorText, {value: stdinBuffer || (running ? '' : 'Start a command to feed stdin'), cursorIndex: stdinCursor, active: running}))
|
|
822
882
|
)
|
|
823
883
|
),
|
|
824
884
|
helpSection,
|