feat(bot/extension/watcher): Discord 아티팩트 알림 개선 — 파일 첨부 전송, truncation 확대, 동적 .md 감시

This commit is contained in:
Variet Worker
2026-03-13 09:46:56 +09:00
parent 9036f1cefc
commit e5a05e3ac4
10 changed files with 266 additions and 57 deletions

View File

@@ -113,6 +113,27 @@ function writeChatSnapshot(text: string) {
}
}
function writeChatSnapshotWithFiles(text: string, files: Array<{name: string, content: string}>) {
try {
const snapshotDir = path.join(bridgePath, 'chat_snapshots');
if (!fs.existsSync(snapshotDir)) { fs.mkdirSync(snapshotDir, { recursive: true }); }
const id = Date.now().toString();
const data = {
id,
project_name: projectName,
content: text,
attached_files: files,
timestamp: Date.now() / 1000,
};
const filePath = path.join(snapshotDir, `${id}.json`);
fs.writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf-8');
logToFile(`[SNAPSHOT] written ${id}.json (${text.length} chars, ${files.length} files)`);
if (activeSessionId) { writeRegistration(activeSessionId); }
} catch (e: any) {
console.log(`Gravity Bridge: snapshot+files write error: ${e.message}`);
}
}
// ─── Command File Watcher (Discord → Antigravity) ───
@@ -1823,8 +1844,8 @@ function setupMonitor() {
if (text.length > 10) {
lastResponseCaptureStep = actualIdx;
logToFile(`[RT-CAPTURE] step=${actualIdx} (${text.length} chars)`);
const truncated = text.length > 1800
? text.substring(0, 1800) + '\n\n_(이하 생략)_'
const truncated = text.length > 3500
? text.substring(0, 3500) + '\n\n_(이하 생략)_'
: text;
writeChatSnapshot(`💬 **AI 응답**\n\n${truncated}`);
break;
@@ -2116,7 +2137,12 @@ function setupMonitor() {
if (notifyStep) {
if (notifyStep.stepIndex > lastNotifyStepIndex) {
lastNotifyStepIndex = notifyStep.stepIndex;
const content = notifyStep.step?.notifyUser?.notificationContent || '';
const notifyData = notifyStep.step?.notifyUser || {} as any;
const content = notifyData.notificationContent || '';
// Log full structure once for schema discovery
if (pollCount <= 3 || notifyStep.stepIndex <= lastNotifyStepIndex + 1) {
logToFile(`[NOTIFY-STEP] keys=[${Object.keys(notifyData).join(',')}]`);
}
logToFile(`[NOTIFY-STEP] NEW step=${notifyStep.stepIndex} content=${content.length} chars`);
// Filter: relay all non-empty notifications
if (content.length > 10) {
@@ -2124,6 +2150,37 @@ function setupMonitor() {
} else if (content.length > 0) {
logToFile(`[NOTIFY-STEP] skipped (too short: ${content.length} chars): ${content}`);
}
// ── PathsToReview: read and relay referenced artifact files ──
const pathsToReview: string[] = notifyData.pathsToReview
|| notifyData.paths_to_review
|| notifyData.filePaths
|| [];
if (pathsToReview.length > 0) {
logToFile(`[NOTIFY-STEP] PathsToReview: ${pathsToReview.length} files`);
for (const filePath of pathsToReview.slice(0, 5)) {
try {
if (fs.existsSync(filePath)) {
const fileContent = fs.readFileSync(filePath, 'utf-8');
const fileName = path.basename(filePath);
const MAX_ARTIFACT_SIZE = 8000;
const truncatedContent = fileContent.length > MAX_ARTIFACT_SIZE
? fileContent.substring(0, MAX_ARTIFACT_SIZE) + '\n\n_(이하 생략)_'
: fileContent;
// Write as snapshot with attached_files for bot to send as Discord file
writeChatSnapshotWithFiles(
`📎 **문서: ${fileName}** (${Math.round(fileContent.length/1024)}KB)`,
[{ name: fileName, content: truncatedContent }]
);
logToFile(`[NOTIFY-STEP] relayed artifact: ${fileName} (${fileContent.length} chars)`);
} else {
logToFile(`[NOTIFY-STEP] artifact not found: ${filePath}`);
}
} catch (e: any) {
logToFile(`[NOTIFY-STEP] artifact read error: ${e.message}`);
}
}
}
}
} else if (pollCount <= 5) {
logToFile(`[NOTIFY-STEP] null (no notify step in session)`);
@@ -2251,8 +2308,8 @@ function setupMonitor() {
if (!textContent && s?.rawOutput) textContent = typeof s.rawOutput === 'string' ? s.rawOutput : JSON.stringify(s.rawOutput);
if (textContent.length > 10) {
logToFile(`[RESPONSE-CAPTURE] found ${sType} (${textContent.length} chars) at step ${offset + ri}`);
const truncated = textContent.length > 1800
? textContent.substring(0, 1800) + '\n\n_(이하 생략)_'
const truncated = textContent.length > 3500
? textContent.substring(0, 3500) + '\n\n_(이하 생략)_'
: textContent;
writeChatSnapshot(`💬 **AI 응답**\n\n${truncated}`);
break;