@ccdd/project 2.0.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 (163) hide show
  1. package/README.md +25 -0
  2. package/dist/monitor-ui/assets/GraphView-CYMJ1Nb7.css +1 -0
  3. package/dist/monitor-ui/assets/GraphView-UjtW4QRC.js +27 -0
  4. package/dist/monitor-ui/assets/ValidationView-CC1FvqUl.js +1 -0
  5. package/dist/monitor-ui/assets/ValidationView-DWl4b8Ug.css +1 -0
  6. package/dist/monitor-ui/assets/_plugin-vue_export-helper-BDNMzG2s.js +1 -0
  7. package/dist/monitor-ui/assets/elk-api-yRi2AOS6.js +1 -0
  8. package/dist/monitor-ui/assets/elk.bundled-CtLobQTy.js +24 -0
  9. package/dist/monitor-ui/assets/graph-layout-worker-CgfWoa9t.js +22 -0
  10. package/dist/monitor-ui/assets/index-CUzg-dht.css +1 -0
  11. package/dist/monitor-ui/assets/index-Cpm0fC0p.js +8 -0
  12. package/dist/monitor-ui/index.html +15 -0
  13. package/dist/scripts/prepare-demo.d.ts +26 -0
  14. package/dist/scripts/prepare-demo.js +121 -0
  15. package/dist/scripts/prepare-demo.js.map +1 -0
  16. package/dist/src/artifacts/groups.d.ts +9 -0
  17. package/dist/src/artifacts/groups.js +77 -0
  18. package/dist/src/artifacts/groups.js.map +1 -0
  19. package/dist/src/artifacts/human.d.ts +38 -0
  20. package/dist/src/artifacts/human.js +156 -0
  21. package/dist/src/artifacts/human.js.map +1 -0
  22. package/dist/src/artifacts/index.d.ts +149 -0
  23. package/dist/src/artifacts/index.js +354 -0
  24. package/dist/src/artifacts/index.js.map +1 -0
  25. package/dist/src/artifacts/instruction.d.ts +23 -0
  26. package/dist/src/artifacts/instruction.js +94 -0
  27. package/dist/src/artifacts/instruction.js.map +1 -0
  28. package/dist/src/artifacts/mcp-server.d.ts +6 -0
  29. package/dist/src/artifacts/mcp-server.js +96 -0
  30. package/dist/src/artifacts/mcp-server.js.map +1 -0
  31. package/dist/src/artifacts/tool-check.d.ts +40 -0
  32. package/dist/src/artifacts/tool-check.js +113 -0
  33. package/dist/src/artifacts/tool-check.js.map +1 -0
  34. package/dist/src/artifacts/types.d.ts +43 -0
  35. package/dist/src/artifacts/types.js +97 -0
  36. package/dist/src/artifacts/types.js.map +1 -0
  37. package/dist/src/broker/config.d.ts +11 -0
  38. package/dist/src/broker/config.js +141 -0
  39. package/dist/src/broker/config.js.map +1 -0
  40. package/dist/src/broker/graph.d.ts +69 -0
  41. package/dist/src/broker/graph.js +94 -0
  42. package/dist/src/broker/graph.js.map +1 -0
  43. package/dist/src/broker/index.d.ts +170 -0
  44. package/dist/src/broker/index.js +931 -0
  45. package/dist/src/broker/index.js.map +1 -0
  46. package/dist/src/cli.d.ts +24 -0
  47. package/dist/src/cli.js +340 -0
  48. package/dist/src/cli.js.map +1 -0
  49. package/dist/src/contracts.d.ts +116 -0
  50. package/dist/src/contracts.js +2 -0
  51. package/dist/src/contracts.js.map +1 -0
  52. package/dist/src/definitions.d.ts +53 -0
  53. package/dist/src/definitions.js +2 -0
  54. package/dist/src/definitions.js.map +1 -0
  55. package/dist/src/doctor/index.d.ts +41 -0
  56. package/dist/src/doctor/index.js +189 -0
  57. package/dist/src/doctor/index.js.map +1 -0
  58. package/dist/src/executors/auth.d.ts +16 -0
  59. package/dist/src/executors/auth.js +150 -0
  60. package/dist/src/executors/auth.js.map +1 -0
  61. package/dist/src/executors/errors.d.ts +6 -0
  62. package/dist/src/executors/errors.js +10 -0
  63. package/dist/src/executors/errors.js.map +1 -0
  64. package/dist/src/executors/index.d.ts +20 -0
  65. package/dist/src/executors/index.js +262 -0
  66. package/dist/src/executors/index.js.map +1 -0
  67. package/dist/src/executors/pi.d.ts +32 -0
  68. package/dist/src/executors/pi.js +190 -0
  69. package/dist/src/executors/pi.js.map +1 -0
  70. package/dist/src/executors/process.d.ts +22 -0
  71. package/dist/src/executors/process.js +70 -0
  72. package/dist/src/executors/process.js.map +1 -0
  73. package/dist/src/local.d.ts +13 -0
  74. package/dist/src/local.js +20 -0
  75. package/dist/src/local.js.map +1 -0
  76. package/dist/src/monitor/actions.d.ts +12 -0
  77. package/dist/src/monitor/actions.js +74 -0
  78. package/dist/src/monitor/actions.js.map +1 -0
  79. package/dist/src/monitor/server.d.ts +8 -0
  80. package/dist/src/monitor/server.js +493 -0
  81. package/dist/src/monitor/server.js.map +1 -0
  82. package/dist/src/monitor/store.d.ts +22 -0
  83. package/dist/src/monitor/store.js +517 -0
  84. package/dist/src/monitor/store.js.map +1 -0
  85. package/dist/src/monitor/types.d.ts +143 -0
  86. package/dist/src/monitor/types.js +2 -0
  87. package/dist/src/monitor/types.js.map +1 -0
  88. package/dist/src/monitor/ui/api.d.ts +11 -0
  89. package/dist/src/monitor/ui/api.js +29 -0
  90. package/dist/src/monitor/ui/api.js.map +1 -0
  91. package/dist/src/monitor/ui/critic-presentation.d.ts +11 -0
  92. package/dist/src/monitor/ui/critic-presentation.js +60 -0
  93. package/dist/src/monitor/ui/critic-presentation.js.map +1 -0
  94. package/dist/src/monitor/ui/format.d.ts +9 -0
  95. package/dist/src/monitor/ui/format.js +22 -0
  96. package/dist/src/monitor/ui/format.js.map +1 -0
  97. package/dist/src/monitor/ui/graph-layout.d.ts +43 -0
  98. package/dist/src/monitor/ui/graph-layout.js +191 -0
  99. package/dist/src/monitor/ui/graph-layout.js.map +1 -0
  100. package/dist/src/monitor/ui/tool-content.d.ts +13 -0
  101. package/dist/src/monitor/ui/tool-content.js +22 -0
  102. package/dist/src/monitor/ui/tool-content.js.map +1 -0
  103. package/dist/src/monitor/ui/tool-input.d.ts +23 -0
  104. package/dist/src/monitor/ui/tool-input.js +112 -0
  105. package/dist/src/monitor/ui/tool-input.js.map +1 -0
  106. package/dist/src/project/cli.d.ts +9 -0
  107. package/dist/src/project/cli.js +306 -0
  108. package/dist/src/project/cli.js.map +1 -0
  109. package/dist/src/project/graph.d.ts +4 -0
  110. package/dist/src/project/graph.js +26 -0
  111. package/dist/src/project/graph.js.map +1 -0
  112. package/dist/src/project/identity.d.ts +5 -0
  113. package/dist/src/project/identity.js +87 -0
  114. package/dist/src/project/identity.js.map +1 -0
  115. package/dist/src/project/index.d.ts +19 -0
  116. package/dist/src/project/index.js +26 -0
  117. package/dist/src/project/index.js.map +1 -0
  118. package/dist/src/project/query.d.ts +9 -0
  119. package/dist/src/project/query.js +136 -0
  120. package/dist/src/project/query.js.map +1 -0
  121. package/dist/src/project/store.d.ts +15 -0
  122. package/dist/src/project/store.js +47 -0
  123. package/dist/src/project/store.js.map +1 -0
  124. package/dist/src/project/types.d.ts +106 -0
  125. package/dist/src/project/types.js +2 -0
  126. package/dist/src/project/types.js.map +1 -0
  127. package/dist/src/requester/index.d.ts +16 -0
  128. package/dist/src/requester/index.js +96 -0
  129. package/dist/src/requester/index.js.map +1 -0
  130. package/dist/src/runtime-paths.d.ts +1 -0
  131. package/dist/src/runtime-paths.js +4 -0
  132. package/dist/src/runtime-paths.js.map +1 -0
  133. package/dist/src/sdk.d.ts +9 -0
  134. package/dist/src/sdk.js +3 -0
  135. package/dist/src/sdk.js.map +1 -0
  136. package/dist/src/tools/contracts.d.ts +108 -0
  137. package/dist/src/tools/contracts.js +2 -0
  138. package/dist/src/tools/contracts.js.map +1 -0
  139. package/dist/src/tools/host.d.ts +7 -0
  140. package/dist/src/tools/host.js +98 -0
  141. package/dist/src/tools/host.js.map +1 -0
  142. package/dist/src/tools/paths.d.ts +2 -0
  143. package/dist/src/tools/paths.js +18 -0
  144. package/dist/src/tools/paths.js.map +1 -0
  145. package/dist/src/tools/runner.d.ts +54 -0
  146. package/dist/src/tools/runner.js +194 -0
  147. package/dist/src/tools/runner.js.map +1 -0
  148. package/dist/src/tools/runtime-host.d.ts +1 -0
  149. package/dist/src/tools/runtime-host.js +116 -0
  150. package/dist/src/tools/runtime-host.js.map +1 -0
  151. package/dist/src/tools/schema.d.ts +6 -0
  152. package/dist/src/tools/schema.js +106 -0
  153. package/dist/src/tools/schema.js.map +1 -0
  154. package/dist/src/worker-client.d.ts +27 -0
  155. package/dist/src/worker-client.js +96 -0
  156. package/dist/src/worker-client.js.map +1 -0
  157. package/dist/src/worker.d.ts +1 -0
  158. package/dist/src/worker.js +50 -0
  159. package/dist/src/worker.js.map +1 -0
  160. package/dist/src/workspaces/index.d.ts +33 -0
  161. package/dist/src/workspaces/index.js +394 -0
  162. package/dist/src/workspaces/index.js.map +1 -0
  163. package/package.json +26 -0
