"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.init = init;
exports.getLanguageConfig = getLanguageConfig;
exports.updateLanguageConfig = updateLanguageConfig;
exports.updateConfig = updateConfig;
exports.getConfigSync = getConfigSync;
exports.getConfig = getConfig;
exports.getGlobalConfig = getGlobalConfig;
exports.updateGlobalConfig = updateGlobalConfig;
exports.migrateConfig = migrateConfig;
exports.loadPrompt = loadPrompt;
exports.getIgnorePattern = getIgnorePattern;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const os = __importStar(require("os"));
const gitignore_to_glob_1 = __importDefault(require("gitignore-to-glob"));
const prompts_1 = require("./prompts");
const types_1 = require("./types");
const utils_1 = require("./utils");
const migrations_1 = require("./migrations");
const defaultConfig = {
    promptsDir: ".knowhow/prompts",
    modules: [],
    plugins: {
        enabled: [
            "embeddings",
            "language",
            "git",
            "vim",
            "github",
            "asana",
            "jira",
            "linear",
            "download",
            "figma",
            "url",
            "tmux",
            "agents-md",
            "exec",
        ],
        disabled: [],
    },
    lintCommands: {
        js: "eslint",
        ts: "tslint",
    },
    sources: [
        {
            input: "src/**/*.mdx",
            output: ".knowhow/docs/",
            prompt: "BasicCodeDocumenter",
        },
        {
            input: ".knowhow/docs/**/*.mdx",
            output: ".knowhow/docs/README.mdx",
            prompt: "BasicProjectDocumenter",
        },
    ],
    embedSources: [
        {
            input: ".knowhow/docs/**/*.mdx",
            output: ".knowhow/embeddings/docs.json",
            prompt: "BasicEmbeddingExplainer",
            chunkSize: 2000,
        },
        {
            input: "src/**/*.ts",
            output: ".knowhow/embeddings/code.json",
            chunkSize: 2000,
        },
    ],
    embeddingModel: types_1.EmbeddingModels.openai.EmbeddingAda2,
    agents: [
        {
            name: "Example agent",
            description: "You can define agents in the config. They will have access to all tools.",
            instructions: "Reply to the user saying 'Hello, world!'",
            model: "gpt-5.4-nano",
            provider: "openai",
        },
    ],
    mcps: [
        {
            name: "browser",
            command: "npx",
            args: ["-y", "@playwright/mcp@latest", "--browser", "chrome"],
        },
    ],
    modelProviders: [
        { provider: "openai", envKey: "OPENAI_API_KEY" },
        { provider: "anthropic", envKey: "ANTHROPIC_API_KEY" },
        { provider: "google", envKey: "GEMINI_API_KEY" },
        { provider: "xai", envKey: "XAI_API_KEY" },
        { provider: "knowhow" },
        { provider: "lms", url: "http://localhost:1234" },
    ],
    ycmd: {
        enabled: false,
        installPath: undefined,
        port: 0,
        logLevel: "info",
        completionTimeout: 5000,
    },
    worker: {
        tunnel: {
            enabled: false,
            allowedPorts: [],
        },
    },
    syncRemote: false,
};
const defaultLanguage = {
    "knowhow config": {
        events: [],
        sources: [
            {
                kind: "file",
                data: [".knowhow/knowhow.json"],
            },
        ],
    },
};
const globalTemplateFolders = ["prompts", "docs", "embeddings"];
const globalTemplateFiles = {
    "knowhow.json": JSON.stringify(defaultConfig, null, 2),
    "language.json": JSON.stringify(defaultLanguage, null, 2),
    ".ignore": "",
    ".hashes.json": "{}",
    ".jwt": "",
};
for (const prompt of prompts_1.Prompts) {
    const promptName = Object.keys(prompt)[0];
    const fileName = "prompts/" + promptName + ".mdx";
    globalTemplateFiles[fileName] = prompt[promptName];
}
function getGlobalConfigDir() {
    return path.join(os.homedir(), ".knowhow");
}
async function ensureGlobalConfigDir() {
    const globalConfigDir = getGlobalConfigDir();
    await (0, utils_1.mkdir)(globalConfigDir, { recursive: true });
    for (const folder of globalTemplateFolders) {
        const folderPath = path.join(globalConfigDir, folder);
        await (0, utils_1.mkdir)(folderPath, { recursive: true });
        fs.chmodSync(folderPath, 0o744);
    }
    for (const file of Object.keys(globalTemplateFiles)) {
        const filePath = path.join(globalConfigDir, file);
        if (!fs.existsSync(filePath)) {
            await (0, utils_1.writeFile)(filePath, globalTemplateFiles[file]);
            fs.chmodSync(filePath, 0o600);
        }
    }
    return globalConfigDir;
}
async function init() {
    console.log("Initializing global knowhow config at ~/.knowhow");
    const globalConfigDir = await ensureGlobalConfigDir();
    const SCRIPT_MODULE = "@tyvm/knowhow-module-script";
    const globalConfigPath = path.join(globalConfigDir, "knowhow.json");
    try {
        const rawGlobal = fs.existsSync(globalConfigPath)
            ? fs.readFileSync(globalConfigPath, "utf8")
            : JSON.stringify(defaultConfig, null, 2);
        const globalConf = JSON.parse(rawGlobal);
        if (!globalConf.modules) {
            globalConf.modules = [];
        }
        if (!globalConf.modules.includes(SCRIPT_MODULE)) {
            globalConf.modules.push(SCRIPT_MODULE);
            fs.writeFileSync(globalConfigPath, JSON.stringify(globalConf, null, 2));
            console.log(`✅ Added ${SCRIPT_MODULE} to ~/.knowhow/knowhow.json modules`);
        }
    }
    catch (e) {
        console.warn(`⚠ Could not update global config to add script module:`, e);
    }
    console.log("Initializing local knowhow config at ./.knowhow");
    await (0, utils_1.mkdir)(".knowhow", { recursive: true });
    for (const folder of globalTemplateFolders) {
        await (0, utils_1.mkdir)(path.join(".knowhow", folder), { recursive: true });
    }
    await copyTemplates(globalConfigDir);
}
async function getLanguageConfig() {
    try {
        if (!fs.existsSync(".knowhow/language.json")) {
            return {};
        }
        const language = JSON.parse(await (0, utils_1.readFile)(".knowhow/language.json", "utf8"));
        return language;
    }
    catch (e) {
        console.warn("Error reading .knowhow/language.json:", e);
        return {};
    }
}
async function updateLanguageConfig(language) {
    await (0, utils_1.writeFile)(".knowhow/language.json", JSON.stringify(language, null, 2));
}
async function updateConfig(config) {
    if (!config || typeof config !== "object") {
        throw new Error("Invalid config object");
    }
    if (fs.existsSync(".knowhow/knowhow.json")) {
        await fs.promises.copyFile(".knowhow/knowhow.json", ".knowhow/knowhow.json.bak");
    }
    await (0, utils_1.writeFile)(".knowhow/knowhow.json", JSON.stringify(config, null, 2));
}
async function copyTemplates(globalConfigDir) {
    for (const folder of globalTemplateFolders) {
        const src = path.join(globalConfigDir, folder);
        const dest = path.join(".knowhow", folder);
        await fs.promises.cp(src, dest, {
            recursive: true,
            filter: (source, destination) => {
                return fs.existsSync(dest) ? false : true;
            },
        });
    }
    for (const file of Object.keys(globalTemplateFiles)) {
        const src = path.join(globalConfigDir, file);
        const dest = path.join(".knowhow", file);
        if (!fs.existsSync(dest)) {
            await fs.promises.copyFile(src, dest);
        }
    }
}
function getConfigSync() {
    try {
        const config = JSON.parse(fs.readFileSync(".knowhow/knowhow.json", "utf8").toString());
        return config;
    }
    catch (e) {
        return {};
    }
}
let loggedWarning = false;
async function getConfig() {
    if (!fs.existsSync(".knowhow/knowhow.json")) {
        if (!loggedWarning) {
            loggedWarning = true;
            if (!process.argv.includes("init")) {
                console.warn("KnowHow config file not found. Please run `knowhow init` to create it.");
            }
        }
        return {};
    }
    try {
        const config = await (0, utils_1.readFile)(".knowhow/knowhow.json", "utf8");
        const parsedConfig = JSON.parse(config);
        return parsedConfig;
    }
    catch (error) {
        console.error("Error reading .knowhow/knowhow.json:", error);
        throw new Error("Failed to load KnowHow configuration.");
    }
}
async function getGlobalConfig() {
    const globalConfigDir = getGlobalConfigDir();
    const globalConfigPath = path.join(globalConfigDir, "knowhow.json");
    if (!fs.existsSync(globalConfigPath)) {
        return {};
    }
    try {
        const config = await (0, utils_1.readFile)(globalConfigPath, "utf8");
        return JSON.parse(config);
    }
    catch (error) {
        console.warn("Failed to load global knowhow config:", error);
        return {};
    }
}
async function updateGlobalConfig(config) {
    if (!config || typeof config !== "object") {
        throw new Error("Invalid config object");
    }
    const globalConfigDir = getGlobalConfigDir();
    await (0, utils_1.mkdir)(globalConfigDir, { recursive: true });
    const globalConfigPath = path.join(globalConfigDir, "knowhow.json");
    if (fs.existsSync(globalConfigPath)) {
        await fs.promises.copyFile(globalConfigPath, globalConfigPath + ".bak");
    }
    await (0, utils_1.writeFile)(globalConfigPath, JSON.stringify(config, null, 2));
}
async function migrateConfig() {
    if (!fs.existsSync(".knowhow/knowhow.json")) {
        return;
    }
    const parsedConfig = await getConfig();
    const { modified, config: migratedConfig } = (0, migrations_1.applyMigrations)(parsedConfig);
    let configModified = modified;
    if (migratedConfig.plugins) {
        const enabled = migratedConfig.plugins.enabled || [];
        const disabled = migratedConfig.plugins.disabled || [];
        const missingPlugins = defaultConfig.plugins.enabled.filter((plugin) => !enabled.includes(plugin) && !disabled.includes(plugin));
        if (missingPlugins.length > 0) {
            console.log(`Adding missing plugins to enabled list: ${missingPlugins.join(", ")}`);
            migratedConfig.plugins.enabled = [...enabled, ...missingPlugins];
            configModified = true;
        }
    }
    if (configModified) {
        await updateConfig(migratedConfig);
    }
}
async function loadPrompt(promptName) {
    const config = await getConfig();
    if (!promptName) {
        return "";
    }
    const promptsDir = config.promptsDir || ".knowhow/prompts";
    const promptFilePath = path.join(promptsDir, `${promptName}.mdx`);
    if (fs.existsSync(promptFilePath)) {
        const prompt = await (0, utils_1.readFile)(promptFilePath, "utf8");
        return ensureTextPlaceholder(prompt);
    }
    if (fs.existsSync(promptName)) {
        const prompt = await (0, utils_1.readFile)(promptName, "utf8");
        return ensureTextPlaceholder(prompt);
    }
    return ensureTextPlaceholder(promptName);
}
function ensureTextPlaceholder(prompt) {
    if (!prompt.includes("{text}")) {
        return `${prompt}\n\n{text}`;
    }
    return prompt;
}
async function getIgnorePattern() {
    const ignoreList = new Array();
    const gitIgnore = await (0, utils_1.fileExists)(".gitignore");
    if (gitIgnore) {
        ignoreList.push(...(0, gitignore_to_glob_1.default)(".gitignore"));
    }
    const knowhowIgnore = await (0, utils_1.fileExists)(".knowhow/.ignore");
    if (knowhowIgnore) {
        ignoreList.push(...(0, gitignore_to_glob_1.default)(".knowhow/.ignore"));
    }
    return ignoreList.map((pattern) => pattern.replace("!", "./"));
}
//# sourceMappingURL=config.js.map