"use strict"; // packages/cocos-ext/src/panels/default/index.ts var LOCALE_STORAGE_KEY = "cocos-mcp-panel-locale"; var STR = { zh: { panelTitle: "Cocos MCP \u63A7\u5236\u53F0", langLabel: "\u754C\u9762\u8BED\u8A00", server: "\u670D\u52A1", running: "\u8FD0\u884C\u4E2D", stopped: "\u5DF2\u505C\u6B62", port: "\u7AEF\u53E3", connections: "\u8FDE\u63A5\u6570", url: "\u9762\u677F URL\uFF08\u4EC5\u4F9B\u53C2\u8003\uFF09", startServer: "\u542F\u52A8\u670D\u52A1", stopServer: "\u505C\u6B62\u670D\u52A1", refresh: "\u5237\u65B0", runSelfTest: "\u4E00\u952E\u68C0\u6D4B", selfTestTitle: "\u8FDE\u63A5\u8BCA\u65AD", selfTestNever: "\u5C1A\u672A\u8FD0\u884C\u68C0\u6D4B", quickStartTitle: "\u9996\u6B21\u4F7F\u7528", quickStartStepServer: "\u542F\u52A8MCP\u670D\u52A1", quickStartStepConfig: "\u914D\u7F6E\u81F3\u5C11\u4E00\u4E2AMCP\u5BA2\u6237\u7AEF", quickStartStepConnect: "\u91CD\u542F\u5BA2\u6237\u7AEF\u5E76\u5EFA\u7ACB\u8FDE\u63A5", quickStartDone: "\u5B8C\u6210", quickStartPending: "\u5F85\u5B8C\u6210", openGuide: "\u6253\u5F00Quick Start", firstPromptLabel: "\u8FDE\u63A5\u6210\u529F\u540E\uFF0C\u5148\u8BA9AI\u8BFB\u53D6\u573A\u666F\uFF0C\u518D\u505A\u4E00\u4E2A\u5C0F\u6539\u52A8\u3002", autoConfigTitle: "\u4E00\u952E\u914D\u7F6E MCP \u5BA2\u6237\u7AEF", serverNamePh: "MCP \u670D\u52A1\u540D\uFF08\u5199\u5165\u5404\u5BA2\u6237\u7AEF\u914D\u7F6E\uFF09", autoConfigAll: "\u4E00\u952E\u914D\u7F6E\u5168\u90E8\u5BA2\u6237\u7AEF", configured: "\u5DF2\u914D\u7F6E", notConfigured: "\u672A\u914D\u7F6E", autoConfig: "\u4E00\u952E\u914D\u7F6E", openConfig: "\u6253\u5F00\u914D\u7F6E", cliTitle: "\u547D\u4EE4\u884C\u53C2\u8003\uFF08Codex / Gemini CLI\uFF09", operationLogs: "\u64CD\u4F5C\u65E5\u5FD7", clear: "\u6E05\u7A7A", logLevelInfo: "\u4FE1\u606F", logLevelWarn: "\u8B66\u544A", logLevelError: "\u9519\u8BEF" }, en: { panelTitle: "Cocos MCP Console", langLabel: "Language", server: "Server", running: "Running", stopped: "Stopped", port: "port", connections: "Connections", url: "Panel URL (reference)", startServer: "Start Server", stopServer: "Stop Server", refresh: "Refresh", runSelfTest: "Run Self-Test", selfTestTitle: "Connection Diagnostics", selfTestNever: "Self-test has not run yet", quickStartTitle: "First Run", quickStartStepServer: "Start the MCP service", quickStartStepConfig: "Configure at least one MCP client", quickStartStepConnect: "Restart the client and connect", quickStartDone: "done", quickStartPending: "pending", openGuide: "Open Quick Start", firstPromptLabel: "After connecting, inspect the scene before one small mutation.", autoConfigTitle: "Auto Config MCP Clients", serverNamePh: "server name (written to each client config)", autoConfigAll: "Auto Config All", configured: "configured", notConfigured: "not configured", autoConfig: "Auto Config", openConfig: "Open Config", cliTitle: "CLI reference (Codex / Gemini CLI)", operationLogs: "Operation Logs", clear: "Clear", logLevelInfo: "info", logLevelWarn: "warn", logLevelError: "error" } }; function readLocale() { try { const v = localStorage.getItem(LOCALE_STORAGE_KEY); if (v === "en" || v === "zh") { return v; } } catch { } return "zh"; } function writeLocale(l) { try { localStorage.setItem(LOCALE_STORAGE_KEY, l); } catch { } } var locale = readLocale(); function t(key) { return STR[locale][key] ?? STR.en[key] ?? key; } var TEMPLATE = `

-
-
-

