github-issue-tower-defence-management 1.143.6 → 1.144.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 (47) hide show
  1. package/CHANGELOG.md +7 -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-y6LyqXlu.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/package.json +1 -1
  17. package/src/adapter/entry-points/cli/index.ts +4 -0
  18. package/src/adapter/entry-points/console/consoleItemUrlLookup.test.ts +63 -0
  19. package/src/adapter/entry-points/console/consoleItemUrlLookup.ts +66 -0
  20. package/src/adapter/entry-points/console/consoleOperationApi.test.ts +155 -0
  21. package/src/adapter/entry-points/console/consoleOperationApi.ts +56 -0
  22. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleCommentComposer.stories.tsx +17 -0
  23. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleCommentComposer.test.tsx +149 -1
  24. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleCommentComposer.tsx +107 -1
  25. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleOperations.ts +22 -0
  26. package/src/adapter/entry-points/console/ui/src/features/console/lib/consoleApi.ts +35 -0
  27. package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsoleItemDetailContainer.test.tsx +1 -0
  28. package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsoleItemDetailContainer.tsx +1 -0
  29. package/src/adapter/entry-points/console/ui-dist/assets/index-y6LyqXlu.js +82 -0
  30. package/src/adapter/entry-points/console/ui-dist/index.html +1 -1
  31. package/src/adapter/entry-points/console/webServer.ts +6 -0
  32. package/src/adapter/repositories/LocalCommandIssueAttachmentRepository.test.ts +136 -0
  33. package/src/adapter/repositories/LocalCommandIssueAttachmentRepository.ts +96 -0
  34. package/src/domain/usecases/adapter-interfaces/IssueAttachmentRepository.ts +9 -0
  35. package/types/adapter/entry-points/cli/index.d.ts.map +1 -1
  36. package/types/adapter/entry-points/console/consoleItemUrlLookup.d.ts +2 -0
  37. package/types/adapter/entry-points/console/consoleItemUrlLookup.d.ts.map +1 -0
  38. package/types/adapter/entry-points/console/consoleOperationApi.d.ts +3 -0
  39. package/types/adapter/entry-points/console/consoleOperationApi.d.ts.map +1 -1
  40. package/types/adapter/entry-points/console/webServer.d.ts +2 -0
  41. package/types/adapter/entry-points/console/webServer.d.ts.map +1 -1
  42. package/types/adapter/repositories/LocalCommandIssueAttachmentRepository.d.ts +15 -0
  43. package/types/adapter/repositories/LocalCommandIssueAttachmentRepository.d.ts.map +1 -0
  44. package/types/domain/usecases/adapter-interfaces/IssueAttachmentRepository.d.ts +9 -0
  45. package/types/domain/usecases/adapter-interfaces/IssueAttachmentRepository.d.ts.map +1 -0
  46. package/bin/adapter/entry-points/console/ui-dist/assets/index-DDQKZmBM.js +0 -81
  47. 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-y6LyqXlu.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
+ }
@@ -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"}