import { ResultBuffer } from "./shared.js";
export var BoltResultType;
(function (BoltResultType) {
    BoltResultType["Text"] = "text";
    BoltResultType["Artifact"] = "artifact";
    BoltResultType["Think"] = "think";
})(BoltResultType || (BoltResultType = {}));
// <boltAction type="file" filePath="package.json">
const fileActionRegex = /<boltAction type="([^"]+)" filePath="([^"]+)"/g;
export class BoltResultBuffer extends ResultBuffer {
    buffer = "";
    currentType = BoltResultType.Text;
    filesSeen = new Set();
    processingFilePath = null;
    add(text) {
        let type = this.currentType;
        if (text.trimStart().startsWith("<boltArtifact")) {
            type = BoltResultType.Artifact;
        }
        else if (text.trimStart().startsWith("<think>")) {
            text = text.replace("<think>", "").trimStart();
            type = BoltResultType.Think;
        }
        if (this.buffer && type !== this.currentType) {
            this.maybeFlush(true);
            this.currentType = type;
            this.add(text);
            return;
        }
        if (text.includes("</boltArtifact>")) {
            const [lhs, rhs] = text.split("</boltArtifact>");
            this.buffer += lhs + "</boltArtifact>";
            this.currentType = BoltResultType.Artifact;
            this.maybeFlush(true);
            if (rhs) {
                this.add(rhs);
                return;
            }
        }
        else if (text.includes("</think>")) {
            const [lhs, rhs] = text.split("</think>");
            this.buffer += lhs;
            this.maybeFlush(true);
            if (rhs) {
                this.add(rhs);
                return;
            }
        }
        if (!this.buffer) {
            this.params.onTypeChange(type);
        }
        this.buffer += text;
        this.currentType = type;
        if (type === BoltResultType.Artifact) {
            this.checkFileActions();
        }
    }
    maybeFlush(force = false) {
        if (this.buffer && (force || this.shouldFlush())) {
            this.removeTrailingTags();
            // ensure the last file action is flushed
            if (this.processingFilePath) {
                this.params.onFlushFile(this.processingFilePath, this.buffer);
            }
            this.params.onFlush(this.currentType, this.buffer);
            this.buffer = "";
            this.currentType = BoltResultType.Text;
            this.processingFilePath = null;
        }
    }
    checkFileActions() {
        const fileActions = this.buffer.matchAll(fileActionRegex);
        for (const fileAction of fileActions) {
            const filePath = fileAction[2];
            if (filePath && !this.filesSeen.has(filePath)) {
                this.filesSeen.add(filePath);
                this.params.onPendingFile(filePath);
                if (this.processingFilePath) {
                    this.params.onFlushFile(this.processingFilePath, this.buffer);
                }
                this.processingFilePath = filePath;
            }
        }
    }
    removeTrailingTags() {
        this.buffer = this.buffer.replace(/<\/think>$/, "");
    }
    shouldFlush() {
        switch (this.currentType) {
            case BoltResultType.Text:
                // match sentence end-like punctuation
                return /[a-zA-Z][.!?][\s\n]?$/.test(this.buffer);
            case BoltResultType.Artifact:
                return this.buffer.trimEnd().endsWith("</boltArtifact>");
            case BoltResultType.Think:
                return this.buffer.trimEnd().endsWith("</think>");
        }
    }
}
//# sourceMappingURL=bolt.js.map