`; var STYLE = ` .wrap { padding: 12px; color: #d4d4d4; font-size: 13px; } .lang-bar { margin-bottom: 10px; } .lang-label { margin-right: 8px; color: #aaa; } .lang-select { background: #2d2d2d; color: #d4d4d4; border: 1px solid #444; border-radius: 4px; padding: 4px 8px; font-size: 13px; } h2 { margin: 0 0 10px 0; font-size: 18px; } h3 { margin: 0 0 8px 0; font-size: 14px; } .card { border: 1px solid #333; border-radius: 6px; padding: 10px; margin-bottom: 10px; background: #1e1e1e; } .row { display: flex; gap: 8px; align-items: center; margin-top: 8px; margin-bottom: 6px; } .mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; background: #111; padding: 8px; border-radius: 4px; margin-bottom: 6px; word-break: break-all; } .logs { max-height: 220px; overflow: auto; background: #111; border-radius: 4px; padding: 8px; } .log { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; margin-bottom: 4px; white-space: pre-wrap; word-break: break-word; } .log.error { color: #ff8a8a; } .log.warn { color: #f7d774; } .log.info { color: #9bd4ff; } .client-row { display: grid; grid-template-columns: 110px 1fr auto auto; gap: 8px; align-items: center; margin: 6px 0; } .tag { padding: 2px 6px; border-radius: 4px; font-size: 12px; background: #333; } .ok { background: #1f5f2f; } .bad { background: #6a2a2a; } .guide-card { border-color: #315b4f; } .guide-heading { justify-content: space-between; margin-top: 0; } .guide-heading h3 { margin: 0; } .guide-steps { display: grid; gap: 6px; } .guide-step { display: grid; grid-template-columns: 68px 1fr; gap: 8px; align-items: center; } .guide-status { padding: 2px 6px; border-radius: 4px; font-size: 12px; text-align: center; background: #5c4622; } .guide-status.done { background: #1f5f2f; } .guide-note { margin-top: 8px; color: #a8c9bd; } .self-test-title { margin-top: 12px; } .self-test-results { display: grid; gap: 5px; } .self-test-row { display: grid; grid-template-columns: 22px 92px 1fr; gap: 6px; align-items: start; } .self-test-icon.ok-text { color: #63d28b; } .self-test-icon.bad-text { color: #ff8a8a; } .self-test-message { color: #aaa; word-break: break-word; } `; module.exports = Editor.Panel.define({ template: TEMPLATE, style: STYLE, $: { langLabel: "#langLabel", langSelect: "#langSelect", panelTitle: "#panelTitle", quickStartTitle: "#quickStartTitle", quickStartSteps: "#quickStartSteps", openGuideBtn: "#openGuideBtn", firstPromptLabel: "#firstPromptLabel", serverLine: "#serverLine", connLine: "#connLine", urlLine: "#urlLine", startBtn: "#startBtn", stopBtn: "#stopBtn", refreshBtn: "#refreshBtn", selfTestBtn: "#selfTestBtn", selfTestTitle: "#selfTestTitle", selfTestResults: "#selfTestResults", autoConfigTitle: "#autoConfigTitle", serverNameInput: "#serverNameInput", addAllBtn: "#addAllBtn", clientList: "#clientList", cliTitle: "#cliTitle", claudeCmd: "#claudeCmd", geminiCmd: "#geminiCmd", logs: "#logs", logsTitle: "#logsTitle", clearLogsBtn: "#clearLogsBtn" }, ready() { const pluginName = "cocos-mcp"; locale = readLocale(); const readServerName = () => { const input = this.$.serverNameInput; const v = (input?.value ?? "").trim(); return v || "cocos-creator"; }; const applyStaticLabels = () => { this.$.langLabel.textContent = t("langLabel"); this.$.panelTitle.textContent = t("panelTitle"); this.$.quickStartTitle.textContent = t("quickStartTitle"); this.$.openGuideBtn.textContent = t("openGuide"); this.$.firstPromptLabel.textContent = t("firstPromptLabel"); this.$.autoConfigTitle.textContent = t("autoConfigTitle"); this.$.cliTitle.textContent = t("cliTitle"); this.$.logsTitle.textContent = t("operationLogs"); this.$.startBtn.textContent = t("startServer"); this.$.stopBtn.textContent = t("stopServer"); this.$.refreshBtn.textContent = t("refresh"); this.$.selfTestBtn.textContent = t("runSelfTest"); this.$.selfTestTitle.textContent = t("selfTestTitle"); this.$.addAllBtn.textContent = t("autoConfigAll"); this.$.clearLogsBtn.textContent = t("clear"); const input = this.$.serverNameInput; if (input) { input.placeholder = t("serverNamePh"); } const sel = this.$.langSelect; if (sel) { sel.value = locale; } }; const logLevelLabel = (level) => { if (level === "error") { return t("logLevelError"); } if (level === "warn") { return t("logLevelWarn"); } return t("logLevelInfo"); }; const render = (state) => { const run = state.server.running ? t("running") : t("stopped"); this.$.serverLine.textContent = `${t("server")}: ${run} (${t("port")}: ${state.server.port ?? "-"})`; this.$.connLine.textContent = `${t("connections")}: ${state.server.connections}`; this.$.urlLine.textContent = `${t("url")}: ${state.server.url ?? "-"}`; this.$.claudeCmd.textContent = state.cliCommands.claude; this.$.geminiCmd.textContent = state.cliCommands.gemini; const selfTestResults = this.$.selfTestResults; selfTestResults.innerHTML = ""; if (!state.selfTest) { selfTestResults.textContent = t("selfTestNever"); } else { for (const check of state.selfTest.checks) { const row = document.createElement("div"); row.className = "self-test-row"; const icon = document.createElement("span"); icon.className = `self-test-icon ${check.ok ? "ok-text" : "bad-text"}`; icon.textContent = check.ok ? "OK" : "X"; const id = document.createElement("strong"); id.textContent = check.id; const message = document.createElement("span"); message.className = "self-test-message"; message.textContent = check.message; row.append(icon, id, message); selfTestResults.appendChild(row); } } const guideSteps = this.$.quickStartSteps; guideSteps.innerHTML = ""; const onboardingSteps = [ { label: t("quickStartStepServer"), done: state.server.running }, { label: t("quickStartStepConfig"), done: state.clients.some((client) => client.configured) }, { label: t("quickStartStepConnect"), done: state.server.connections > 0 } ]; for (const step of onboardingSteps) { const row = document.createElement("div"); row.className = "guide-step"; const status = document.createElement("span"); status.className = `guide-status${step.done ? " done" : ""}`; status.textContent = step.done ? t("quickStartDone") : t("quickStartPending"); const label = document.createElement("span"); label.textContent = step.label; row.append(status, label); guideSteps.appendChild(row); } const list = this.$.clientList; list.innerHTML = ""; for (const c of state.clients) { const row = document.createElement("div"); row.className = "client-row"; const tagText = c.configured ? t("configured") : t("notConfigured"); const tagClass = c.configured ? "ok" : "bad"; row.innerHTML = ` ${c.name} ${c.configPath} ${tagText}
${t("autoConfig")} ${t("openConfig")}
`; list.appendChild(row); } list.querySelectorAll(".cfg-btn").forEach((el) => { el.addEventListener("confirm", async () => { const clientType = el.getAttribute("data-client"); await Editor.Message.request(pluginName, "add-mcp-to-client", clientType, readServerName()); await refresh(); }); }); list.querySelectorAll(".open-btn").forEach((el) => { el.addEventListener("confirm", async () => { const clientType = el.getAttribute("data-client"); await Editor.Message.request(pluginName, "open-client-config", clientType); }); }); const logs = this.$.logs; logs.innerHTML = ""; for (const l of state.logs.slice().reverse()) { const line = document.createElement("div"); line.className = `log ${l.level}`; line.textContent = `${l.ts} [${logLevelLabel(l.level)}] ${l.message}`; logs.appendChild(line); } }; const refresh = async () => { applyStaticLabels(); const state = await Editor.Message.request(pluginName, "get-mcp-panel-state", readServerName()); render(state); }; this.$.langSelect?.addEventListener("change", () => { const sel = this.$.langSelect; const v = sel?.value === "en" ? "en" : "zh"; locale = v; writeLocale(v); refresh().catch((e) => console.error("[cocos-mcp panel] refresh after locale", e)); }); this.$.startBtn?.addEventListener("confirm", async () => { await Editor.Message.request(pluginName, "start-mcp-server"); await refresh(); }); this.$.stopBtn?.addEventListener("confirm", async () => { await Editor.Message.request(pluginName, "stop-mcp-server"); await refresh(); }); this.$.refreshBtn?.addEventListener("confirm", refresh); this.$.selfTestBtn?.addEventListener("confirm", async () => { await Editor.Message.request(pluginName, "run-mcp-self-test", readServerName()); await refresh(); }); this.$.openGuideBtn?.addEventListener("confirm", async () => { await Editor.Message.request(pluginName, "open-user-guide"); }); this.$.addAllBtn?.addEventListener("confirm", async () => { await Editor.Message.request(pluginName, "add-mcp-to-all-clients", readServerName()); await refresh(); }); this.$.clearLogsBtn?.addEventListener("confirm", async () => { await Editor.Message.request(pluginName, "clear-panel-logs"); await refresh(); }); this.$.serverNameInput?.addEventListener("change", refresh); refresh().catch((e) => { console.error("[cocos-mcp panel] initial refresh failed", e); }); } });