github-issue-tower-defence-management 1.192.0 → 1.194.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/CHANGELOG.md +26 -0
- package/README.md +4 -0
- package/bin/adapter/entry-points/cli/index.js +19 -0
- package/bin/adapter/entry-points/cli/index.js.map +1 -1
- package/bin/adapter/entry-points/console/consoleOperationApi.js +9 -2
- package/bin/adapter/entry-points/console/consoleOperationApi.js.map +1 -1
- package/bin/adapter/entry-points/console/ui-dist/assets/{index-RaFqjB7u.js → index-CYwLv9pf.js} +2 -2
- package/bin/adapter/entry-points/console/ui-dist/index.html +1 -1
- package/bin/adapter/entry-points/handlers/tokenStatusWriter.js +1 -0
- package/bin/adapter/entry-points/handlers/tokenStatusWriter.js.map +1 -1
- package/bin/adapter/repositories/NodeLocalCommandRunner.js +5 -0
- package/bin/adapter/repositories/NodeLocalCommandRunner.js.map +1 -1
- package/bin/adapter/repositories/NodeTmuxSessionRepository.js +29 -0
- package/bin/adapter/repositories/NodeTmuxSessionRepository.js.map +1 -1
- package/bin/adapter/repositories/ProxyClaudeTokenUsageRepository.js +4 -2
- package/bin/adapter/repositories/ProxyClaudeTokenUsageRepository.js.map +1 -1
- package/bin/domain/usecases/StartPreparationUseCase.js +70 -22
- package/bin/domain/usecases/StartPreparationUseCase.js.map +1 -1
- package/bin/domain/usecases/console/GenerateConsoleListsUseCase.js +1 -3
- package/bin/domain/usecases/console/GenerateConsoleListsUseCase.js.map +1 -1
- package/bin/domain/usecases/dashboard/GenerateTokenStatusUseCase.js +12 -4
- package/bin/domain/usecases/dashboard/GenerateTokenStatusUseCase.js.map +1 -1
- package/package.json +1 -1
- package/src/adapter/entry-points/cli/index.test.ts +102 -0
- package/src/adapter/entry-points/cli/index.ts +43 -0
- package/src/adapter/entry-points/console/consoleOperationApi.test.ts +19 -5
- package/src/adapter/entry-points/console/consoleOperationApi.ts +18 -1
- package/src/adapter/entry-points/console/ui/e2e/consoleScenario.spec.ts +45 -0
- package/src/adapter/entry-points/console/ui/e2e/consoleTestHarness.ts +7 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleStoryList.stories.tsx +31 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleStoryList.test.tsx +96 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleStoryList.tsx +20 -2
- package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsolePage.test.tsx +159 -0
- package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsolePage.tsx +17 -1
- package/src/adapter/entry-points/console/ui-dist/assets/{index-RaFqjB7u.js → index-CYwLv9pf.js} +2 -2
- package/src/adapter/entry-points/console/ui-dist/index.html +1 -1
- package/src/adapter/entry-points/handlers/inTmuxByHumanSessionReconciler.test.ts +1 -0
- package/src/adapter/entry-points/handlers/notifySilentTmuxSessions.test.ts +1 -0
- package/src/adapter/entry-points/handlers/resetDegeneratedTmuxSessions.test.ts +4 -1
- package/src/adapter/entry-points/handlers/situationFileWriter.test.ts +2 -0
- package/src/adapter/entry-points/handlers/staleTmuxSessionCleaner.test.ts +1 -0
- package/src/adapter/entry-points/handlers/tokenStatusWriter.ts +1 -0
- package/src/adapter/repositories/LocalCommandIssueAttachmentRepository.test.ts +4 -0
- package/src/adapter/repositories/LocalProcessLiveSessionProcessSnapshotProvider.test.ts +1 -0
- package/src/adapter/repositories/NodeLocalCommandRunner.test.ts +16 -0
- package/src/adapter/repositories/NodeLocalCommandRunner.ts +5 -1
- package/src/adapter/repositories/NodeSubAgentProcessLister.test.ts +1 -0
- package/src/adapter/repositories/NodeTmuxSessionRepository.test.ts +132 -0
- package/src/adapter/repositories/NodeTmuxSessionRepository.ts +37 -0
- package/src/adapter/repositories/ProxyClaudeTokenUsageRepository.test.ts +38 -0
- package/src/adapter/repositories/ProxyClaudeTokenUsageRepository.ts +6 -2
- package/src/adapter/repositories/TmuxSilentSessionNotificationRepository.test.ts +2 -0
- package/src/domain/usecases/RevertOrphanedPreparationUseCase.test.ts +1 -0
- package/src/domain/usecases/StartPreparationUseCase.test.ts +213 -2
- package/src/domain/usecases/StartPreparationUseCase.ts +155 -48
- package/src/domain/usecases/adapter-interfaces/LocalCommandRunner.ts +1 -0
- package/src/domain/usecases/adapter-interfaces/TmuxSessionRepository.ts +4 -0
- package/src/domain/usecases/console/GenerateConsoleListsUseCase.test.ts +5 -4
- package/src/domain/usecases/console/GenerateConsoleListsUseCase.ts +9 -11
- package/src/domain/usecases/dashboard/GenerateTokenStatusUseCase.test.ts +63 -0
- package/src/domain/usecases/dashboard/GenerateTokenStatusUseCase.ts +13 -4
- package/src/domain/usecases/intmux/InTmuxByHumanSessionReconcileUseCase.test.ts +1 -0
- package/src/domain/usecases/issueReactivationTriggerIsPending.test.ts +1 -0
- package/types/adapter/entry-points/cli/index.d.ts.map +1 -1
- package/types/adapter/entry-points/console/consoleOperationApi.d.ts +1 -0
- package/types/adapter/entry-points/console/consoleOperationApi.d.ts.map +1 -1
- package/types/adapter/entry-points/handlers/tokenStatusWriter.d.ts.map +1 -1
- package/types/adapter/repositories/NodeLocalCommandRunner.d.ts +1 -0
- package/types/adapter/repositories/NodeLocalCommandRunner.d.ts.map +1 -1
- package/types/adapter/repositories/NodeTmuxSessionRepository.d.ts +1 -0
- package/types/adapter/repositories/NodeTmuxSessionRepository.d.ts.map +1 -1
- package/types/adapter/repositories/ProxyClaudeTokenUsageRepository.d.ts.map +1 -1
- package/types/domain/usecases/StartPreparationUseCase.d.ts +10 -1
- package/types/domain/usecases/StartPreparationUseCase.d.ts.map +1 -1
- package/types/domain/usecases/adapter-interfaces/LocalCommandRunner.d.ts +1 -0
- package/types/domain/usecases/adapter-interfaces/LocalCommandRunner.d.ts.map +1 -1
- package/types/domain/usecases/adapter-interfaces/TmuxSessionRepository.d.ts +1 -0
- package/types/domain/usecases/adapter-interfaces/TmuxSessionRepository.d.ts.map +1 -1
- package/types/domain/usecases/console/GenerateConsoleListsUseCase.d.ts.map +1 -1
- package/types/domain/usecases/dashboard/GenerateTokenStatusUseCase.d.ts +1 -0
- package/types/domain/usecases/dashboard/GenerateTokenStatusUseCase.d.ts.map +1 -1
|
@@ -994,6 +994,165 @@ describe('ConsolePage auto-advance tab', () => {
|
|
|
994
994
|
});
|
|
995
995
|
});
|
|
996
996
|
|
|
997
|
+
it('shows the stories tab badge count as the number of non-GRAY stories', async () => {
|
|
998
|
+
global.fetch = jest.fn(async (url: string) => {
|
|
999
|
+
const listMatch = url.match(/\/projects\/[^/]+\/([^/]+)\/list\.json/);
|
|
1000
|
+
if (listMatch !== null) {
|
|
1001
|
+
const tab = listMatch[1];
|
|
1002
|
+
if (tab === 'stories') {
|
|
1003
|
+
return {
|
|
1004
|
+
ok: true,
|
|
1005
|
+
status: 200,
|
|
1006
|
+
json: async () => ({
|
|
1007
|
+
generatedAt: '2026-06-19T00:00:00.000Z',
|
|
1008
|
+
stories: [
|
|
1009
|
+
{
|
|
1010
|
+
storyName: 'TDPM Console port',
|
|
1011
|
+
storyOptionId: 'st1',
|
|
1012
|
+
color: 'BLUE',
|
|
1013
|
+
openItemCount: 3,
|
|
1014
|
+
storyViewUrl: null,
|
|
1015
|
+
},
|
|
1016
|
+
{
|
|
1017
|
+
storyName: 'regular / workflow improvement',
|
|
1018
|
+
storyOptionId: 'st2',
|
|
1019
|
+
color: 'GRAY',
|
|
1020
|
+
openItemCount: 2,
|
|
1021
|
+
storyViewUrl: null,
|
|
1022
|
+
},
|
|
1023
|
+
],
|
|
1024
|
+
defaultNameWithOwner: null,
|
|
1025
|
+
storyOrder: [],
|
|
1026
|
+
}),
|
|
1027
|
+
};
|
|
1028
|
+
}
|
|
1029
|
+
return { ok: true, status: 200, json: async () => listPayload(tab) };
|
|
1030
|
+
}
|
|
1031
|
+
if (url === '/api/projects') {
|
|
1032
|
+
return {
|
|
1033
|
+
ok: true,
|
|
1034
|
+
status: 200,
|
|
1035
|
+
json: async () => ({ pjcodes: ['acme'] }),
|
|
1036
|
+
};
|
|
1037
|
+
}
|
|
1038
|
+
return { ok: true, status: 200, json: async () => ({ body: '# body' }) };
|
|
1039
|
+
}) as unknown as typeof fetch;
|
|
1040
|
+
|
|
1041
|
+
const { container } = render(<ConsolePage />);
|
|
1042
|
+
|
|
1043
|
+
await waitFor(() => {
|
|
1044
|
+
const tabs = [...container.querySelectorAll('.console-tab')];
|
|
1045
|
+
const storiesTab = tabs.find((el) => el.textContent?.includes('Stories'));
|
|
1046
|
+
expect(storiesTab).toBeTruthy();
|
|
1047
|
+
expect(storiesTab?.querySelector('.console-tab-badge')?.textContent).toBe(
|
|
1048
|
+
'1',
|
|
1049
|
+
);
|
|
1050
|
+
});
|
|
1051
|
+
});
|
|
1052
|
+
|
|
1053
|
+
it('reads console-story-show-gray from localStorage and shows gray stories when true', async () => {
|
|
1054
|
+
localStorage.setItem('console-story-show-gray', 'true');
|
|
1055
|
+
window.history.replaceState({}, '', '/projects/acme/stories?k=token');
|
|
1056
|
+
global.fetch = jest.fn(async (url: string) => {
|
|
1057
|
+
const listMatch = url.match(/\/projects\/[^/]+\/([^/]+)\/list\.json/);
|
|
1058
|
+
if (listMatch !== null) {
|
|
1059
|
+
const tab = listMatch[1];
|
|
1060
|
+
if (tab === 'stories') {
|
|
1061
|
+
return {
|
|
1062
|
+
ok: true,
|
|
1063
|
+
status: 200,
|
|
1064
|
+
json: async () => ({
|
|
1065
|
+
generatedAt: '2026-06-19T00:00:00.000Z',
|
|
1066
|
+
stories: [
|
|
1067
|
+
{
|
|
1068
|
+
storyName: 'TDPM Console port',
|
|
1069
|
+
storyOptionId: 'st1',
|
|
1070
|
+
color: 'BLUE',
|
|
1071
|
+
openItemCount: 3,
|
|
1072
|
+
storyViewUrl: null,
|
|
1073
|
+
},
|
|
1074
|
+
{
|
|
1075
|
+
storyName: 'regular / workflow improvement',
|
|
1076
|
+
storyOptionId: 'st2',
|
|
1077
|
+
color: 'GRAY',
|
|
1078
|
+
openItemCount: 2,
|
|
1079
|
+
storyViewUrl: null,
|
|
1080
|
+
},
|
|
1081
|
+
],
|
|
1082
|
+
defaultNameWithOwner: null,
|
|
1083
|
+
storyOrder: [],
|
|
1084
|
+
}),
|
|
1085
|
+
};
|
|
1086
|
+
}
|
|
1087
|
+
return { ok: true, status: 200, json: async () => listPayload(tab) };
|
|
1088
|
+
}
|
|
1089
|
+
if (url === '/api/projects') {
|
|
1090
|
+
return {
|
|
1091
|
+
ok: true,
|
|
1092
|
+
status: 200,
|
|
1093
|
+
json: async () => ({ pjcodes: ['acme'] }),
|
|
1094
|
+
};
|
|
1095
|
+
}
|
|
1096
|
+
return { ok: true, status: 200, json: async () => ({ body: '# body' }) };
|
|
1097
|
+
}) as unknown as typeof fetch;
|
|
1098
|
+
|
|
1099
|
+
const { findByText } = render(<ConsolePage />);
|
|
1100
|
+
expect(
|
|
1101
|
+
await findByText('regular / workflow improvement'),
|
|
1102
|
+
).toBeInTheDocument();
|
|
1103
|
+
});
|
|
1104
|
+
|
|
1105
|
+
it('writes true to console-story-show-gray in localStorage when the toggle button is clicked', async () => {
|
|
1106
|
+
window.history.replaceState({}, '', '/projects/acme/stories?k=token');
|
|
1107
|
+
global.fetch = jest.fn(async (url: string) => {
|
|
1108
|
+
const listMatch = url.match(/\/projects\/[^/]+\/([^/]+)\/list\.json/);
|
|
1109
|
+
if (listMatch !== null) {
|
|
1110
|
+
const tab = listMatch[1];
|
|
1111
|
+
if (tab === 'stories') {
|
|
1112
|
+
return {
|
|
1113
|
+
ok: true,
|
|
1114
|
+
status: 200,
|
|
1115
|
+
json: async () => ({
|
|
1116
|
+
generatedAt: '2026-06-19T00:00:00.000Z',
|
|
1117
|
+
stories: [
|
|
1118
|
+
{
|
|
1119
|
+
storyName: 'TDPM Console port',
|
|
1120
|
+
storyOptionId: 'st1',
|
|
1121
|
+
color: 'BLUE',
|
|
1122
|
+
openItemCount: 3,
|
|
1123
|
+
storyViewUrl: null,
|
|
1124
|
+
},
|
|
1125
|
+
{
|
|
1126
|
+
storyName: 'regular / workflow improvement',
|
|
1127
|
+
storyOptionId: 'st2',
|
|
1128
|
+
color: 'GRAY',
|
|
1129
|
+
openItemCount: 2,
|
|
1130
|
+
storyViewUrl: null,
|
|
1131
|
+
},
|
|
1132
|
+
],
|
|
1133
|
+
defaultNameWithOwner: null,
|
|
1134
|
+
storyOrder: [],
|
|
1135
|
+
}),
|
|
1136
|
+
};
|
|
1137
|
+
}
|
|
1138
|
+
return { ok: true, status: 200, json: async () => listPayload(tab) };
|
|
1139
|
+
}
|
|
1140
|
+
if (url === '/api/projects') {
|
|
1141
|
+
return {
|
|
1142
|
+
ok: true,
|
|
1143
|
+
status: 200,
|
|
1144
|
+
json: async () => ({ pjcodes: ['acme'] }),
|
|
1145
|
+
};
|
|
1146
|
+
}
|
|
1147
|
+
return { ok: true, status: 200, json: async () => ({ body: '# body' }) };
|
|
1148
|
+
}) as unknown as typeof fetch;
|
|
1149
|
+
|
|
1150
|
+
const { findByRole } = render(<ConsolePage />);
|
|
1151
|
+
const toggleBtn = await findByRole('button', { name: 'Show archived' });
|
|
1152
|
+
fireEvent.click(toggleBtn);
|
|
1153
|
+
expect(localStorage.getItem('console-story-show-gray')).toBe('true');
|
|
1154
|
+
});
|
|
1155
|
+
|
|
997
1156
|
it('navigates to the next project when a completing action fires after the project timer elapses', async () => {
|
|
998
1157
|
localStorage.setItem(
|
|
999
1158
|
'tdpm-timer-settings',
|
|
@@ -97,7 +97,9 @@ export const ConsolePage = () => {
|
|
|
97
97
|
continue;
|
|
98
98
|
}
|
|
99
99
|
if (tab.name === 'stories') {
|
|
100
|
-
result[tab.name] = snapshot.stories.
|
|
100
|
+
result[tab.name] = snapshot.stories.filter(
|
|
101
|
+
(s) => s.color !== 'GRAY',
|
|
102
|
+
).length;
|
|
101
103
|
} else {
|
|
102
104
|
result[tab.name] = countPendingItems(
|
|
103
105
|
snapshot.items,
|
|
@@ -330,6 +332,18 @@ export const ConsolePage = () => {
|
|
|
330
332
|
|
|
331
333
|
const detailScreenRef = useConsoleSwipeNavigation(handleSwipe);
|
|
332
334
|
|
|
335
|
+
const [showGray, setShowGray] = useState(
|
|
336
|
+
() => localStorage.getItem('console-story-show-gray') === 'true',
|
|
337
|
+
);
|
|
338
|
+
|
|
339
|
+
const handleToggleGray = useCallback((): void => {
|
|
340
|
+
setShowGray((prev) => {
|
|
341
|
+
const next = !prev;
|
|
342
|
+
localStorage.setItem('console-story-show-gray', String(next));
|
|
343
|
+
return next;
|
|
344
|
+
});
|
|
345
|
+
}, []);
|
|
346
|
+
|
|
333
347
|
const storiesSnapshot = snapshots.stories;
|
|
334
348
|
const storyEntries = storiesSnapshot?.stories ?? [];
|
|
335
349
|
const defaultNameWithOwner = storiesSnapshot?.defaultNameWithOwner ?? null;
|
|
@@ -502,9 +516,11 @@ export const ConsolePage = () => {
|
|
|
502
516
|
stories={storyEntries}
|
|
503
517
|
isLoading={isLoading}
|
|
504
518
|
error={error}
|
|
519
|
+
showGray={showGray}
|
|
505
520
|
onCreateIssue={handleCreateIssue}
|
|
506
521
|
onAddStory={handleStoryAdd}
|
|
507
522
|
onSelectColor={handleSelectColor}
|
|
523
|
+
onToggleGray={handleToggleGray}
|
|
508
524
|
optimisticColors={storyOptimisticColors}
|
|
509
525
|
colorChangeInFlight={storyColorChangeInFlight}
|
|
510
526
|
colorErrors={storyColorErrors}
|