@sascha384/tic 5.0.0 → 5.2.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/.claude-plugin/plugin.json +1 -1
- package/dist/app.js +4 -1
- package/dist/app.js.map +1 -1
- package/dist/commands.d.ts +23 -1
- package/dist/commands.js +636 -16
- package/dist/commands.js.map +1 -1
- package/dist/components/BranchList.js +21 -20
- package/dist/components/BranchList.js.map +1 -1
- package/dist/components/Header.js +6 -2
- package/dist/components/Header.js.map +1 -1
- package/dist/components/HelpScreen.d.ts +1 -9
- package/dist/components/HelpScreen.js +32 -228
- package/dist/components/HelpScreen.js.map +1 -1
- package/dist/components/IterationPicker.js +3 -2
- package/dist/components/IterationPicker.js.map +1 -1
- package/dist/components/MarkdownEditor.d.ts +1 -0
- package/dist/components/MarkdownEditor.js +173 -0
- package/dist/components/MarkdownEditor.js.map +1 -0
- package/dist/components/PullRequestList.js +14 -13
- package/dist/components/PullRequestList.js.map +1 -1
- package/dist/components/Settings.js +31 -26
- package/dist/components/Settings.js.map +1 -1
- package/dist/components/StatusScreen.js +19 -15
- package/dist/components/StatusScreen.js.map +1 -1
- package/dist/components/WorkItemForm.js +26 -35
- package/dist/components/WorkItemForm.js.map +1 -1
- package/dist/components/WorkItemList.d.ts +0 -1
- package/dist/components/WorkItemList.js +84 -100
- package/dist/components/WorkItemList.js.map +1 -1
- package/dist/components/markdownHighlight.d.ts +20 -0
- package/dist/components/markdownHighlight.js +195 -0
- package/dist/components/markdownHighlight.js.map +1 -0
- package/dist/storage/index.js +14 -11
- package/dist/storage/index.js.map +1 -1
- package/dist/stores/backendDataStore.d.ts +1 -0
- package/dist/stores/backendDataStore.js +1 -0
- package/dist/stores/backendDataStore.js.map +1 -1
- package/dist/stores/editorStore.d.ts +53 -0
- package/dist/stores/editorStore.js +513 -0
- package/dist/stores/editorStore.js.map +1 -0
- package/dist/stores/navigationStore.d.ts +1 -1
- package/dist/stores/navigationStore.js +1 -1
- package/dist/stores/navigationStore.js.map +1 -1
- package/package.json +1 -1
|
@@ -15,7 +15,7 @@ import { useScrollViewport } from '../hooks/useScrollViewport.js';
|
|
|
15
15
|
import { useBackendDataStore, backendDataStore, } from '../stores/backendDataStore.js';
|
|
16
16
|
import { useShallow } from 'zustand/shallow';
|
|
17
17
|
import { buildTree, sortTree } from './buildTree.js';
|
|
18
|
-
import { getVisibleCommands, } from '../commands.js';
|
|
18
|
+
import { getVisibleCommands, buildFooterHints, matchesCommand, } from '../commands.js';
|
|
19
19
|
import { OverlayPanel } from './OverlayPanel.js';
|
|
20
20
|
import { DetailPanel } from './DetailPanel.js';
|
|
21
21
|
import { undoStore } from '../stores/undoStore.js';
|
|
@@ -127,29 +127,6 @@ export function getTargetIds(markedIds, cursorItem) {
|
|
|
127
127
|
}
|
|
128
128
|
return cursorItem ? [cursorItem.id] : [];
|
|
129
129
|
}
|
|
130
|
-
export function buildHelpText(availableWidth) {
|
|
131
|
-
const shortcuts = [
|
|
132
|
-
{ key: '↑↓', label: 'navigate' },
|
|
133
|
-
{ key: '←→', label: 'expand' },
|
|
134
|
-
{ key: 'enter', label: 'edit' },
|
|
135
|
-
{ key: 'c', label: 'create' },
|
|
136
|
-
{ key: 'd', label: 'delete' },
|
|
137
|
-
{ key: 'u', label: 'undo' },
|
|
138
|
-
{ key: '/', label: 'commands' },
|
|
139
|
-
{ key: ',', label: 'settings' },
|
|
140
|
-
{ key: '?', label: 'help' },
|
|
141
|
-
];
|
|
142
|
-
const sep = ' ';
|
|
143
|
-
let result = '';
|
|
144
|
-
for (const s of shortcuts) {
|
|
145
|
-
const entry = `${s.key} ${s.label}`;
|
|
146
|
-
const candidate = result ? result + sep + entry : entry;
|
|
147
|
-
if (candidate.length > availableWidth)
|
|
148
|
-
break;
|
|
149
|
-
result = candidate;
|
|
150
|
-
}
|
|
151
|
-
return result;
|
|
152
|
-
}
|
|
153
130
|
export function WorkItemList() {
|
|
154
131
|
const { accent, success, error: errorColor, warning: warningColor, marked, mutedDim, } = useThemeStore((s) => s.colors);
|
|
155
132
|
// Backend data store - split by change frequency for minimal re-renders
|
|
@@ -395,7 +372,8 @@ export function WorkItemList() {
|
|
|
395
372
|
const markedDistribution = useMemo(() => getMarkedDistribution(markedIds, treeItems.map((t) => t.item), viewport.start, viewport.end), [markedIds, treeItems, viewport.start, viewport.end]);
|
|
396
373
|
// Block 1.5: Description scroll handler — active when full description is shown
|
|
397
374
|
useInput((_input, key) => {
|
|
398
|
-
if (
|
|
375
|
+
if (matchesCommand('list-toggle-description', _input, key) ||
|
|
376
|
+
key.escape) {
|
|
399
377
|
setShowFullDescription(false);
|
|
400
378
|
setDescriptionScrollOffset(0);
|
|
401
379
|
return;
|
|
@@ -410,67 +388,57 @@ export function WorkItemList() {
|
|
|
410
388
|
}, { isActive: showFullDescription && activeOverlay === null });
|
|
411
389
|
// Block 3: Main input handler — only active when no overlay is open
|
|
412
390
|
useInput((input, key) => {
|
|
413
|
-
if (input
|
|
391
|
+
if (matchesCommand('list-command-bar', input, key)) {
|
|
414
392
|
openOverlay({ type: 'command-bar' });
|
|
415
393
|
return;
|
|
416
394
|
}
|
|
417
|
-
if (input
|
|
395
|
+
if (matchesCommand('help', input, key)) {
|
|
418
396
|
navigateToHelp();
|
|
419
397
|
return;
|
|
420
398
|
}
|
|
421
|
-
if (key
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
else {
|
|
433
|
-
if (rangeAnchor !== null)
|
|
434
|
-
setRangeAnchor(null);
|
|
435
|
-
setCursor(Math.max(0, cursor - 1));
|
|
436
|
-
}
|
|
399
|
+
if (matchesCommand('list-range-select', input, key)) {
|
|
400
|
+
const anchor = rangeAnchor ?? cursor;
|
|
401
|
+
if (rangeAnchor === null)
|
|
402
|
+
setRangeAnchor(cursor);
|
|
403
|
+
const newCursor = key.upArrow
|
|
404
|
+
? Math.max(0, cursor - 1)
|
|
405
|
+
: Math.min(treeItems.length - 1, cursor + 1);
|
|
406
|
+
setCursor(newCursor);
|
|
407
|
+
const start = Math.min(anchor, newCursor);
|
|
408
|
+
const end = Math.max(anchor, newCursor);
|
|
409
|
+
setMarkedIds(new Set(treeItems.slice(start, end + 1).map((t) => t.item.id)));
|
|
437
410
|
clearWarning();
|
|
438
411
|
}
|
|
439
|
-
if (key
|
|
440
|
-
if (
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
const newCursor = Math.min(treeItems.length - 1, cursor + 1);
|
|
445
|
-
setCursor(newCursor);
|
|
446
|
-
const start = Math.min(anchor, newCursor);
|
|
447
|
-
const end = Math.max(anchor, newCursor);
|
|
448
|
-
setMarkedIds(new Set(treeItems.slice(start, end + 1).map((t) => t.item.id)));
|
|
412
|
+
if (matchesCommand('list-navigate', input, key)) {
|
|
413
|
+
if (rangeAnchor !== null)
|
|
414
|
+
setRangeAnchor(null);
|
|
415
|
+
if (key.upArrow) {
|
|
416
|
+
setCursor(Math.max(0, cursor - 1));
|
|
449
417
|
}
|
|
450
418
|
else {
|
|
451
|
-
if (rangeAnchor !== null)
|
|
452
|
-
setRangeAnchor(null);
|
|
453
419
|
setCursor(Math.min(treeItems.length - 1, cursor + 1));
|
|
454
420
|
}
|
|
455
421
|
clearWarning();
|
|
456
422
|
}
|
|
457
|
-
if (key
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
}
|
|
465
|
-
if (key.home) {
|
|
466
|
-
setCursor(0);
|
|
423
|
+
if (matchesCommand('list-page', input, key)) {
|
|
424
|
+
if (key.pageUp) {
|
|
425
|
+
setCursor(Math.max(0, cursor - viewport.maxVisible));
|
|
426
|
+
}
|
|
427
|
+
else {
|
|
428
|
+
setCursor(Math.min(treeItems.length - 1, cursor + viewport.maxVisible));
|
|
429
|
+
}
|
|
467
430
|
clearWarning();
|
|
468
431
|
}
|
|
469
|
-
if (key
|
|
470
|
-
|
|
432
|
+
if (matchesCommand('list-home-end', input, key)) {
|
|
433
|
+
if (key.home) {
|
|
434
|
+
setCursor(0);
|
|
435
|
+
}
|
|
436
|
+
else {
|
|
437
|
+
setCursor(treeItems.length - 1);
|
|
438
|
+
}
|
|
471
439
|
clearWarning();
|
|
472
440
|
}
|
|
473
|
-
if (key
|
|
441
|
+
if (matchesCommand('list-expand', input, key) && treeItems.length > 0) {
|
|
474
442
|
const current = treeItems[cursor];
|
|
475
443
|
if (current &&
|
|
476
444
|
current.hasChildren &&
|
|
@@ -478,7 +446,7 @@ export function WorkItemList() {
|
|
|
478
446
|
toggleExpanded(current.item.id);
|
|
479
447
|
}
|
|
480
448
|
}
|
|
481
|
-
if (key
|
|
449
|
+
if (matchesCommand('list-collapse', input, key) && treeItems.length > 0) {
|
|
482
450
|
const current = treeItems[cursor];
|
|
483
451
|
if (current) {
|
|
484
452
|
if (current.hasChildren && !collapsedIds.has(current.item.id)) {
|
|
@@ -491,30 +459,30 @@ export function WorkItemList() {
|
|
|
491
459
|
}
|
|
492
460
|
}
|
|
493
461
|
}
|
|
494
|
-
if (key
|
|
462
|
+
if (matchesCommand('edit', input, key) && treeItems.length > 0) {
|
|
495
463
|
setFormMode('item');
|
|
496
464
|
selectWorkItem(treeItems[cursor].item.id);
|
|
497
465
|
navigate('form');
|
|
498
466
|
}
|
|
499
|
-
if (input
|
|
467
|
+
if (matchesCommand('quit', input, key))
|
|
500
468
|
exit();
|
|
501
|
-
if (input
|
|
469
|
+
if (matchesCommand('iterations', input, key) && capabilities.iterations)
|
|
502
470
|
navigate('iteration-picker');
|
|
503
|
-
if (input
|
|
471
|
+
if (matchesCommand('list-pr-list', input, key)) {
|
|
504
472
|
navigate('pr-list');
|
|
505
473
|
return;
|
|
506
474
|
}
|
|
507
|
-
if (input
|
|
475
|
+
if (matchesCommand('list-branch-manage', input, key) && gitAvailable) {
|
|
508
476
|
navigate('branch-list');
|
|
509
477
|
return;
|
|
510
478
|
}
|
|
511
|
-
if (input
|
|
479
|
+
if (matchesCommand('settings', input, key)) {
|
|
512
480
|
if (updateInfo?.updateAvailable) {
|
|
513
481
|
setSettingsInitialFocus('update-now');
|
|
514
482
|
}
|
|
515
483
|
navigate('settings');
|
|
516
484
|
}
|
|
517
|
-
if (input
|
|
485
|
+
if (matchesCommand('create', input, key)) {
|
|
518
486
|
if (capabilities.templates && templates.length > 0) {
|
|
519
487
|
openOverlay({ type: 'template-picker' });
|
|
520
488
|
}
|
|
@@ -525,13 +493,13 @@ export function WorkItemList() {
|
|
|
525
493
|
navigate('form');
|
|
526
494
|
}
|
|
527
495
|
}
|
|
528
|
-
if (input
|
|
496
|
+
if (matchesCommand('delete', input, key) && treeItems.length > 0) {
|
|
529
497
|
const targetIds = getTargetIds(markedIds, treeItems[cursor]?.item);
|
|
530
498
|
if (targetIds.length > 0) {
|
|
531
499
|
openOverlay({ type: 'delete-confirm', targetIds });
|
|
532
500
|
}
|
|
533
501
|
}
|
|
534
|
-
if (input
|
|
502
|
+
if (matchesCommand('list-undo', input, key)) {
|
|
535
503
|
const entry = undoStore.getState().popUndo();
|
|
536
504
|
if (!entry || !backend)
|
|
537
505
|
return;
|
|
@@ -581,7 +549,9 @@ export function WorkItemList() {
|
|
|
581
549
|
.setToast(err instanceof Error ? err.message : 'Undo failed');
|
|
582
550
|
});
|
|
583
551
|
}
|
|
584
|
-
if (
|
|
552
|
+
if (matchesCommand('open', input, key) &&
|
|
553
|
+
treeItems.length > 0 &&
|
|
554
|
+
backend) {
|
|
585
555
|
void (async () => {
|
|
586
556
|
const itemId = treeItems[cursor].item.id;
|
|
587
557
|
await backend.openItem(itemId);
|
|
@@ -591,7 +561,9 @@ export function WorkItemList() {
|
|
|
591
561
|
.catch(() => { });
|
|
592
562
|
})().catch(() => { });
|
|
593
563
|
}
|
|
594
|
-
if (
|
|
564
|
+
if (matchesCommand('branch', input, key) &&
|
|
565
|
+
gitAvailable &&
|
|
566
|
+
treeItems.length > 0) {
|
|
595
567
|
const item = treeItems[cursor].item;
|
|
596
568
|
const comments = item.comments;
|
|
597
569
|
try {
|
|
@@ -620,39 +592,43 @@ export function WorkItemList() {
|
|
|
620
592
|
.reloadItem(item.id)
|
|
621
593
|
.catch(() => { });
|
|
622
594
|
}
|
|
623
|
-
if (input
|
|
595
|
+
if (matchesCommand('status', input, key)) {
|
|
624
596
|
navigate('status');
|
|
625
597
|
}
|
|
626
|
-
if (input
|
|
598
|
+
if (matchesCommand('sort', input, key)) {
|
|
627
599
|
openOverlay({ type: 'sort-picker' });
|
|
628
600
|
}
|
|
629
|
-
if (input
|
|
601
|
+
if (matchesCommand('filter', input, key)) {
|
|
630
602
|
openOverlay({ type: 'filter-picker' });
|
|
631
603
|
}
|
|
632
|
-
if (input
|
|
604
|
+
if (matchesCommand('load-view', input, key)) {
|
|
633
605
|
openOverlay({ type: 'view-picker' });
|
|
634
606
|
}
|
|
635
|
-
if (input
|
|
607
|
+
if (matchesCommand('clear-filters', input, key) && filterCount > 0) {
|
|
636
608
|
filterStore.getState().clearFilters();
|
|
637
609
|
setToast('Filters cleared');
|
|
638
610
|
}
|
|
639
|
-
if (input
|
|
611
|
+
if (matchesCommand('list-status', input, key) && treeItems.length > 0) {
|
|
640
612
|
const targetIds = getTargetIds(markedIds, treeItems[cursor]?.item);
|
|
641
613
|
if (targetIds.length > 0) {
|
|
642
614
|
openOverlay({ type: 'status-picker', targetIds });
|
|
643
615
|
}
|
|
644
616
|
}
|
|
645
|
-
if (input
|
|
617
|
+
if (matchesCommand('toggle-detail-panel', input, key)) {
|
|
646
618
|
void configStore
|
|
647
619
|
.getState()
|
|
648
620
|
.update({ showDetailPanel: !showDetailPanel })
|
|
649
621
|
.catch(() => { });
|
|
650
622
|
}
|
|
651
|
-
if (
|
|
623
|
+
if (matchesCommand('list-toggle-description', input, key) &&
|
|
624
|
+
showDetailPanel &&
|
|
625
|
+
hasDescription) {
|
|
652
626
|
setShowFullDescription(true);
|
|
653
627
|
setDescriptionScrollOffset(0);
|
|
654
628
|
}
|
|
655
|
-
if (
|
|
629
|
+
if (matchesCommand('list-pr-create', input, key) &&
|
|
630
|
+
prCapabilities.create &&
|
|
631
|
+
treeItems.length > 0) {
|
|
656
632
|
const item = treeItems[cursor]?.item;
|
|
657
633
|
if (item) {
|
|
658
634
|
const cwd = process.cwd();
|
|
@@ -674,14 +650,16 @@ export function WorkItemList() {
|
|
|
674
650
|
});
|
|
675
651
|
}
|
|
676
652
|
}
|
|
677
|
-
if (
|
|
653
|
+
if (matchesCommand('list-tab', input, key) &&
|
|
654
|
+
capabilities.customTypes &&
|
|
655
|
+
types.length > 0) {
|
|
678
656
|
const currentIdx = types.indexOf(activeType ?? '');
|
|
679
657
|
const nextType = types[(currentIdx + 1) % types.length];
|
|
680
658
|
setActiveType(nextType);
|
|
681
659
|
setCursor(0);
|
|
682
660
|
clearWarning();
|
|
683
661
|
}
|
|
684
|
-
if (input
|
|
662
|
+
if (matchesCommand('sync', input, key) && syncManager) {
|
|
685
663
|
void syncManager
|
|
686
664
|
.sync()
|
|
687
665
|
.then(() => {
|
|
@@ -691,12 +669,12 @@ export function WorkItemList() {
|
|
|
691
669
|
// Errors recorded in syncStatus by SyncManager
|
|
692
670
|
});
|
|
693
671
|
}
|
|
694
|
-
if (input
|
|
672
|
+
if (matchesCommand('mark', input, key) && treeItems.length > 0) {
|
|
695
673
|
setRangeAnchor(null);
|
|
696
674
|
const itemId = treeItems[cursor].item.id;
|
|
697
675
|
toggleMarked(itemId);
|
|
698
676
|
}
|
|
699
|
-
if (input
|
|
677
|
+
if (matchesCommand('clear-marks', input, key) && treeItems.length > 0) {
|
|
700
678
|
setRangeAnchor(null);
|
|
701
679
|
const visibleIds = treeItems.map((t) => t.item.id);
|
|
702
680
|
const allMarked = visibleIds.every((id) => markedIds.has(id));
|
|
@@ -707,10 +685,10 @@ export function WorkItemList() {
|
|
|
707
685
|
setMarkedIds(new Set(visibleIds));
|
|
708
686
|
}
|
|
709
687
|
}
|
|
710
|
-
if (input
|
|
688
|
+
if (matchesCommand('bulk-menu', input, key) && treeItems.length > 0) {
|
|
711
689
|
openOverlay({ type: 'bulk-menu' });
|
|
712
690
|
}
|
|
713
|
-
if (input
|
|
691
|
+
if (matchesCommand('set-priority', input, key) &&
|
|
714
692
|
capabilities.fields.priority &&
|
|
715
693
|
treeItems.length > 0) {
|
|
716
694
|
const targetIds = getTargetIds(markedIds, treeItems[cursor]?.item);
|
|
@@ -718,13 +696,15 @@ export function WorkItemList() {
|
|
|
718
696
|
openOverlay({ type: 'priority-picker', targetIds });
|
|
719
697
|
}
|
|
720
698
|
}
|
|
721
|
-
if (
|
|
699
|
+
if (matchesCommand('list-parent', input, key) &&
|
|
700
|
+
capabilities.fields.parent &&
|
|
701
|
+
treeItems.length > 0) {
|
|
722
702
|
const targetIds = getTargetIds(markedIds, treeItems[cursor]?.item);
|
|
723
703
|
if (targetIds.length > 0) {
|
|
724
704
|
openOverlay({ type: 'parent-input', targetIds });
|
|
725
705
|
}
|
|
726
706
|
}
|
|
727
|
-
if (input
|
|
707
|
+
if (matchesCommand('set-assignee', input, key) &&
|
|
728
708
|
capabilities.fields.assignee &&
|
|
729
709
|
treeItems.length > 0) {
|
|
730
710
|
const targetIds = getTargetIds(markedIds, treeItems[cursor]?.item);
|
|
@@ -732,13 +712,17 @@ export function WorkItemList() {
|
|
|
732
712
|
openOverlay({ type: 'assignee-input', targetIds });
|
|
733
713
|
}
|
|
734
714
|
}
|
|
735
|
-
if (
|
|
715
|
+
if (matchesCommand('set-labels', input, key) &&
|
|
716
|
+
capabilities.fields.labels &&
|
|
717
|
+
treeItems.length > 0) {
|
|
736
718
|
const targetIds = getTargetIds(markedIds, treeItems[cursor]?.item);
|
|
737
719
|
if (targetIds.length > 0) {
|
|
738
720
|
openOverlay({ type: 'labels-input', targetIds });
|
|
739
721
|
}
|
|
740
722
|
}
|
|
741
|
-
if (
|
|
723
|
+
if (matchesCommand('set-type', input, key) &&
|
|
724
|
+
capabilities.customTypes &&
|
|
725
|
+
treeItems.length > 0) {
|
|
742
726
|
const targetIds = getTargetIds(markedIds, treeItems[cursor]?.item);
|
|
743
727
|
if (targetIds.length > 0) {
|
|
744
728
|
openOverlay({ type: 'type-picker', targetIds });
|
|
@@ -1644,6 +1628,6 @@ export function WorkItemList() {
|
|
|
1644
1628
|
else {
|
|
1645
1629
|
closeOverlay();
|
|
1646
1630
|
}
|
|
1647
|
-
}, onCancel: () => closeOverlay() })) : toast ? (_jsxs(Box, { children: [_jsx(Text, { color: success, children: toast.message }), positionText && _jsxs(Text, { dimColor: mutedDim, children: [" ", positionText] })] })) : (_jsxs(Box, { children: [_jsx(Text, { dimColor: mutedDim, children:
|
|
1631
|
+
}, onCancel: () => closeOverlay() })) : toast ? (_jsxs(Box, { children: [_jsx(Text, { color: success, children: toast.message }), positionText && _jsxs(Text, { dimColor: mutedDim, children: [" ", positionText] })] })) : (_jsxs(Box, { children: [_jsx(Text, { dimColor: mutedDim, children: buildFooterHints('list', commandContext, terminalWidth - (positionText ? positionText.length + 2 : 0)) }), positionText && _jsxs(Text, { dimColor: mutedDim, children: [" ", positionText] })] })) }), warning && (_jsx(Box, { children: _jsxs(Text, { color: warningColor, children: ["\u26A0 ", warning] }) })), updateInfo?.updateAvailable && activeOverlay === null && (_jsx(Box, { children: _jsxs(Text, { color: warningColor, children: ["Update available: ", updateInfo.current, " \u2192 ", updateInfo.latest, " Press , to update in Settings"] }) }))] }));
|
|
1648
1632
|
}
|
|
1649
1633
|
//# sourceMappingURL=WorkItemList.js.map
|