github-issue-tower-defence-management 1.146.0 → 1.146.2

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 (111) hide show
  1. package/CHANGELOG.md +23 -9
  2. package/README.md +1 -1
  3. package/bin/adapter/entry-points/cli/index.js +29 -7
  4. package/bin/adapter/entry-points/cli/index.js.map +1 -1
  5. package/bin/adapter/entry-points/cli/projectConfig.js +3 -0
  6. package/bin/adapter/entry-points/cli/projectConfig.js.map +1 -1
  7. package/bin/adapter/entry-points/console/consoleGithubTokenResolver.js +41 -0
  8. package/bin/adapter/entry-points/console/consoleGithubTokenResolver.js.map +1 -0
  9. package/bin/adapter/entry-points/console/consoleOperationApi.js +34 -16
  10. package/bin/adapter/entry-points/console/consoleOperationApi.js.map +1 -1
  11. package/bin/adapter/entry-points/console/ensureConsoleRunning.js +6 -1
  12. package/bin/adapter/entry-points/console/ensureConsoleRunning.js.map +1 -1
  13. package/bin/adapter/entry-points/console/webServer.js +3 -4
  14. package/bin/adapter/entry-points/console/webServer.js.map +1 -1
  15. package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js +3 -1
  16. package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js.map +1 -1
  17. package/bin/adapter/repositories/GraphqlProjectRepository.js +75 -4
  18. package/bin/adapter/repositories/GraphqlProjectRepository.js.map +1 -1
  19. package/bin/adapter/repositories/utils.js +2 -4
  20. package/bin/adapter/repositories/utils.js.map +1 -1
  21. package/bin/domain/entities/ProjectFieldName.js +6 -0
  22. package/bin/domain/entities/ProjectFieldName.js.map +1 -0
  23. package/bin/domain/entities/RequiredProjectField.js +47 -0
  24. package/bin/domain/entities/RequiredProjectField.js.map +1 -0
  25. package/bin/domain/usecases/HandleScheduledEventUseCase.js +5 -1
  26. package/bin/domain/usecases/HandleScheduledEventUseCase.js.map +1 -1
  27. package/bin/domain/usecases/ProjectRequiredFieldCreateUseCase.js +25 -0
  28. package/bin/domain/usecases/ProjectRequiredFieldCreateUseCase.js.map +1 -0
  29. package/bin/domain/usecases/SetupTowerDefenceProjectUseCase.js +6 -1
  30. package/bin/domain/usecases/SetupTowerDefenceProjectUseCase.js.map +1 -1
  31. package/bin/domain/usecases/dashboard/DashboardProjectCode.js +17 -13
  32. package/bin/domain/usecases/dashboard/DashboardProjectCode.js.map +1 -1
  33. package/package.json +1 -1
  34. package/src/adapter/entry-points/cli/index.test.ts +62 -2
  35. package/src/adapter/entry-points/cli/index.ts +58 -11
  36. package/src/adapter/entry-points/cli/projectConfig.ts +8 -0
  37. package/src/adapter/entry-points/console/consoleDataDelivery.test.ts +37 -39
  38. package/src/adapter/entry-points/console/consoleDoneStore.test.ts +33 -33
  39. package/src/adapter/entry-points/console/consoleGithubTokenResolver.test.ts +135 -0
  40. package/src/adapter/entry-points/console/consoleGithubTokenResolver.ts +55 -0
  41. package/src/adapter/entry-points/console/consoleItemUrlLookup.test.ts +6 -6
  42. package/src/adapter/entry-points/console/consoleOperationApi.test.ts +92 -70
  43. package/src/adapter/entry-points/console/consoleOperationApi.ts +51 -44
  44. package/src/adapter/entry-points/console/consoleProjectResolver.test.ts +35 -35
  45. package/src/adapter/entry-points/console/dashboardComposeService.test.ts +28 -28
  46. package/src/adapter/entry-points/console/dashboardEmitterComposerKey.test.ts +26 -20
  47. package/src/adapter/entry-points/console/ensureConsoleRunning.test.ts +19 -2
  48. package/src/adapter/entry-points/console/ensureConsoleRunning.ts +8 -0
  49. package/src/adapter/entry-points/console/ui/e2e/consoleScenario.spec.ts +1 -1
  50. package/src/adapter/entry-points/console/ui/e2e/consoleTestHarness.ts +1 -1
  51. package/src/adapter/entry-points/console/ui/src/features/console/components/layout/ConsoleTabList.stories.tsx +2 -2
  52. package/src/adapter/entry-points/console/ui/src/features/console/components/layout/ConsoleTabList.test.tsx +3 -3
  53. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleNavigation.test.ts +19 -31
  54. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleOperations.test.ts +24 -32
  55. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleOverlay.test.ts +6 -6
  56. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsolePjcode.test.ts +4 -4
  57. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleTabData.test.ts +8 -8
  58. package/src/adapter/entry-points/console/ui/src/features/console/lib/consoleApi.test.ts +5 -5
  59. package/src/adapter/entry-points/console/ui/src/features/console/logic/overlay.test.ts +1 -1
  60. package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsolePage.test.tsx +13 -13
  61. package/src/adapter/entry-points/console/webServer.test.ts +55 -52
  62. package/src/adapter/entry-points/console/webServer.ts +5 -4
  63. package/src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.test.ts +2 -2
  64. package/src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.ts +4 -0
  65. package/src/adapter/entry-points/handlers/dashboardRowWriter.test.ts +5 -5
  66. package/src/adapter/entry-points/handlers/inTmuxByHumanDataWriter.test.ts +5 -5
  67. package/src/adapter/repositories/GraphqlProjectRepository.ts +110 -4
  68. package/src/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.test.ts +1 -1
  69. package/src/adapter/repositories/utils.ts +3 -3
  70. package/src/domain/entities/ProjectFieldName.ts +2 -0
  71. package/src/domain/entities/RequiredProjectField.ts +64 -0
  72. package/src/domain/usecases/HandleScheduledEventUseCase.test.ts +4 -0
  73. package/src/domain/usecases/HandleScheduledEventUseCase.ts +5 -0
  74. package/src/domain/usecases/NotifySilentLiveSessionsUseCase.test.ts +3 -3
  75. package/src/domain/usecases/ProjectRequiredFieldCreateUseCase.test.ts +159 -0
  76. package/src/domain/usecases/ProjectRequiredFieldCreateUseCase.ts +32 -0
  77. package/src/domain/usecases/SetWorkflowManagementIssueToStoryUseCase.test.ts +19 -19
  78. package/src/domain/usecases/SetupTowerDefenceProjectUseCase.test.ts +24 -14
  79. package/src/domain/usecases/SetupTowerDefenceProjectUseCase.ts +10 -1
  80. package/src/domain/usecases/adapter-interfaces/ProjectRepository.ts +6 -0
  81. package/src/domain/usecases/dashboard/ComposeDashboardUseCase.test.ts +28 -28
  82. package/src/domain/usecases/dashboard/DashboardProjectCode.test.ts +21 -21
  83. package/src/domain/usecases/dashboard/DashboardProjectCode.ts +21 -15
  84. package/types/adapter/entry-points/cli/index.d.ts.map +1 -1
  85. package/types/adapter/entry-points/cli/projectConfig.d.ts +1 -0
  86. package/types/adapter/entry-points/cli/projectConfig.d.ts.map +1 -1
  87. package/types/adapter/entry-points/console/consoleGithubTokenResolver.d.ts +6 -0
  88. package/types/adapter/entry-points/console/consoleGithubTokenResolver.d.ts.map +1 -0
  89. package/types/adapter/entry-points/console/consoleOperationApi.d.ts +2 -1
  90. package/types/adapter/entry-points/console/consoleOperationApi.d.ts.map +1 -1
  91. package/types/adapter/entry-points/console/ensureConsoleRunning.d.ts +1 -1
  92. package/types/adapter/entry-points/console/ensureConsoleRunning.d.ts.map +1 -1
  93. package/types/adapter/entry-points/console/webServer.d.ts +2 -2
  94. package/types/adapter/entry-points/console/webServer.d.ts.map +1 -1
  95. package/types/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.d.ts.map +1 -1
  96. package/types/adapter/repositories/GraphqlProjectRepository.d.ts +4 -1
  97. package/types/adapter/repositories/GraphqlProjectRepository.d.ts.map +1 -1
  98. package/types/adapter/repositories/utils.d.ts.map +1 -1
  99. package/types/domain/entities/ProjectFieldName.d.ts +2 -0
  100. package/types/domain/entities/ProjectFieldName.d.ts.map +1 -0
  101. package/types/domain/entities/RequiredProjectField.d.ts +13 -0
  102. package/types/domain/entities/RequiredProjectField.d.ts.map +1 -0
  103. package/types/domain/usecases/HandleScheduledEventUseCase.d.ts +3 -1
  104. package/types/domain/usecases/HandleScheduledEventUseCase.d.ts.map +1 -1
  105. package/types/domain/usecases/ProjectRequiredFieldCreateUseCase.d.ts +10 -0
  106. package/types/domain/usecases/ProjectRequiredFieldCreateUseCase.d.ts.map +1 -0
  107. package/types/domain/usecases/SetupTowerDefenceProjectUseCase.d.ts.map +1 -1
  108. package/types/domain/usecases/adapter-interfaces/ProjectRepository.d.ts +3 -0
  109. package/types/domain/usecases/adapter-interfaces/ProjectRepository.d.ts.map +1 -1
  110. package/types/domain/usecases/dashboard/DashboardProjectCode.d.ts +2 -2
  111. package/types/domain/usecases/dashboard/DashboardProjectCode.d.ts.map +1 -1