@@ -0,0 +1,493 @@
1
+ import { createServer } from 'node:http';
2
+ import { readFile, readdir } from 'node:fs/promises';
3
+ import { createHash, createHmac, randomBytes, timingSafeEqual } from 'node:crypto';
4
+ import { isDeepStrictEqual } from 'node:util';
5
+ import { createArtifactViewer, createArtifactTools } from '../artifacts/index.js';
6
+ import { createHumanArtifactTools } from '../artifacts/human.js';
7
+ import { describeReviewTools } from '../tools/runner.js';
8
+ import { readStoredArtifactScope } from '../requester/index.js';
9
+ import { reopenWorkspace } from '../workspaces/index.js';
10
+ import { createMonitorStore } from './store.js';
11
+ import { inspectProject } from '../project/index.js';
12
+ import { MonitorActionError, authorizeWorkspace, claimReview, completeReview, executeReviewTool } from './actions.js';
13
+ const ARTIFACT_BUDGET_MS = 10_000;
14
+ const MAX_ARTIFACT_READS = 2;
15
+ const identifier = /^[A-Za-z0-9][A-Za-z0-9_-]*$/;
16
+ class HttpError extends MonitorActionError {
17
+ }
18
+ function parameters(url, allowed) {
19
+ for (const name of url.searchParams.keys()) {
20
+ if (!allowed.includes(name) || url.searchParams.getAll(name).length !== 1)
21
+ throw new HttpError(400, '알 수 없거나 중복된 조회 조건입니다.');
22
+ }
23
+ }
24
+ function number(value, fallback, minimum, maximum) {
25
+ if (value === null)
26
+ return fallback;
27
+ const parsed = Number(value);
28
+ if (!/^\d+$/.test(value) || !Number.isSafeInteger(parsed) || parsed < minimum || parsed > maximum)
29
+ throw new HttpError(400, `조회 범위는 ${minimum}~${maximum} 사이의 정수여야 합니다.`);
30
+ return parsed;
31
+ }
32
+ function id(value, maximumLength = 128) {
33
+ let decoded;
34
+ try {
35
+ decoded = decodeURIComponent(value);
36
+ }
37
+ catch {
38
+ throw new HttpError(400, '올바르지 않은 식별자입니다.');
39
+ }
40
+ if (decoded.length > maximumLength || !identifier.test(decoded))
41
+ throw new HttpError(400, '올바르지 않은 식별자입니다.');
42
+ return decoded;
43
+ }
44
+ function errorCode(value) {
45
+ return value && typeof value === 'object' && 'code' in value && typeof value.code === 'string' ? value.code : undefined;
46
+ }
47
+ function safeError(value) {
48
+ if (value instanceof MonitorActionError)
49
+ return value;
50
+ const code = errorCode(value);
51
+ if (['WORKSPACE_CHANGED', 'WORKSPACE_CACHE_TAMPERED', 'WORKSPACE_ARTIFACT_MISMATCH'].includes(code ?? ''))
52
+ return new HttpError(409, '리뷰 입력이 변경되어 이 Artifact를 확인할 수 없습니다.');
53
+ if (code === 'ENOENT' || code === 'ENOTDIR')
54
+ return new HttpError(409, '보관된 리뷰 입력을 찾을 수 없습니다. 원본 또는 복사본이 이동·삭제되었을 수 있습니다.');
55
+ if (code === 'HUMAN_TOOL_UNAVAILABLE')
56
+ return new HttpError(409, '등록된 프로그램을 시작할 수 없습니다. 설치 여부와 도구 설정을 확인하세요.');
57
+ if (code === 'HUMAN_TOOL_FAILED')
58
+ return new HttpError(409, '등록된 프로그램이 정상적으로 끝나지 않았습니다. 프로그램과 도구 설정을 확인하세요.');
59
+ if (code === 'HUMAN_TOOL_TIMEOUT')
60
+ return new HttpError(504, '등록된 프로그램의 실행 시간이 초과되었습니다.');
61
+ if (code === 'ARTIFACT_TOOL_TIMEOUT')
62
+ return new HttpError(504, '도구 실행 시간이 초과되었습니다.');
63
+ if (code === 'ARTIFACT_TOOL_FAILED')
64
+ return new HttpError(409, '도구를 실행하지 못했습니다. 입력과 등록된 프로그램을 확인한 뒤 다시 시도하세요.');
65
+ if (code === 'UNKNOWN_ARTIFACT_TOOL')
66
+ return new HttpError(400, '이 Artifact에 등록되지 않은 도구입니다.');
67
+ if (code === 'ABORTED')
68
+ return new HttpError(409, '도구 실행이 중단되었습니다.');
69
+ if (code === 'EACCES' || code === 'EPERM')
70
+ return new HttpError(409, '리뷰 입력을 읽을 권한이 없습니다.');
71
+ const message = value instanceof Error ? value.message : '';
72
+ if (/claimed|reviewer who/i.test(message))
73
+ return new HttpError(403, '이 브라우저에서 맡은 리뷰만 처리할 수 있습니다.');
74
+ if (/waiting for a human|already completed|alarm delivery|lock review requires/i.test(message))
75
+ return new HttpError(409, '리뷰 상태가 변경되었거나 아직 준비되지 않았습니다. 목록을 새로고침하세요.');
76
+ if (/worker|saved.*configuration|saved.*settings/i.test(message))
77
+ return new HttpError(503, '다음 리뷰의 작업자를 시작할 수 없습니다. 저장된 실행 설정을 확인하고 해당 Run을 재개하세요.');
78
+ return new HttpError(400, '요청된 범위의 Artifact를 읽을 수 없습니다. 파일 경로와 읽기 범위를 확인하세요.');
79
+ }
80
+ function protect(request, port) {
81
+ const host = request.headers.host;
82
+ const hosts = [`127.0.0.1:${port}`, `localhost:${port}`];
83
+ if (!host || !hosts.includes(host))
84
+ throw new HttpError(403, '이 모니터의 로컬 주소로 접속하세요.');
85
+ const origin = request.headers.origin;
86
+ if (origin !== undefined && origin !== `http://${host}`)
87
+ throw new HttpError(403, '같은 모니터 화면에서 보낸 요청만 허용합니다.');
88
+ const site = request.headers['sec-fetch-site'];
89
+ if (site !== undefined && site !== 'same-origin' && site !== 'none')
90
+ throw new HttpError(403, '외부 페이지에서 이 모니터에 접근할 수 없습니다.');
91
+ if (request.method !== 'GET' && request.method !== 'POST')
92
+ throw new HttpError(405, '지원하지 않는 요청 방식입니다.');
93
+ if (request.method === 'POST' && origin !== `http://${host}`)
94
+ throw new HttpError(403, '같은 모니터 화면에서 보낸 요청만 허용합니다.');
95
+ if (request.method === 'GET' && (request.headers['transfer-encoding'] !== undefined || (request.headers['content-length'] !== undefined && request.headers['content-length'] !== '0')))
96
+ throw new HttpError(400, '조회 요청에는 본문을 보낼 수 없습니다.');
97
+ return host;
98
+ }
99
+ function headers(response) {
100
+ response.setHeader('Cache-Control', 'no-store');
101
+ response.setHeader('Content-Security-Policy', "default-src 'none'; script-src 'self'; style-src 'self'; connect-src 'self'; img-src 'self' data:; base-uri 'none'; frame-ancestors 'none'; form-action 'none'");
102
+ response.setHeader('X-Content-Type-Options', 'nosniff');
103
+ response.setHeader('Referrer-Policy', 'no-referrer');
104
+ response.setHeader('Cross-Origin-Resource-Policy', 'same-origin');
105
+ response.setHeader('X-Frame-Options', 'DENY');
106
+ }
107
+ function json(response, value, status = 200) {
108
+ if (response.destroyed || response.writableEnded)
109
+ return;
110
+ response.writeHead(status, { 'content-type': 'application/json; charset=utf-8' });
111
+ response.end(JSON.stringify(value));
112
+ }
113
+ const cookieName = 'ccdd_monitor_session';
114
+ const bearerPattern = /^[A-Za-z0-9_-]{43}$/;
115
+ function tokenFrom(request) {
116
+ const matches = (request.headers.cookie ?? '').split(';').map(part => part.trim()).filter(part => part.startsWith(`${cookieName}=`));
117
+ if (matches.length !== 1)
118
+ return undefined;
119
+ const token = matches[0].slice(cookieName.length + 1);
120
+ return bearerPattern.test(token) ? token : undefined;
121
+ }
122
+ function reviewer(token) { return `browser-${createHash('sha256').update(token).digest('hex').slice(0, 24)}`; }
123
+ function session(secret, token) {
124
+ return { reviewerId: reviewer(token), csrfToken: createHmac('sha256', secret).update(token).digest('base64url') };
125
+ }
126
+ function authenticate(request, secret) {
127
+ const token = tokenFrom(request), supplied = request.headers['x-ccdd-csrf'];
128
+ if (!token || typeof supplied !== 'string' || !bearerPattern.test(supplied) || !timingSafeEqual(Buffer.from(supplied), Buffer.from(session(secret, token).csrfToken)))
129
+ throw new HttpError(403, '리뷰어 세션을 확인할 수 없습니다. 화면을 새로고침한 후 다시 시도하세요.');
130
+ return reviewer(token);
131
+ }
132
+ const object = (value) => value !== null && typeof value === 'object' && !Array.isArray(value);
133
+ function bodyShape(value, keys) {
134
+ if (!object(value) || Object.keys(value).some(key => !keys.includes(key)))
135
+ throw new HttpError(400, '요청 본문의 항목이 올바르지 않습니다.');
136
+ }
137
+ async function body(request) {
138
+ if (!/^application\/json(?:;\s*charset=utf-8)?$/i.test(request.headers['content-type'] ?? ''))
139
+ throw new HttpError(415, 'JSON 형식으로 요청하세요.');
140
+ if (Number(request.headers['content-length'] ?? 0) > 32_768)
141
+ throw new HttpError(413, '요청 본문은 32KiB 이하여야 합니다.');
142
+ return await new Promise((ok, no) => {
143
+ const chunks = [];
144
+ let size = 0;
145
+ const cleanup = () => { clearTimeout(timer); request.off('data', data); request.off('end', end); request.off('aborted', abort); request.off('error', no); };
146
+ const fail = (error) => { cleanup(); request.resume(); no(error); };
147
+ const abort = () => fail(new HttpError(400, '요청 전송이 중단되었습니다.'));
148
+ const data = (chunk) => { size += chunk.length; if (size > 32_768)
149
+ fail(new HttpError(413, '요청 본문은 32KiB 이하여야 합니다.'));
150
+ else
151
+ chunks.push(chunk); };
152
+ const end = () => { cleanup(); try {
153
+ ok(JSON.parse(Buffer.concat(chunks).toString('utf8')));
154
+ }
155
+ catch {
156
+ no(new HttpError(400, 'JSON 요청 본문을 확인하세요.'));
157
+ } };
158
+ const timer = setTimeout(() => fail(new HttpError(408, '요청 본문 전송 시간이 초과되었습니다.')), 5_000);
159
+ request.on('data', data);
160
+ request.once('end', end);
161
+ request.once('aborted', abort);
162
+ request.once('error', no);
163
+ });
164
+ }
165
+ async function staticAssets() {
166
+ const root = new URL('../../monitor-ui/', import.meta.url);
167
+ const assets = new Map();
168
+ const visit = async (directory, prefix) => {
169
+ for (const entry of await readdir(directory, { withFileTypes: true })) {
170
+ const path = `${prefix}${entry.name}`;
171
+ if (entry.isDirectory())
172
+ await visit(new URL(`${entry.name}/`, directory), `${path}/`);
173
+ else if (entry.isFile()) {
174
+ const extension = entry.name.split('.').at(-1);
175
+ const mime = extension === 'html' ? 'text/html' : extension === 'js' ? 'text/javascript' : extension === 'css' ? 'text/css' : extension === 'svg' ? 'image/svg+xml' : undefined;
176
+ if (mime)
177
+ assets.set(path === '/index.html' ? '/' : path, [mime, await readFile(new URL(entry.name, directory))]);
178
+ }
179
+ }
180
+ };
181
+ await visit(root, '/');
182
+ if (!assets.has('/'))
183
+ throw new Error('모니터 화면 파일이 없습니다. 패키지를 다시 빌드하세요.');
184
+ return assets;
185
+ }
186
+ async function decorateDetail(detail, record, reviewerId) {
187
+ const waiting = detail.request.kind === 'human' && detail.request.status === 'WAITING_HUMAN';
188
+ const claimedByMe = Boolean(reviewerId && detail.request.claimedBy === reviewerId);
189
+ detail.human = {
190
+ canClaim: waiting && !detail.request.claimedBy && detail.request.workerState !== 'missing',
191
+ canComplete: waiting && claimedByMe && Boolean(record.request.notifiedAt) && detail.request.workerState !== 'missing',
192
+ claimedByMe,
193
+ };
194
+ detail.tools = [];
195
+ detail.artifactPreview = record.request.configManifest ? 'tools' : 'legacy';
196
+ if (detail.request.kind === 'human') {
197
+ try {
198
+ if (record.request.configManifest) {
199
+ // A monitor GET only projects the stored manifest. Loading a TS config is executable work.
200
+ detail.tools = describeReviewTools({ artifacts: record.request.artifacts, configManifest: record.request.configManifest, audience: 'human' })
201
+ .map(tool => ({ name: tool.name, artifactId: tool.artifactId, operation: tool.operation, description: tool.description, inputSchema: tool.inputSchema }));
202
+ }
203
+ else {
204
+ await authorizeWorkspace(record);
205
+ const registry = await createHumanArtifactTools({ worktreePath: record.request.workspace.path, artifacts: record.request.artifacts, artifactTypes: record.request.artifactTypes, allowLegacy: true, signal: AbortSignal.timeout(5_000) });
206
+ detail.tools = registry.tools.map(tool => ({ name: tool.name, artifactId: tool.artifactId, operation: tool.operation, description: tool.description, inputSchema: tool.inputSchema }));
207
+ }
208
+ }
209
+ catch {
210
+ detail.toolIssue = '이 리뷰의 도구를 준비할 수 없습니다. 보관된 입력과 도구 정의를 확인하세요.';
211
+ }
212
+ }
213
+ return detail;
214
+ }
215
+ /** Optional transport: GET observes; authenticated, explicit POST delegates durable Human actions. */
216
+ export async function startMonitor(options = {}) {
217
+ const requestedPort = options.port ?? 4318;
218
+ if (!Number.isInteger(requestedPort) || requestedPort < 0 || requestedPort > 65535)
219
+ throw new Error('모니터 포트는 0~65535 사이의 정수여야 합니다.');
220
+ const store = createMonitorStore(options);
221
+ const assets = await staticAssets();
222
+ const sessionSecret = randomBytes(32);
223
+ const mutations = new Set();
224
+ let port = requestedPort, closing = false, closePromise;
225
+ const active = new Set();
226
+ const jobs = new Set();
227
+ const server = createServer({ maxHeaderSize: 16_384 }, (request, response) => {
228
+ headers(response);
229
+ const job = (async () => {
230
+ const host = protect(request, port);
231
+ if (!request.url?.startsWith('/') || request.url.startsWith('//'))
232
+ throw new HttpError(400, '올바르지 않은 조회 주소입니다.');
233
+ const url = new URL(request.url, `http://${host}`);
234
+ if (closing)
235
+ throw new HttpError(503, '모니터를 종료하고 있습니다.');
236
+ const asset = assets.get(url.pathname);
237
+ if (asset && request.method === 'GET') {
238
+ parameters(url, []);
239
+ response.writeHead(200, { 'content-type': `${asset[0]}; charset=utf-8` });
240
+ response.end(asset[1]);
241
+ return;
242
+ }
243
+ if (url.pathname === '/api/session' && request.method === 'GET') {
244
+ parameters(url, []);
245
+ const token = tokenFrom(request) ?? randomBytes(32).toString('base64url');
246
+ response.setHeader('Set-Cookie', `${cookieName}=${token}; Path=/; HttpOnly; SameSite=Strict; Max-Age=31536000`);
247
+ json(response, session(sessionSecret, token));
248
+ return;
249
+ }
250
+ if (request.method === 'POST') {
251
+ const validation = /^\/api\/projects\/([^/]+)\/validation$/.exec(url.pathname);
252
+ if (validation) {
253
+ parameters(url, []);
254
+ authenticate(request, sessionSecret);
255
+ bodyShape(await body(request), []);
256
+ if (active.size >= MAX_ARTIFACT_READS)
257
+ throw new HttpError(429, '다른 입력을 확인하고 있습니다. 잠시 후 다시 시도하세요.');
258
+ const context = await store.projectContext(id(validation[1]));
259
+ if (!context)
260
+ throw new HttpError(404, '프로젝트를 찾을 수 없습니다.');
261
+ const controller = new AbortController();
262
+ const disconnect = () => { if (!response.writableEnded)
263
+ controller.abort(new Error('Monitor client disconnected')); };
264
+ request.once('aborted', disconnect);
265
+ response.once('close', disconnect);
266
+ active.add(controller);
267
+ const timer = setTimeout(() => controller.abort(new HttpError(504, '현재 입력 확인 시간이 초과되었습니다. CLI에서 다시 확인하세요.')), 30_000);
268
+ try {
269
+ const { plan } = await inspectProject({ ...context, recursive: true, signal: controller.signal });
270
+ json(response, { plan, observedAt: new Date().toISOString() });
271
+ }
272
+ catch (error) {
273
+ if (controller.signal.aborted)
274
+ throw controller.signal.reason;
275
+ throw new HttpError(409, '현재 입력을 확인할 수 없습니다. ccdd-project config check로 설정과 입력을 확인하세요.');
276
+ }
277
+ finally {
278
+ clearTimeout(timer);
279
+ request.off('aborted', disconnect);
280
+ response.off('close', disconnect);
281
+ active.delete(controller);
282
+ }
283
+ return;
284
+ }
285
+ const action = /^\/api\/requests\/([^/]+)\/([^/]+)\/(claim|complete|tools\/([^/]+))$/.exec(url.pathname);
286
+ if (!action)
287
+ throw new HttpError(405, '이 주소는 조회 요청만 허용합니다.');
288
+ parameters(url, []);
289
+ const reviewerId = authenticate(request, sessionSecret);
290
+ const input = await body(request);
291
+ const projectId = id(action[1]), requestId = id(action[2]);
292
+ const key = `${projectId}/${requestId}`;
293
+ if (mutations.has(key))
294
+ throw new HttpError(409, '이 리뷰의 다른 작업을 처리하고 있습니다. 잠시 후 다시 시도하세요.');
295
+ mutations.add(key);
296
+ try {
297
+ const record = await store.request(projectId, requestId);
298
+ if (!record)
299
+ throw new HttpError(404, '리뷰 요청을 찾을 수 없습니다.');
300
+ if (record.request.id !== requestId)
301
+ throw new HttpError(409, '저장된 리뷰 식별자가 일치하지 않습니다.');
302
+ if (action[3] === 'claim') {
303
+ bodyShape(input, []);
304
+ await claimReview(record, reviewerId);
305
+ }
306
+ else if (action[3] === 'complete') {
307
+ bodyShape(input, ['verdict', 'summary', 'evidence']);
308
+ if ((input.verdict !== 'GREEN' && input.verdict !== 'RED') || typeof input.summary !== 'string' || !input.summary.trim() || input.summary.length > 12_000 || !Array.isArray(input.evidence) || input.evidence.length < 1 || input.evidence.length > 100 || !input.evidence.every(item => typeof item === 'string' && item.trim().length > 0 && item.length <= 4_000))
309
+ throw new HttpError(400, '판정, 요약과 근거 목록을 확인하세요.');
310
+ await completeReview(record, reviewerId, { verdict: input.verdict, summary: input.summary, evidence: input.evidence });
311
+ }
312
+ else {
313
+ bodyShape(input, ['arguments']);
314
+ if (!object(input.arguments))
315
+ throw new HttpError(400, '도구 입력은 JSON 객체여야 합니다.');
316
+ if (active.size >= MAX_ARTIFACT_READS)
317
+ throw new HttpError(429, '다른 도구를 처리하고 있습니다. 잠시 후 다시 시도하세요.');
318
+ const controller = new AbortController();
319
+ const disconnect = () => { if (!response.writableEnded)
320
+ controller.abort(new Error('Monitor client disconnected')); };
321
+ request.once('aborted', disconnect);
322
+ response.once('close', disconnect);
323
+ active.add(controller);
324
+ const timer = setTimeout(() => controller.abort(new HttpError(504, '도구 실행 시간이 초과되었습니다.')), 120_000);
325
+ try {
326
+ json(response, { result: await executeReviewTool(record, reviewerId, id(action[4], 129), input.arguments, controller.signal) });
327
+ }
328
+ finally {
329
+ clearTimeout(timer);
330
+ request.off('aborted', disconnect);
331
+ response.off('close', disconnect);
332
+ active.delete(controller);
333
+ }
334
+ return;
335
+ }
336
+ const updated = await store.detail(projectId, requestId);
337
+ if (!updated)
338
+ throw new HttpError(404, '리뷰 요청을 찾을 수 없습니다.');
339
+ json(response, await decorateDetail(updated, record, reviewerId));
340
+ }
341
+ finally {
342
+ mutations.delete(key);
343
+ }
344
+ return;
345
+ }
346
+ if (url.pathname === '/api/runs') {
347
+ parameters(url, ['project', 'limit', 'offset']);
348
+ const project = url.searchParams.get('project');
349
+ json(response, await store.runs({ project: project === null ? undefined : id(project), limit: number(url.searchParams.get('limit'), 50, 1, 100), offset: number(url.searchParams.get('offset'), 0, 0, Number.MAX_SAFE_INTEGER) }));
350
+ return;
351
+ }
352
+ const graphRoute = /^\/api\/graphs\/([^/]+)\/([^/]+)$/.exec(url.pathname);
353
+ if (graphRoute) {
354
+ parameters(url, []);
355
+ const graph = await store.graph(id(graphRoute[1]), id(graphRoute[2]));
356
+ if (!graph)
357
+ throw new HttpError(404, '선택한 실행을 찾을 수 없습니다.');
358
+ json(response, graph);
359
+ return;
360
+ }
361
+ if (url.pathname === '/api/requests') {
362
+ parameters(url, ['project', 'run', 'filter', 'lane', 'limit', 'offset']);
363
+ const filter = url.searchParams.get('filter') ?? 'all';
364
+ if (!['all', 'active', 'attention'].includes(filter))
365
+ throw new HttpError(400, '알 수 없는 요청 필터입니다.');
366
+ const projectValue = url.searchParams.get('project');
367
+ const project = projectValue === null ? undefined : id(projectValue);
368
+ const runValue = url.searchParams.get('run');
369
+ const run = runValue === null ? undefined : id(runValue);
370
+ if (run !== undefined && project === undefined)
371
+ throw new HttpError(400, '실행을 선택하려면 프로젝트를 먼저 선택하세요.');
372
+ const limit = number(url.searchParams.get('limit'), 50, 1, 100);
373
+ const offset = number(url.searchParams.get('offset'), 0, 0, Number.MAX_SAFE_INTEGER);
374
+ const lane = url.searchParams.get('lane') ?? undefined;
375
+ if (lane !== undefined && !['requested', 'running', 'success', 'failure'].includes(lane))
376
+ throw new HttpError(400, '알 수 없는 칸반 열입니다.');
377
+ json(response, await store.overview({ project, run, filter: filter, lane: lane, limit, offset }));
378
+ return;
379
+ }
380
+ const detail = /^\/api\/requests\/([^/]+)\/([^/]+)$/.exec(url.pathname);
381
+ if (detail) {
382
+ parameters(url, []);
383
+ const result = await store.detail(id(detail[1]), id(detail[2]));
384
+ if (!result)
385
+ throw new HttpError(404, '리뷰 요청을 찾을 수 없습니다.');
386
+ const record = await store.request(id(detail[1]), id(detail[2]));
387
+ const token = tokenFrom(request);
388
+ json(response, record ? await decorateDetail(result, record, token ? reviewer(token) : undefined) : result);
389
+ return;
390
+ }
391
+ const artifact = /^\/api\/requests\/([^/]+)\/([^/]+)\/artifacts\/([^/]+)$/.exec(url.pathname);
392
+ if (!artifact)
393
+ throw new HttpError(404, '조회 주소를 찾을 수 없습니다.');
394
+ parameters(url, ['operation', 'path', 'startLine', 'lineCount', 'offset', 'limit']);
395
+ if (active.size >= MAX_ARTIFACT_READS) {
396
+ response.setHeader('Retry-After', '1');
397
+ throw new HttpError(429, '다른 Artifact를 확인하고 있습니다. 잠시 후 다시 시도하세요.');
398
+ }
399
+ const controller = new AbortController();
400
+ const disconnect = () => { if (!response.writableEnded)
401
+ controller.abort(new Error('Monitor client disconnected')); };
402
+ request.once('aborted', disconnect);
403
+ response.once('close', disconnect);
404
+ const timer = setTimeout(() => controller.abort(new HttpError(504, 'Artifact 확인 시간이 초과되었습니다. 더 작은 입력으로 다시 시도하세요.')), ARTIFACT_BUDGET_MS);
405
+ active.add(controller);
406
+ try {
407
+ const projectId = id(artifact[1]), requestId = id(artifact[2]), artifactId = id(artifact[3]);
408
+ const record = await store.request(projectId, requestId);
409
+ controller.signal.throwIfAborted();
410
+ if (!record)
411
+ throw new HttpError(404, '리뷰 요청을 찾을 수 없습니다.');
412
+ if (record.request.id !== requestId)
413
+ throw new HttpError(409, '저장된 리뷰 요청의 식별자가 일치하지 않습니다.');
414
+ if (record.request.configManifest)
415
+ throw new HttpError(409, '이 Artifact는 등록된 도구로 확인하세요. Human 리뷰는 검토 탭의 제공된 프로그램을 사용할 수 있습니다.');
416
+ await authorizeWorkspace(record);
417
+ controller.signal.throwIfAborted();
418
+ const handle = await reopenWorkspace(record.request.workspace, { signal: controller.signal });
419
+ try {
420
+ await handle.assertUnchanged();
421
+ const expected = await readStoredArtifactScope({ repoPath: handle.descriptor.path, criticId: record.request.criticId });
422
+ if (!expected || !isDeepStrictEqual(expected.artifacts, record.request.artifacts) || !isDeepStrictEqual(expected.artifactTypes, record.request.artifactTypes))
423
+ throw new HttpError(409, '저장된 Artifact 범위가 리뷰 입력의 정의와 일치하지 않습니다.');
424
+ const viewer = await createArtifactViewer({ worktreePath: handle.descriptor.path, artifacts: record.request.artifacts, artifactTypes: record.request.artifactTypes, signal: handle.signal });
425
+ const definition = viewer.listArtifacts().find(item => item.id === artifactId);
426
+ if (!definition)
427
+ throw new HttpError(404, '이 리뷰 요청에 포함된 Artifact가 아닙니다.');
428
+ const operation = url.searchParams.get('operation') ?? (definition.directory ? 'list' : 'read');
429
+ if (operation !== 'read' && operation !== 'list')
430
+ throw new HttpError(400, '지원하지 않는 Artifact 조회 방식입니다.');
431
+ const registry = createArtifactTools(viewer, { audience: 'viewer' });
432
+ const toolName = `${operation}_${artifactId}`;
433
+ const tool = registry.tools.find(item => item.name === toolName);
434
+ if (!tool)
435
+ throw new HttpError(400, '이 Artifact에는 해당 조회 도구가 없습니다.');
436
+ const args = {};
437
+ if (url.searchParams.has('path'))
438
+ args.path = url.searchParams.get('path');
439
+ for (const [key, minimum, maximum] of [['startLine', 1, Number.MAX_SAFE_INTEGER], ['lineCount', 1, 500], ['offset', 0, Number.MAX_SAFE_INTEGER], ['limit', 1, 200]]) {
440
+ if (url.searchParams.has(key))
441
+ args[key] = number(url.searchParams.get(key), minimum, minimum, maximum);
442
+ }
443
+ const result = await registry.call(toolName, args);
444
+ await handle.assertUnchanged();
445
+ handle.signal.throwIfAborted();
446
+ const page = { artifact: { id: definition.id, path: definition.path, directory: definition.directory, description: tool.description }, result };
447
+ json(response, page);
448
+ }
449
+ finally {
450
+ await handle.close();
451
+ }
452
+ }
453
+ catch (error) {
454
+ throw controller.signal.aborted ? controller.signal.reason : safeError(error);
455
+ }
456
+ finally {
457
+ clearTimeout(timer);
458
+ request.off('aborted', disconnect);
459
+ response.off('close', disconnect);
460
+ active.delete(controller);
461
+ }
462
+ })().catch(error => {
463
+ const safe = safeError(error);
464
+ if (safe.status === 405)
465
+ response.setHeader('Allow', 'GET');
466
+ json(response, { error: safe.message }, safe.status);
467
+ }).finally(() => { jobs.delete(job); });
468
+ jobs.add(job);
469
+ });
470
+ server.headersTimeout = 10_000;
471
+ server.requestTimeout = 15_000;
472
+ await new Promise((ok, no) => { server.once('error', no); server.listen(requestedPort, '127.0.0.1', () => { server.off('error', no); ok(); }); });
473
+ const address = server.address();
474
+ if (!address || typeof address === 'string')
475
+ throw new Error('모니터의 로컬 주소를 확인할 수 없습니다.');
476
+ port = address.port;
477
+ return {
478
+ url: `http://127.0.0.1:${port}`,
479
+ close() {
480
+ if (!closePromise) {
481
+ closing = true;
482
+ for (const controller of active)
483
+ controller.abort(new HttpError(503, '모니터를 종료하고 있습니다.'));
484
+ closePromise = (async () => {
485
+ await new Promise((ok, no) => { server.close(error => error ? no(error) : ok()); server.closeIdleConnections(); });
486
+ await Promise.allSettled([...jobs]);
487
+ })();
488
+ }
489
+ return closePromise;
490
+ },
491
+ };
492
+ }
493
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/monitor/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { ReviewRequest } from '../contracts.js';
2
+ import type { MonitorDetail, MonitorLane, MonitorOverview, MonitorQuery, MonitorRequest, MonitorSources, MonitorRunOverview, MonitorRunQuery, MonitorGraph } from './types.js';
3
+ export interface MonitorStoredRequest {
4
+ request: ReviewRequest;
5
+ repoPath: string;
6
+ stateDir: string;
7
+ repoId: string;
8
+ }
9
+ export declare function monitorLane(request: Pick<MonitorRequest, 'status' | 'claimedBy'>): MonitorLane;
10
+ /** Optional observer: opening or querying it never runs reconciliation or changes review state. */
11
+ export declare function createMonitorStore(options?: MonitorSources): {
12
+ runs(query?: MonitorRunQuery): Promise<MonitorRunOverview>;
13
+ projectContext(project: string): Promise<{
14
+ repoId: string;
15
+ repoPath: string;
16
+ stateDir: string;
17
+ } | null>;
18
+ graph(project: string, runId: string): Promise<MonitorGraph | null>;
19
+ overview(query?: MonitorQuery): Promise<MonitorOverview>;
20
+ detail(project: string, requestId: string): Promise<MonitorDetail | null>;
21
+ request(project: string, requestId: string): Promise<MonitorStoredRequest | null>;
22
+ };