github-issue-tower-defence-management 1.143.6 → 1.144.1

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 (63) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/bin/adapter/entry-points/cli/index.js +2 -0
  3. package/bin/adapter/entry-points/cli/index.js.map +1 -1
  4. package/bin/adapter/entry-points/console/consoleItemUrlLookup.js +88 -0
  5. package/bin/adapter/entry-points/console/consoleItemUrlLookup.js.map +1 -0
  6. package/bin/adapter/entry-points/console/consoleOperationApi.js +44 -1
  7. package/bin/adapter/entry-points/console/consoleOperationApi.js.map +1 -1
  8. package/bin/adapter/entry-points/console/ui-dist/assets/index-BYoG8oQb.js +82 -0
  9. package/bin/adapter/entry-points/console/ui-dist/index.html +1 -1
  10. package/bin/adapter/entry-points/console/webServer.js +3 -0
  11. package/bin/adapter/entry-points/console/webServer.js.map +1 -1
  12. package/bin/adapter/repositories/LocalCommandIssueAttachmentRepository.js +75 -0
  13. package/bin/adapter/repositories/LocalCommandIssueAttachmentRepository.js.map +1 -0
  14. package/bin/domain/usecases/adapter-interfaces/IssueAttachmentRepository.js +3 -0
  15. package/bin/domain/usecases/adapter-interfaces/IssueAttachmentRepository.js.map +1 -0
  16. package/bin/domain/usecases/console/GenerateConsoleListsUseCase.js +26 -3
  17. package/bin/domain/usecases/console/GenerateConsoleListsUseCase.js.map +1 -1
  18. package/package.json +1 -1
  19. package/src/adapter/entry-points/cli/index.ts +4 -0
  20. package/src/adapter/entry-points/console/consoleItemUrlLookup.test.ts +63 -0
  21. package/src/adapter/entry-points/console/consoleItemUrlLookup.ts +66 -0
  22. package/src/adapter/entry-points/console/consoleOperationApi.test.ts +155 -0
  23. package/src/adapter/entry-points/console/consoleOperationApi.ts +56 -0
  24. package/src/adapter/entry-points/console/ui/e2e/consoleTestHarness.ts +3 -0
  25. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleCommentComposer.stories.tsx +17 -0
  26. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleCommentComposer.test.tsx +149 -1
  27. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleCommentComposer.tsx +107 -1
  28. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleDetailPrefetch.test.ts +1 -0
  29. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleItemDetailData.test.ts +2 -0
  30. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleOperations.ts +22 -0
  31. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleTabData.test.ts +39 -0
  32. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleTabData.ts +14 -1
  33. package/src/adapter/entry-points/console/ui/src/features/console/lib/consoleApi.ts +35 -0
  34. package/src/adapter/entry-points/console/ui/src/features/console/logic/grouping.test.ts +1 -0
  35. package/src/adapter/entry-points/console/ui/src/features/console/logic/overlay.test.ts +1 -0
  36. package/src/adapter/entry-points/console/ui/src/features/console/logic/types.ts +1 -0
  37. package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsoleItemDetailContainer.test.tsx +43 -1
  38. package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsoleItemDetailContainer.tsx +8 -2
  39. package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsolePage.test.tsx +7 -0
  40. package/src/adapter/entry-points/console/ui/src/features/console/testing/fixtures.ts +5 -0
  41. package/src/adapter/entry-points/console/ui-dist/assets/index-BYoG8oQb.js +82 -0
  42. package/src/adapter/entry-points/console/ui-dist/index.html +1 -1
  43. package/src/adapter/entry-points/console/webServer.ts +6 -0
  44. package/src/adapter/repositories/LocalCommandIssueAttachmentRepository.test.ts +136 -0
  45. package/src/adapter/repositories/LocalCommandIssueAttachmentRepository.ts +96 -0
  46. package/src/domain/usecases/adapter-interfaces/IssueAttachmentRepository.ts +9 -0
  47. package/src/domain/usecases/console/GenerateConsoleListsUseCase.test.ts +62 -0
  48. package/src/domain/usecases/console/GenerateConsoleListsUseCase.ts +45 -3
  49. package/types/adapter/entry-points/cli/index.d.ts.map +1 -1
  50. package/types/adapter/entry-points/console/consoleItemUrlLookup.d.ts +2 -0
  51. package/types/adapter/entry-points/console/consoleItemUrlLookup.d.ts.map +1 -0
  52. package/types/adapter/entry-points/console/consoleOperationApi.d.ts +3 -0
  53. package/types/adapter/entry-points/console/consoleOperationApi.d.ts.map +1 -1
  54. package/types/adapter/entry-points/console/webServer.d.ts +2 -0
  55. package/types/adapter/entry-points/console/webServer.d.ts.map +1 -1
  56. package/types/adapter/repositories/LocalCommandIssueAttachmentRepository.d.ts +15 -0
  57. package/types/adapter/repositories/LocalCommandIssueAttachmentRepository.d.ts.map +1 -0
  58. package/types/domain/usecases/adapter-interfaces/IssueAttachmentRepository.d.ts +9 -0
  59. package/types/domain/usecases/adapter-interfaces/IssueAttachmentRepository.d.ts.map +1 -0
  60. package/types/domain/usecases/console/GenerateConsoleListsUseCase.d.ts +2 -0
  61. package/types/domain/usecases/console/GenerateConsoleListsUseCase.d.ts.map +1 -1
  62. package/bin/adapter/entry-points/console/ui-dist/assets/index-DDQKZmBM.js +0 -81
  63. package/src/adapter/entry-points/console/ui-dist/assets/index-DDQKZmBM.js +0 -81
