#!/usr/bin/env node
"use strict";
/**
 * MyContext Core MCP Server (The Living Brain Bridge)
 *
 * This server connects the MyContext AI CLI to the GitLab Duo Agent Platform.
 * It provides a "Living Brain" context to Duo Agents, allowing them to
 * understand and modify the project's architecture deterministically.
 */
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.MyContextMCPServer = void 0;
const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
const ContextService_1 = require("../services/ContextService");
const fileSystem_1 = require("../utils/fileSystem");
const ContextSyncer_1 = require("../services/ContextSyncer");
const path = __importStar(require("path"));
const chalk_1 = __importDefault(require("chalk"));
const fs_extra_1 = __importDefault(require("fs-extra"));
const dotenv_1 = __importDefault(require("dotenv"));
const dotenv_expand_1 = __importDefault(require("dotenv-expand"));
class MyContextMCPServer {
    constructor(projectPath) {
        this.projectPath = projectPath || process.cwd();
        // Load environment variables
        const candidates = [
            path.join(this.projectPath, ".mycontext", ".env.local"),
            path.join(this.projectPath, ".mycontext", ".env"),
            path.join(this.projectPath, ".env.local"),
            path.join(this.projectPath, ".env"),
        ];
        for (const p of candidates) {
            if (fs_extra_1.default.pathExistsSync(p)) {
                const result = dotenv_1.default.config({ path: p });
                dotenv_expand_1.default.expand(result);
            }
        }
        this.server = new index_js_1.Server({
            name: "mycontext-core-server",
            version: "1.0.0",
        }, {
            capabilities: {
                tools: {},
            },
        });
        this.contextService = new ContextService_1.ContextService(this.projectPath);
        this.contextSyncer = new ContextSyncer_1.ContextSyncer(this.projectPath);
        this.fsManager = new fileSystem_1.FileSystemManager();
        this.setupToolHandlers();
    }
    setupToolHandlers() {
        this.server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
            return {
                tools: this.getAvailableTools(),
            };
        });
        this.server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
            const { name, arguments: args } = request.params;
            try {
                switch (name) {
                    case "get_living_brain":
                        return await this.handleGetLivingBrain();
                    case "query_architecture":
                        return await this.handleQueryArchitecture(args);
                    case "sync_brain":
                        return await this.handleSyncBrain();
                    case "validate_intent":
                        return await this.handleValidateIntent(args);
                    case "update_brain_metadata":
                        return await this.handleUpdateBrainMetadata(args);
                    default:
                        throw new Error(`Unknown tool: ${name}`);
                }
            }
            catch (error) {
                return {
                    content: [
                        {
                            type: "text",
                            text: `❌ Error in ${name}: ${error.message}`,
                        },
                    ],
                    isError: true,
                };
            }
        });
    }
    getAvailableTools() {
        return [
            {
                name: "get_living_brain",
                description: "Returns the full structural context of the project (The Living Brain). Use this to understand the project architecture, PRDs, and component systems.",
                inputSchema: { type: "object", properties: {} },
            },
            {
                name: "query_architecture",
                description: "Query a specific path in the project architecture (e.g., 'prd.goals' or 'brand.colors').",
                inputSchema: {
                    type: "object",
                    properties: {
                        path: { type: "string", description: "Dot-notation path to the desired metadata" },
                    },
                    required: ["path"],
                },
            },
            {
                name: "sync_brain",
                description: "Scans the codebase and updates the Living Brain to match the current ground truth of the project structure.",
                inputSchema: { type: "object", properties: {} },
            },
            {
                name: "validate_intent",
                description: "Validates a proposed change or feature against the Project's 'Prime Objective' to prevent architectural drift.",
                inputSchema: {
                    type: "object",
                    properties: {
                        intent: { type: "string", description: "The action or feature the agent wants to perform" },
                    },
                    required: ["intent"],
                },
            },
            {
                name: "update_brain_metadata",
                description: "Updates specific metadata in the Living Brain (e.g., adding a new feature or updating a success metric).",
                inputSchema: {
                    type: "object",
                    properties: {
                        path: { type: "string", description: "Path to update" },
                        value: { type: "any", description: "New value to set" },
                    },
                    required: ["path", "value"],
                },
            },
        ];
    }
    async handleGetLivingBrain() {
        await this.contextService.initialize();
        const manifest = this.contextService.getManifest();
        if (!manifest) {
            throw new Error("No Living Brain (context.json) found. Ensure 'mycontext init' has been run.");
        }
        return {
            content: [
                {
                    type: "text",
                    text: JSON.stringify(manifest, null, 2),
                },
            ],
        };
    }
    async handleQueryArchitecture(args) {
        const { path: queryPath } = args;
        await this.contextService.initialize();
        const result = await this.contextService.queryContext({ path: queryPath });
        return {
            content: [
                {
                    type: "text",
                    text: result ? JSON.stringify(result, null, 2) : `No data found at path: ${queryPath}`,
                },
            ],
        };
    }
    async handleSyncBrain() {
        console.error(chalk_1.default.blue("🛰️  Syncing Living Brain with codebase..."));
        try {
            const result = await this.contextSyncer.syncAll();
            const summary = [
                "✅ Living Brain synchronized successfully.",
                `- Context Updated: ${result.contextUpdated}`,
                `- README Updated: ${result.readmeUpdated}`,
                result.contextDiff ? `\n**Context Changes:**\n${result.contextDiff}` : "- No context changes detected."
            ].join("\n");
            return {
                content: [
                    {
                        type: "text",
                        text: summary,
                    },
                ],
            };
        }
        catch (error) {
            throw new Error(`Sync failed: ${error.message}`);
        }
    }
    async handleValidateIntent(args) {
        const { intent } = args;
        await this.contextService.initialize();
        const result = await this.contextService.validateIntent(intent);
        const status = result.valid ? "✅ ALIGNED" : "❌ DEVIATION DETECTED";
        return {
            content: [
                {
                    type: "text",
                    text: `${status}\n\n**Reason**: ${result.reason || "Aligned with Prime Objective"}\n**Narrative Weight**: ${result.narrativeWeight}`,
                },
            ],
        };
    }
    async handleUpdateBrainMetadata(args) {
        const { path: updatePath, value } = args;
        await this.contextService.initialize();
        await this.contextService.updateManifest(updatePath, value);
        await this.contextService.save();
        // Refresh MD views after saving
        const manifest = this.contextService.getManifest();
        if (manifest) {
            await this.contextSyncer.refreshMarkdownViews(manifest);
        }
        return {
            content: [
                {
                    type: "text",
                    text: `✅ Metadata at '${updatePath}' has been updated and human-readable views refreshed.`,
                },
            ],
        };
    }
    async start() {
        const transport = new stdio_js_1.StdioServerTransport();
        await this.server.connect(transport);
        console.error("MyContext Core MCP Server running on stdio");
    }
}
exports.MyContextMCPServer = MyContextMCPServer;
// Start server if run directly
if (require.main === module) {
    const projectPath = process.argv[2] || process.cwd();
    const server = new MyContextMCPServer(projectPath);
    server.start().catch(console.error);
}
//# sourceMappingURL=mycontext-server.js.map