github-issue-tower-defence-management 1.174.2 → 1.175.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.
Files changed (82) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/bin/adapter/entry-points/console/consoleDoneStore.js +0 -2
  3. package/bin/adapter/entry-points/console/consoleDoneStore.js.map +1 -1
  4. package/bin/adapter/entry-points/console/consoleTabNames.js +0 -1
  5. package/bin/adapter/entry-points/console/consoleTabNames.js.map +1 -1
  6. package/bin/adapter/entry-points/console/dashboardComposeService.js +2 -4
  7. package/bin/adapter/entry-points/console/dashboardComposeService.js.map +1 -1
  8. package/bin/adapter/entry-points/console/ui-dist/assets/{index-g4SqIzCh.js → index-BhDothvr.js} +1 -1
  9. package/bin/adapter/entry-points/console/ui-dist/index.html +1 -1
  10. package/bin/domain/entities/WorkflowStatus.js +1 -6
  11. package/bin/domain/entities/WorkflowStatus.js.map +1 -1
  12. package/bin/domain/usecases/NotifyFinishedIssuePreparationUseCase.js +4 -5
  13. package/bin/domain/usecases/NotifyFinishedIssuePreparationUseCase.js.map +1 -1
  14. package/bin/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.js +0 -39
  15. package/bin/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.js.map +1 -1
  16. package/bin/domain/usecases/RevertOrphanedPreparationUseCase.js +4 -5
  17. package/bin/domain/usecases/RevertOrphanedPreparationUseCase.js.map +1 -1
  18. package/bin/domain/usecases/SetupTowerDefenceProjectUseCase.js +15 -1
  19. package/bin/domain/usecases/SetupTowerDefenceProjectUseCase.js.map +1 -1
  20. package/bin/domain/usecases/console/GenerateConsoleListsUseCase.js +0 -2
  21. package/bin/domain/usecases/console/GenerateConsoleListsUseCase.js.map +1 -1
  22. package/bin/domain/usecases/dashboard/ComposeDashboardUseCase.js +2 -3
  23. package/bin/domain/usecases/dashboard/ComposeDashboardUseCase.js.map +1 -1
  24. package/bin/domain/usecases/dashboard/GenerateDashboardRowUseCase.js +0 -1
  25. package/bin/domain/usecases/dashboard/GenerateDashboardRowUseCase.js.map +1 -1
  26. package/bin/domain/usecases/findLastAgentDeclaringReport.js +12 -0
  27. package/bin/domain/usecases/findLastAgentDeclaringReport.js.map +1 -0
  28. package/package.json +1 -1
  29. package/src/adapter/entry-points/console/consoleDoneStore.ts +0 -2
  30. package/src/adapter/entry-points/console/consoleTabNames.ts +0 -1
  31. package/src/adapter/entry-points/console/dashboardComposeService.test.ts +4 -8
  32. package/src/adapter/entry-points/console/dashboardComposeService.ts +1 -3
  33. package/src/adapter/entry-points/console/dashboardEmitterComposerKey.test.ts +12 -17
  34. package/src/adapter/entry-points/console/ui/e2e/consoleScenario.spec.ts +4 -32
  35. package/src/adapter/entry-points/console/ui/e2e/consoleTestHarness.ts +1 -18
  36. package/src/adapter/entry-points/console/ui/src/features/console/components/layout/ConsoleTabList.stories.tsx +3 -7
  37. package/src/adapter/entry-points/console/ui/src/features/console/components/layout/ConsoleTabList.test.tsx +2 -4
  38. package/src/adapter/entry-points/console/ui/src/features/console/components/operations/ConsoleOperationMenu.test.tsx +1 -1
  39. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleNavigation.test.ts +6 -8
  40. package/src/adapter/entry-points/console/ui/src/features/console/logic/tabAdvance.test.ts +8 -17
  41. package/src/adapter/entry-points/console/ui/src/features/console/logic/types.ts +0 -2
  42. package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsoleItemDetailContainer.test.tsx +3 -3
  43. package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsolePage.test.tsx +5 -6
  44. package/src/adapter/entry-points/console/ui-dist/assets/{index-g4SqIzCh.js → index-BhDothvr.js} +1 -1
  45. package/src/adapter/entry-points/console/ui-dist/index.html +1 -1
  46. package/src/adapter/entry-points/console/webServer.test.ts +4 -6
  47. package/src/adapter/entry-points/handlers/consoleListsWriter.test.ts +30 -26
  48. package/src/adapter/entry-points/handlers/dashboardRowWriter.test.ts +5 -6
  49. package/src/domain/entities/WorkflowStatus.ts +0 -5
  50. package/src/domain/usecases/NotifyFinishedIssuePreparationUseCase.test.ts +32 -0
  51. package/src/domain/usecases/NotifyFinishedIssuePreparationUseCase.ts +7 -8
  52. package/src/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.test.ts +198 -863
  53. package/src/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.ts +0 -68
  54. package/src/domain/usecases/RevertOrphanedPreparationUseCase.ts +8 -11
  55. package/src/domain/usecases/SetupTowerDefenceProjectUseCase.test.ts +89 -51
  56. package/src/domain/usecases/SetupTowerDefenceProjectUseCase.ts +30 -2
  57. package/src/domain/usecases/console/GenerateConsoleListsUseCase.test.ts +62 -72
  58. package/src/domain/usecases/console/GenerateConsoleListsUseCase.ts +0 -8
  59. package/src/domain/usecases/dashboard/ComposeDashboardUseCase.test.ts +19 -28
  60. package/src/domain/usecases/dashboard/ComposeDashboardUseCase.ts +2 -3
  61. package/src/domain/usecases/dashboard/GenerateDashboardRowUseCase.test.ts +11 -12
  62. package/src/domain/usecases/dashboard/GenerateDashboardRowUseCase.ts +0 -3
  63. package/src/domain/usecases/findLastAgentDeclaringReport.test.ts +71 -0
  64. package/src/domain/usecases/findLastAgentDeclaringReport.ts +17 -0
  65. package/src/domain/usecases/intmux/GenerateInTmuxByHumanDataUseCase.test.ts +2 -2
  66. package/types/adapter/entry-points/console/consoleDoneStore.d.ts.map +1 -1
  67. package/types/adapter/entry-points/console/consoleTabNames.d.ts.map +1 -1
  68. package/types/adapter/entry-points/console/dashboardComposeService.d.ts.map +1 -1
  69. package/types/domain/entities/WorkflowStatus.d.ts +0 -1
  70. package/types/domain/entities/WorkflowStatus.d.ts.map +1 -1
  71. package/types/domain/usecases/NotifyFinishedIssuePreparationUseCase.d.ts.map +1 -1
  72. package/types/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.d.ts.map +1 -1
  73. package/types/domain/usecases/RevertOrphanedPreparationUseCase.d.ts.map +1 -1
  74. package/types/domain/usecases/SetupTowerDefenceProjectUseCase.d.ts +1 -0
  75. package/types/domain/usecases/SetupTowerDefenceProjectUseCase.d.ts.map +1 -1
  76. package/types/domain/usecases/console/GenerateConsoleListsUseCase.d.ts +1 -2
  77. package/types/domain/usecases/console/GenerateConsoleListsUseCase.d.ts.map +1 -1
  78. package/types/domain/usecases/dashboard/ComposeDashboardUseCase.d.ts.map +1 -1
  79. package/types/domain/usecases/dashboard/GenerateDashboardRowUseCase.d.ts +0 -1
  80. package/types/domain/usecases/dashboard/GenerateDashboardRowUseCase.d.ts.map +1 -1
  81. package/types/domain/usecases/findLastAgentDeclaringReport.d.ts +5 -0
  82. package/types/domain/usecases/findLastAgentDeclaringReport.d.ts.map +1 -0
