"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.FsSyncedAgentWatcher = void 0;
const fs_1 = __importDefault(require("fs"));
const promises_1 = __importDefault(require("fs/promises"));
const path_1 = __importDefault(require("path"));
const messagesToRenderEvents_1 = require("../../chat/renderer/messagesToRenderEvents");
const EventService_1 = require("../EventService");
class FsSyncedAgentWatcher {
    taskId = "";
    taskPath = "";
    watcher = null;
    lastThreadLength = 0;
    agentName = "unknown";
    debounceTimer = null;
    agentEvents = new EventService_1.EventService();
    eventTypes = {
        done: "done",
        toolCall: "tool:pre_call",
        toolUsed: "tool:post_call",
        agentSay: "agent:say",
        threadUpdate: "thread_update",
    };
    async startWatching(taskId) {
        this.taskId = taskId;
        this.taskPath = path_1.default.join(".knowhow/processes/agents", taskId);
        const metadata = await this.readMetadata();
        if (metadata) {
            const threads = metadata.threads || [];
            const lastThread = threads[threads.length - 1] || [];
            this.agentName = metadata.agentName || taskId;
            this.lastThreadLength = lastThread.length;
        }
        try {
            this.watcher = fs_1.default.watch(this.taskPath, (event, filename) => {
                if (filename === "metadata.json" || filename === null) {
                    if (this.debounceTimer)
                        clearTimeout(this.debounceTimer);
                    this.debounceTimer = setTimeout(() => {
                        this.onMetadataChanged().catch(() => { });
                    }, 200);
                }
            });
        }
        catch (err) {
            console.warn(`⚠️  Could not watch ${this.taskPath}: ${err.message}`);
        }
        console.log(`👁️  Watching fs-synced agent: ${taskId} (${this.agentName})`);
        console.log(`   Type /logs 20 to see recent messages, or type to send a message`);
    }
    async onMetadataChanged() {
        const metadata = await this.readMetadata();
        if (!metadata?.threads)
            return;
        const threads = metadata.threads;
        const lastThread = threads[threads.length - 1] || [];
        const newMessages = lastThread.slice(this.lastThreadLength);
        if (newMessages.length > 0) {
            const renderEvents = (0, messagesToRenderEvents_1.messagesToRenderEvents)(newMessages, this.taskId, this.agentName);
            for (const event of renderEvents) {
                if (event.type === "toolCall") {
                    this.agentEvents.emit(this.eventTypes.toolCall, {
                        toolCall: event.toolCall,
                    });
                }
                else if (event.type === "toolResult") {
                    this.agentEvents.emit(this.eventTypes.toolUsed, {
                        toolCall: event.toolCall,
                        functionResp: event.result,
                    });
                }
                else if (event.type === "agentMessage") {
                    this.agentEvents.emit(this.eventTypes.agentSay, {
                        message: event.message,
                    });
                }
            }
            this.agentEvents.emit(this.eventTypes.threadUpdate, lastThread);
            this.lastThreadLength = lastThread.length;
        }
        const status = metadata.status;
        const result = metadata.result;
        if ((status === "completed" || status === "killed") && result != null) {
            this.stopWatching();
            this.agentEvents.emit(this.eventTypes.done, result);
        }
    }
    async sendMessage(message) {
        const inputPath = path_1.default.join(this.taskPath, "input.txt");
        await promises_1.default.writeFile(inputPath, message, "utf8");
    }
    async getThreads() {
        const metadata = await this.readMetadata();
        return metadata?.threads || [];
    }
    stopWatching() {
        if (this.debounceTimer) {
            clearTimeout(this.debounceTimer);
            this.debounceTimer = null;
        }
        this.watcher?.close();
        this.watcher = null;
        console.log(`🔌 Stopped watching agent: ${this.taskId}`);
    }
    async pause() {
        const statusPath = path_1.default.join(this.taskPath, "status.txt");
        await promises_1.default.writeFile(statusPath, "paused", "utf8");
        console.log(`⏸️  Paused remote agent: ${this.taskId}`);
    }
    async unpause() {
        const statusPath = path_1.default.join(this.taskPath, "status.txt");
        await promises_1.default.writeFile(statusPath, "running", "utf8");
        console.log(`▶️  Unpaused remote agent: ${this.taskId}`);
    }
    async kill() {
        const statusPath = path_1.default.join(this.taskPath, "status.txt");
        await promises_1.default.writeFile(statusPath, "killed", "utf8");
        console.log(`🛑 Killed remote agent: ${this.taskId}`);
    }
    async readMetadata() {
        try {
            const metaPath = path_1.default.join(this.taskPath, "metadata.json");
            const content = await promises_1.default.readFile(metaPath, "utf8");
            return JSON.parse(content);
        }
        catch {
            return null;
        }
    }
}
exports.FsSyncedAgentWatcher = FsSyncedAgentWatcher;
//# sourceMappingURL=FsSyncer.js.map