@@ -244,7 +244,7 @@ test('lists a still-open item and keeps its tab visible when the browser overlay
244
244
 
245
245
  await page.evaluate(() => {
246
246
  localStorage.setItem(
247
- 'pv_overlay_umino',
247
+ 'pv_overlay_acme',
248
248
  JSON.stringify({
249
249
  PVTI_lADOABCD1234zgTODO00869: {
250
250
  done: true,
@@ -19,7 +19,7 @@ import {
19
19
  } from '../../consoleReadApi';
20
20
  import { startWebServer } from '../../webServer';
21
21
 
22
- export const CONSOLE_E2E_PJCODE = 'umino';
22
+ export const CONSOLE_E2E_PJCODE = 'acme';
23
23
  export const CONSOLE_E2E_TOKEN = 'console-e2e-fixture-token-3f9c1a';
24
24
 
25
25
  export type ConsoleE2eReviewCommentCall = {
@@ -7,9 +7,9 @@ const meta: Meta<typeof ConsoleTabList> = {
7
7
  title: 'Console/ConsoleTabList',
8
8
  component: ConsoleTabList,
9
9
  args: {
10
- pjcode: 'umino',
10
+ pjcode: 'acme',
11
11
  generatedAt: '2026-06-19T08:42:11.000Z',
12
- tabHref: (tab: ConsoleTabName) => `/projects/umino/${tab}`,
12
+ tabHref: (tab: ConsoleTabName) => `/projects/acme/${tab}`,
13
13
  onSelectTab: () => {},
14
14
  },
15
15
  };
@@ -13,9 +13,9 @@ const counts: Record<ConsoleTabName, number> = {
13
13
  };
14
14
 
15
15
  const baseProps = {
16
- pjcode: 'umino',
16
+ pjcode: 'acme',
17
17
  generatedAt: '2026-06-19T08:42:11.000Z',
18
- tabHref: (tab: ConsoleTabName) => `/projects/umino/${tab}`,
18
+ tabHref: (tab: ConsoleTabName) => `/projects/acme/${tab}`,
19
19
  onSelectTab: () => {},
20
20
  };
21
21
 
@@ -87,7 +87,7 @@ describe('ConsoleTabList', () => {
87
87
  const { getByText } = render(
88
88
  <ConsoleTabList {...baseProps} activeTab="prs" counts={counts} />,
89
89
  );
90
- expect(getByText('umino')).toBeInTheDocument();
90
+ expect(getByText('acme')).toBeInTheDocument();
91
91
  expect(getByText('snapshot: 2026-06-19T08:42:11.000Z')).toBeInTheDocument();
92
92
  });
93
93
 
@@ -21,15 +21,15 @@ const counts = (
21
21
 
22
22
  describe('parseTabFromPath', () => {
23
23
  it('reads a known tab from the project path', () => {
24
- expect(parseTabFromPath('/projects/umino/triage')).toBe('triage');
24
+ expect(parseTabFromPath('/projects/acme/triage')).toBe('triage');
25
25
  });
26
26
 
27
27
  it('returns null for an unknown tab segment', () => {
28
- expect(parseTabFromPath('/projects/umino/unknown')).toBeNull();
28
+ expect(parseTabFromPath('/projects/acme/unknown')).toBeNull();
29
29
  });
30
30
 
31
31
  it('returns null when there is no tab segment', () => {
32
- expect(parseTabFromPath('/projects/umino')).toBeNull();
32
+ expect(parseTabFromPath('/projects/acme')).toBeNull();
33
33
  });
34
34
  });
35
35
 
@@ -45,39 +45,31 @@ describe('parseItemKeyFromHash', () => {
45
45
 
46
46
  describe('useConsoleNavigation', () => {
47
47
  beforeEach(() => {
48
- window.history.replaceState({}, '', '/projects/umino/prs?k=token');
48
+ window.history.replaceState({}, '', '/projects/acme/prs?k=token');
49
49
  });
50
50
 
51
51
  it('reads the active tab from the path and no selected item', () => {
52
- const { result } = renderHook(() =>
53
- useConsoleNavigation('umino', counts()),
54
- );
52
+ const { result } = renderHook(() => useConsoleNavigation('acme', counts()));
55
53
  expect(result.current.activeTab).toBe('prs');
56
54
  expect(result.current.selectedItemKey).toBeNull();
57
55
  });
58
56
 
59
57
  it('builds a project tab href', () => {
60
- const { result } = renderHook(() =>
61
- useConsoleNavigation('umino', counts()),
62
- );
63
- expect(result.current.tabHref('triage')).toBe('/projects/umino/triage');
58
+ const { result } = renderHook(() => useConsoleNavigation('acme', counts()));
59
+ expect(result.current.tabHref('triage')).toBe('/projects/acme/triage');
64
60
  });
65
61
 
66
62
  it('selects a tab and updates the path', () => {
67
- const { result } = renderHook(() =>
68
- useConsoleNavigation('umino', counts()),
69
- );
63
+ const { result } = renderHook(() => useConsoleNavigation('acme', counts()));
70
64
  act(() => {
71
65
  result.current.selectTab('unread');
72
66
  });
73
67
  expect(result.current.activeTab).toBe('unread');
74
- expect(window.location.pathname).toBe('/projects/umino/unread');
68
+ expect(window.location.pathname).toBe('/projects/acme/unread');
75
69
  });
76
70
 
77
71
  it('opens an item and reflects it in the hash', () => {
78
- const { result } = renderHook(() =>
79
- useConsoleNavigation('umino', counts()),
80
- );
72
+ const { result } = renderHook(() => useConsoleNavigation('acme', counts()));
81
73
  act(() => {
82
74
  result.current.openItem('PVTI_open');
83
75
  });
@@ -86,10 +78,8 @@ describe('useConsoleNavigation', () => {
86
78
  });
87
79
 
88
80
  it('closes an item and clears the hash', () => {
89
- window.history.replaceState({}, '', '/projects/umino/prs#item/PVTI_open');
90
- const { result } = renderHook(() =>
91
- useConsoleNavigation('umino', counts()),
92
- );
81
+ window.history.replaceState({}, '', '/projects/acme/prs#item/PVTI_open');
82
+ const { result } = renderHook(() => useConsoleNavigation('acme', counts()));
93
83
  expect(result.current.selectedItemKey).toBe('PVTI_open');
94
84
  act(() => {
95
85
  result.current.closeItem();
@@ -101,13 +91,13 @@ describe('useConsoleNavigation', () => {
101
91
 
102
92
  describe('useConsoleNavigation default tab without a tab segment', () => {
103
93
  beforeEach(() => {
104
- window.history.replaceState({}, '', '/projects/umino?k=token');
94
+ window.history.replaceState({}, '', '/projects/acme?k=token');
105
95
  });
106
96
 
107
97
  it('lands on the left-most tab when all tabs are non-empty', () => {
108
98
  const { result } = renderHook(() =>
109
99
  useConsoleNavigation(
110
- 'umino',
100
+ 'acme',
111
101
  counts({
112
102
  'workflow-blocker': 3,
113
103
  prs: 5,
@@ -124,7 +114,7 @@ describe('useConsoleNavigation default tab without a tab segment', () => {
124
114
  it('skips the empty left-most tab and lands on the next non-empty tab', () => {
125
115
  const { result } = renderHook(() =>
126
116
  useConsoleNavigation(
127
- 'umino',
117
+ 'acme',
128
118
  counts({ 'workflow-blocker': 0, prs: 0, triage: 8 }),
129
119
  ),
130
120
  );
@@ -132,16 +122,14 @@ describe('useConsoleNavigation default tab without a tab segment', () => {
132
122
  });
133
123
 
134
124
  it('falls back to the first tab when every tab is empty', () => {
135
- const { result } = renderHook(() =>
136
- useConsoleNavigation('umino', counts()),
137
- );
125
+ const { result } = renderHook(() => useConsoleNavigation('acme', counts()));
138
126
  expect(result.current.activeTab).toBe('workflow-blocker');
139
127
  });
140
128
 
141
129
  it('updates the default tab when counts arrive after the initial render', () => {
142
130
  const { result, rerender } = renderHook(
143
131
  ({ tabCounts }: { tabCounts: Record<ConsoleTabName, number> }) =>
144
- useConsoleNavigation('umino', tabCounts),
132
+ useConsoleNavigation('acme', tabCounts),
145
133
  { initialProps: { tabCounts: counts() } },
146
134
  );
147
135
  expect(result.current.activeTab).toBe('workflow-blocker');
@@ -150,9 +138,9 @@ describe('useConsoleNavigation default tab without a tab segment', () => {
150
138
  });
151
139
 
152
140
  it('keeps the tab from the path even when counts are present', () => {
153
- window.history.replaceState({}, '', '/projects/umino/triage?k=token');
141
+ window.history.replaceState({}, '', '/projects/acme/triage?k=token');
154
142
  const { result } = renderHook(() =>
155
- useConsoleNavigation('umino', counts({ unread: 6 })),
143
+ useConsoleNavigation('acme', counts({ unread: 6 })),
156
144
  );
157
145
  expect(result.current.activeTab).toBe('triage');
158
146
  });
@@ -44,10 +44,10 @@ const lastBody = (fetchMock: jest.Mock): Record<string, unknown> => {
44
44
 
45
45
  const setup = () => {
46
46
  localStorage.clear();
47
- window.history.replaceState({}, '', '/projects/umino/prs?k=token');
47
+ window.history.replaceState({}, '', '/projects/acme/prs?k=token');
48
48
  return renderHook(() => {
49
- const overlay = useConsoleOverlay('umino');
50
- const operations = useConsoleOperations('umino', 'prs', overlay);
49
+ const overlay = useConsoleOverlay('acme');
50
+ const operations = useConsoleOperations('acme', 'prs', overlay);
51
51
  return { overlay, operations };
52
52
  });
53
53
  };
@@ -65,7 +65,7 @@ describe('useConsoleOperations', () => {
65
65
  });
66
66
  expect(fetchMock.mock.calls[0][0]).toBe('/api/review');
67
67
  expect(lastBody(fetchMock)).toMatchObject({
68
- pjcode: 'umino',
68
+ pjcode: 'acme',
69
69
  action: 'close',
70
70
  prUrl: prItem.url,
71
71
  commentBody: 'totally wrong',
@@ -99,7 +99,7 @@ describe('useConsoleOperations', () => {
99
99
  );
100
100
  });
101
101
  const stored = JSON.parse(
102
- localStorage.getItem(overlayStorageKey('umino')) ?? '{}',
102
+ localStorage.getItem(overlayStorageKey('acme')) ?? '{}',
103
103
  );
104
104
  expect(stored[prItem.projectItemId].done).toBe(true);
105
105
  });
@@ -115,7 +115,7 @@ describe('useConsoleOperations', () => {
115
115
  });
116
116
  expect(fetchMock.mock.calls[0][0]).toBe('/api/triage');
117
117
  expect(lastBody(fetchMock)).toMatchObject({
118
- pjcode: 'umino',
118
+ pjcode: 'acme',
119
119
  action: 'close_not_planned',
120
120
  issueUrl: issueItem.url,
121
121
  });
@@ -129,13 +129,13 @@ describe('useConsoleOperations', () => {
129
129
  });
130
130
  expect(fetchMock.mock.calls[0][0]).toBe('/api/triage');
131
131
  expect(lastBody(fetchMock)).toMatchObject({
132
- pjcode: 'umino',
132
+ pjcode: 'acme',
133
133
  action: 'close',
134
134
  issueUrl: prItem.url,
135
135
  });
136
136
  expect(prItem.url).toContain('/pull/');
137
137
  const stored = JSON.parse(
138
- localStorage.getItem(overlayStorageKey('umino')) ?? '{}',
138
+ localStorage.getItem(overlayStorageKey('acme')) ?? '{}',
139
139
  );
140
140
  expect(stored[prItem.projectItemId].done).toBe(true);
141
141
  });
@@ -152,7 +152,7 @@ describe('useConsoleOperations', () => {
152
152
  statusName: option.name,
153
153
  });
154
154
  const stored = JSON.parse(
155
- localStorage.getItem(overlayStorageKey('umino')) ?? '{}',
155
+ localStorage.getItem(overlayStorageKey('acme')) ?? '{}',
156
156
  );
157
157
  expect(stored[issueItem.projectItemId].status.name).toBe(option.name);
158
158
  });
@@ -166,7 +166,7 @@ describe('useConsoleOperations', () => {
166
166
  });
167
167
  expect(fetchMock.mock.calls[0][0]).toBe('/api/intmux');
168
168
  expect(lastBody(fetchMock)).toMatchObject({
169
- pjcode: 'umino',
169
+ pjcode: 'acme',
170
170
  action: 'set_intmux',
171
171
  });
172
172
  });
@@ -181,7 +181,7 @@ describe('useConsoleOperations', () => {
181
181
  );
182
182
  });
183
183
  const stored = JSON.parse(
184
- localStorage.getItem(overlayStorageKey('umino')) ?? '{}',
184
+ localStorage.getItem(overlayStorageKey('acme')) ?? '{}',
185
185
  );
186
186
  expect(stored[issueItem.projectItemId].done).toBe(true);
187
187
  });
@@ -189,18 +189,10 @@ describe('useConsoleOperations', () => {
189
189
  it('marks done on snooze in the todo-by-human tab so the item is skipped', async () => {
190
190
  captureFetch();
191
191
  localStorage.clear();
192
- window.history.replaceState(
193
- {},
194
- '',
195
- '/projects/umino/todo-by-human?k=token',
196
- );
192
+ window.history.replaceState({}, '', '/projects/acme/todo-by-human?k=token');
197
193
  const { result } = renderHook(() => {
198
- const overlay = useConsoleOverlay('umino');
199
- const operations = useConsoleOperations(
200
- 'umino',
201
- 'todo-by-human',
202
- overlay,
203
- );
194
+ const overlay = useConsoleOverlay('acme');
195
+ const operations = useConsoleOperations('acme', 'todo-by-human', overlay);
204
196
  return { overlay, operations };
205
197
  });
206
198
  await act(async () => {
@@ -210,7 +202,7 @@ describe('useConsoleOperations', () => {
210
202
  );
211
203
  });
212
204
  const stored = JSON.parse(
213
- localStorage.getItem(overlayStorageKey('umino')) ?? '{}',
205
+ localStorage.getItem(overlayStorageKey('acme')) ?? '{}',
214
206
  );
215
207
  expect(stored[issueItem.projectItemId].done).toBe(true);
216
208
  });
@@ -241,7 +233,7 @@ describe('useConsoleOperations', () => {
241
233
  });
242
234
  expect(fetchMock.mock.calls[0][0]).toBe('/api/comment');
243
235
  expect(lastBody(fetchMock)).toMatchObject({
244
- pjcode: 'umino',
236
+ pjcode: 'acme',
245
237
  url: issueItem.url,
246
238
  body: 'Thanks for the parity fix.',
247
239
  });
@@ -266,7 +258,7 @@ describe('useConsoleOperations', () => {
266
258
  });
267
259
  expect(fetchMock.mock.calls[0][0]).toBe('/api/reviewcomment');
268
260
  expect(lastBody(fetchMock)).toEqual({
269
- pjcode: 'umino',
261
+ pjcode: 'acme',
270
262
  url: prItem.url,
271
263
  path: 'src/index.ts',
272
264
  line: 42,
@@ -295,7 +287,7 @@ describe('useConsoleOperations', () => {
295
287
  });
296
288
  expect(fetchMock.mock.calls[0][0]).toBe('/api/review');
297
289
  expect(lastBody(fetchMock)).toMatchObject({
298
- pjcode: 'umino',
290
+ pjcode: 'acme',
299
291
  action: 'request_changes',
300
292
  prUrl: prItem.url,
301
293
  commentBody: 'src/index.ts:17 Please rename this variable.',
@@ -341,13 +333,13 @@ describe('useConsoleOperations', () => {
341
333
  it('invalidates the operated item body and comments cache on a review', async () => {
342
334
  captureFetch();
343
335
  localStorage.clear();
344
- window.history.replaceState({}, '', '/projects/umino/prs?k=token');
336
+ window.history.replaceState({}, '', '/projects/acme/prs?k=token');
345
337
  const caches = buildOperationCaches();
346
338
  const bodyInvalidate = jest.spyOn(caches.body, 'invalidate');
347
339
  const commentsInvalidate = jest.spyOn(caches.comments, 'invalidate');
348
340
  const { result } = renderHook(() => {
349
- const overlay = useConsoleOverlay('umino');
350
- const operations = useConsoleOperations('umino', 'prs', overlay, caches);
341
+ const overlay = useConsoleOverlay('acme');
342
+ const operations = useConsoleOperations('acme', 'prs', overlay, caches);
351
343
  return { overlay, operations };
352
344
  });
353
345
  await act(async () => {
@@ -373,12 +365,12 @@ describe('useConsoleOperations', () => {
373
365
  }));
374
366
  global.fetch = fetchMock as unknown as typeof fetch;
375
367
  localStorage.clear();
376
- window.history.replaceState({}, '', '/projects/umino/prs?k=token');
368
+ window.history.replaceState({}, '', '/projects/acme/prs?k=token');
377
369
  const caches = buildOperationCaches();
378
370
  const commentsInvalidate = jest.spyOn(caches.comments, 'invalidate');
379
371
  const { result } = renderHook(() => {
380
- const overlay = useConsoleOverlay('umino');
381
- const operations = useConsoleOperations('umino', 'prs', overlay, caches);
372
+ const overlay = useConsoleOverlay('acme');
373
+ const operations = useConsoleOperations('acme', 'prs', overlay, caches);
382
374
  return { overlay, operations };
383
375
  });
384
376
  await act(async () => {
@@ -9,32 +9,32 @@ describe('useConsoleOverlay', () => {
9
9
 
10
10
  it('starts from the persisted overlay', () => {
11
11
  localStorage.setItem(
12
- overlayStorageKey('umino'),
12
+ overlayStorageKey('acme'),
13
13
  JSON.stringify({ PVTI_1: { ts: 5, mode: 'prs', done: true } }),
14
14
  );
15
- const { result } = renderHook(() => useConsoleOverlay('umino'));
15
+ const { result } = renderHook(() => useConsoleOverlay('acme'));
16
16
  expect(result.current.overlay.PVTI_1?.done).toBe(true);
17
17
  });
18
18
 
19
19
  it('patches and persists overlay entries with timestamp and mode', () => {
20
- const { result } = renderHook(() => useConsoleOverlay('umino'));
20
+ const { result } = renderHook(() => useConsoleOverlay('acme'));
21
21
  act(() => {
22
22
  result.current.patchOverlay('PVTI_2', { done: true }, 'triage');
23
23
  });
24
24
  expect(result.current.overlay.PVTI_2?.done).toBe(true);
25
25
  expect(result.current.overlay.PVTI_2?.mode).toBe('triage');
26
26
  const stored = JSON.parse(
27
- localStorage.getItem(overlayStorageKey('umino')) ?? '{}',
27
+ localStorage.getItem(overlayStorageKey('acme')) ?? '{}',
28
28
  );
29
29
  expect(stored.PVTI_2.done).toBe(true);
30
30
  });
31
31
 
32
32
  it('ignores malformed persisted entries', () => {
33
33
  localStorage.setItem(
34
- overlayStorageKey('umino'),
34
+ overlayStorageKey('acme'),
35
35
  JSON.stringify({ bad: { no: 'ts' } }),
36
36
  );
37
- const { result } = renderHook(() => useConsoleOverlay('umino'));
37
+ const { result } = renderHook(() => useConsoleOverlay('acme'));
38
38
  expect(result.current.overlay.bad).toBeUndefined();
39
39
  });
40
40
  });
@@ -2,13 +2,13 @@ import { parsePjcodeFromPath } from './useConsolePjcode';
2
2
 
3
3
  describe('parsePjcodeFromPath', () => {
4
4
  it('extracts the pjcode from a projects path', () => {
5
- expect(parsePjcodeFromPath('/projects/umino')).toBe('umino');
6
- expect(parsePjcodeFromPath('/projects/umino/prs')).toBe('umino');
7
- expect(parsePjcodeFromPath('/projects/xmile/triage')).toBe('xmile');
5
+ expect(parsePjcodeFromPath('/projects/acme')).toBe('acme');
6
+ expect(parsePjcodeFromPath('/projects/acme/prs')).toBe('acme');
7
+ expect(parsePjcodeFromPath('/projects/globex/triage')).toBe('globex');
8
8
  });
9
9
 
10
10
  it('tolerates a trailing slash', () => {
11
- expect(parsePjcodeFromPath('/projects/utage3/')).toBe('utage3');
11
+ expect(parsePjcodeFromPath('/projects/umbrella/')).toBe('umbrella');
12
12
  });
13
13
 
14
14
  it('returns null when the path is not under projects', () => {
@@ -16,7 +16,7 @@ describe('useConsoleTabData', () => {
16
16
  ok: true,
17
17
  status: 200,
18
18
  json: async () => ({
19
- pjcode: 'umino',
19
+ pjcode: 'acme',
20
20
  generatedAt: '2026-06-19T00:00:00.000Z',
21
21
  statusOptions: [{ id: 's1', name: 'Unread', color: 'ORANGE' }],
22
22
  storyColors: {},
@@ -27,13 +27,13 @@ describe('useConsoleTabData', () => {
27
27
  }));
28
28
  global.fetch = fetchMock as unknown as typeof fetch;
29
29
 
30
- const { result } = renderHook(() => useConsoleTabData('umino'));
30
+ const { result } = renderHook(() => useConsoleTabData('acme'));
31
31
  await waitFor(() => {
32
32
  expect(result.current.isLoading).toBe(false);
33
33
  });
34
34
  expect(fetchMock).toHaveBeenCalledTimes(CONSOLE_TABS.length);
35
35
  expect(fetchMock).toHaveBeenCalledWith(
36
- expect.stringContaining('/projects/umino/prs/list.json'),
36
+ expect.stringContaining('/projects/acme/prs/list.json'),
37
37
  );
38
38
  expect(result.current.snapshots.prs?.items.length).toBe(1);
39
39
  expect(result.current.snapshots.prs?.generatedAt).toBe(
@@ -46,7 +46,7 @@ describe('useConsoleTabData', () => {
46
46
  ok: true,
47
47
  status: 200,
48
48
  json: async () => ({
49
- pjcode: 'umino',
49
+ pjcode: 'acme',
50
50
  generatedAt: '2026-06-19T00:00:00.000Z',
51
51
  statusOptions: [],
52
52
  storyColors: {},
@@ -68,7 +68,7 @@ describe('useConsoleTabData', () => {
68
68
  }));
69
69
  global.fetch = fetchMock as unknown as typeof fetch;
70
70
 
71
- const { result } = renderHook(() => useConsoleTabData('umino'));
71
+ const { result } = renderHook(() => useConsoleTabData('acme'));
72
72
  await waitFor(() => {
73
73
  expect(result.current.isLoading).toBe(false);
74
74
  });
@@ -87,7 +87,7 @@ describe('useConsoleTabData', () => {
87
87
  ok: true,
88
88
  status: 200,
89
89
  json: async () => ({
90
- pjcode: 'umino',
90
+ pjcode: 'acme',
91
91
  generatedAt: '2026-06-19T00:00:00.000Z',
92
92
  statusOptions: [],
93
93
  storyColors: {},
@@ -99,7 +99,7 @@ describe('useConsoleTabData', () => {
99
99
  }));
100
100
  global.fetch = fetchMock as unknown as typeof fetch;
101
101
 
102
- const { result } = renderHook(() => useConsoleTabData('umino'));
102
+ const { result } = renderHook(() => useConsoleTabData('acme'));
103
103
  await waitFor(() => {
104
104
  expect(result.current.snapshots.prs?.items.length).toBe(1);
105
105
  });
@@ -123,7 +123,7 @@ describe('useConsoleTabData', () => {
123
123
  json: async () => ({}),
124
124
  }));
125
125
  global.fetch = fetchMock as unknown as typeof fetch;
126
- const { result } = renderHook(() => useConsoleTabData('umino'));
126
+ const { result } = renderHook(() => useConsoleTabData('acme'));
127
127
  await waitFor(() => {
128
128
  expect(result.current.error).toBe('HTTP 500');
129
129
  });
@@ -256,7 +256,7 @@ describe('postConsoleOperation', () => {
256
256
  it('posts a JSON body to the operation endpoint', async () => {
257
257
  const fetchMock = mockFetchOnce({ ok: true });
258
258
  await postConsoleOperation('/api/review', {
259
- pjcode: 'umino',
259
+ pjcode: 'acme',
260
260
  action: 'approve',
261
261
  prUrl: 'https://github.com/o/r/pull/1',
262
262
  projectItemId: 'PVTI_1',
@@ -268,7 +268,7 @@ describe('postConsoleOperation', () => {
268
268
 
269
269
  const failingReview = (): Promise<void> =>
270
270
  postConsoleOperation('/api/review', {
271
- pjcode: 'umino',
271
+ pjcode: 'acme',
272
272
  action: 'approve',
273
273
  prUrl: 'https://github.com/o/r/pull/1',
274
274
  projectItemId: 'PVTI_1',
@@ -299,7 +299,7 @@ describe('postConsoleReviewComment', () => {
299
299
  it('posts the inline review comment body to the reviewcomment endpoint', async () => {
300
300
  const fetchMock = mockFetchOnce({ ok: true });
301
301
  await postConsoleReviewComment({
302
- pjcode: 'umino',
302
+ pjcode: 'acme',
303
303
  url: 'https://github.com/o/r/pull/1',
304
304
  path: 'src/index.ts',
305
305
  line: 42,
@@ -310,7 +310,7 @@ describe('postConsoleReviewComment', () => {
310
310
  expect(url).toBe('/api/reviewcomment');
311
311
  expect(init).toMatchObject({ method: 'POST' });
312
312
  expect(JSON.parse((init as { body: string }).body)).toEqual({
313
- pjcode: 'umino',
313
+ pjcode: 'acme',
314
314
  url: 'https://github.com/o/r/pull/1',
315
315
  path: 'src/index.ts',
316
316
  line: 42,
@@ -329,7 +329,7 @@ describe('postConsoleReviewComment', () => {
329
329
  );
330
330
  await expect(
331
331
  postConsoleReviewComment({
332
- pjcode: 'umino',
332
+ pjcode: 'acme',
333
333
  url: 'https://github.com/o/r/pull/1',
334
334
  path: 'src/index.ts',
335
335
  line: 42,
@@ -30,7 +30,7 @@ const item = (number: number): ConsoleListItem => ({
30
30
 
31
31
  describe('overlay helpers', () => {
32
32
  it('builds the per-project storage key', () => {
33
- expect(overlayStorageKey('umino')).toBe('pv_overlay_umino');
33
+ expect(overlayStorageKey('acme')).toBe('pv_overlay_acme');
34
34
  });
35
35
 
36
36
  it('uses the projectItemId as the overlay key when present', () => {
@@ -20,7 +20,7 @@ jest.mock('../lib/mermaidLoader', () => ({
20
20
  }));
21
21
 
22
22
  const listPayload = (tab: string) => ({
23
- pjcode: 'umino',
23
+ pjcode: 'acme',
24
24
  generatedAt: '2026-06-19T00:00:00.000Z',
25
25
  statusOptions: [{ id: 's1', name: 'Awaiting Workspace', color: 'BLUE' }],
26
26
  storyOptions: [{ id: 'st1', name: 'TDPM Console port', color: 'BLUE' }],
@@ -89,7 +89,7 @@ const installFetch = (): void => {
89
89
  describe('ConsolePage', () => {
90
90
  beforeEach(() => {
91
91
  localStorage.clear();
92
- window.history.replaceState({}, '', '/projects/umino/prs?k=token');
92
+ window.history.replaceState({}, '', '/projects/acme/prs?k=token');
93
93
  installFetch();
94
94
  });
95
95
 
@@ -254,7 +254,7 @@ describe('ConsolePage', () => {
254
254
  expect(getByText('Add serveConsole subcommand')).toBeInTheDocument();
255
255
  });
256
256
  expect(queryByText('TDPM Console')).toBeNull();
257
- expect(queryByText('project: umino')).toBeNull();
257
+ expect(queryByText('project: acme')).toBeNull();
258
258
  });
259
259
 
260
260
  it('removes a processed workflow-blocker item from the list and decrements its tab badge, like every other tab', async () => {
@@ -312,7 +312,7 @@ describe('ConsolePage', () => {
312
312
  });
313
313
  global.fetch = fetchMock as unknown as typeof fetch;
314
314
  localStorage.setItem(
315
- 'pv_overlay_umino',
315
+ 'pv_overlay_acme',
316
316
  JSON.stringify({
317
317
  PVTI_B1: {
318
318
  ts: Date.parse('2026-06-19T00:05:00.000Z'),
@@ -324,7 +324,7 @@ describe('ConsolePage', () => {
324
324
  window.history.replaceState(
325
325
  {},
326
326
  '',
327
- '/projects/umino/workflow-blocker?k=token',
327
+ '/projects/acme/workflow-blocker?k=token',
328
328
  );
329
329
 
330
330
  const { getByText, queryByText } = render(<ConsolePage />);
@@ -378,7 +378,7 @@ describe('ConsolePage', () => {
378
378
  });
379
379
  global.fetch = fetchMock as unknown as typeof fetch;
380
380
  localStorage.setItem(
381
- 'pv_overlay_umino',
381
+ 'pv_overlay_acme',
382
382
  JSON.stringify({
383
383
  PVTI_B1: {
384
384
  ts: Date.parse('2026-06-18T23:00:00.000Z'),
@@ -390,7 +390,7 @@ describe('ConsolePage', () => {
390
390
  window.history.replaceState(
391
391
  {},
392
392
  '',
393
- '/projects/umino/workflow-blocker?k=token',
393
+ '/projects/acme/workflow-blocker?k=token',
394
394
  );
395
395
 
396
396
  const { getByText } = render(<ConsolePage />);
@@ -462,7 +462,7 @@ describe('ConsolePage', () => {
462
462
  });
463
463
 
464
464
  const twoItemPrPayload = () => ({
465
- pjcode: 'umino',
465
+ pjcode: 'acme',
466
466
  generatedAt: '2026-06-19T00:00:00.000Z',
467
467
  statusOptions: [{ id: 's1', name: 'Awaiting Workspace', color: 'BLUE' }],
468
468
  storyOptions: [{ id: 'st1', name: 'TDPM Console port', color: 'BLUE' }],
@@ -533,7 +533,7 @@ const swipeDetailScreen = (
533
533
  describe('ConsolePage swipe navigation', () => {
534
534
  beforeEach(() => {
535
535
  localStorage.clear();
536
- window.history.replaceState({}, '', '/projects/umino/prs?k=token');
536
+ window.history.replaceState({}, '', '/projects/acme/prs?k=token');
537
537
  const fetchMock = jest.fn(async (url: string) => {
538
538
  const listMatch = url.match(/\/projects\/[^/]+\/([^/]+)\/list\.json/);
539
539
  if (listMatch !== null) {
@@ -601,7 +601,7 @@ describe('ConsolePage swipe navigation', () => {
601
601
  describe('ConsolePage auto-advance', () => {
602
602
  beforeEach(() => {
603
603
  localStorage.clear();
604
- window.history.replaceState({}, '', '/projects/umino/prs?k=token');
604
+ window.history.replaceState({}, '', '/projects/acme/prs?k=token');
605
605
  const fetchMock = jest.fn(async (url: string) => {
606
606
  const listMatch = url.match(/\/projects\/[^/]+\/([^/]+)\/list\.json/);
607
607
  if (listMatch !== null) {
@@ -644,7 +644,7 @@ describe('ConsolePage auto-advance', () => {
644
644
  describe('ConsolePage scroll reset', () => {
645
645
  beforeEach(() => {
646
646
  localStorage.clear();
647
- window.history.replaceState({}, '', '/projects/umino/prs?k=token');
647
+ window.history.replaceState({}, '', '/projects/acme/prs?k=token');
648
648
  const fetchMock = jest.fn(async (url: string) => {
649
649
  const listMatch = url.match(/\/projects\/[^/]+\/([^/]+)\/list\.json/);
650
650
  if (listMatch !== null) {
@@ -706,7 +706,7 @@ describe('ConsolePage scroll reset', () => {
706
706
  describe('ConsolePage comment composer isolation', () => {
707
707
  beforeEach(() => {
708
708
  localStorage.clear();
709
- window.history.replaceState({}, '', '/projects/umino/prs?k=token');
709
+ window.history.replaceState({}, '', '/projects/acme/prs?k=token');
710
710
  const fetchMock = jest.fn(async (url: string, init?: RequestInit) => {
711
711
  const listMatch = url.match(/\/projects\/[^/]+\/([^/]+)\/list\.json/);
712
712
  if (listMatch !== null) {
@@ -784,7 +784,7 @@ describe('ConsolePage comment composer isolation', () => {
784
784
  describe('ConsolePage auto-advance tab', () => {
785
785
  beforeEach(() => {
786
786
  localStorage.clear();
787
- window.history.replaceState({}, '', '/projects/umino/prs?k=token');
787
+ window.history.replaceState({}, '', '/projects/acme/prs?k=token');
788
788
  installFetch();
789
789
  });
790
790