@sascha384/tic 4.8.0 → 5.0.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/auth/gitlab.js +12 -5
- package/dist/auth/gitlab.js.map +1 -1
- package/dist/commands.d.ts +5 -0
- package/dist/commands.js +90 -1
- package/dist/commands.js.map +1 -1
- package/dist/components/BranchList.js +417 -281
- package/dist/components/BranchList.js.map +1 -1
- package/dist/components/ColorPill.js +3 -3
- package/dist/components/ColorPill.js.map +1 -1
- package/dist/components/CommandBar.d.ts +8 -0
- package/dist/components/CommandBar.js +142 -0
- package/dist/components/CommandBar.js.map +1 -0
- package/dist/components/DetailPanel.js +2 -2
- package/dist/components/DetailPanel.js.map +1 -1
- package/dist/components/ErrorBoundary.d.ts +1 -1
- package/dist/components/Header.js +6 -2
- package/dist/components/Header.js.map +1 -1
- package/dist/components/HelpScreen.js +3 -2
- package/dist/components/HelpScreen.js.map +1 -1
- package/dist/components/OverlayPanel.d.ts +1 -1
- package/dist/components/PullRequestList.js +118 -18
- package/dist/components/PullRequestList.js.map +1 -1
- package/dist/components/Settings.js +5 -0
- package/dist/components/Settings.js.map +1 -1
- package/dist/components/StatusScreen.js +16 -8
- package/dist/components/StatusScreen.js.map +1 -1
- package/dist/components/TableLayout.d.ts +26 -10
- package/dist/components/TableLayout.js +67 -146
- package/dist/components/TableLayout.js.map +1 -1
- package/dist/components/WorkItemForm.js +5 -0
- package/dist/components/WorkItemForm.js.map +1 -1
- package/dist/components/WorkItemList.js +119 -93
- package/dist/components/WorkItemList.js.map +1 -1
- package/dist/git.d.ts +8 -0
- package/dist/git.js.map +1 -1
- package/dist/implement.js +7 -3
- package/dist/implement.js.map +1 -1
- package/dist/stores/backendDataStore.d.ts +6 -0
- package/dist/stores/backendDataStore.js +81 -1
- package/dist/stores/backendDataStore.js.map +1 -1
- package/dist/stores/navigationStore.d.ts +4 -0
- package/dist/stores/navigationStore.js +10 -0
- package/dist/stores/navigationStore.js.map +1 -1
- package/dist/stores/uiStore.d.ts +12 -0
- package/dist/stores/uiStore.js.map +1 -1
- package/dist/test-helpers.d.ts +7 -0
- package/dist/test-helpers.js +208 -0
- package/dist/test-helpers.js.map +1 -0
- package/drizzle/meta/_journal.json +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsxs as _jsxs,
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useState, useMemo, useEffect, useCallback, useRef } from 'react';
|
|
3
3
|
import { Box, Text, useInput, useApp } from 'ink';
|
|
4
4
|
import { navigationStore, useNavigationStore, } from '../stores/navigationStore.js';
|
|
@@ -9,6 +9,7 @@ import { configStore, useConfigStore } from '../stores/configStore.js';
|
|
|
9
9
|
import { uiStore, useUIStore, getOverlayTargetIds } from '../stores/uiStore.js';
|
|
10
10
|
import { getMarkedDistribution } from './getMarkedDistribution.js';
|
|
11
11
|
import { TableLayout } from './TableLayout.js';
|
|
12
|
+
import { ColorPill } from './ColorPill.js';
|
|
12
13
|
import { useTerminalSize } from '../hooks/useTerminalSize.js';
|
|
13
14
|
import { useScrollViewport } from '../hooks/useScrollViewport.js';
|
|
14
15
|
import { useBackendDataStore, backendDataStore, } from '../stores/backendDataStore.js';
|
|
@@ -18,12 +19,108 @@ import { getVisibleCommands, } from '../commands.js';
|
|
|
18
19
|
import { OverlayPanel } from './OverlayPanel.js';
|
|
19
20
|
import { DetailPanel } from './DetailPanel.js';
|
|
20
21
|
import { undoStore } from '../stores/undoStore.js';
|
|
21
|
-
import {
|
|
22
|
+
import { CommandBar } from './CommandBar.js';
|
|
22
23
|
import { isSoftDeleteBackend } from '../backends/types.js';
|
|
23
24
|
import { filterStore, useFilterStore } from '../stores/filterStore.js';
|
|
24
25
|
import { useThemeStore } from '../stores/themeStore.js';
|
|
25
26
|
import { applyFilters, countActiveFilters, summarizeFilters, } from '../filters.js';
|
|
26
27
|
const EMPTY_VIEWS = [];
|
|
28
|
+
function buildWorkItemColumns(capabilities, collapsedIds, accent) {
|
|
29
|
+
const columns = [];
|
|
30
|
+
// ID column
|
|
31
|
+
columns.push({
|
|
32
|
+
key: 'id',
|
|
33
|
+
header: 'ID',
|
|
34
|
+
width: 4, // overridden dynamically via useMemo
|
|
35
|
+
required: true,
|
|
36
|
+
sortable: true,
|
|
37
|
+
render: (ti, selected) => (_jsx(Text, { color: selected ? accent : undefined, bold: selected, dimColor: ti.isCrossType && !selected, children: ti.item.id })),
|
|
38
|
+
});
|
|
39
|
+
// Title column (flex)
|
|
40
|
+
columns.push({
|
|
41
|
+
key: 'title',
|
|
42
|
+
header: 'Title',
|
|
43
|
+
width: -1,
|
|
44
|
+
required: true,
|
|
45
|
+
sortable: true,
|
|
46
|
+
render: (ti, selected) => {
|
|
47
|
+
const { item, prefix, isCrossType, hasChildren } = ti;
|
|
48
|
+
const collapseIndicator = hasChildren
|
|
49
|
+
? collapsedIds.has(item.id)
|
|
50
|
+
? '\u25B6 '
|
|
51
|
+
: '\u25BC '
|
|
52
|
+
: ' ';
|
|
53
|
+
const typeLabel = isCrossType ? ` (${item.type})` : '';
|
|
54
|
+
return (_jsxs(Text, { color: selected ? accent : undefined, bold: selected, dimColor: isCrossType && !selected, wrap: "truncate", children: [capabilities.relationships ? prefix : '', collapseIndicator, item.title, typeLabel] }));
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
// Status column
|
|
58
|
+
columns.push({
|
|
59
|
+
key: 'status',
|
|
60
|
+
header: 'Status',
|
|
61
|
+
width: 14,
|
|
62
|
+
hidePriority: 3,
|
|
63
|
+
sortable: true,
|
|
64
|
+
render: (ti, selected) => {
|
|
65
|
+
const hasUnresolvedDeps = ti.item.dependsOn.length > 0;
|
|
66
|
+
return (_jsxs(_Fragment, { children: [capabilities.fields.dependsOn && hasUnresolvedDeps && (_jsxs(Text, { dimColor: ti.isCrossType && !selected, children: ['\u29D7', " "] })), _jsx(ColorPill, { field: "status", value: ti.item.status })] }));
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
// Assignee column (conditional)
|
|
70
|
+
if (capabilities.fields.assignee) {
|
|
71
|
+
columns.push({
|
|
72
|
+
key: 'assignee',
|
|
73
|
+
header: 'Assignee',
|
|
74
|
+
width: 20,
|
|
75
|
+
hidePriority: 4,
|
|
76
|
+
sortable: true,
|
|
77
|
+
hasData: (items) => items.some(({ item }) => !!item.assignee),
|
|
78
|
+
render: (ti, selected) => (_jsx(Text, { color: selected ? accent : undefined, bold: selected, dimColor: ti.isCrossType && !selected, wrap: "truncate", children: ti.item.assignee })),
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
// Labels column (conditional)
|
|
82
|
+
if (capabilities.fields.labels) {
|
|
83
|
+
columns.push({
|
|
84
|
+
key: 'labels',
|
|
85
|
+
header: 'Labels',
|
|
86
|
+
width: 20,
|
|
87
|
+
hidePriority: 2,
|
|
88
|
+
hasData: (items) => items.some(({ item }) => item.labels.length > 0),
|
|
89
|
+
render: (ti) => {
|
|
90
|
+
const maxWidth = 20;
|
|
91
|
+
const rendered = [];
|
|
92
|
+
let usedWidth = 0;
|
|
93
|
+
for (const label of ti.item.labels) {
|
|
94
|
+
const pillWidth = label.length + 2;
|
|
95
|
+
const needed = usedWidth === 0 ? pillWidth : pillWidth + 1;
|
|
96
|
+
if (usedWidth + needed > maxWidth) {
|
|
97
|
+
const remaining = ti.item.labels.length - rendered.length;
|
|
98
|
+
if (remaining > 0) {
|
|
99
|
+
return (_jsxs(Box, { gap: 1, children: [rendered.map((l) => (_jsx(ColorPill, { field: "label", value: l }, l))), _jsxs(Text, { dimColor: true, children: ["+", remaining] })] }));
|
|
100
|
+
}
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
rendered.push(label);
|
|
104
|
+
usedWidth += needed;
|
|
105
|
+
}
|
|
106
|
+
return (_jsx(Box, { gap: 1, children: rendered.map((l) => (_jsx(ColorPill, { field: "label", value: l }, l))) }));
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
// Priority column (conditional)
|
|
111
|
+
if (capabilities.fields.priority) {
|
|
112
|
+
columns.push({
|
|
113
|
+
key: 'priority',
|
|
114
|
+
header: 'Priority',
|
|
115
|
+
width: 12,
|
|
116
|
+
hidePriority: 1,
|
|
117
|
+
sortable: true,
|
|
118
|
+
hasData: (items) => items.some(({ item }) => !!item.priority),
|
|
119
|
+
render: (ti) => ti.item.priority ? (_jsx(ColorPill, { field: "priority", value: ti.item.priority })) : (_jsx(Text, { children: " " })),
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
return columns;
|
|
123
|
+
}
|
|
27
124
|
export function getTargetIds(markedIds, cursorItem) {
|
|
28
125
|
if (markedIds.size > 0) {
|
|
29
126
|
return [...markedIds];
|
|
@@ -102,11 +199,9 @@ export function WorkItemList() {
|
|
|
102
199
|
const filterCount = useMemo(() => countActiveFilters(activeFilters), [activeFilters]);
|
|
103
200
|
const { setCursor, toggleExpanded, toggleMarked, clearMarked, setMarkedIds, setRangeAnchor, clampCursor, removeDeletedItem, toggleSortColumn, clearSort, } = listViewStore.getState();
|
|
104
201
|
// Local state for inputs and templates
|
|
105
|
-
const [allSearchItems, setAllSearchItems] = useState([]);
|
|
106
202
|
const [templates, setTemplates] = useState([]);
|
|
107
203
|
const [showFullDescription, setShowFullDescription] = useState(false);
|
|
108
204
|
const [descriptionScrollOffset, setDescriptionScrollOffset] = useState(0);
|
|
109
|
-
const [commandBarQuery, setCommandBarQuery] = useState('');
|
|
110
205
|
// UI overlay state from store
|
|
111
206
|
const { activeOverlay, warning, toast } = useUIStore(useShallow((s) => ({
|
|
112
207
|
activeOverlay: s.activeOverlay,
|
|
@@ -268,25 +363,6 @@ export function WorkItemList() {
|
|
|
268
363
|
setShowFullDescription(false);
|
|
269
364
|
setDescriptionScrollOffset(0);
|
|
270
365
|
}, [cursor]);
|
|
271
|
-
useEffect(() => {
|
|
272
|
-
if (activeOverlay?.type !== 'command-bar' || !backend)
|
|
273
|
-
return;
|
|
274
|
-
let cancelled = false;
|
|
275
|
-
void backend
|
|
276
|
-
.listWorkItems()
|
|
277
|
-
.then((items) => {
|
|
278
|
-
if (!cancelled)
|
|
279
|
-
setAllSearchItems(items);
|
|
280
|
-
})
|
|
281
|
-
.catch((err) => {
|
|
282
|
-
uiStore
|
|
283
|
-
.getState()
|
|
284
|
-
.setToast(err instanceof Error ? err.message : 'Failed to load items');
|
|
285
|
-
});
|
|
286
|
-
return () => {
|
|
287
|
-
cancelled = true;
|
|
288
|
-
};
|
|
289
|
-
}, [activeOverlay?.type, backend]);
|
|
290
366
|
// Description viewport calculation
|
|
291
367
|
const currentItem = treeItems[cursor]?.item;
|
|
292
368
|
const descriptionLines = currentItem?.description?.split('\n') ?? [];
|
|
@@ -520,9 +596,12 @@ export function WorkItemList() {
|
|
|
520
596
|
const comments = item.comments;
|
|
521
597
|
try {
|
|
522
598
|
const itemUrl = backend?.getItemUrl(item.id) || '';
|
|
599
|
+
// Suspend terminal for interactive child process
|
|
600
|
+
process.stdin.setRawMode?.(false);
|
|
523
601
|
const result = beginImplementation(item, comments, { branchMode, branchCommand, copyToClipboard }, process.cwd(), { itemUrl });
|
|
524
|
-
// Restore
|
|
602
|
+
// Restore terminal after interactive shell
|
|
525
603
|
process.stdin.setRawMode?.(true);
|
|
604
|
+
console.clear();
|
|
526
605
|
let msg = result.resumed
|
|
527
606
|
? `Resumed work on #${item.id}`
|
|
528
607
|
: `Started work on #${item.id}`;
|
|
@@ -533,6 +612,7 @@ export function WorkItemList() {
|
|
|
533
612
|
}
|
|
534
613
|
catch (e) {
|
|
535
614
|
process.stdin.setRawMode?.(true);
|
|
615
|
+
console.clear();
|
|
536
616
|
setWarning(e instanceof Error ? e.message : 'Failed to start implementation');
|
|
537
617
|
}
|
|
538
618
|
void backendDataStore
|
|
@@ -665,12 +745,6 @@ export function WorkItemList() {
|
|
|
665
745
|
}
|
|
666
746
|
}
|
|
667
747
|
}, { isActive: activeOverlay === null && !showFullDescription });
|
|
668
|
-
const handleSearchSelect = (item) => {
|
|
669
|
-
setCommandBarQuery('');
|
|
670
|
-
closeOverlay();
|
|
671
|
-
selectWorkItem(item.id);
|
|
672
|
-
navigate('form');
|
|
673
|
-
};
|
|
674
748
|
const commandContext = {
|
|
675
749
|
screen: 'list',
|
|
676
750
|
markedCount: markedIds.size,
|
|
@@ -682,6 +756,11 @@ export function WorkItemList() {
|
|
|
682
756
|
gitAvailable,
|
|
683
757
|
hasActiveFilters: filterCount > 0,
|
|
684
758
|
hasSavedViews: savedViews.length > 0,
|
|
759
|
+
hasSelectedBranch: false,
|
|
760
|
+
isCurrentBranch: false,
|
|
761
|
+
hasWorktree: false,
|
|
762
|
+
hasPrCreateCapability: false,
|
|
763
|
+
hasSelectedPr: false,
|
|
685
764
|
};
|
|
686
765
|
const paletteCommands = useMemo(() => getVisibleCommands(commandContext), [
|
|
687
766
|
commandContext.markedCount,
|
|
@@ -692,52 +771,6 @@ export function WorkItemList() {
|
|
|
692
771
|
syncManager,
|
|
693
772
|
gitAvailable,
|
|
694
773
|
]);
|
|
695
|
-
const recentIds = useRecentCommandsStore((s) => s.recentIds);
|
|
696
|
-
const commandBarItems = useMemo(() => {
|
|
697
|
-
const query = commandBarQuery.toLowerCase();
|
|
698
|
-
// Build command items (recent + categorized)
|
|
699
|
-
const commandMap = new Map(paletteCommands.map((c) => [c.id, c]));
|
|
700
|
-
const recentItems = [];
|
|
701
|
-
for (const id of recentIds) {
|
|
702
|
-
const cmd = commandMap.get(id);
|
|
703
|
-
if (cmd) {
|
|
704
|
-
recentItems.push({
|
|
705
|
-
id: `recent-${cmd.id}`,
|
|
706
|
-
label: cmd.label,
|
|
707
|
-
value: cmd.id,
|
|
708
|
-
category: 'Recent',
|
|
709
|
-
kind: 'command',
|
|
710
|
-
});
|
|
711
|
-
}
|
|
712
|
-
}
|
|
713
|
-
const commandItems = paletteCommands.map((cmd) => ({
|
|
714
|
-
id: cmd.id,
|
|
715
|
-
label: cmd.label,
|
|
716
|
-
value: cmd.id,
|
|
717
|
-
category: cmd.category,
|
|
718
|
-
kind: 'command',
|
|
719
|
-
}));
|
|
720
|
-
let allItems = [...recentItems, ...commandItems];
|
|
721
|
-
// Filter commands by query
|
|
722
|
-
if (query) {
|
|
723
|
-
allItems = allItems.filter((item) => item.label.toLowerCase().includes(query));
|
|
724
|
-
// Add up to 5 matching issues
|
|
725
|
-
const matchingIssues = allSearchItems
|
|
726
|
-
.filter((item) => item.title.toLowerCase().includes(query) ||
|
|
727
|
-
item.id.toLowerCase().includes(query))
|
|
728
|
-
.slice(0, 5)
|
|
729
|
-
.map((item) => ({
|
|
730
|
-
id: `issue-${item.id}`,
|
|
731
|
-
label: `#${item.id} ${item.title}`,
|
|
732
|
-
value: item.id,
|
|
733
|
-
hint: item.type,
|
|
734
|
-
category: 'Issues',
|
|
735
|
-
kind: 'issue',
|
|
736
|
-
}));
|
|
737
|
-
allItems = [...allItems, ...matchingIssues];
|
|
738
|
-
}
|
|
739
|
-
return allItems;
|
|
740
|
-
}, [paletteCommands, recentIds, commandBarQuery, allSearchItems]);
|
|
741
774
|
const sortPickerItems = useMemo(() => {
|
|
742
775
|
const columns = [
|
|
743
776
|
{ column: 'id', label: 'ID' },
|
|
@@ -874,9 +907,7 @@ export function WorkItemList() {
|
|
|
874
907
|
return items;
|
|
875
908
|
}, [savedViews, defaultView, activeViewName, lastViewName, filterCount]);
|
|
876
909
|
const handleCommandSelect = (command) => {
|
|
877
|
-
setCommandBarQuery('');
|
|
878
910
|
closeOverlay();
|
|
879
|
-
recentCommandsStore.getState().addRecent(command.id);
|
|
880
911
|
switch (command.id) {
|
|
881
912
|
case 'create':
|
|
882
913
|
selectWorkItem(null);
|
|
@@ -914,8 +945,10 @@ export function WorkItemList() {
|
|
|
914
945
|
const comments = item.comments;
|
|
915
946
|
try {
|
|
916
947
|
const itemUrl = backend?.getItemUrl(item.id) || '';
|
|
948
|
+
process.stdin.setRawMode?.(false);
|
|
917
949
|
const result = beginImplementation(item, comments, { branchMode, branchCommand, copyToClipboard }, process.cwd(), { itemUrl });
|
|
918
950
|
process.stdin.setRawMode?.(true);
|
|
951
|
+
console.clear();
|
|
919
952
|
let msg = result.resumed
|
|
920
953
|
? `Resumed work on #${item.id}`
|
|
921
954
|
: `Started work on #${item.id}`;
|
|
@@ -926,6 +959,7 @@ export function WorkItemList() {
|
|
|
926
959
|
}
|
|
927
960
|
catch (e) {
|
|
928
961
|
process.stdin.setRawMode?.(true);
|
|
962
|
+
console.clear();
|
|
929
963
|
setWarning(e instanceof Error ? e.message : 'Failed to start implementation');
|
|
930
964
|
}
|
|
931
965
|
void backendDataStore
|
|
@@ -1068,24 +1102,16 @@ export function WorkItemList() {
|
|
|
1068
1102
|
? activeType.charAt(0).toUpperCase() + activeType.slice(1) + 's'
|
|
1069
1103
|
: '';
|
|
1070
1104
|
const visibleTreeItems = useMemo(() => treeItems.slice(viewport.start, viewport.end), [treeItems, viewport.start, viewport.end]);
|
|
1105
|
+
const workItemColumns = useMemo(() => {
|
|
1106
|
+
const maxIdLen = visibleTreeItems.reduce((max, { item }) => Math.max(max, item.id.length), 2);
|
|
1107
|
+
const cols = buildWorkItemColumns(capabilities, collapsedIds, accent);
|
|
1108
|
+
cols[0].width = maxIdLen + 2;
|
|
1109
|
+
return cols;
|
|
1110
|
+
}, [visibleTreeItems, capabilities, collapsedIds, accent]);
|
|
1071
1111
|
const positionText = treeItems.length > viewport.maxVisible
|
|
1072
1112
|
? `${cursor + 1}/${treeItems.length}`
|
|
1073
1113
|
: '';
|
|
1074
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { wrap: "truncate", children: [_jsxs(Text, { bold: true, color: accent, children: [typeLabel, " \u2014 ", iteration] }), _jsx(Text, { dimColor: mutedDim, children: ` (${filterCount > 0 ? `${items.length}/${unfilteredCount}` : items.length} item${unfilteredCount === 1 ? '' : 's'})` }), markedCount > 0 && (_jsxs(Text, { color: marked, children: [` ● ${markedCount}`, markedDistribution.above > 0 && ` ↑${markedDistribution.above}`, markedDistribution.below > 0 && ` ↓${markedDistribution.below}`] })), filterCount > 0 && (_jsx(Text, { color: warningColor, children: ` [${filterCount} filter${filterCount === 1 ? '' : 's'}${activeViewName ? `: ${activeViewName}` : ''}]` }))] }) }), _jsx(TableLayout, {
|
|
1075
|
-
if (item.kind === 'issue') {
|
|
1076
|
-
const workItem = allSearchItems.find((i) => i.id === item.value);
|
|
1077
|
-
if (workItem)
|
|
1078
|
-
handleSearchSelect(workItem);
|
|
1079
|
-
}
|
|
1080
|
-
else {
|
|
1081
|
-
const cmd = paletteCommands.find((c) => c.id === item.value);
|
|
1082
|
-
if (cmd)
|
|
1083
|
-
handleCommandSelect(cmd);
|
|
1084
|
-
}
|
|
1085
|
-
}, onCancel: () => {
|
|
1086
|
-
setCommandBarQuery('');
|
|
1087
|
-
closeOverlay();
|
|
1088
|
-
} })) : activeOverlay?.type === 'bulk-menu' ? ((() => {
|
|
1114
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { wrap: "truncate", children: [_jsxs(Text, { bold: true, color: accent, children: [typeLabel, " \u2014 ", iteration] }), _jsx(Text, { dimColor: mutedDim, children: ` (${filterCount > 0 ? `${items.length}/${unfilteredCount}` : items.length} item${unfilteredCount === 1 ? '' : 's'})` }), markedCount > 0 && (_jsxs(Text, { color: marked, children: [` ● ${markedCount}`, markedDistribution.above > 0 && ` ↑${markedDistribution.above}`, markedDistribution.below > 0 && ` ↓${markedDistribution.below}`] })), filterCount > 0 && (_jsx(Text, { color: warningColor, children: ` [${filterCount} filter${filterCount === 1 ? '' : 's'}${activeViewName ? `: ${activeViewName}` : ''}]` }))] }) }), _jsx(TableLayout, { items: visibleTreeItems, columns: workItemColumns, cursor: viewport.visibleCursor, terminalWidth: terminalWidth, getKey: (ti) => `${ti.item.id}-${ti.item.type}`, isMarked: (ti) => markedIds.has(ti.item.id), sortStack: sortStack }), treeItems.length === 0 && !loading && initError && (_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: errorColor, children: "Failed to connect to backend:" }), _jsx(Box, { marginLeft: 2, children: _jsx(Text, { color: errorColor, children: initError }) }), _jsx(Text, { dimColor: mutedDim, children: "Press , for settings or q to quit." })] })), treeItems.length === 0 && !loading && !initError && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: mutedDim, children: ["No ", activeType ?? 'item', "s in this iteration. Press c to create, / to search all."] }) })), loading && treeItems.length === 0 && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: mutedDim, children: "Loading..." }) })), showDetailPanel && treeItems.length > 0 && treeItems[cursor] && (_jsx(Box, { marginTop: 1, children: _jsx(DetailPanel, { item: treeItems[cursor].item, terminalWidth: terminalWidth, showFullDescription: showFullDescription, descriptionScrollOffset: descriptionScrollOffset, maxDescriptionHeight: maxDescriptionHeight }) })), _jsx(Box, { marginTop: 1, children: showFullDescription ? (_jsxs(Box, { children: [_jsx(Text, { dimColor: mutedDim, children: "\u2191\u2193 scroll space/esc close" }), positionText && _jsxs(Text, { dimColor: mutedDim, children: [" ", positionText] })] })) : activeOverlay?.type === 'command-bar' ? (_jsx(CommandBar, { commands: paletteCommands, onCommand: handleCommandSelect, onCancel: closeOverlay })) : activeOverlay?.type === 'bulk-menu' ? ((() => {
|
|
1089
1115
|
const bulkItems = [];
|
|
1090
1116
|
bulkItems.push({
|
|
1091
1117
|
id: 'status',
|