@@ -25,7 +25,6 @@ describe('buildComposeDashboardInput', () => {
25
25
  writeProject(dataDir, 'acme', {
26
26
  pjcode: 'acme',
27
27
  capturedAt: 'x',
28
- unread: 3,
29
28
  todo: 1,
30
29
  qc: 2,
31
30
  fail: 0,
@@ -42,7 +41,6 @@ describe('buildComposeDashboardInput', () => {
42
41
  {
43
42
  code: 'ac',
44
43
  row: {
45
- unread: 3,
46
44
  todo: 1,
47
45
  qc: 2,
48
46
  fail: 0,
@@ -62,7 +60,7 @@ describe('buildComposeDashboardInput', () => {
62
60
  it('treats a project file with a missing field as an absent row', () => {
63
61
  const dataDir = makeDataDir();
64
62
  try {
65
- writeProject(dataDir, 'acme', { unread: 1, todo: 1 });
63
+ writeProject(dataDir, 'acme', { todo: 1 });
66
64
  const input = buildComposeDashboardInput({
67
65
  dashboardDataDir: dataDir,
68
66
  projectNames: ['acme'],
@@ -365,7 +363,6 @@ describe('composeDashboardText', () => {
365
363
  writeProject(dataDir, 'acme', {
366
364
  pjcode: 'acme',
367
365
  capturedAt: 'x',
368
- unread: 3,
369
366
  todo: 1,
370
367
  qc: 2,
371
368
  fail: 0,
@@ -411,9 +408,9 @@ describe('composeDashboardText', () => {
411
408
  ).toBe(
412
409
  '<tt>M55%&nbsp;C62%&nbsp;D89%&nbsp;cy14</tt><br>\n' +
413
410
  '<tt>LA&nbsp;16&nbsp;23&nbsp;40</tt><br>\n' +
414
- '<tt>pj&nbsp;&nbsp;&nbsp;unr&nbsp;tdo&nbsp;aqc&nbsp;fal&nbsp;prp&nbsp;aws&nbsp;dep</tt><br>\n' +
415
- '<tt>🟢ac&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;1</tt><br>\n' +
416
- '<tt>&nbsp;&nbsp;in&nbsp;&nbsp;--&nbsp;&nbsp;--&nbsp;&nbsp;--&nbsp;&nbsp;--&nbsp;&nbsp;--&nbsp;&nbsp;--&nbsp;&nbsp;--</tt><br>\n' +
411
+ '<tt>pj&nbsp;&nbsp;&nbsp;tdo&nbsp;aqc&nbsp;fal&nbsp;prp&nbsp;aws&nbsp;dep</tt><br>\n' +
412
+ '<tt>🟢ac&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;1</tt><br>\n' +
413
+ '<tt>&nbsp;&nbsp;in&nbsp;&nbsp;--&nbsp;&nbsp;--&nbsp;&nbsp;--&nbsp;&nbsp;--&nbsp;&nbsp;--&nbsp;&nbsp;--</tt><br>\n' +
417
414
  '<tt></tt><br>\n' +
418
415
  '<tt>🟢alice&nbsp;&nbsp;10%&nbsp;0d01h00&nbsp;&nbsp;12%&nbsp;5d00h00&nbsp;2&nbsp;1</tt><br>\n',
419
416
  );
@@ -445,7 +442,6 @@ describe('dashboardComposeFilesPresent', () => {
445
442
  const minimalProject = {
446
443
  pjcode: 'acme',
447
444
  capturedAt: 'x',
448
- unread: 0,
449
445
  todo: 0,
450
446
  qc: 0,
451
447
  fail: 0,
@@ -44,7 +44,6 @@ const parseDashboardRow = (value: unknown): DashboardRow | null => {
44
44
  if (!isRecord(value)) {
45
45
  return null;
46
46
  }
47
- const unread = asFiniteNumber(value.unread);
48
47
  const todo = asFiniteNumber(value.todo);
49
48
  const qc = asFiniteNumber(value.qc);
50
49
  const fail = asFiniteNumber(value.fail);
@@ -53,7 +52,6 @@ const parseDashboardRow = (value: unknown): DashboardRow | null => {
53
52
  const dep = asFiniteNumber(value.dep);
54
53
  const blocker = asFiniteNumber(value.blocker);
55
54
  if (
56
- unread === null ||
57
55
  todo === null ||
58
56
  qc === null ||
59
57
  fail === null ||
@@ -64,7 +62,7 @@ const parseDashboardRow = (value: unknown): DashboardRow | null => {
64
62
  ) {
65
63
  return null;
66
64
  }
67
- return { unread, todo, qc, fail, pr, ws, dep, blocker };
65
+ return { todo, qc, fail, pr, ws, dep, blocker };
68
66
  };
69
67
 
70
68
  const readProjectRow = (
@@ -71,7 +71,7 @@ describe('dashboard emitter filename matches composer lookup key', () => {
71
71
  dashboardDataDir: dir,
72
72
  pjcode: projectName,
73
73
  assigneeLogin: ASSIGNEE,
74
- issues: [makeIssue({ status: 'Unread' })],
74
+ issues: [makeIssue({ status: 'Awaiting Workspace' })],
75
75
  generatedAt: '2026-06-26T12:00:00.000Z',
76
76
  });
77
77
 
@@ -90,7 +90,7 @@ describe('dashboard emitter filename matches composer lookup key', () => {
90
90
  dashboardDataDir: dir,
91
91
  pjcode: projectName,
92
92
  assigneeLogin: ASSIGNEE,
93
- issues: [makeIssue({ status: 'Unread' })],
93
+ issues: [makeIssue({ status: 'Awaiting Workspace' })],
94
94
  generatedAt: '2026-06-26T12:00:00.000Z',
95
95
  });
96
96
  }
@@ -119,7 +119,10 @@ describe('dashboard emitter filename matches composer lookup key', () => {
119
119
 
120
120
  it('composes the full grid with no fallback row and shows the 2-char display labels', () => {
121
121
  const issuesByName: Record<string, Issue[]> = {
122
- acme: [makeIssue({ status: 'Unread' }), makeIssue({ status: 'Unread' })],
122
+ acme: [
123
+ makeIssue({ status: 'Failed Preparation' }),
124
+ makeIssue({ status: 'Failed Preparation' }),
125
+ ],
123
126
  globex: [makeIssue({ status: 'Awaiting Quality Check' })],
124
127
  initech: [makeIssue({ status: 'Awaiting Workspace' })],
125
128
  umbrella: [makeIssue({ status: 'Todo by human' })],
@@ -160,22 +163,14 @@ describe('dashboard emitter filename matches composer lookup key', () => {
160
163
  [
161
164
  wrap('M55% C62% D93% cy13'),
162
165
  wrap('LA 16 23 40'),
163
- wrap('pj unr tdo aqc fal prp aws dep'),
166
+ wrap('pj tdo aqc fal prp aws dep'),
167
+ wrap(`🟢${toDashboardDisplayLabel('acme')} 0 0 2 0 0 0`),
168
+ wrap(`🟢${toDashboardDisplayLabel('globex')} 0 1 0 0 0 0`),
169
+ wrap(`🟢${toDashboardDisplayLabel('initech')} 0 0 0 0 1 0`),
164
170
  wrap(
165
- `🟢${toDashboardDisplayLabel('acme')} 2 0 0 0 0 0 0`,
166
- ),
167
- wrap(
168
- `🟢${toDashboardDisplayLabel('globex')} 0 0 1 0 0 0 0`,
169
- ),
170
- wrap(
171
- `🟢${toDashboardDisplayLabel('initech')} 0 0 0 0 0 1 0`,
172
- ),
173
- wrap(
174
- `🟢${toDashboardDisplayLabel('umbrella')} 0 1 0 0 0 0 0`,
175
- ),
176
- wrap(
177
- `🟢${toDashboardDisplayLabel('soylent')} 0 0 0 0 1 0 0`,
171
+ `🟢${toDashboardDisplayLabel('umbrella')} 1 0 0 0 0 0`,
178
172
  ),
173
+ wrap(`🟢${toDashboardDisplayLabel('soylent')} 0 0 0 1 0 0`),
179
174
  wrap(''),
180
175
  ].join('\n') + '\n';
181
176
  expect(composed).toBe(expected);
@@ -28,14 +28,6 @@ const tabBadge = (page: Page, label: string) =>
28
28
  const itemRowByText = (page: Page, text: string) =>
29
29
  page.locator('.console-item-row', { hasText: text });
30
30
 
31
- const processSelectedItemViaStatus = async (page: Page): Promise<void> => {
32
- const statusButton = page
33
- .locator('.console-op-button', { hasText: 'Awaiting Workspace' })
34
- .first();
35
- await expect(statusButton).toBeVisible();
36
- await statusButton.click();
37
- };
38
-
39
31
  test('shows CI and conflict badges in the directly opened PR detail header', async ({
40
32
  page,
41
33
  }) => {
@@ -72,7 +64,6 @@ test('processing tabs drives auto-advance and keeps emptied badges at zero', asy
72
64
 
73
65
  await expect(activeTabLabel(page)).toHaveText('Awaiting Quality Check');
74
66
  await expect(tabBadge(page, 'Awaiting Quality Check')).toHaveText('1');
75
- await expect(tabBadge(page, 'Unread')).toHaveText('2');
76
67
  await expect(tabBadge(page, 'Triage')).toHaveText('2');
77
68
  await expect(tabBadge(page, 'Todo by human')).toHaveText('1');
78
69
 
@@ -86,38 +77,19 @@ test('processing tabs drives auto-advance and keeps emptied badges at zero', asy
86
77
  await expect(approveButton).toBeVisible();
87
78
  await approveButton.click();
88
79
 
89
- await expect(activeTabLabel(page)).toHaveText('Unread', { timeout: 8000 });
90
- await expect(tabByLabel(page, 'Awaiting Quality Check')).toHaveCount(0, {
91
- timeout: 8000,
92
- });
93
-
94
- await itemRowByText(
95
- page,
96
- 'Scaffold React console UI under entry-points with build bundling',
97
- ).click();
98
- await processSelectedItemViaStatus(page);
99
- await expect(tabBadge(page, 'Unread')).toHaveText('1', { timeout: 8000 });
100
- await tabByLabel(page, 'Unread').click();
101
-
102
- await itemRowByText(
103
- page,
104
- 'Add server-side console API handlers for read and operation endpoints',
105
- ).click();
106
- await processSelectedItemViaStatus(page);
107
-
108
80
  await expect(activeTabLabel(page)).toHaveText('Triage', { timeout: 8000 });
109
- await expect(tabByLabel(page, 'Unread')).toHaveCount(0, {
81
+ await expect(tabByLabel(page, 'Awaiting Quality Check')).toHaveCount(0, {
110
82
  timeout: 8000,
111
83
  });
112
84
 
113
85
  await tabByLabel(page, 'Todo by human').click();
114
86
  await expect(activeTabLabel(page)).toHaveText('Todo by human');
115
- await expect(tabByLabel(page, 'Unread')).toHaveCount(0);
87
+ await expect(tabByLabel(page, 'Awaiting Quality Check')).toHaveCount(0);
116
88
  await expect(tabBadge(page, 'Todo by human')).toHaveText('1');
117
89
 
118
90
  await tabByLabel(page, 'Triage').click();
119
91
  await expect(activeTabLabel(page)).toHaveText('Triage');
120
- await expect(tabByLabel(page, 'Unread')).toHaveCount(0);
92
+ await expect(tabByLabel(page, 'Awaiting Quality Check')).toHaveCount(0);
121
93
  await expect(tabBadge(page, 'Triage')).toHaveText('2');
122
94
  });
123
95
 
@@ -348,7 +320,7 @@ test('renders the stories tab with non-gray stories, their open item counts, and
348
320
  const tdpmRow = page.locator('.console-story-list-row', {
349
321
  hasText: 'TDPM Console port',
350
322
  });
351
- await expect(tdpmRow.locator('.console-story-count')).toHaveText('6');
323
+ await expect(tdpmRow.locator('.console-story-count')).toHaveText('4');
352
324
  await expect(
353
325
  tdpmRow.locator('.console-op-button', { hasText: 'Add task' }),
354
326
  ).toBeVisible();
@@ -110,7 +110,6 @@ const AWAITING_WORKSPACE_OPTION: ConsoleFixtureFieldOption = {
110
110
  };
111
111
 
112
112
  const STATUS_OPTIONS: ConsoleFixtureFieldOption[] = [
113
- { id: 'f75ad846', name: 'Unread', color: 'ORANGE' },
114
113
  AWAITING_WORKSPACE_OPTION,
115
114
  { id: 'f57f1ce9', name: 'Preparation', color: 'YELLOW' },
116
115
  { id: 'fd313492', name: 'Failed Preparation', color: 'RED' },
@@ -236,22 +235,6 @@ export const CONSOLE_E2E_TAB_ITEMS: Record<string, ConsoleFixtureListItem[]> = {
236
235
  '2026-06-10T11:42:00.000Z',
237
236
  ),
238
237
  ],
239
- unread: [
240
- issueItem(
241
- 845,
242
- 'Scaffold React console UI under entry-points with build bundling',
243
- 'UNR00845',
244
- 'TDPM Console port',
245
- '2026-06-16T22:01:55.000Z',
246
- ),
247
- issueItem(
248
- 853,
249
- 'Add server-side console API handlers for read and operation endpoints',
250
- 'UNR00853',
251
- 'TDPM Console port',
252
- '2026-06-17T05:48:09.000Z',
253
- ),
254
- ],
255
238
  'failed-preparation': [
256
239
  {
257
240
  ...issueItem(
@@ -295,7 +278,7 @@ const CONSOLE_E2E_STORIES_SNAPSHOT = {
295
278
  storyName: 'TDPM Console port',
296
279
  storyOptionId: '1491051e',
297
280
  color: 'BLUE',
298
- openItemCount: 6,
281
+ openItemCount: 4,
299
282
  },
300
283
  {
301
284
  storyName: 'Publish product documentation site',
@@ -23,7 +23,6 @@ const counts: Record<ConsoleTabName, number> = {
23
23
  'workflow-blocker': 5,
24
24
  prs: 35,
25
25
  triage: 132,
26
- unread: 18,
27
26
  'failed-preparation': 2,
28
27
  'todo-by-human': 66,
29
28
  'todo-by-agent': 24,
@@ -44,9 +43,8 @@ export const ZeroCountTabsHidden: Story = {
44
43
  'workflow-blocker': 0,
45
44
  prs: 35,
46
45
  triage: 0,
47
- unread: 18,
48
46
  'failed-preparation': 0,
49
- 'todo-by-human': 0,
47
+ 'todo-by-human': 18,
50
48
  'todo-by-agent': 0,
51
49
  stories: 0,
52
50
  },
@@ -60,9 +58,8 @@ export const ZeroCountActiveTabStaysVisible: Story = {
60
58
  'workflow-blocker': 0,
61
59
  prs: 35,
62
60
  triage: 0,
63
- unread: 18,
64
61
  'failed-preparation': 0,
65
- 'todo-by-human': 0,
62
+ 'todo-by-human': 18,
66
63
  'todo-by-agent': 0,
67
64
  stories: 0,
68
65
  },
@@ -71,12 +68,11 @@ export const ZeroCountActiveTabStaysVisible: Story = {
71
68
 
72
69
  export const AfterAutoAdvanceToNextTab: Story = {
73
70
  args: {
74
- activeTab: 'unread',
71
+ activeTab: 'failed-preparation',
75
72
  counts: {
76
73
  'workflow-blocker': 0,
77
74
  prs: 0,
78
75
  triage: 0,
79
- unread: 7,
80
76
  'failed-preparation': 2,
81
77
  'todo-by-human': 4,
82
78
  'todo-by-agent': 0,
@@ -6,7 +6,6 @@ const counts: Record<ConsoleTabName, number> = {
6
6
  'workflow-blocker': 4,
7
7
  prs: 3,
8
8
  triage: 0,
9
- unread: 5,
10
9
  'failed-preparation': 0,
11
10
  'todo-by-human': 2,
12
11
  'todo-by-agent': 3,
@@ -27,7 +26,6 @@ describe('ConsoleTabList', () => {
27
26
  <ConsoleTabList {...baseProps} activeTab="prs" counts={counts} />,
28
27
  );
29
28
  expect(queryByText('Awaiting Quality Check')).not.toBeNull();
30
- expect(queryByText('Unread')).not.toBeNull();
31
29
  expect(queryByText('Todo by human')).not.toBeNull();
32
30
  expect(queryByText('Todo by agent')).not.toBeNull();
33
31
  expect(queryByText('Triage')).toBeNull();
@@ -114,8 +112,8 @@ describe('ConsoleTabList', () => {
114
112
  onSelectTab={onSelectTab}
115
113
  />,
116
114
  );
117
- fireEvent.click(getByText('Unread'));
118
- expect(onSelectTab).toHaveBeenCalledWith('unread');
115
+ fireEvent.click(getByText('Todo by human'));
116
+ expect(onSelectTab).toHaveBeenCalledWith('todo-by-human');
119
117
  });
120
118
 
121
119
  it('prefixes the snapshot info with "(cached)" and sets data-from-cache when data is from cache', () => {
@@ -91,7 +91,7 @@ describe('ConsoleOperationMenu', () => {
91
91
  it('hides the review group when there is no pull request', () => {
92
92
  const { queryByText } = render(
93
93
  <ConsoleOperationMenu
94
- tab="unread"
94
+ tab="todo-by-human"
95
95
  item={issueItem}
96
96
  hasPullRequest={false}
97
97
  rejectEnabled={false}
@@ -12,7 +12,6 @@ const counts = (
12
12
  'workflow-blocker': 0,
13
13
  prs: 0,
14
14
  triage: 0,
15
- unread: 0,
16
15
  'failed-preparation': 0,
17
16
  'todo-by-human': 0,
18
17
  'todo-by-agent': 0,
@@ -63,10 +62,10 @@ describe('useConsoleNavigation', () => {
63
62
  it('selects a tab and updates the path', () => {
64
63
  const { result } = renderHook(() => useConsoleNavigation('acme', counts()));
65
64
  act(() => {
66
- result.current.selectTab('unread');
65
+ result.current.selectTab('triage');
67
66
  });
68
- expect(result.current.activeTab).toBe('unread');
69
- expect(window.location.pathname).toBe('/projects/acme/unread');
67
+ expect(result.current.activeTab).toBe('triage');
68
+ expect(window.location.pathname).toBe('/projects/acme/triage');
70
69
  });
71
70
 
72
71
  it('opens an item and reflects it in the hash', () => {
@@ -103,7 +102,6 @@ describe('useConsoleNavigation default tab without a tab segment', () => {
103
102
  'workflow-blocker': 3,
104
103
  prs: 5,
105
104
  triage: 2,
106
- unread: 9,
107
105
  'failed-preparation': 1,
108
106
  'todo-by-human': 4,
109
107
  }),
@@ -134,14 +132,14 @@ describe('useConsoleNavigation default tab without a tab segment', () => {
134
132
  { initialProps: { tabCounts: counts() } },
135
133
  );
136
134
  expect(result.current.activeTab).toBe('workflow-blocker');
137
- rerender({ tabCounts: counts({ unread: 6 }) });
138
- expect(result.current.activeTab).toBe('unread');
135
+ rerender({ tabCounts: counts({ triage: 6 }) });
136
+ expect(result.current.activeTab).toBe('triage');
139
137
  });
140
138
 
141
139
  it('keeps the tab from the path even when counts are present', () => {
142
140
  window.history.replaceState({}, '', '/projects/acme/triage?k=token');
143
141
  const { result } = renderHook(() =>
144
- useConsoleNavigation('acme', counts({ unread: 6 })),
142
+ useConsoleNavigation('acme', counts({ triage: 6 })),
145
143
  );
146
144
  expect(result.current.activeTab).toBe('triage');
147
145
  });
@@ -2,7 +2,7 @@ import {
2
2
  findNextNonEmptyTabToRight,
3
3
  resolveDefaultActiveTab,
4
4
  } from './tabAdvance';
5
- import { CONSOLE_TABS, type ConsoleTabName } from './types';
5
+ import type { ConsoleTabName } from './types';
6
6
 
7
7
  const counts = (
8
8
  overrides: Partial<Record<ConsoleTabName, number>>,
@@ -10,7 +10,6 @@ const counts = (
10
10
  'workflow-blocker': 0,
11
11
  prs: 0,
12
12
  triage: 0,
13
- unread: 0,
14
13
  'failed-preparation': 0,
15
14
  'todo-by-human': 0,
16
15
  'todo-by-agent': 0,
@@ -18,17 +17,10 @@ const counts = (
18
17
  ...overrides,
19
18
  });
20
19
 
21
- describe('CONSOLE_TABS ordering', () => {
22
- it('places Unread before Triage so unseen items are worked first', () => {
23
- const names = CONSOLE_TABS.map((tab) => tab.name);
24
- expect(names.indexOf('unread')).toBeLessThan(names.indexOf('triage'));
25
- });
26
- });
27
-
28
20
  describe('findNextNonEmptyTabToRight', () => {
29
21
  it('returns the first non-empty tab to the right of the active tab', () => {
30
- expect(findNextNonEmptyTabToRight('prs', counts({ unread: 7 }))).toBe(
31
- 'unread',
22
+ expect(findNextNonEmptyTabToRight('prs', counts({ triage: 7 }))).toBe(
23
+ 'triage',
32
24
  );
33
25
  });
34
26
 
@@ -36,7 +28,7 @@ describe('findNextNonEmptyTabToRight', () => {
36
28
  expect(
37
29
  findNextNonEmptyTabToRight(
38
30
  'prs',
39
- counts({ triage: 0, unread: 0, 'todo-by-human': 4 }),
31
+ counts({ triage: 0, 'todo-by-human': 4 }),
40
32
  ),
41
33
  ).toBe('todo-by-human');
42
34
  });
@@ -51,14 +43,14 @@ describe('findNextNonEmptyTabToRight', () => {
51
43
  });
52
44
 
53
45
  it('returns the immediately adjacent tab when it is non-empty', () => {
54
- expect(
55
- findNextNonEmptyTabToRight('prs', counts({ triage: 12, unread: 7 })),
56
- ).toBe('unread');
46
+ expect(findNextNonEmptyTabToRight('prs', counts({ triage: 12 }))).toBe(
47
+ 'triage',
48
+ );
57
49
  });
58
50
 
59
51
  it('returns null when no tab to the right has any items', () => {
60
52
  expect(
61
- findNextNonEmptyTabToRight('unread', counts({ prs: 35 })),
53
+ findNextNonEmptyTabToRight('todo-by-human', counts({ prs: 35 })),
62
54
  ).toBeNull();
63
55
  });
64
56
 
@@ -77,7 +69,6 @@ describe('resolveDefaultActiveTab', () => {
77
69
  'workflow-blocker': 3,
78
70
  prs: 5,
79
71
  triage: 2,
80
- unread: 9,
81
72
  'failed-preparation': 1,
82
73
  'todo-by-human': 4,
83
74
  }),
@@ -145,7 +145,6 @@ export type ConsoleTabName =
145
145
  | 'workflow-blocker'
146
146
  | 'prs'
147
147
  | 'triage'
148
- | 'unread'
149
148
  | 'failed-preparation'
150
149
  | 'todo-by-human'
151
150
  | 'todo-by-agent'
@@ -166,7 +165,6 @@ export type ConsoleTab = {
166
165
  export const CONSOLE_TABS: ConsoleTab[] = [
167
166
  { name: 'workflow-blocker', label: 'Workflow Blocker' },
168
167
  { name: 'prs', label: 'Awaiting Quality Check' },
169
- { name: 'unread', label: 'Unread' },
170
168
  { name: 'triage', label: 'Triage' },
171
169
  { name: 'failed-preparation', label: 'Failed Preparation' },
172
170
  { name: 'todo-by-human', label: 'Todo by human' },
@@ -163,7 +163,7 @@ describe('ConsoleItemDetailContainer', () => {
163
163
  }));
164
164
  const { container, getByPlaceholderText, getByText } = render(
165
165
  <ConsoleItemDetailContainer
166
- tab="unread"
166
+ tab="todo-by-human"
167
167
  item={issueItem}
168
168
  caches={buildCaches()}
169
169
  operations={operations}
@@ -253,7 +253,7 @@ describe('ConsoleItemDetailContainer', () => {
253
253
  }));
254
254
  const { container, getByPlaceholderText, getByText } = render(
255
255
  <ConsoleItemDetailContainer
256
- tab="unread"
256
+ tab="todo-by-human"
257
257
  item={issueItem}
258
258
  caches={buildCaches()}
259
259
  operations={operations}
@@ -420,7 +420,7 @@ describe('ConsoleItemDetailContainer', () => {
420
420
  getByText,
421
421
  } = render(
422
422
  <ConsoleItemDetailContainer
423
- tab="unread"
423
+ tab="todo-by-human"
424
424
  item={issueItemWithRelatedPullRequest}
425
425
  caches={buildCaches({
426
426
  relatedPrs: [relatedPullRequest],
@@ -47,7 +47,7 @@ const listPayload = (tab: string) => ({
47
47
  createdAt: '2026-06-17T00:00:00.000Z',
48
48
  },
49
49
  ]
50
- : tab === 'unread'
50
+ : tab === 'todo-by-human'
51
51
  ? [
52
52
  {
53
53
  number: 866,
@@ -60,7 +60,7 @@ const listPayload = (tab: string) => ({
60
60
  isPr: false,
61
61
  relatedOpenPullRequestUrls: [],
62
62
  story: 'TDPM Console port',
63
- status: 'Unread',
63
+ status: 'Todo by human',
64
64
  nextActionDate: null,
65
65
  nextActionHour: null,
66
66
  dependedIssueUrls: [],
@@ -271,7 +271,7 @@ describe('ConsolePage', () => {
271
271
  expect(getByText('Add serveConsole subcommand')).toBeInTheDocument();
272
272
  });
273
273
 
274
- fireEvent.click(getByText('Unread'));
274
+ fireEvent.click(getByText('Todo by human'));
275
275
  await waitFor(() => {
276
276
  expect(
277
277
  getByText('Notify finished issue preparation'),
@@ -288,10 +288,9 @@ describe('ConsolePage', () => {
288
288
  });
289
289
  const tabs = within(tabBar());
290
290
  expect(tabs.queryByText('Awaiting Quality Check')).not.toBeNull();
291
- expect(tabs.queryByText('Unread')).not.toBeNull();
291
+ expect(tabs.queryByText('Todo by human')).not.toBeNull();
292
292
  expect(tabs.queryByText('Triage')).toBeNull();
293
293
  expect(tabs.queryByText('Failed Preparation')).toBeNull();
294
- expect(tabs.queryByText('Todo by human')).toBeNull();
295
294
  });
296
295
 
297
296
  it('does not render the project header bar above the tab bar', async () => {
@@ -855,7 +854,7 @@ describe('ConsolePage auto-advance tab', () => {
855
854
  });
856
855
  expect(
857
856
  within(tabBar())
858
- .getByText('Unread')
857
+ .getByText('Todo by human')
859
858
  .closest('a')
860
859
  ?.getAttribute('aria-current'),
861
860
  ).toBe('page');