Function bodies 284 total
ScheduleFileScanner.deleteTask method · typescript · L273-L292 (20 LOC)src/schedule/schedule-file-scanner.ts
async deleteTask(taskId: string): Promise<boolean> {
// Task ID format: schedule-{slug}
if (!taskId.startsWith('schedule-')) {
return false;
}
const slug = taskId.slice('schedule-'.length);
const filePath = path.join(this.schedulesDir, `${slug}.md`);
try {
await fs.unlink(filePath);
logger.info({ taskId, filePath }, 'Deleted schedule file');
return true;
} catch (error) {
if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
return false;
}
throw error;
}
}ScheduleFileScanner.getFilePath method · typescript · L297-L302 (6 LOC)src/schedule/schedule-file-scanner.ts
getFilePath(taskId: string): string {
const slug = taskId.startsWith('schedule-')
? taskId.slice('schedule-'.length)
: taskId;
return path.join(this.schedulesDir, `${slug}.md`);
}ScheduleFileWatcher.constructor method · typescript · L64-L70 (7 LOC)src/schedule/schedule-file-watcher.ts
constructor(options: ScheduleFileWatcherOptions) {
this.schedulesDir = options.schedulesDir;
this.onFileAdded = options.onFileAdded;
this.onFileChanged = options.onFileChanged;
this.onFileRemoved = options.onFileRemoved;
this.debounceMs = options.debounceMs ?? 100;
}ScheduleFileWatcher.start method · typescript · L75-L104 (30 LOC)src/schedule/schedule-file-watcher.ts
async start(): Promise<void> {
if (this.running) {
logger.warn('File watcher already running');
return;
}
// Ensure directory exists
await fs.promises.mkdir(this.schedulesDir, { recursive: true });
try {
this.watcher = fs.watch(
this.schedulesDir,
{ persistent: true, recursive: false },
(eventType, filename) => {
this.handleFileEvent(eventType, filename);
}
);
this.watcher.on('error', (error) => {
logger.error({ err: error }, 'File watcher error');
});
this.running = true;
logger.info({ schedulesDir: this.schedulesDir }, 'File watcher started');
} catch (error) {
logger.error({ err: error }, 'Failed to start file watcher');
throw error;
}
}ScheduleFileWatcher.stop method · typescript · L109-L123 (15 LOC)src/schedule/schedule-file-watcher.ts
stop(): void {
if (this.watcher) {
this.watcher.close();
this.watcher = null;
}
// Clear all debounce timers
for (const timer of this.debounceTimers.values()) {
clearTimeout(timer);
}
this.debounceTimers.clear();
this.running = false;
logger.info('File watcher stopped');
}ScheduleFileWatcher.handleFileEvent method · typescript · L135-L156 (22 LOC)src/schedule/schedule-file-watcher.ts
private handleFileEvent(eventType: string, filename: string | null): void {
if (!filename || !filename.endsWith('.md')) {
return;
}
const filePath = path.join(this.schedulesDir, filename);
logger.debug({ eventType, filename }, 'File event received');
// Clear existing timer for this file
const existingTimer = this.debounceTimers.get(filePath);
if (existingTimer) {
clearTimeout(existingTimer);
}
// Debounce the event
const timer = setTimeout(() => {
this.debounceTimers.delete(filePath);
this.processFileEvent(eventType, filePath, filename);
}, this.debounceMs);
this.debounceTimers.set(filePath, timer);
}ScheduleFileWatcher.processFileEvent method · typescript · L161-L192 (32 LOC)src/schedule/schedule-file-watcher.ts
private async processFileEvent(eventType: string, filePath: string, filename: string): Promise<void> {
const taskId = this.generateTaskId(filename);
try {
if (eventType === 'rename') {
// Check if file exists to determine if it was added or removed
const exists = await this.fileExists(filePath);
if (exists) {
// File added or renamed to this name
const task = await this.parseFile(filePath);
if (task) {
logger.info({ taskId, filename }, 'Schedule file added');
this.onFileAdded(task);
}
} else {
// File removed
logger.info({ taskId, filename }, 'Schedule file removed');
this.onFileRemoved(taskId, filePath);
}
} else if (eventType === 'change') {
// File modified
const task = await this.parseFile(filePath);
if (task) {
logger.info({ taskId, filename }, 'Schedule file changed');
this.onFileCSource: Repobility analyzer · https://repobility.com
ScheduleFileWatcher.fileExists method · typescript · L197-L204 (8 LOC)src/schedule/schedule-file-watcher.ts
private async fileExists(filePath: string): Promise<boolean> {
try {
await fs.promises.access(filePath);
return true;
} catch {
return false;
}
}ScheduleFileWatcher.parseFile method · typescript · L209-L238 (30 LOC)src/schedule/schedule-file-watcher.ts
private async parseFile(filePath: string): Promise<ScheduleFileTask | null> {
try {
const content = await fs.promises.readFile(filePath, 'utf-8');
const stats = await fs.promises.stat(filePath);
const frontmatter = this.parseFrontmatter(content);
if (!frontmatter['name'] || !frontmatter['cron'] || !frontmatter['chatId']) {
return null;
}
const fileName = path.basename(filePath);
const prompt = this.extractContent(content);
return {
id: this.generateTaskId(fileName),
name: frontmatter['name'] as string,
cron: frontmatter['cron'] as string,
chatId: frontmatter['chatId'] as string,
prompt,
enabled: (frontmatter['enabled'] as boolean) ?? true,
createdBy: frontmatter['createdBy'] as string | undefined,
createdAt: (frontmatter['createdAt'] as string) || stats.birthtime.toISOString(),
sourceFile: filePath,
fileMtime: stats.mtime,
};
} catchScheduleFileWatcher.parseFrontmatter method · typescript · L243-L277 (35 LOC)src/schedule/schedule-file-watcher.ts
private parseFrontmatter(content: string): Record<string, unknown> {
const frontmatterRegex = /^---\s*\n([\s\S]*?)\n---\s*\n/;
const match = content.match(frontmatterRegex);
if (!match) {
return {};
}
const [, frontmatterText] = match;
const frontmatter: Record<string, unknown> = {};
const lines = frontmatterText.split('\n');
for (const line of lines) {
const colonIndex = line.indexOf(':');
if (colonIndex === -1) { continue; }
const key = line.slice(0, colonIndex).trim();
const value = line.slice(colonIndex + 1).trim();
switch (key) {
case 'name':
case 'cron':
case 'chatId':
case 'createdBy':
case 'createdAt':
frontmatter[key] = value.replace(/^["']|["']$/g, '');
break;
case 'enabled':
frontmatter[key] = value === 'true';
break;
}
}
return frontmatter;
}ScheduleManager.constructor method · typescript · L104-L112 (9 LOC)src/schedule/schedule-manager.ts
constructor(options: ScheduleManagerOptions) {
this.fileScanner = new ScheduleFileScanner({ schedulesDir: options.schedulesDir });
this.maxTasksPerChat = options.maxTasksPerChat ?? 50;
this.maxSameNameTasks = options.maxSameNameTasks ?? 1;
logger.info(
{ schedulesDir: options.schedulesDir, maxTasksPerChat: this.maxTasksPerChat },
'ScheduleManager initialized (no cache)'
);
}ScheduleManager.loadAll method · typescript · L118-L125 (8 LOC)src/schedule/schedule-manager.ts
private async loadAll(): Promise<Map<string, ScheduledTask>> {
const tasks = await this.fileScanner.scanAll();
const map = new Map<string, ScheduledTask>();
for (const task of tasks) {
map.set(task.id, task);
}
return map;
}ScheduleManager.create method · typescript · L141-L178 (38 LOC)src/schedule/schedule-manager.ts
async create(options: CreateScheduleOptions): Promise<ScheduledTask> {
// Validate: Check task count limit for this chatId
const existingTasks = await this.listByChatId(options.chatId);
if (existingTasks.length >= this.maxTasksPerChat) {
throw new Error(
`Task limit exceeded: maximum ${this.maxTasksPerChat} tasks per chat. ` +
`Please delete some existing tasks first.`
);
}
// Validate: Check for tasks with the same name (prevent infinite recursion)
const sameNameTasks = existingTasks.filter(t => t.name === options.name);
if (sameNameTasks.length >= this.maxSameNameTasks) {
throw new Error(
`Task "${options.name}" already exists. ` +
`Please use a different name or delete the existing task first.`
);
}
const slug = this.generateSlug(options.name);
const task: ScheduledTask = {
id: `schedule-${slug}`,
name: options.name,
cron: options.cron,
prompt: options.prompt,
ScheduleManager.generateSlug method · typescript · L183-L192 (10 LOC)src/schedule/schedule-manager.ts
private generateSlug(name: string): string {
const baseSlug = name
.toLowerCase()
.replace(/[^a-z0-9\u4e00-\u9fff]+/g, '-')
.replace(/^-+|-+$/g, '');
// Add short UUID to ensure uniqueness
const shortId = uuidv4().slice(0, 8);
return `${baseSlug}-${shortId}`;
}ScheduleManager.update method · typescript · L243-L260 (18 LOC)src/schedule/schedule-manager.ts
async update(id: string, updates: Partial<Omit<ScheduledTask, 'id' | 'createdAt'>>): Promise<ScheduledTask | undefined> {
const tasks = await this.loadAll();
const task = tasks.get(id);
if (!task) {
return undefined;
}
const updatedTask: ScheduledTask = {
...task,
...updates,
};
// Write to file
await this.fileScanner.writeTask(updatedTask);
logger.info({ taskId: id, updates }, 'Updated scheduled task');
return updatedTask;
}Repobility · severity-and-effort ranking · https://repobility.com
Scheduler.constructor method · typescript · L71-L76 (6 LOC)src/schedule/scheduler.ts
constructor(options: SchedulerOptions) {
this.scheduleManager = options.scheduleManager;
this.pilot = options.pilot;
this.callbacks = options.callbacks;
logger.info('Scheduler created');
}Scheduler.start method · typescript · L82-L97 (16 LOC)src/schedule/scheduler.ts
async start(): Promise<void> {
if (this.running) {
logger.warn('Scheduler already running');
return;
}
this.running = true;
// Load and schedule all enabled tasks
const tasks = await this.scheduleManager.listEnabled();
for (const task of tasks) {
await this.addTask(task);
}
logger.info({ taskCount: this.activeJobs.size }, 'Scheduler started');
}Scheduler.stop method · typescript · L103-L113 (11 LOC)src/schedule/scheduler.ts
stop(): void {
this.running = false;
for (const [taskId, entry] of this.activeJobs) {
void entry.job.stop();
logger.debug({ taskId }, 'Stopped cron job');
}
this.activeJobs.clear();
logger.info('Scheduler stopped');
}Scheduler.addTask method · typescript · L121-L144 (24 LOC)src/schedule/scheduler.ts
addTask(task: ScheduledTask): void {
// Remove existing job if any
this.removeTask(task.id);
if (!task.enabled) {
logger.debug({ taskId: task.id }, 'Task is disabled, not scheduling');
return;
}
try {
const job = new CronJob(
task.cron,
() => this.executeTask(task),
null,
true, // start
'Asia/Shanghai' // timezone
);
this.activeJobs.set(task.id, { taskId: task.id, job, task });
logger.info({ taskId: task.id, cron: task.cron, name: task.name }, 'Scheduled task');
} catch (error) {
logger.error({ err: error, taskId: task.id, cron: task.cron }, 'Invalid cron expression');
}
}Scheduler.removeTask method · typescript · L151-L158 (8 LOC)src/schedule/scheduler.ts
removeTask(taskId: string): void {
const entry = this.activeJobs.get(taskId);
if (entry) {
void entry.job.stop();
this.activeJobs.delete(taskId);
logger.info({ taskId }, 'Removed scheduled task');
}
}Scheduler.buildScheduledTaskPrompt method · typescript · L167-L184 (18 LOC)src/schedule/scheduler.ts
private buildScheduledTaskPrompt(task: ScheduledTask): string {
return `⚠️ **Scheduled Task Execution Context**
You are executing a scheduled task named "${task.name}".
**IMPORTANT RULES:**
1. Do NOT create new scheduled tasks
2. Do NOT modify existing scheduled tasks
3. Focus on completing the task described below
4. If you need to run something periodically, report this need to the user instead
Scheduled task creation is blocked during scheduled task execution to prevent infinite recursion.
---
**Task Prompt:**
${task.prompt}`;
}Scheduler.executeTask method · typescript · L192-L243 (52 LOC)src/schedule/scheduler.ts
private async executeTask(task: ScheduledTask): Promise<void> {
// Check blocking mechanism
if (task.blocking && this.runningTasks.has(task.id)) {
logger.info(
{ taskId: task.id, name: task.name },
'Task skipped - previous execution still running'
);
return;
}
logger.info({ taskId: task.id, name: task.name }, 'Executing scheduled task');
// Mark task as running
this.runningTasks.add(task.id);
try {
// Send start notification
await this.callbacks.sendMessage(
task.chatId,
`⏰ 定时任务「${task.name}」开始执行...`
);
// Build wrapped prompt with anti-recursion instructions
const wrappedPrompt = this.buildScheduledTaskPrompt(task);
// Execute task using Pilot's executeOnce method
await this.pilot.executeOnce(
task.chatId,
wrappedPrompt,
`${task.id}-${Date.now()}`,
task.createdBy
);
// Update last execution time
await this.schFileStorageService.constructor method · typescript · L35-L43 (9 LOC)src/services/file-storage-service.ts
constructor(config: FileStorageConfig) {
this.storageDir = config.storageDir;
this.maxFileSize = config.maxFileSize ?? 100 * 1024 * 1024; // 100MB
logger.info({
storageDir: this.storageDir,
maxFileSize: this.maxFileSize,
}, 'FileStorageService created');
}Provenance: Repobility (https://repobility.com) — every score reproducible from /scan/
FileStorageService.storeFromLocal method · typescript · L56-L92 (37 LOC)src/services/file-storage-service.ts
async storeFromLocal(
localPath: string,
fileName: string,
mimeType?: string,
source: 'user' | 'agent' = 'user',
chatId?: string
): Promise<FileReference> {
const stats = await fs.stat(localPath);
if (stats.size > this.maxFileSize) {
throw new Error(`File size exceeds maximum allowed size: ${stats.size} > ${this.maxFileSize}`);
}
const fileRef = createFileReference(fileName, source, {
mimeType,
size: stats.size,
chatId,
});
const fileDir = path.join(this.storageDir, fileRef.id);
await fs.mkdir(fileDir, { recursive: true });
const storedPath = path.join(fileDir, fileName);
await fs.copyFile(localPath, storedPath);
fileRef.storageKey = storedPath;
this.files.set(fileRef.id, { ref: fileRef, localPath: storedPath });
logger.info({
fileId: fileRef.id,
fileName,
size: stats.size,
source,
}, 'File stored from local path');
return fileRef;
}FileStorageService.storeFromBase64 method · typescript · L97-L133 (37 LOC)src/services/file-storage-service.ts
async storeFromBase64(
content: string,
fileName: string,
mimeType?: string,
source: 'user' | 'agent' = 'agent',
chatId?: string
): Promise<FileReference> {
const buffer = Buffer.from(content, 'base64');
if (buffer.length > this.maxFileSize) {
throw new Error(`File size exceeds maximum allowed size: ${buffer.length} > ${this.maxFileSize}`);
}
const fileRef = createFileReference(fileName, source, {
mimeType,
size: buffer.length,
chatId,
});
const fileDir = path.join(this.storageDir, fileRef.id);
await fs.mkdir(fileDir, { recursive: true });
const storedPath = path.join(fileDir, fileName);
await fs.writeFile(storedPath, buffer);
fileRef.storageKey = storedPath;
this.files.set(fileRef.id, { ref: fileRef, localPath: storedPath });
logger.info({
fileId: fileRef.id,
fileName,
size: buffer.length,
source,
}, 'File stored from base64');
return fileRef;
}FileStorageService.getContent method · typescript · L145-L153 (9 LOC)src/services/file-storage-service.ts
async getContent(fileId: string): Promise<string> {
const stored = this.files.get(fileId);
if (!stored) {
throw new Error(`File not found: ${fileId}`);
}
const buffer = await fs.readFile(stored.localPath);
return buffer.toString('base64');
}readJsonBody function · typescript · L42-L67 (26 LOC)src/services/file-transfer-api.ts
function readJsonBody<T>(req: IncomingMessage, maxSize: number): Promise<T> {
return new Promise((resolve, reject) => {
let body = '';
let size = 0;
req.on('data', (chunk: Buffer) => {
size += chunk.length;
if (size > maxSize) {
req.destroy();
reject(new Error(`Request body too large: ${size} > ${maxSize}`));
return;
}
body += chunk.toString();
});
req.on('end', () => {
try {
resolve(JSON.parse(body) as T);
} catch (error) {
reject(new Error(`Invalid JSON: ${(error as Error).message}`));
}
});
req.on('error', reject);
});
}createFileTransferAPIHandler function · typescript · L89-L216 (128 LOC)src/services/file-transfer-api.ts
export function createFileTransferAPIHandler(config: FileTransferAPIConfig) {
const { storageService, maxBodySize = 100 * 1024 * 1024 } = config;
/**
* Handle file API requests.
*/
return async (req: IncomingMessage, res: ServerResponse): Promise<boolean> => {
const url = req.url || '/';
const method = req.method || 'GET';
// Parse URL path
const [urlPath] = url.split('?');
const pathParts = urlPath.split('/').filter(Boolean);
// Check if this is a file API request
if (pathParts[0] !== 'api' || pathParts[1] !== 'files') {
return false; // Not a file API request
}
try {
// GET /api/files - Get storage stats
if (method === 'GET' && pathParts.length === 2) {
const stats = storageService.getStats();
sendJson(res, 200, { success: true, data: stats });
return true;
}
// POST /api/files - Upload file
if (method === 'POST' && pathParts.length === 2) {
const request = await rDialogueMessageTracker.buildWarning method · typescript · L54-L71 (18 LOC)src/task/dialogue-message-tracker.ts
buildWarning(reason: string, taskId?: string): string {
const parts = [
'⚠️ **任务完成但无反馈消息**',
'',
`结束原因: ${reason}`,
];
if (taskId) {
parts.push(`任务 ID: ${taskId}`);
}
parts.push('', '这可能表示:');
parts.push('- Agent 没有生成任何输出');
parts.push('- 所有消息都通过内部工具处理');
parts.push('- 可能存在配置问题');
return parts.join('\n');
}DialogueOrchestrator.constructor method · typescript · L75-L81 (7 LOC)src/task/dialogue-orchestrator.ts
constructor(config: DialogueOrchestratorConfig) {
this.evaluatorConfig = config.evaluatorConfig;
// Initialize extracted services
this.messageTracker = new DialogueMessageTracker();
this.fileManager = new TaskFileManager();
}DialogueOrchestrator.cleanup method · typescript · L99-L104 (6 LOC)src/task/dialogue-orchestrator.ts
cleanup(): void {
logger.debug({ taskId: this.taskId }, 'Cleaning up dialogue orchestrator');
this.taskId = '';
this.currentChatId = undefined;
this.messageTracker.reset();
}All rows above produced by Repobility · https://repobility.com
DialogueOrchestrator.writeFinalSummary method · typescript · L225-L233 (9 LOC)src/task/dialogue-orchestrator.ts
private async writeFinalSummary(): Promise<void> {
try {
const summary = this.generateFinalSummary();
await this.fileManager.writeFinalSummary(this.taskId, summary);
logger.info({ taskId: this.taskId }, 'Final summary written');
} catch (error) {
logger.error({ err: error, taskId: this.taskId }, 'Failed to write final summary');
}
}DialogueOrchestrator.generateFinalSummary method · typescript · L238-L276 (39 LOC)src/task/dialogue-orchestrator.ts
private generateFinalSummary(): string {
const timestamp = new Date().toISOString();
const duration = this.iterationCount > 0 ? `${this.iterationCount} iterations` : 'Unknown';
return `# Final Summary: ${this.taskId}
**Task ID**: ${this.taskId}
**Completed**: ${timestamp}
**Total Iterations**: ${this.iterationCount}
**Total Duration**: ${duration}
## Overview
Task completed successfully after ${this.iterationCount} iteration(s).
## Iteration History
${Array.from({ length: this.iterationCount }, (_, i) => `- Iteration ${i + 1}: Executed`).join('\n')}
## Final Results
✅ Task completed - all objectives achieved
## Key Deliverables
- Task specification: \`tasks/${this.taskId}/task.md\`
- Evaluation results: \`tasks/${this.taskId}/iterations/iter-*/evaluation.md\`
- Execution results: \`tasks/${this.taskId}/iterations/iter-*/execution.md\`
- Final result: \`tasks/${this.taskId}/final_result.md\`
## Lessons Learned
Task execution completed successfully with file-driTaskFileManager.constructor method · typescript · L40-L45 (6 LOC)src/task/file-manager.ts
constructor(workspaceDir?: string, private readonly subdirectory?: string) {
this.workspaceDir = workspaceDir || Config.getWorkspaceDir();
this.tasksBaseDir = this.subdirectory
? path.join(this.workspaceDir, 'tasks', this.subdirectory)
: path.join(this.workspaceDir, 'tasks');
}TaskFileManager.ensureBaseDir method · typescript · L50-L57 (8 LOC)src/task/file-manager.ts
private async ensureBaseDir(): Promise<void> {
try {
await fs.mkdir(this.tasksBaseDir, { recursive: true });
} catch (error) {
logger.error({ err: error }, 'Failed to create base tasks directory');
throw error;
}
}TaskFileManager.initializeTask method · typescript · L122-L135 (14 LOC)src/task/file-manager.ts
async initializeTask(taskId: string): Promise<void> {
await this.ensureBaseDir();
const taskDir = this.getTaskDir(taskId);
const iterationsDir = this.getIterationsDir(taskId);
try {
await fs.mkdir(iterationsDir, { recursive: true });
logger.debug({ taskId, taskDir }, 'Task directory initialized');
} catch (error) {
logger.error({ err: error, taskId }, 'Failed to initialize task directory');
throw error;
}
}TaskFileManager.writeTaskSpec method · typescript · L143-L154 (12 LOC)src/task/file-manager.ts
async writeTaskSpec(taskId: string, content: string): Promise<void> {
const taskDir = this.getTaskDir(taskId);
const taskSpecPath = path.join(taskDir, 'task.md');
try {
await fs.writeFile(taskSpecPath, content, 'utf-8');
logger.debug({ taskId, path: taskSpecPath }, 'Task spec written');
} catch (error) {
logger.error({ err: error, taskId }, 'Failed to write task spec');
throw error;
}
}TaskFileManager.readTaskSpec method · typescript · L162-L172 (11 LOC)src/task/file-manager.ts
async readTaskSpec(taskId: string): Promise<string> {
const taskSpecPath = path.join(this.getTaskDir(taskId), 'task.md');
try {
const content = await fs.readFile(taskSpecPath, 'utf-8');
return content;
} catch (error) {
logger.error({ err: error, taskId }, 'Failed to read task spec');
throw error;
}
}TaskFileManager.createIteration method · typescript · L184-L195 (12 LOC)src/task/file-manager.ts
async createIteration(taskId: string, iteration: number): Promise<void> {
const iterationDir = this.getIterationDir(taskId, iteration);
const stepsDir = this.getStepsDir(taskId, iteration);
try {
await fs.mkdir(stepsDir, { recursive: true });
logger.debug({ taskId, iteration, iterationDir }, 'Iteration directory created');
} catch (error) {
logger.error({ err: error, taskId, iteration }, 'Failed to create iteration directory');
throw error;
}
}Source: Repobility analyzer · https://repobility.com
TaskFileManager.writeEvaluation method · typescript · L204-L214 (11 LOC)src/task/file-manager.ts
async writeEvaluation(taskId: string, iteration: number, content: string): Promise<void> {
const evaluationPath = path.join(this.getIterationDir(taskId, iteration), 'evaluation.md');
try {
await fs.writeFile(evaluationPath, content, 'utf-8');
logger.debug({ taskId, iteration }, 'Evaluation written');
} catch (error) {
logger.error({ err: error, taskId, iteration }, 'Failed to write evaluation');
throw error;
}
}TaskFileManager.readEvaluation method · typescript · L223-L233 (11 LOC)src/task/file-manager.ts
async readEvaluation(taskId: string, iteration: number): Promise<string> {
const evaluationPath = path.join(this.getIterationDir(taskId, iteration), 'evaluation.md');
try {
const content = await fs.readFile(evaluationPath, 'utf-8');
return content;
} catch (error) {
logger.error({ err: error, taskId, iteration }, 'Failed to read evaluation');
throw error;
}
}TaskFileManager.hasEvaluation method · typescript · L253-L262 (10 LOC)src/task/file-manager.ts
async hasEvaluation(taskId: string, iteration: number): Promise<boolean> {
const evaluationPath = this.getEvaluationPath(taskId, iteration);
try {
await fs.access(evaluationPath);
return true;
} catch {
return false;
}
}TaskFileManager.writeExecution method · typescript · L271-L281 (11 LOC)src/task/file-manager.ts
async writeExecution(taskId: string, iteration: number, content: string): Promise<void> {
const executionPath = this.getExecutionPath(taskId, iteration);
try {
await fs.writeFile(executionPath, content, 'utf-8');
logger.debug({ taskId, iteration }, 'Execution written');
} catch (error) {
logger.error({ err: error, taskId, iteration }, 'Failed to write execution');
throw error;
}
}TaskFileManager.readExecution method · typescript · L290-L300 (11 LOC)src/task/file-manager.ts
async readExecution(taskId: string, iteration: number): Promise<string> {
const executionPath = this.getExecutionPath(taskId, iteration);
try {
const content = await fs.readFile(executionPath, 'utf-8');
return content;
} catch (error) {
logger.error({ err: error, taskId, iteration }, 'Failed to read execution');
throw error;
}
}TaskFileManager.hasExecution method · typescript · L320-L329 (10 LOC)src/task/file-manager.ts
async hasExecution(taskId: string, iteration: number): Promise<boolean> {
const executionPath = this.getExecutionPath(taskId, iteration);
try {
await fs.access(executionPath);
return true;
} catch {
return false;
}
}TaskFileManager.writeStepResult method · typescript · L341-L351 (11 LOC)src/task/file-manager.ts
async writeStepResult(taskId: string, iteration: number, step: number, content: string): Promise<void> {
const stepResultPath = path.join(this.getStepsDir(taskId, iteration), `step-${step}.md`);
try {
await fs.writeFile(stepResultPath, content, 'utf-8');
logger.debug({ taskId, iteration, step }, 'Step result written');
} catch (error) {
logger.error({ err: error, taskId, iteration, step }, 'Failed to write step result');
throw error;
}
}TaskFileManager.writeFinalSummary method · typescript · L361-L371 (11 LOC)src/task/file-manager.ts
async writeFinalSummary(taskId: string, content: string): Promise<void> {
const summaryPath = path.join(this.getIterationsDir(taskId), 'final-summary.md');
try {
await fs.writeFile(summaryPath, content, 'utf-8');
logger.info({ taskId, summaryPath }, 'Final summary written');
} catch (error) {
logger.error({ err: error, taskId }, 'Failed to write final summary');
throw error;
}
}Repobility · severity-and-effort ranking · https://repobility.com
TaskFileManager.taskExists method · typescript · L379-L388 (10 LOC)src/task/file-manager.ts
async taskExists(taskId: string): Promise<boolean> {
const taskDir = this.getTaskDir(taskId);
try {
await fs.access(taskDir);
return true;
} catch {
return false;
}
}TaskFileManager.listIterations method · typescript · L396-L417 (22 LOC)src/task/file-manager.ts
async listIterations(taskId: string): Promise<number[]> {
const iterationsDir = this.getIterationsDir(taskId);
try {
const entries = await fs.readdir(iterationsDir, { withFileTypes: true });
const iterations: number[] = [];
for (const entry of entries) {
if (entry.isDirectory() && entry.name.startsWith('iter-')) {
const match = entry.name.match(/^iter-(\d+)$/);
if (match) {
iterations.push(parseInt(match[1], 10));
}
}
}
return iterations.sort((a, b) => a - b);
} catch (error) {
logger.error({ err: error, taskId }, 'Failed to list iterations');
return [];
}
}TaskFileManager.cleanupTask method · typescript · L451-L461 (11 LOC)src/task/file-manager.ts
async cleanupTask(taskId: string): Promise<void> {
const taskDir = this.getTaskDir(taskId);
try {
await fs.rm(taskDir, { recursive: true, force: true });
logger.info({ taskId }, 'Task directory cleaned up');
} catch (error) {
logger.error({ err: error, taskId }, 'Failed to cleanup task directory');
throw error;
}
}