@@ -4,7 +4,7 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>TDPM Console</title>
7
- <script type="module" crossorigin src="/assets/index-DDQKZmBM.js"></script>
7
+ <script type="module" crossorigin src="/assets/index-BYoG8oQb.js"></script>
8
8
  <link rel="stylesheet" crossorigin href="/assets/index-CKX2ny-z.css">
9
9
  </head>
10
10
  <body>
@@ -1,6 +1,7 @@
1
1
  import * as http from 'http';
2
2
  import * as fs from 'fs';
3
3
  import * as path from 'path';
4
+ import { IssueAttachmentRepository } from '../../../domain/usecases/adapter-interfaces/IssueAttachmentRepository';
4
5
  import { IssueRepository } from '../../../domain/usecases/adapter-interfaces/IssueRepository';
5
6
  import {
6
7
  CONSOLE_LIST_TAB_NAMES,
@@ -22,6 +23,7 @@ import {
22
23
  ConsoleOperationContext,
23
24
  ConsolePjcodeValidator,
24
25
  ConsoleProjectResolver,
26
+ handleAttachmentUpload,
25
27
  handleComment,
26
28
  handleIntmux,
27
29
  handleReview,
@@ -217,6 +219,7 @@ export type WebServerOptions = {
217
219
  issueRepository?: IssueRepository | null;
218
220
  resolveProject?: ConsoleProjectResolver | null;
219
221
  isPjcodeConfigured?: ConsolePjcodeValidator | null;
222
+ issueAttachmentRepository?: IssueAttachmentRepository | null;
220
223
  issueTitleStateCache?: IssueTitleStateCache | null;
221
224
  pullRequestStatusCache?: PullRequestStatusCache | null;
222
225
  };
@@ -478,6 +481,8 @@ const dispatchOperation = (
478
481
  return handleComment(context, body);
479
482
  case '/api/reviewcomment':
480
483
  return handleReviewComment(context, body);
484
+ case '/api/upload':
485
+ return handleAttachmentUpload(context, body);
481
486
  default:
482
487
  return null;
483
488
  }
@@ -503,6 +508,7 @@ const handleOperationApi = async (
503
508
  resolveProject,
504
509
  isPjcodeConfigured,
505
510
  consoleDataOutputDir: options.consoleDataOutputDir,
511
+ issueAttachmentRepository: options.issueAttachmentRepository ?? null,
506
512
  };
507
513
  const dispatched = dispatchOperation(context, requestPath, body);
508
514
  if (dispatched === null) {
@@ -0,0 +1,136 @@
1
+ import { mkdtemp, readdir } from 'fs/promises';
2
+ import { tmpdir } from 'os';
3
+ import { join } from 'path';
4
+ import { LocalCommandRunner } from '../../domain/usecases/adapter-interfaces/LocalCommandRunner';
5
+ import {
6
+ LocalCommandIssueAttachmentRepository,
7
+ relabelAttachmentMarkdown,
8
+ resolveAttachmentExtension,
9
+ sanitizeAttachmentFileName,
10
+ UPLOAD_COMMAND,
11
+ } from './LocalCommandIssueAttachmentRepository';
12
+
13
+ describe('sanitizeAttachmentFileName', () => {
14
+ it('should keep a safe file name unchanged', () => {
15
+ expect(sanitizeAttachmentFileName('screenshot.png')).toBe('screenshot.png');
16
+ });
17
+
18
+ it('should drop directory components and replace unsafe characters', () => {
19
+ expect(sanitizeAttachmentFileName('../../etc/pass wd;rm.png')).toBe(
20
+ 'pass_wd_rm.png',
21
+ );
22
+ });
23
+
24
+ it('should fall back to a default name when nothing safe remains', () => {
25
+ expect(sanitizeAttachmentFileName('')).toBe('attachment');
26
+ });
27
+ });
28
+
29
+ describe('resolveAttachmentExtension', () => {
30
+ it('should return the matching allowed extension', () => {
31
+ expect(resolveAttachmentExtension('Screenshot 2026.PNG')).toBe('.png');
32
+ });
33
+
34
+ it('should return an empty extension for an unlisted one', () => {
35
+ expect(resolveAttachmentExtension('payload.sh')).toBe('');
36
+ });
37
+ });
38
+
39
+ describe('relabelAttachmentMarkdown', () => {
40
+ it('should replace the label of an image markdown', () => {
41
+ expect(
42
+ relabelAttachmentMarkdown(
43
+ '![attachment](https://example.com/a)',
44
+ 'shot.png',
45
+ ),
46
+ ).toBe('![shot.png](https://example.com/a)');
47
+ });
48
+
49
+ it('should replace the label of a link markdown', () => {
50
+ expect(
51
+ relabelAttachmentMarkdown(
52
+ '[attachment](https://example.com/a)',
53
+ 'note.md',
54
+ ),
55
+ ).toBe('[note.md](https://example.com/a)');
56
+ });
57
+
58
+ it('should keep unexpected output unchanged', () => {
59
+ expect(relabelAttachmentMarkdown('unexpected output', 'shot.png')).toBe(
60
+ 'unexpected output',
61
+ );
62
+ });
63
+ });
64
+
65
+ describe('LocalCommandIssueAttachmentRepository', () => {
66
+ it('should upload the written file and return the markdown the command printed', async () => {
67
+ const root = await mkdtemp(join(tmpdir(), 'attachment-test-root-'));
68
+ const received: { program: string; args: string[] }[] = [];
69
+ const runner: LocalCommandRunner = {
70
+ runCommand: async (program, args) => {
71
+ received.push({ program, args });
72
+ return {
73
+ stdout:
74
+ '![screenshot](https://github.com/user-attachments/assets/11111111-2222-3333-4444-555555555555)\n',
75
+ stderr: '',
76
+ exitCode: 0,
77
+ };
78
+ },
79
+ };
80
+ const repository = new LocalCommandIssueAttachmentRepository(runner, root);
81
+
82
+ const markdown = await repository.uploadAttachment({
83
+ issueOrPullRequestUrl: 'https://github.com/owner/repo/issues/1',
84
+ fileName: 'screenshot.png',
85
+ content: new Uint8Array([1, 2, 3]),
86
+ });
87
+
88
+ expect(markdown).toBe(
89
+ '![screenshot.png](https://github.com/user-attachments/assets/11111111-2222-3333-4444-555555555555)',
90
+ );
91
+ expect(received).toHaveLength(1);
92
+ expect(received[0].program).toBe(UPLOAD_COMMAND);
93
+ expect(received[0].args[0].endsWith('/attachment.png')).toBe(true);
94
+ expect(received[0].args[1]).toBe('https://github.com/owner/repo/issues/1');
95
+ expect(await readdir(root)).toEqual([]);
96
+ });
97
+
98
+ it('should throw with the command stderr when the upload command fails', async () => {
99
+ const root = await mkdtemp(join(tmpdir(), 'attachment-test-root-'));
100
+ const runner: LocalCommandRunner = {
101
+ runCommand: async () => ({
102
+ stdout: '',
103
+ stderr: 'Error: No GitHub web session is available\n',
104
+ exitCode: 1,
105
+ }),
106
+ };
107
+ const repository = new LocalCommandIssueAttachmentRepository(runner, root);
108
+
109
+ await expect(
110
+ repository.uploadAttachment({
111
+ issueOrPullRequestUrl: 'https://github.com/owner/repo/issues/1',
112
+ fileName: 'screenshot.png',
113
+ content: new Uint8Array([1]),
114
+ }),
115
+ ).rejects.toThrow(
116
+ `${UPLOAD_COMMAND} failed with exit code 1: Error: No GitHub web session is available`,
117
+ );
118
+ expect(await readdir(root)).toEqual([]);
119
+ });
120
+
121
+ it('should throw when the upload command prints no markdown', async () => {
122
+ const root = await mkdtemp(join(tmpdir(), 'attachment-test-root-'));
123
+ const runner: LocalCommandRunner = {
124
+ runCommand: async () => ({ stdout: '\n', stderr: '', exitCode: 0 }),
125
+ };
126
+ const repository = new LocalCommandIssueAttachmentRepository(runner, root);
127
+
128
+ await expect(
129
+ repository.uploadAttachment({
130
+ issueOrPullRequestUrl: 'https://github.com/owner/repo/issues/1',
131
+ fileName: 'screenshot.png',
132
+ content: new Uint8Array([1]),
133
+ }),
134
+ ).rejects.toThrow(`${UPLOAD_COMMAND} returned no markdown`);
135
+ });
136
+ });
@@ -0,0 +1,96 @@
1
+ import { mkdtemp, rm, writeFile } from 'fs/promises';
2
+ import { tmpdir } from 'os';
3
+ import { join } from 'path';
4
+ import {
5
+ IssueAttachmentRepository,
6
+ IssueAttachmentUploadRequest,
7
+ } from '../../domain/usecases/adapter-interfaces/IssueAttachmentRepository';
8
+ import { LocalCommandRunner } from '../../domain/usecases/adapter-interfaces/LocalCommandRunner';
9
+
10
+ export const UPLOAD_COMMAND = 'upload-file-to-gh-issue';
11
+
12
+ export const ALLOWED_ATTACHMENT_EXTENSIONS = [
13
+ '.png',
14
+ '.jpg',
15
+ '.jpeg',
16
+ '.gif',
17
+ '.webp',
18
+ '.svg',
19
+ '.pdf',
20
+ '.txt',
21
+ '.md',
22
+ '.log',
23
+ '.csv',
24
+ '.json',
25
+ '.zip',
26
+ '.mov',
27
+ '.mp4',
28
+ ] as const;
29
+
30
+ export const UPLOAD_FILE_BASE_NAME = 'attachment';
31
+
32
+ export const sanitizeAttachmentFileName = (fileName: string): string => {
33
+ const base = fileName.split('/').pop() ?? '';
34
+ const sanitized = base.replace(/[^A-Za-z0-9._-]/g, '_');
35
+ return sanitized.length === 0 ? UPLOAD_FILE_BASE_NAME : sanitized;
36
+ };
37
+
38
+ export const resolveAttachmentExtension = (fileName: string): string => {
39
+ const lower = sanitizeAttachmentFileName(fileName).toLowerCase();
40
+ const matched = ALLOWED_ATTACHMENT_EXTENSIONS.find((extension) =>
41
+ lower.endsWith(extension),
42
+ );
43
+ return matched === undefined ? '' : matched;
44
+ };
45
+
46
+ export const relabelAttachmentMarkdown = (
47
+ markdown: string,
48
+ label: string,
49
+ ): string => {
50
+ const match = /^(!?)\[[^\]]*\]\((.*)\)$/.exec(markdown);
51
+ if (match === null) {
52
+ return markdown;
53
+ }
54
+ return `${match[1]}[${label}](${match[2]})`;
55
+ };
56
+
57
+ export class LocalCommandIssueAttachmentRepository implements IssueAttachmentRepository {
58
+ constructor(
59
+ private readonly localCommandRunner: LocalCommandRunner,
60
+ private readonly temporaryDirectoryRoot: string = tmpdir(),
61
+ ) {}
62
+
63
+ async uploadAttachment(
64
+ request: IssueAttachmentUploadRequest,
65
+ ): Promise<string> {
66
+ const directory = await mkdtemp(
67
+ join(this.temporaryDirectoryRoot, 'console-attachment-'),
68
+ );
69
+ const filePath = join(
70
+ directory,
71
+ `${UPLOAD_FILE_BASE_NAME}${resolveAttachmentExtension(request.fileName)}`,
72
+ );
73
+ try {
74
+ await writeFile(filePath, request.content);
75
+ const result = await this.localCommandRunner.runCommand(UPLOAD_COMMAND, [
76
+ filePath,
77
+ request.issueOrPullRequestUrl,
78
+ ]);
79
+ if (result.exitCode !== 0) {
80
+ throw new Error(
81
+ `${UPLOAD_COMMAND} failed with exit code ${result.exitCode}: ${result.stderr.trim()}`,
82
+ );
83
+ }
84
+ const markdown = result.stdout.trim();
85
+ if (markdown.length === 0) {
86
+ throw new Error(`${UPLOAD_COMMAND} returned no markdown`);
87
+ }
88
+ return relabelAttachmentMarkdown(
89
+ markdown,
90
+ sanitizeAttachmentFileName(request.fileName),
91
+ );
92
+ } finally {
93
+ await rm(directory, { recursive: true, force: true });
94
+ }
95
+ }
96
+ }
@@ -0,0 +1,9 @@
1
+ export type IssueAttachmentUploadRequest = {
2
+ issueOrPullRequestUrl: string;
3
+ fileName: string;
4
+ content: Uint8Array;
5
+ };
6
+
7
+ export interface IssueAttachmentRepository {
8
+ uploadAttachment(request: IssueAttachmentUploadRequest): Promise<string>;
9
+ }
@@ -378,6 +378,7 @@ describe('GenerateConsoleListsUseCase', () => {
378
378
  'nextActionHour',
379
379
  'number',
380
380
  'projectItemId',
381
+ 'relatedOpenPullRequestUrls',
381
382
  'repo',
382
383
  'status',
383
384
  'story',
@@ -582,6 +583,67 @@ describe('GenerateConsoleListsUseCase', () => {
582
583
  });
583
584
  });
584
585
 
586
+ describe('related open pull requests', () => {
587
+ const awaitingQualityCheckIssue = (): Issue =>
588
+ makeIssue({ status: 'Awaiting Quality Check' });
589
+
590
+ it('projects the open pull request that closes the issue', () => {
591
+ const issue = awaitingQualityCheckIssue();
592
+ const pullRequest = makeIssue({
593
+ status: 'Awaiting Quality Check',
594
+ isPr: true,
595
+ url: 'https://github.com/demo/repo/pull/501',
596
+ closingIssueReferenceUrls: [issue.url],
597
+ });
598
+ const result = run([issue, pullRequest]);
599
+ const projected = result.prs.items.find((item) => item.url === issue.url);
600
+ expect(projected?.relatedOpenPullRequestUrls).toEqual([
601
+ 'https://github.com/demo/repo/pull/501',
602
+ ]);
603
+ });
604
+
605
+ it('ignores a closed pull request that closes the issue', () => {
606
+ const issue = awaitingQualityCheckIssue();
607
+ const pullRequest = makeIssue({
608
+ isPr: true,
609
+ isClosed: true,
610
+ url: 'https://github.com/demo/repo/pull/502',
611
+ closingIssueReferenceUrls: [issue.url],
612
+ });
613
+ const result = run([issue, pullRequest]);
614
+ const projected = result.prs.items.find((item) => item.url === issue.url);
615
+ expect(projected?.relatedOpenPullRequestUrls).toEqual([]);
616
+ });
617
+
618
+ it('collects the linkage from a pull request that no tab shows', () => {
619
+ const issue = awaitingQualityCheckIssue();
620
+ const pullRequest = makeIssue({
621
+ status: 'In Tmux by agent',
622
+ assignees: ['another-person'],
623
+ isPr: true,
624
+ url: 'https://github.com/demo/repo/pull/503',
625
+ closingIssueReferenceUrls: [issue.url],
626
+ });
627
+ const result = run([issue, pullRequest]);
628
+ const projected = result.prs.items.find((item) => item.url === issue.url);
629
+ expect(projected?.relatedOpenPullRequestUrls).toEqual([
630
+ 'https://github.com/demo/repo/pull/503',
631
+ ]);
632
+ });
633
+
634
+ it('leaves the list empty when no open pull request closes the issue', () => {
635
+ const issue = awaitingQualityCheckIssue();
636
+ const unrelatedPullRequest = makeIssue({
637
+ isPr: true,
638
+ url: 'https://github.com/demo/repo/pull/504',
639
+ closingIssueReferenceUrls: ['https://github.com/demo/repo/issues/999'],
640
+ });
641
+ const result = run([issue, unrelatedPullRequest]);
642
+ const projected = result.prs.items.find((item) => item.url === issue.url);
643
+ expect(projected?.relatedOpenPullRequestUrls).toEqual([]);
644
+ });
645
+ });
646
+
585
647
  describe('project without a story field', () => {
586
648
  const projectNoStory = baseProject(null);
587
649
 
@@ -25,6 +25,7 @@ export type ConsoleListItem = {
25
25
  dependedIssueUrls: string[];
26
26
  labels: string[];
27
27
  createdAt: string;
28
+ relatedOpenPullRequestUrls: string[];
28
29
  };
29
30
 
30
31
  export type ConsoleFieldOption = {
@@ -96,6 +97,9 @@ export class GenerateConsoleListsUseCase {
96
97
  const storyOrder = storyOptions.map((option) => option.name);
97
98
  const statusOptions = project.status.statuses;
98
99
 
100
+ const relatedOpenPullRequestUrlsByIssueUrl =
101
+ this.buildRelatedOpenPullRequestUrlsByIssueUrl(issues);
102
+
99
103
  const visibleIssues = issues.filter(
100
104
  (issue) =>
101
105
  issue.status?.toLowerCase() !==
@@ -117,7 +121,14 @@ export class GenerateConsoleListsUseCase {
117
121
  storyOrder,
118
122
  storyColors: this.buildStoryColorsObject(storyOptions),
119
123
  items: this.sortByStoryOrder(
120
- sourceIssues.filter(selector).map((issue) => this.projectItem(issue)),
124
+ sourceIssues
125
+ .filter(selector)
126
+ .map((issue) =>
127
+ this.projectItem(
128
+ issue,
129
+ relatedOpenPullRequestUrlsByIssueUrl.get(issue.url) ?? [],
130
+ ),
131
+ ),
121
132
  storyOrder,
122
133
  ),
123
134
  });
@@ -183,7 +194,12 @@ export class GenerateConsoleListsUseCase {
183
194
  issue.status?.toLowerCase() !==
184
195
  IN_TMUX_BY_AGENT_STATUS_NAME.toLowerCase(),
185
196
  )
186
- .map((issue) => this.projectItem(issue)),
197
+ .map((issue) =>
198
+ this.projectItem(
199
+ issue,
200
+ relatedOpenPullRequestUrlsByIssueUrl.get(issue.url) ?? [],
201
+ ),
202
+ ),
187
203
  storyOrder,
188
204
  ),
189
205
  },
@@ -208,7 +224,32 @@ export class GenerateConsoleListsUseCase {
208
224
  issue.story !== null && issue.story.toLowerCase() === target;
209
225
  };
210
226
 
211
- private projectItem = (issue: Issue): ConsoleListItem => ({
227
+ private buildRelatedOpenPullRequestUrlsByIssueUrl = (
228
+ issues: Issue[],
229
+ ): Map<string, string[]> => {
230
+ const urlsByIssueUrl = new Map<string, string[]>();
231
+ for (const issue of issues) {
232
+ if (!issue.isPr || issue.isClosed) {
233
+ continue;
234
+ }
235
+ for (const referencedIssueUrl of issue.closingIssueReferenceUrls) {
236
+ const existing = urlsByIssueUrl.get(referencedIssueUrl);
237
+ if (existing === undefined) {
238
+ urlsByIssueUrl.set(referencedIssueUrl, [issue.url]);
239
+ continue;
240
+ }
241
+ if (!existing.includes(issue.url)) {
242
+ existing.push(issue.url);
243
+ }
244
+ }
245
+ }
246
+ return urlsByIssueUrl;
247
+ };
248
+
249
+ private projectItem = (
250
+ issue: Issue,
251
+ relatedOpenPullRequestUrls: string[],
252
+ ): ConsoleListItem => ({
212
253
  number: issue.number,
213
254
  title: issue.title,
214
255
  url: issue.url,
@@ -225,6 +266,7 @@ export class GenerateConsoleListsUseCase {
225
266
  dependedIssueUrls: issue.dependedIssueUrls,
226
267
  labels: issue.labels,
227
268
  createdAt: issue.createdAt.toISOString(),
269
+ relatedOpenPullRequestUrls,
228
270
  });
229
271
 
230
272
  private buildFieldOptions = (
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/cli/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EACL,UAAU,EACV,cAAc,EACd,wBAAwB,EACxB,YAAY,EACZ,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AAuJzB,eAAO,MAAM,OAAO,SAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/cli/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EACL,UAAU,EACV,cAAc,EACd,wBAAwB,EACxB,YAAY,EACZ,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AAwJzB,eAAO,MAAM,OAAO,SAAgB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const findConsoleItemUrl: (consoleDataOutputDir: string, pjcode: string, requestedUrl: string) => string | null;
2
+ //# sourceMappingURL=consoleItemUrlLookup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consoleItemUrlLookup.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/console/consoleItemUrlLookup.ts"],"names":[],"mappings":"AAoDA,eAAO,MAAM,kBAAkB,GAC7B,sBAAsB,MAAM,EAC5B,QAAQ,MAAM,EACd,cAAc,MAAM,KACnB,MAAM,GAAG,IASX,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { IssueRepository } from '../../../domain/usecases/adapter-interfaces/IssueRepository';
2
+ import { IssueAttachmentRepository } from '../../../domain/usecases/adapter-interfaces/IssueAttachmentRepository';
2
3
  import { Project } from '../../../domain/entities/Project';
3
4
  export declare const AWAITING_WORKSPACE_STATUS_NAME = "awaiting workspace";
4
5
  export declare const IN_TMUX_BY_HUMAN_STATUS_NAME = "in tmux by human";
@@ -13,6 +14,7 @@ export type ConsoleOperationContext = {
13
14
  resolveProject: ConsoleProjectResolver;
14
15
  isPjcodeConfigured: ConsolePjcodeValidator;
15
16
  consoleDataOutputDir: string | null;
17
+ issueAttachmentRepository: IssueAttachmentRepository | null;
16
18
  };
17
19
  export type ConsoleOperationResponse = {
18
20
  statusCode: number;
@@ -21,6 +23,7 @@ export type ConsoleOperationResponse = {
21
23
  export declare const handleReview: (context: ConsoleOperationContext, body: Record<string, unknown>) => Promise<ConsoleOperationResponse>;
22
24
  export declare const handleTriage: (context: ConsoleOperationContext, body: Record<string, unknown>) => Promise<ConsoleOperationResponse>;
23
25
  export declare const handleComment: (context: ConsoleOperationContext, body: Record<string, unknown>) => Promise<ConsoleOperationResponse>;
26
+ export declare const handleAttachmentUpload: (context: ConsoleOperationContext, body: Record<string, unknown>) => Promise<ConsoleOperationResponse>;
24
27
  export declare const handleReviewComment: (context: ConsoleOperationContext, body: Record<string, unknown>) => Promise<ConsoleOperationResponse>;
25
28
  export declare const handleIntmux: (context: ConsoleOperationContext, body: Record<string, unknown>) => Promise<ConsoleOperationResponse>;
26
29
  //# sourceMappingURL=consoleOperationApi.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"consoleOperationApi.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/console/consoleOperationApi.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EAEhB,MAAM,6DAA6D,CAAC;AACrE,OAAO,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAI3D,eAAO,MAAM,8BAA8B,uBAAuB,CAAC;AACnE,eAAO,MAAM,4BAA4B,qBAAqB,CAAC;AAE/D,MAAM,MAAM,qBAAqB,GAAG;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG,CACnC,MAAM,EAAE,MAAM,KACX,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAAC;AAE3C,MAAM,MAAM,sBAAsB,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;AAEjE,MAAM,MAAM,uBAAuB,GAAG;IACpC,eAAe,EAAE,eAAe,CAAC;IACjC,cAAc,EAAE,sBAAsB,CAAC;IACvC,kBAAkB,EAAE,sBAAsB,CAAC;IAC3C,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,OAAO,CAAC;CACf,CAAC;AAsJF,eAAO,MAAM,YAAY,GACvB,SAAS,uBAAuB,EAChC,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,OAAO,CAAC,wBAAwB,CAoFlC,CAAC;AAEF,eAAO,MAAM,YAAY,GACvB,SAAS,uBAAuB,EAChC,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,OAAO,CAAC,wBAAwB,CA6FlC,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,SAAS,uBAAuB,EAChC,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,OAAO,CAAC,wBAAwB,CA2BlC,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,SAAS,uBAAuB,EAChC,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,OAAO,CAAC,wBAAwB,CAiClC,CAAC;AAEF,eAAO,MAAM,YAAY,GACvB,SAAS,uBAAuB,EAChC,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,OAAO,CAAC,wBAAwB,CAiClC,CAAC"}
1
+ {"version":3,"file":"consoleOperationApi.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/console/consoleOperationApi.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EAEhB,MAAM,6DAA6D,CAAC;AACrE,OAAO,EAAE,yBAAyB,EAAE,MAAM,uEAAuE,CAAC;AAClH,OAAO,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAK3D,eAAO,MAAM,8BAA8B,uBAAuB,CAAC;AACnE,eAAO,MAAM,4BAA4B,qBAAqB,CAAC;AAE/D,MAAM,MAAM,qBAAqB,GAAG;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG,CACnC,MAAM,EAAE,MAAM,KACX,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAAC;AAE3C,MAAM,MAAM,sBAAsB,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;AAEjE,MAAM,MAAM,uBAAuB,GAAG;IACpC,eAAe,EAAE,eAAe,CAAC;IACjC,cAAc,EAAE,sBAAsB,CAAC;IACvC,kBAAkB,EAAE,sBAAsB,CAAC;IAC3C,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,yBAAyB,EAAE,yBAAyB,GAAG,IAAI,CAAC;CAC7D,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,OAAO,CAAC;CACf,CAAC;AA2JF,eAAO,MAAM,YAAY,GACvB,SAAS,uBAAuB,EAChC,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,OAAO,CAAC,wBAAwB,CAoFlC,CAAC;AAEF,eAAO,MAAM,YAAY,GACvB,SAAS,uBAAuB,EAChC,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,OAAO,CAAC,wBAAwB,CA6FlC,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,SAAS,uBAAuB,EAChC,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,OAAO,CAAC,wBAAwB,CA2BlC,CAAC;AAEF,eAAO,MAAM,sBAAsB,GACjC,SAAS,uBAAuB,EAChC,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,OAAO,CAAC,wBAAwB,CA2ClC,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,SAAS,uBAAuB,EAChC,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,OAAO,CAAC,wBAAwB,CAiClC,CAAC;AAEF,eAAO,MAAM,YAAY,GACvB,SAAS,uBAAuB,EAChC,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,OAAO,CAAC,wBAAwB,CAiClC,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import * as http from 'http';
2
+ import { IssueAttachmentRepository } from '../../../domain/usecases/adapter-interfaces/IssueAttachmentRepository';
2
3
  import { IssueRepository } from '../../../domain/usecases/adapter-interfaces/IssueRepository';
3
4
  import { IssueTitleStateCache, PullRequestStatusCache } from './consoleReadApi';
4
5
  import { ConsolePjcodeValidator, ConsoleProjectResolver } from './consoleOperationApi';
@@ -28,6 +29,7 @@ export type WebServerOptions = {
28
29
  issueRepository?: IssueRepository | null;
29
30
  resolveProject?: ConsoleProjectResolver | null;
30
31
  isPjcodeConfigured?: ConsolePjcodeValidator | null;
32
+ issueAttachmentRepository?: IssueAttachmentRepository | null;
31
33
  issueTitleStateCache?: IssueTitleStateCache | null;
32
34
  pullRequestStatusCache?: PullRequestStatusCache | null;
33
35
  };
@@ -1 +1 @@
1
- {"version":3,"file":"webServer.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/console/webServer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"webServer.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/console/webServer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { IssueAttachmentRepository, IssueAttachmentUploadRequest } from '../../domain/usecases/adapter-interfaces/IssueAttachmentRepository';
2
+ import { LocalCommandRunner } from '../../domain/usecases/adapter-interfaces/LocalCommandRunner';
3
+ export declare const UPLOAD_COMMAND = "upload-file-to-gh-issue";
4
+ export declare const ALLOWED_ATTACHMENT_EXTENSIONS: readonly [".png", ".jpg", ".jpeg", ".gif", ".webp", ".svg", ".pdf", ".txt", ".md", ".log", ".csv", ".json", ".zip", ".mov", ".mp4"];
5
+ export declare const UPLOAD_FILE_BASE_NAME = "attachment";
6
+ export declare const sanitizeAttachmentFileName: (fileName: string) => string;
7
+ export declare const resolveAttachmentExtension: (fileName: string) => string;
8
+ export declare const relabelAttachmentMarkdown: (markdown: string, label: string) => string;
9
+ export declare class LocalCommandIssueAttachmentRepository implements IssueAttachmentRepository {
10
+ private readonly localCommandRunner;
11
+ private readonly temporaryDirectoryRoot;
12
+ constructor(localCommandRunner: LocalCommandRunner, temporaryDirectoryRoot?: string);
13
+ uploadAttachment(request: IssueAttachmentUploadRequest): Promise<string>;
14
+ }
15
+ //# sourceMappingURL=LocalCommandIssueAttachmentRepository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocalCommandIssueAttachmentRepository.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/LocalCommandIssueAttachmentRepository.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,yBAAyB,EACzB,4BAA4B,EAC7B,MAAM,oEAAoE,CAAC;AAC5E,OAAO,EAAE,kBAAkB,EAAE,MAAM,6DAA6D,CAAC;AAEjG,eAAO,MAAM,cAAc,4BAA4B,CAAC;AAExD,eAAO,MAAM,6BAA6B,qIAgBhC,CAAC;AAEX,eAAO,MAAM,qBAAqB,eAAe,CAAC;AAElD,eAAO,MAAM,0BAA0B,GAAI,UAAU,MAAM,KAAG,MAI7D,CAAC;AAEF,eAAO,MAAM,0BAA0B,GAAI,UAAU,MAAM,KAAG,MAM7D,CAAC;AAEF,eAAO,MAAM,yBAAyB,GACpC,UAAU,MAAM,EAChB,OAAO,MAAM,KACZ,MAMF,CAAC;AAEF,qBAAa,qCAAsC,YAAW,yBAAyB;IAEnF,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,sBAAsB;gBADtB,kBAAkB,EAAE,kBAAkB,EACtC,sBAAsB,GAAE,MAAiB;IAGtD,gBAAgB,CACpB,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,MAAM,CAAC;CA+BnB"}
@@ -0,0 +1,9 @@
1
+ export type IssueAttachmentUploadRequest = {
2
+ issueOrPullRequestUrl: string;
3
+ fileName: string;
4
+ content: Uint8Array;
5
+ };
6
+ export interface IssueAttachmentRepository {
7
+ uploadAttachment(request: IssueAttachmentUploadRequest): Promise<string>;
8
+ }
9
+ //# sourceMappingURL=IssueAttachmentRepository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IssueAttachmentRepository.d.ts","sourceRoot":"","sources":["../../../../src/domain/usecases/adapter-interfaces/IssueAttachmentRepository.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,4BAA4B,GAAG;IACzC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,UAAU,CAAC;CACrB,CAAC;AAEF,MAAM,WAAW,yBAAyB;IACxC,gBAAgB,CAAC,OAAO,EAAE,4BAA4B,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC1E"}
@@ -17,6 +17,7 @@ export type ConsoleListItem = {
17
17
  dependedIssueUrls: string[];
18
18
  labels: string[];
19
19
  createdAt: string;
20
+ relatedOpenPullRequestUrls: string[];
20
21
  };
21
22
  export type ConsoleFieldOption = {
22
23
  id: string;
@@ -63,6 +64,7 @@ export declare class GenerateConsoleListsUseCase {
63
64
  run: (input: GenerateConsoleListsInput) => ConsoleLists;
64
65
  private isActionable;
65
66
  private workflowBlockerSelector;
67
+ private buildRelatedOpenPullRequestUrlsByIssueUrl;
66
68
  private projectItem;
67
69
  private buildFieldOptions;
68
70
  private buildStoryColorsObject;
@@ -1 +1 @@
1
- {"version":3,"file":"GenerateConsoleListsUseCase.d.ts","sourceRoot":"","sources":["../../../../src/domain/usecases/console/GenerateConsoleListsUseCase.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"GenerateConsoleListsUseCase.d.ts","sourceRoot":"","sources":["../../../../src/domain/usecases/console/GenerateConsoleListsUseCase.ts"],"names":[],"mappings":"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"}