Phase 3: provider-retry.ts — shared Claude rotation loop (SSOT) - retryClaudeWithRotation extracted from message-agent-executor + task-scheduler - ~200 lines of duplicated retry logic removed Phase 4: types.ts — AgentOutputPhase + VisiblePhase unified Phase 5: types.ts — AgentConfig extended with claudeThinking/claudeThinkingBudget Utilities (utils.ts): - getErrorMessage: 14 occurrences of instanceof Error pattern → 1 function - readJsonFile/writeJsonFile: 19 occurrences of JSON+fs pattern → 2 functions - fetchWithTimeout: 3 occurrences of AbortController pattern → 1 function - formatElapsedKorean: deduplicated from task-watch-status + message-turn-controller Protocol (agent-protocol.ts): - OUTPUT_START/END_MARKER centralized (runners keep local copies with SSOT reference) - IMAGE_TAG_RE, IPC constants documented Runner: show "대화 요약 중..." progress message during auto-compact Net: -137 lines, 354/354 tests passing
26 lines
842 B
TypeScript
26 lines
842 B
TypeScript
import fs from 'fs';
|
|
import path from 'path';
|
|
|
|
import { writeJsonFile } from './utils.js';
|
|
|
|
function resolveInputDir(ipcDir: string): string {
|
|
return path.join(ipcDir, 'input');
|
|
}
|
|
|
|
export function queueFollowUpMessage(ipcDir: string, text: string): string {
|
|
const inputDir = resolveInputDir(ipcDir);
|
|
fs.mkdirSync(inputDir, { recursive: true });
|
|
const filename = `${Date.now()}-${Math.random().toString(36).slice(2, 6)}.json`;
|
|
const filepath = path.join(inputDir, filename);
|
|
const tempPath = `${filepath}.tmp`;
|
|
writeJsonFile(tempPath, { type: 'message', text });
|
|
fs.renameSync(tempPath, filepath);
|
|
return filename;
|
|
}
|
|
|
|
export function writeCloseSentinel(ipcDir: string): void {
|
|
const inputDir = resolveInputDir(ipcDir);
|
|
fs.mkdirSync(inputDir, { recursive: true });
|
|
fs.writeFileSync(path.join(inputDir, '_close'), '');
|
|
}
|