xiaozhi-client 1.5.0-beta.7 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
File without changes
package/dist/cli.js CHANGED
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env node
2
- var J=Object.defineProperty;var g=(n,e)=>J(n,"name",{value:e,configurable:!0});var X=(n,e)=>()=>(n&&(e=n(n=0)),e);var me=(n,e)=>{for(var o in e)J(n,o,{get:e[o],enumerable:!0})};import z from"fs";import xe from"path";import M from"chalk";import{createConsola as Ie}from"consola";function Ee(n){let e=n.getFullYear(),o=String(n.getMonth()+1).padStart(2,"0"),t=String(n.getDate()).padStart(2,"0"),r=String(n.getHours()).padStart(2,"0"),i=String(n.getMinutes()).padStart(2,"0"),c=String(n.getSeconds()).padStart(2,"0");return`${e}-${o}-${t} ${r}:${i}:${c}`}var $,w,R=X(()=>{"use strict";g(Ee,"formatDateTime");$=class{static{g(this,"Logger")}logFilePath=null;writeStream=null;consolaInstance;isDaemonMode;constructor(){this.isDaemonMode=process.env.XIAOZHI_DAEMON==="true",this.consolaInstance=Ie({formatOptions:{date:!1,colors:!0,compact:!0},fancy:!1});let e=this.isDaemonMode;this.consolaInstance.setReporters([{log:g(o=>{let t={info:"INFO",success:"SUCCESS",warn:"WARN",error:"ERROR",debug:"DEBUG",log:"LOG"},r={info:M.blue,success:M.green,warn:M.yellow,error:M.red,debug:M.gray,log:g(h=>h,"log")},i=t[o.type]||o.type.toUpperCase(),c=r[o.type]||(h=>h),a=Ee(new Date),f=c(`[${i}]`),d=`[${a}] ${f} ${o.args.join(" ")}`;if(!e)try{console.error(d)}catch(h){if(h instanceof Error&&h.message?.includes("EPIPE"))return;throw h}},"log")}])}initLogFile(e){this.logFilePath=xe.join(e,"xiaozhi.log"),z.existsSync(this.logFilePath)||z.writeFileSync(this.logFilePath,""),this.writeStream=z.createWriteStream(this.logFilePath,{flags:"a",encoding:"utf8"})}logToFile(e,o,...t){if(this.writeStream){let i=`[${new Date().toISOString()}] [${e.toUpperCase()}] ${o}`,c=t.length>0?`${i} ${t.map(a=>typeof a=="object"?JSON.stringify(a):String(a)).join(" ")}`:i;this.writeStream.write(`${c}
3
- `)}}enableFileLogging(e){e&&!this.writeStream&&this.logFilePath?this.writeStream=z.createWriteStream(this.logFilePath,{flags:"a",encoding:"utf8"}):!e&&this.writeStream&&(this.writeStream.end(),this.writeStream=null)}info(e,...o){this.consolaInstance.info(e,...o),this.logToFile("info",e,...o)}success(e,...o){this.consolaInstance.success(e,...o),this.logToFile("success",e,...o)}warn(e,...o){this.consolaInstance.warn(e,...o),this.logToFile("warn",e,...o)}error(e,...o){this.consolaInstance.error(e,...o),this.logToFile("error",e,...o)}debug(e,...o){this.consolaInstance.debug(e,...o),this.logToFile("debug",e,...o)}log(e,...o){this.consolaInstance.log(e,...o),this.logToFile("log",e,...o)}withTag(e){return this}close(){this.writeStream&&(this.writeStream.end(),this.writeStream=null)}},w=new $});var se={};me(se,{MCPServer:()=>H});import{spawn as ze}from"child_process";import{randomUUID as Re}from"crypto";import{EventEmitter as Ne}from"events";import j from"path";import{fileURLToPath as ie}from"url";import D from"express";var ke,Lo,y,H,ce=X(()=>{"use strict";R();ke=ie(import.meta.url),Lo=j.dirname(ke),y=w.withTag("mcp-server"),H=class extends Ne{static{g(this,"MCPServer")}app;server=null;clients=new Map;mcpProxy=null;port;constructor(e=3e3){super(),this.port=e,this.app=D(),this.setupMiddleware(),this.setupRoutes()}setupMiddleware(){this.app.use(D.json()),this.app.use(D.urlencoded({extended:!0})),this.app.use((e,o,t)=>{o.header("Access-Control-Allow-Origin","*"),o.header("Access-Control-Allow-Methods","GET, POST, OPTIONS"),o.header("Access-Control-Allow-Headers","Content-Type, Accept"),o.header("Cache-Control","no-cache"),t()})}setupRoutes(){this.app.get("/sse",(e,o)=>{let t=Date.now().toString(),r=Re();o.setHeader("Content-Type","text/event-stream"),o.setHeader("Cache-Control","no-cache, no-transform"),o.setHeader("Connection","keep-alive"),o.setHeader("X-Accel-Buffering","no"),this.clients.set(r,{id:t,sessionId:r,response:o}),y.info(`MCP client connected: ${t} (session: ${r})`),o.write(`event: endpoint
2
+ var L=Object.defineProperty;var g=(n,e)=>L(n,"name",{value:e,configurable:!0});var X=(n,e)=>()=>(n&&(e=n(n=0)),e);var me=(n,e)=>{for(var o in e)L(n,o,{get:e[o],enumerable:!0})};import R from"fs";import xe from"path";import M from"chalk";import{createConsola as Ie}from"consola";function Ee(n){let e=n.getFullYear(),o=String(n.getMonth()+1).padStart(2,"0"),t=String(n.getDate()).padStart(2,"0"),r=String(n.getHours()).padStart(2,"0"),i=String(n.getMinutes()).padStart(2,"0"),c=String(n.getSeconds()).padStart(2,"0");return`${e}-${o}-${t} ${r}:${i}:${c}`}var $,w,z=X(()=>{"use strict";g(Ee,"formatDateTime");$=class{static{g(this,"Logger")}logFilePath=null;writeStream=null;consolaInstance;isDaemonMode;constructor(){this.isDaemonMode=process.env.XIAOZHI_DAEMON==="true",this.consolaInstance=Ie({formatOptions:{date:!1,colors:!0,compact:!0},fancy:!1});let e=this.isDaemonMode;this.consolaInstance.setReporters([{log:g(o=>{let t={info:"INFO",success:"SUCCESS",warn:"WARN",error:"ERROR",debug:"DEBUG",log:"LOG"},r={info:M.blue,success:M.green,warn:M.yellow,error:M.red,debug:M.gray,log:g(h=>h,"log")},i=t[o.type]||o.type.toUpperCase(),c=r[o.type]||(h=>h),a=Ee(new Date),d=c(`[${i}]`),m=`[${a}] ${d} ${o.args.join(" ")}`;if(!e)try{console.error(m)}catch(h){if(h instanceof Error&&h.message?.includes("EPIPE"))return;throw h}},"log")}])}initLogFile(e){this.logFilePath=xe.join(e,"xiaozhi.log"),R.existsSync(this.logFilePath)||R.writeFileSync(this.logFilePath,""),this.writeStream=R.createWriteStream(this.logFilePath,{flags:"a",encoding:"utf8"})}logToFile(e,o,...t){if(this.writeStream){let i=`[${new Date().toISOString()}] [${e.toUpperCase()}] ${o}`,c=t.length>0?`${i} ${t.map(a=>typeof a=="object"?JSON.stringify(a):String(a)).join(" ")}`:i;this.writeStream.write(`${c}
3
+ `)}}enableFileLogging(e){e&&!this.writeStream&&this.logFilePath?this.writeStream=R.createWriteStream(this.logFilePath,{flags:"a",encoding:"utf8"}):!e&&this.writeStream&&(this.writeStream.end(),this.writeStream=null)}info(e,...o){this.consolaInstance.info(e,...o),this.logToFile("info",e,...o)}success(e,...o){this.consolaInstance.success(e,...o),this.logToFile("success",e,...o)}warn(e,...o){this.consolaInstance.warn(e,...o),this.logToFile("warn",e,...o)}error(e,...o){this.consolaInstance.error(e,...o),this.logToFile("error",e,...o)}debug(e,...o){this.consolaInstance.debug(e,...o),this.logToFile("debug",e,...o)}log(e,...o){this.consolaInstance.log(e,...o),this.logToFile("log",e,...o)}withTag(e){return this}close(){this.writeStream&&(this.writeStream.end(),this.writeStream=null)}},w=new $});var se={};me(se,{MCPServer:()=>H});import{spawn as Re}from"child_process";import{randomUUID as ze}from"crypto";import{EventEmitter as Ne}from"events";import j from"path";import{fileURLToPath as ie}from"url";import D from"express";var ke,Jo,y,H,ce=X(()=>{"use strict";z();ke=ie(import.meta.url),Jo=j.dirname(ke),y=w.withTag("mcp-server"),H=class extends Ne{static{g(this,"MCPServer")}app;server=null;clients=new Map;mcpProxy=null;port;constructor(e=3e3){super(),this.port=e,this.app=D(),this.setupMiddleware(),this.setupRoutes()}setupMiddleware(){this.app.use(D.json()),this.app.use(D.urlencoded({extended:!0})),this.app.use((e,o,t)=>{o.header("Access-Control-Allow-Origin","*"),o.header("Access-Control-Allow-Methods","GET, POST, OPTIONS"),o.header("Access-Control-Allow-Headers","Content-Type, Accept"),o.header("Cache-Control","no-cache"),t()})}setupRoutes(){this.app.get("/sse",(e,o)=>{let t=Date.now().toString(),r=ze();o.setHeader("Content-Type","text/event-stream"),o.setHeader("Cache-Control","no-cache, no-transform"),o.setHeader("Connection","keep-alive"),o.setHeader("X-Accel-Buffering","no"),this.clients.set(r,{id:t,sessionId:r,response:o}),y.info(`MCP client connected: ${t} (session: ${r})`),o.write(`event: endpoint
4
4
  data: /messages?sessionId=${r}
5
5
 
6
6
  `),e.on("close",()=>{this.clients.delete(r),y.info(`MCP client disconnected: ${t} (session: ${r})`)})}),this.app.post("/messages",async(e,o)=>{try{let t=e.query.sessionId,r=e.body;if(y.info(`Received message via SSE transport (session: ${t}):`,JSON.stringify(r)),!t||!this.clients.has(t)){o.status(400).json({jsonrpc:"2.0",error:{code:-32600,message:"Invalid or missing sessionId"},id:r.id});return}if(!this.mcpProxy){o.status(503).json({jsonrpc:"2.0",error:{code:-32603,message:"MCP proxy not running"},id:r.id});return}if(r.id===void 0)y.info(`Forwarding notification: ${r.method}`),this.mcpProxy.stdin.write(`${JSON.stringify(r)}
7
- `),o.status(202).send();else{let i=await this.forwardToProxy(r),c=this.clients.get(t);c&&this.sendToClient(c,i),o.status(202).send()}}catch(t){y.error("SSE message error:",t),o.status(500).json({jsonrpc:"2.0",error:{code:-32603,message:t instanceof Error?t.message:"Internal error"},id:e.body.id})}}),this.app.post("/rpc",async(e,o)=>{try{let t=e.body;if(y.debug("Received RPC message:",t),!this.mcpProxy){o.status(503).json({jsonrpc:"2.0",error:{code:-32603,message:"MCP proxy not running"},id:t.id});return}let r=await this.forwardToProxy(t);o.json(r)}catch(t){y.error("RPC error:",t),o.status(500).json({jsonrpc:"2.0",error:{code:-32603,message:t instanceof Error?t.message:"Internal error"},id:e.body.id})}}),this.app.get("/health",(e,o)=>{o.json({status:"ok",mode:"mcp-server",proxy:this.mcpProxy?"running":"stopped",clients:this.clients.size})})}async forwardToProxy(e){return new Promise((o,t)=>{if(!this.mcpProxy||!this.mcpProxy.stdin||!this.mcpProxy.stdout){t(new Error("MCP proxy not available"));return}let r,i=g(c=>{try{let a=c.toString().split(`
8
- `).filter(f=>f.trim());for(let f of a)try{let d=JSON.parse(f);if(y.debug(`Received response from proxy: ${f}`),d.id===e.id||e.method==="notifications/initialized"&&!d.id){r&&clearTimeout(r),this.mcpProxy?.stdout?.removeListener("data",i),o(d);return}}catch{y.debug(`Non-JSON line from proxy: ${f}`)}}catch(a){r&&clearTimeout(r),t(a)}},"messageHandler");this.mcpProxy.stdout.on("data",i),y.info(`Forwarding message to proxy: ${JSON.stringify(e)}`),this.mcpProxy.stdin.write(`${JSON.stringify(e)}
9
- `),r=setTimeout(()=>{this.mcpProxy?.stdout?.removeListener("data",i),y.warn(`Request timeout for message id: ${e.id}, method: ${e.method} - This may be normal if the response was already sent via SSE`),o({jsonrpc:"2.0",id:e.id,result:{_timeout:!0,message:"Response may have been sent via SSE"}})},3e4)})}sendToClient(e,o){try{let t=`event: message
7
+ `),o.status(202).send();else{let i=await this.forwardToProxy(r),c=this.clients.get(t);c&&this.sendToClient(c,i),o.status(202).send()}}catch(t){y.error("SSE message error:",t),o.status(500).json({jsonrpc:"2.0",error:{code:-32603,message:t instanceof Error?t.message:"Internal error"},id:e.body.id})}}),this.app.post("/rpc",async(e,o)=>{try{let t=e.body;if(y.debug("Received RPC message:",t),!this.mcpProxy){o.status(503).json({jsonrpc:"2.0",error:{code:-32603,message:"MCP proxy not running"},id:t.id});return}let r=await this.forwardToProxy(t);o.json(r)}catch(t){y.error("RPC error:",t),o.status(500).json({jsonrpc:"2.0",error:{code:-32603,message:t instanceof Error?t.message:"Internal error"},id:e.body.id})}}),this.app.get("/health",(e,o)=>{o.json({status:"ok",mode:"mcp-server",proxy:this.mcpProxy?"running":"stopped",clients:this.clients.size})})}responseBuffer="";pendingRequests=new Map;async forwardToProxy(e){return new Promise((o,t)=>{if(!this.mcpProxy||!this.mcpProxy.stdin||!this.mcpProxy.stdout){t(new Error("MCP proxy not available"));return}let r=setTimeout(()=>{this.pendingRequests.delete(e.id),y.warn(`Request timeout for message id: ${e.id}, method: ${e.method} - This may be normal if the response was already sent via SSE`),o({jsonrpc:"2.0",id:e.id,result:{_timeout:!0,message:"Response may have been sent via SSE"}})},3e4);this.pendingRequests.set(e.id,{resolve:o,reject:t,timeoutId:r}),y.info(`Forwarding message to proxy: ${JSON.stringify(e)}`),this.mcpProxy.stdin.write(`${JSON.stringify(e)}
8
+ `)})}handleProxyResponse(e){try{this.responseBuffer+=e.toString();let o=this.responseBuffer.split(`
9
+ `);this.responseBuffer=o.pop()||"";for(let t of o)if(t.trim())try{let r=JSON.parse(t);if(y.debug(`Received response from proxy: ${t.substring(0,200)}...`),r.id!==void 0&&this.pendingRequests.has(r.id)){let i=this.pendingRequests.get(r.id);clearTimeout(i.timeoutId),this.pendingRequests.delete(r.id),i.resolve(r)}}catch{y.debug(`Non-JSON line from proxy: ${t}`)}}catch(o){y.error("Error handling proxy response:",o)}}sendToClient(e,o){try{let t=`event: message
10
10
  data: ${JSON.stringify(o)}
11
11
 
12
- `;e.response.write(t)}catch(t){y.error(`Failed to send to client ${e.id}:`,t),this.clients.delete(e.sessionId)}}broadcastToClients(e){for(let o of this.clients.values())this.sendToClient(o,e)}async start(){try{await this.startMCPProxy(),this.server=this.app.listen(this.port,()=>{y.info(`MCP Server listening on port ${this.port}`),y.info(`SSE endpoint: http://localhost:${this.port}/sse`),y.info(`Messages endpoint: http://localhost:${this.port}/messages`),y.info(`RPC endpoint: http://localhost:${this.port}/rpc`)}),this.emit("started")}catch(e){throw y.error("Failed to start MCP server:",e),e}}async startMCPProxy(){let e=ie(import.meta.url),o=j.dirname(e),t=null;for(let r=0;r<5;r++){let i=j.join(o,"mcpServerProxy.js"),c=await import("fs");if(c.existsSync(i)){t=i;break}let a=j.join(o,"dist","mcpServerProxy.js");if(c.existsSync(a)){t=a;break}o=j.dirname(o)}if(!t)throw new Error("Could not find mcpServerProxy.js in the project structure");y.info(`Starting MCP proxy from: ${t}`),this.mcpProxy=ze("node",[t],{stdio:["pipe","pipe","pipe"],env:{...process.env,MCP_SERVER_MODE:"true",XIAOZHI_CONFIG_DIR:process.env.XIAOZHI_CONFIG_DIR||process.cwd()}}),this.mcpProxy.on("error",r=>{y.error("MCP proxy error:",r)}),this.mcpProxy.on("exit",(r,i)=>{y.warn(`MCP proxy exited with code ${r}, signal ${i}`),this.mcpProxy=null}),this.mcpProxy.stderr&&this.mcpProxy.stderr.on("data",r=>{let i=r.toString().trim();i.includes("[ERROR]")||i.includes("Error:")||i.includes("Failed")?y.error("MCP proxy stderr:",i):y.info("MCP proxy output:",i)}),await new Promise((r,i)=>{let c=setTimeout(()=>{i(new Error("MCP proxy startup timeout"))},1e4),a=g(f=>{let d=f.toString();(d.includes("MCP proxy ready")||d.includes("started"))&&(clearTimeout(c),this.mcpProxy?.stdout?.removeListener("data",a),r())},"dataHandler");this.mcpProxy?.stdout?.on("data",a)}),y.info("MCP proxy started successfully")}async stop(){y.info("Stopping MCP server...");for(let e of this.clients.values())try{e.response.end()}catch{}this.clients.clear(),this.server&&(await new Promise(e=>{this.server.close(()=>e())}),this.server=null),this.mcpProxy&&(this.mcpProxy.kill("SIGTERM"),await new Promise(e=>{this.mcpProxy.on("exit",()=>e()),setTimeout(()=>{this.mcpProxy?.kill("SIGKILL"),e()},5e3)}),this.mcpProxy=null),this.emit("stopped"),y.info("MCP server stopped")}}});import{spawn as W}from"child_process";import u from"fs";import m from"path";import{fileURLToPath as I}from"url";import s from"chalk";import{Command as Ae}from"commander";import b from"ora";import be from"omelette";import{copyFileSync as he,existsSync as Z,readFileSync as ue,writeFileSync as ye}from"fs";import{dirname as Ce,resolve as B}from"path";import{fileURLToPath as ve}from"url";var Se=Ce(ve(import.meta.url)),k={heartbeatInterval:3e4,heartbeatTimeout:1e4,reconnectInterval:5e3},A=class n{static{g(this,"ConfigManager")}static instance;defaultConfigPath;config=null;constructor(){this.defaultConfigPath=B(Se,"xiaozhi.config.default.json")}getConfigFilePath(){let e=process.env.XIAOZHI_CONFIG_DIR||process.cwd();return B(e,"xiaozhi.config.json")}static getInstance(){return n.instance||(n.instance=new n),n.instance}configExists(){let e=this.getConfigFilePath();return Z(e)}initConfig(){if(!Z(this.defaultConfigPath))throw new Error("\u9ED8\u8BA4\u914D\u7F6E\u6587\u4EF6 xiaozhi.config.default.json \u4E0D\u5B58\u5728");if(this.configExists())throw new Error("\u914D\u7F6E\u6587\u4EF6 xiaozhi.config.json \u5DF2\u5B58\u5728\uFF0C\u65E0\u9700\u91CD\u590D\u521D\u59CB\u5316");let e=this.getConfigFilePath();he(this.defaultConfigPath,e),this.config=null}loadConfig(){if(!this.configExists())throw new Error("\u914D\u7F6E\u6587\u4EF6 xiaozhi.config.json \u4E0D\u5B58\u5728\uFF0C\u8BF7\u5148\u8FD0\u884C xiaozhi init \u521D\u59CB\u5316\u914D\u7F6E");try{let e=this.getConfigFilePath(),o=ue(e,"utf8"),t=JSON.parse(o);return this.validateConfig(t),t}catch(e){throw e instanceof SyntaxError?new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF: ${e.message}`):e}}validateConfig(e){if(!e||typeof e!="object")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1A\u6839\u5BF9\u8C61\u65E0\u6548");let o=e;if(o.mcpEndpoint===void 0||o.mcpEndpoint===null)throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u5B57\u6BB5\u65E0\u6548");if(typeof o.mcpEndpoint!="string")if(Array.isArray(o.mcpEndpoint)){if(o.mcpEndpoint.length===0)throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u6570\u7EC4\u4E0D\u80FD\u4E3A\u7A7A");for(let t of o.mcpEndpoint)if(typeof t!="string"||t.trim()==="")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u6570\u7EC4\u4E2D\u7684\u6BCF\u4E2A\u5143\u7D20\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32")}else throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u5FC5\u987B\u662F\u5B57\u7B26\u4E32\u6216\u5B57\u7B26\u4E32\u6570\u7EC4");if(!o.mcpServers||typeof o.mcpServers!="object")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers \u5B57\u6BB5\u65E0\u6548");for(let[t,r]of Object.entries(o.mcpServers)){if(!r||typeof r!="object")throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers.${t} \u65E0\u6548`);let i=r;if(i.url&&typeof i.url=="string"){if(i.type&&i.type!=="sse"&&i.type!=="streamable-http")throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers.${t}.type \u5FC5\u987B\u662F "sse" \u6216 "streamable-http"`)}else{if(!i.command||typeof i.command!="string")throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers.${t}.command \u65E0\u6548`);if(!Array.isArray(i.args))throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers.${t}.args \u5FC5\u987B\u662F\u6570\u7EC4`);if(i.env&&typeof i.env!="object")throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers.${t}.env \u5FC5\u987B\u662F\u5BF9\u8C61`)}}}getConfig(){return this.config||(this.config=this.loadConfig()),JSON.parse(JSON.stringify(this.config))}getMcpEndpoint(){let e=this.getConfig();return Array.isArray(e.mcpEndpoint)?e.mcpEndpoint[0]||"":e.mcpEndpoint}getMcpEndpoints(){let e=this.getConfig();return Array.isArray(e.mcpEndpoint)?[...e.mcpEndpoint]:e.mcpEndpoint?[e.mcpEndpoint]:[]}getMcpServers(){return this.getConfig().mcpServers}getMcpServerConfig(){return this.getConfig().mcpServerConfig||{}}getServerToolsConfig(e){return this.getMcpServerConfig()[e]?.tools||{}}isToolEnabled(e,o){return this.getServerToolsConfig(e)[o]?.enable!==!1}updateMcpEndpoint(e){if(Array.isArray(e)){if(e.length===0)throw new Error("MCP \u7AEF\u70B9\u6570\u7EC4\u4E0D\u80FD\u4E3A\u7A7A");for(let r of e)if(!r||typeof r!="string")throw new Error("MCP \u7AEF\u70B9\u6570\u7EC4\u4E2D\u7684\u6BCF\u4E2A\u5143\u7D20\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32")}else if(!e||typeof e!="string")throw new Error("MCP \u7AEF\u70B9\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let t={...this.getConfig(),mcpEndpoint:e};this.saveConfig(t)}addMcpEndpoint(e){if(!e||typeof e!="string")throw new Error("MCP \u7AEF\u70B9\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let o=this.getConfig(),t=this.getMcpEndpoints();if(t.includes(e))throw new Error(`MCP \u7AEF\u70B9 ${e} \u5DF2\u5B58\u5728`);let r=[...t,e],i={...o,mcpEndpoint:r};this.saveConfig(i)}removeMcpEndpoint(e){if(!e||typeof e!="string")throw new Error("MCP \u7AEF\u70B9\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let o=this.getConfig(),t=this.getMcpEndpoints();if(t.indexOf(e)===-1)throw new Error(`MCP \u7AEF\u70B9 ${e} \u4E0D\u5B58\u5728`);if(t.length===1)throw new Error("\u4E0D\u80FD\u5220\u9664\u6700\u540E\u4E00\u4E2A MCP \u7AEF\u70B9");let i=t.filter(a=>a!==e),c={...o,mcpEndpoint:i};this.saveConfig(c)}updateMcpServer(e,o){if(!e||typeof e!="string")throw new Error("\u670D\u52A1\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");if("type"in o&&o.type==="sse"){if(!o.url||typeof o.url!="string")throw new Error("SSE \u670D\u52A1\u914D\u7F6E\u7684 url \u5B57\u6BB5\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32")}else{let i=o;if(!i.command||typeof i.command!="string")throw new Error("\u670D\u52A1\u914D\u7F6E\u7684 command \u5B57\u6BB5\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");if(!Array.isArray(i.args))throw new Error("\u670D\u52A1\u914D\u7F6E\u7684 args \u5B57\u6BB5\u5FC5\u987B\u662F\u6570\u7EC4");if(i.env&&typeof i.env!="object")throw new Error("\u670D\u52A1\u914D\u7F6E\u7684 env \u5B57\u6BB5\u5FC5\u987B\u662F\u5BF9\u8C61")}let t=this.getConfig(),r={...t,mcpServers:{...t.mcpServers,[e]:o}};this.saveConfig(r)}removeMcpServer(e){if(!e||typeof e!="string")throw new Error("\u670D\u52A1\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let o=this.getConfig();if(!o.mcpServers[e])throw new Error(`\u670D\u52A1 ${e} \u4E0D\u5B58\u5728`);let t={...o.mcpServers};delete t[e];let r={...o,mcpServers:t};this.saveConfig(r)}updateServerToolsConfig(e,o){let r={...this.getConfig()};r.mcpServerConfig||(r.mcpServerConfig={}),r.mcpServerConfig[e]={tools:o},this.saveConfig(r)}setToolEnabled(e,o,t,r){let c={...this.getConfig()};c.mcpServerConfig||(c.mcpServerConfig={}),c.mcpServerConfig[e]||(c.mcpServerConfig[e]={tools:{}}),c.mcpServerConfig[e].tools[o]={enable:t,...r&&{description:r}},this.saveConfig(c)}saveConfig(e){try{this.validateConfig(e);let o=this.getConfigFilePath(),t=JSON.stringify(e,null,2);ye(o,t,"utf8"),this.config=e}catch(o){throw new Error(`\u4FDD\u5B58\u914D\u7F6E\u5931\u8D25: ${o instanceof Error?o.message:String(o)}`)}}reloadConfig(){this.config=null}getConfigPath(){return this.getConfigFilePath()}getDefaultConfigPath(){return this.defaultConfigPath}getConnectionConfig(){let o=this.getConfig().connection||{};return{heartbeatInterval:o.heartbeatInterval??k.heartbeatInterval,heartbeatTimeout:o.heartbeatTimeout??k.heartbeatTimeout,reconnectInterval:o.reconnectInterval??k.reconnectInterval}}getHeartbeatInterval(){return this.getConnectionConfig().heartbeatInterval}getHeartbeatTimeout(){return this.getConnectionConfig().heartbeatTimeout}getReconnectInterval(){return this.getConnectionConfig().reconnectInterval}updateConnectionConfig(e){let o=this.getConfig(),r={...o.connection||{},...e},i={...o,connection:r};this.saveConfig(i)}setHeartbeatInterval(e){if(e<=0)throw new Error("\u5FC3\u8DF3\u68C0\u6D4B\u95F4\u9694\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({heartbeatInterval:e})}setHeartbeatTimeout(e){if(e<=0)throw new Error("\u5FC3\u8DF3\u8D85\u65F6\u65F6\u95F4\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({heartbeatTimeout:e})}setReconnectInterval(e){if(e<=0)throw new Error("\u91CD\u8FDE\u95F4\u9694\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({reconnectInterval:e})}getModelScopeConfig(){return this.getConfig().modelscope||{}}getModelScopeApiKey(){return this.getModelScopeConfig().apiKey||process.env.MODELSCOPE_API_TOKEN}updateModelScopeConfig(e){let o=this.getConfig(),r={...o.modelscope||{},...e},i={...o,modelscope:r};this.saveConfig(i)}setModelScopeApiKey(e){if(!e||typeof e!="string")throw new Error("API Key \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");this.updateModelScopeConfig({apiKey:e})}getWebUIConfig(){return this.getConfig().webUI||{}}getWebUIPort(){return this.getWebUIConfig().port??9999}updateWebUIConfig(e){let o=this.getConfig(),r={...o.webUI||{},...e},i={...o,webUI:r};this.saveConfig(i)}setWebUIPort(e){if(!Number.isInteger(e)||e<=0||e>65535)throw new Error("\u7AEF\u53E3\u53F7\u5FC5\u987B\u662F 1-65535 \u4E4B\u95F4\u7684\u6574\u6570");this.updateWebUIConfig({port:e})}},l=A.getInstance();function we(){try{if(!l.configExists())return[];let n=l.getMcpServers();return Object.keys(n)}catch{return[]}}g(we,"getMcpServerNames");function Pe(n){try{if(!l.configExists())return[];let e=l.getServerToolsConfig(n);return Object.keys(e)}catch{return[]}}g(Pe,"getServerToolNames");function V(){let n=be("xiaozhi <command>");if(n.on("command",({reply:e})=>{e(["create","init","config","start","stop","status","attach","restart","mcp","completion"])}),n.on("complete",(e,{line:o,before:t,reply:r})=>{process.env.XIAOZHI_DEBUG_COMPLETION&&console.error(`Debug completion - line: "${o}", before: "${t}", fragment: "${e}"`);let i=o.trim().split(/\s+/),a=o!==o.trim()?i.length:i.length-1;if(i[1]==="mcp"){let f=i[2];if(a===2){let d=["list","server","tool"],h=i[2]||"",C=d.filter(v=>v.startsWith(h));r(C);return}if(a===3){switch(f){case"list":{let d=["--tools"],h=i[3]||"",C=d.filter(v=>v.startsWith(h));r(C);break}case"server":case"tool":{let d=we(),h=i[3]||"",C=d.filter(v=>v.startsWith(h));r(C);break}default:r([])}return}if(a===4&&f==="tool"){let d=i[3],h=Pe(d),C=i[4]||"",v=h.filter(E=>E.startsWith(C));r(v);return}if(a===5&&f==="tool"){let d=["enable","disable"],h=i[5]||"",C=d.filter(v=>v.startsWith(h));r(C);return}}if(a===2){switch(i[1]){case"create":r(["--template","-t"]);break;case"start":case"restart":r(["--daemon","-d"]);break;case"completion":r(["install","uninstall"]);break;default:r([])}return}r([])}),process.argv.includes("--completion")){try{console.log(n.setupShellInitFile())}catch(e){console.error("\u751F\u6210\u81EA\u52A8\u8865\u5168\u811A\u672C\u65F6\u51FA\u9519:",e)}process.exit(0)}process.argv.includes("--completion-fish")&&(console.log(n.setupShellInitFile("fish")),process.exit(0)),process.argv.includes("--compzsh")||process.argv.includes("--compbash"),n.init()}g(V,"setupAutoCompletion");function K(){console.log("\u{1F680} xiaozhi \u81EA\u52A8\u8865\u5168\u8BBE\u7F6E"),console.log(),console.log("\u8981\u542F\u7528\u81EA\u52A8\u8865\u5168\uFF0C\u8BF7\u6839\u636E\u4F60\u7684shell\u6267\u884C\u4EE5\u4E0B\u547D\u4EE4\uFF1A"),console.log(),console.log("\u{1F4DD} Zsh (\u63A8\u8350):"),console.log(" xiaozhi --completion >> ~/.xiaozhi-completion.zsh"),console.log(" echo 'source ~/.xiaozhi-completion.zsh' >> ~/.zshrc"),console.log(" source ~/.zshrc"),console.log(),console.log("\u{1F4DD} Bash:"),console.log(" xiaozhi --completion >> ~/.xiaozhi-completion.bash"),console.log(" echo 'source ~/.xiaozhi-completion.bash' >> ~/.bash_profile"),console.log(" source ~/.bash_profile"),console.log(),console.log("\u{1F4DD} Fish:"),console.log(" xiaozhi --completion-fish >> ~/.config/fish/completions/xiaozhi.fish"),console.log(),console.log("\u2728 \u8BBE\u7F6E\u5B8C\u6210\u540E\uFF0C\u4F60\u5C31\u53EF\u4EE5\u4F7F\u7528 Tab \u952E\u8FDB\u884C\u81EA\u52A8\u8865\u5168\u4E86\uFF01"),console.log(),console.log("\u{1F4A1} \u793A\u4F8B:"),console.log(" xiaozhi m<Tab> # \u2192 mcp"),console.log(" xiaozhi mcp l<Tab> # \u2192 list"),console.log(" xiaozhi mcp tool <Tab> # \u2192 \u663E\u793A\u6240\u6709\u670D\u52A1\u5668\u540D\u79F0")}g(K,"showCompletionHelp");R();import p from"chalk";import Y from"cli-table3";import F from"ora";function Q(n){let e=0;for(let o of n)/[\u4e00-\u9fff\u3400-\u4dbf\uff00-\uffef]/.test(o)?e+=2:e+=1;return e}g(Q,"getDisplayWidth");function q(n,e){if(Q(n)<=e)return n;if(e<=3)return"";let o="",t=0,r=!1;for(let i of n){let c=/[\u4e00-\u9fff\u3400-\u4dbf\uff00-\uffef]/.test(i)?2:1;if(t+c>e-3){if(!r)return"";o+="...";break}o+=i,t+=c,r=!0}return o}g(q,"truncateToWidth");async function ee(n={}){let e=F("\u83B7\u53D6 MCP \u670D\u52A1\u5217\u8868...").start();try{let o=l.getMcpServers(),t=Object.keys(o);if(t.length===0){e.warn("\u672A\u914D\u7F6E\u4EFB\u4F55 MCP \u670D\u52A1"),console.log(p.yellow("\u{1F4A1} \u63D0\u793A: \u4F7F\u7528 'xiaozhi config' \u547D\u4EE4\u914D\u7F6E MCP \u670D\u52A1"));return}if(e.succeed(`\u627E\u5230 ${t.length} \u4E2A MCP \u670D\u52A1`),n.tools){console.log(),console.log(p.bold("MCP \u670D\u52A1\u5DE5\u5177\u5217\u8868:")),console.log();let r=8,i=[];for(let a of t){let f=l.getServerToolsConfig(a),d=Object.keys(f);i.push(...d)}for(let a of i){let f=Q(a);f>r&&(r=f)}r=Math.max(10,Math.min(r+2,30));let c=new Y({head:[p.bold("MCP"),p.bold("\u5DE5\u5177\u540D\u79F0"),p.bold("\u72B6\u6001"),p.bold("\u63CF\u8FF0")],colWidths:[15,r,8,40],wordWrap:!0,style:{head:[],border:[]}});for(let a of t){let f=l.getServerToolsConfig(a),d=Object.keys(f);if(d.length===0)c.push([p.gray(a),p.gray("-"),p.gray("-"),p.gray("\u6682\u672A\u8BC6\u522B\u5230\u76F8\u5173\u5DE5\u5177")]);else{c.length>0&&c.push([{colSpan:4,content:""}]);for(let h of d){let C=f[h],v=C.enable?p.green("\u542F\u7528"):p.red("\u7981\u7528"),E=q(C.description||"",32);c.push([a,h,v,E])}}}console.log(c.toString())}else{console.log(),console.log(p.bold("MCP \u670D\u52A1\u5217\u8868:")),console.log();for(let r of t){let i=o[r],c=l.getServerToolsConfig(r),a=Object.keys(c).length,f=Object.values(c).filter(d=>d.enable!==!1).length;console.log(`${p.cyan("\u2022")} ${p.bold(r)}`),"url"in i?("type"in i&&i.type==="sse"?console.log(` \u7C7B\u578B: ${p.gray("SSE")}`):console.log(` \u7C7B\u578B: ${p.gray("Streamable HTTP")}`),console.log(` URL: ${p.gray(i.url)}`)):console.log(` \u547D\u4EE4: ${p.gray(i.command)} ${p.gray(i.args.join(" "))}`),a>0?console.log(` \u5DE5\u5177: ${p.green(f)} \u542F\u7528 / ${p.yellow(a)} \u603B\u8BA1`):console.log(` \u5DE5\u5177: ${p.gray("\u672A\u626B\u63CF (\u8BF7\u5148\u542F\u52A8\u670D\u52A1)")}`),console.log()}}console.log(p.gray("\u{1F4A1} \u63D0\u793A:")),console.log(p.gray(" - \u4F7F\u7528 'xiaozhi mcp list --tools' \u67E5\u770B\u6240\u6709\u5DE5\u5177")),console.log(p.gray(" - \u4F7F\u7528 'xiaozhi mcp <\u670D\u52A1\u540D> list' \u67E5\u770B\u6307\u5B9A\u670D\u52A1\u7684\u5DE5\u5177")),console.log(p.gray(" - \u4F7F\u7528 'xiaozhi mcp <\u670D\u52A1\u540D> <\u5DE5\u5177\u540D> enable/disable' \u542F\u7528/\u7981\u7528\u5DE5\u5177"))}catch(o){e.fail("\u83B7\u53D6 MCP \u670D\u52A1\u5217\u8868\u5931\u8D25"),console.error(p.red(`\u9519\u8BEF: ${o instanceof Error?o.message:String(o)}`)),process.exit(1)}}g(ee,"listMcpServers");async function oe(n){let e=F(`\u83B7\u53D6 ${n} \u670D\u52A1\u7684\u5DE5\u5177\u5217\u8868...`).start();try{if(!l.getMcpServers()[n]){e.fail(`\u670D\u52A1 '${n}' \u4E0D\u5B58\u5728`),console.log(p.yellow("\u{1F4A1} \u63D0\u793A: \u4F7F\u7528 'xiaozhi mcp list' \u67E5\u770B\u6240\u6709\u53EF\u7528\u670D\u52A1"));return}let t=l.getServerToolsConfig(n),r=Object.keys(t);if(r.length===0){e.warn(`\u670D\u52A1 '${n}' \u6682\u65E0\u5DE5\u5177\u4FE1\u606F`),console.log(p.yellow("\u{1F4A1} \u63D0\u793A: \u8BF7\u5148\u542F\u52A8\u670D\u52A1\u4EE5\u626B\u63CF\u5DE5\u5177\u5217\u8868"));return}e.succeed(`\u670D\u52A1 '${n}' \u5171\u6709 ${r.length} \u4E2A\u5DE5\u5177`),console.log(),console.log(p.bold(`${n} \u670D\u52A1\u5DE5\u5177\u5217\u8868:`)),console.log();let i=new Y({head:[p.bold("\u5DE5\u5177\u540D\u79F0"),p.bold("\u72B6\u6001"),p.bold("\u63CF\u8FF0")],colWidths:[30,8,50],wordWrap:!0,style:{head:[],border:[]}});for(let c of r){let a=t[c],f=a.enable?p.green("\u542F\u7528"):p.red("\u7981\u7528"),d=q(a.description||"",40);i.push([c,f,d])}console.log(i.toString()),console.log(),console.log(p.gray("\u{1F4A1} \u63D0\u793A:")),console.log(p.gray(` - \u4F7F\u7528 'xiaozhi mcp ${n} <\u5DE5\u5177\u540D> enable' \u542F\u7528\u5DE5\u5177`)),console.log(p.gray(` - \u4F7F\u7528 'xiaozhi mcp ${n} <\u5DE5\u5177\u540D> disable' \u7981\u7528\u5DE5\u5177`))}catch(o){e.fail("\u83B7\u53D6\u5DE5\u5177\u5217\u8868\u5931\u8D25"),console.error(p.red(`\u9519\u8BEF: ${o instanceof Error?o.message:String(o)}`)),process.exit(1)}}g(oe,"listServerTools");async function te(n,e,o){let t=o?"\u542F\u7528":"\u7981\u7528",r=F(`${t}\u5DE5\u5177 ${n}/${e}...`).start();try{if(!l.getMcpServers()[n]){r.fail(`\u670D\u52A1 '${n}' \u4E0D\u5B58\u5728`),console.log(p.yellow("\u{1F4A1} \u63D0\u793A: \u4F7F\u7528 'xiaozhi mcp list' \u67E5\u770B\u6240\u6709\u53EF\u7528\u670D\u52A1"));return}let c=l.getServerToolsConfig(n);if(!c[e]){r.fail(`\u5DE5\u5177 '${e}' \u5728\u670D\u52A1 '${n}' \u4E2D\u4E0D\u5B58\u5728`),console.log(p.yellow(`\u{1F4A1} \u63D0\u793A: \u4F7F\u7528 'xiaozhi mcp ${n} list' \u67E5\u770B\u8BE5\u670D\u52A1\u7684\u6240\u6709\u5DE5\u5177`));return}l.setToolEnabled(n,e,o,c[e].description),r.succeed(`\u6210\u529F${t}\u5DE5\u5177 ${p.cyan(n)}/${p.cyan(e)}`),console.log(),console.log(p.gray("\u{1F4A1} \u63D0\u793A: \u5DE5\u5177\u72B6\u6001\u66F4\u6539\u5C06\u5728\u4E0B\u6B21\u542F\u52A8\u670D\u52A1\u65F6\u751F\u6548"))}catch(i){r.fail(`${t}\u5DE5\u5177\u5931\u8D25`),console.error(p.red(`\u9519\u8BEF: ${i instanceof Error?i.message:String(i)}`)),process.exit(1)}}g(te,"setToolEnabled");import{spawn as ne}from"child_process";import{existsSync as U}from"fs";import{readFile as re}from"fs/promises";import{createServer as Me}from"http";import{dirname as $e,join as P}from"path";import{parse as Te}from"url";import{fileURLToPath as je}from"url";import{WebSocketServer as Oe}from"ws";R();var T=class{static{g(this,"WebServer")}httpServer;wss;logger;port;clientInfo={status:"disconnected",mcpEndpoint:"",activeMCPServers:[]};heartbeatTimeout;HEARTBEAT_TIMEOUT=35e3;constructor(e){if(e===void 0)try{this.port=l.getWebUIPort()}catch{this.port=9999}else this.port=e;this.logger=new $,this.httpServer=Me((o,t)=>{this.handleHttpRequest(o,t)}),this.wss=new Oe({server:this.httpServer}),this.setupWebSocket()}async handleHttpRequest(e,o){let{pathname:t}=Te(e.url||"",!0);if(o.setHeader("Access-Control-Allow-Origin","*"),o.setHeader("Access-Control-Allow-Methods","GET, POST, PUT, OPTIONS"),o.setHeader("Access-Control-Allow-Headers","Content-Type"),e.method==="OPTIONS"){o.writeHead(200),o.end();return}try{if(e.method==="GET"&&!t?.startsWith("/api/")){await this.serveStaticFile(t||"/",o);return}if(t==="/api/config"&&e.method==="GET"){let r=l.getConfig();o.writeHead(200,{"Content-Type":"application/json"}),o.end(JSON.stringify(r))}else if(t==="/api/config"&&e.method==="PUT"){let r="";e.on("data",i=>{r+=i.toString()}),e.on("end",async()=>{try{let i=JSON.parse(r);this.updateConfig(i),this.broadcastConfigUpdate(i),o.writeHead(200,{"Content-Type":"application/json"}),o.end(JSON.stringify({success:!0})),this.logger.info("\u914D\u7F6E\u5DF2\u66F4\u65B0")}catch(i){o.writeHead(400,{"Content-Type":"application/json"}),o.end(JSON.stringify({error:i instanceof Error?i.message:String(i)}))}})}else t==="/api/status"&&e.method==="GET"?(o.writeHead(200,{"Content-Type":"application/json"}),o.end(JSON.stringify(this.clientInfo))):(o.writeHead(404),o.end("Not Found"))}catch(r){this.logger.error("HTTP request error:",r),o.writeHead(500,{"Content-Type":"application/json"}),o.end(JSON.stringify({error:"Internal Server Error"}))}}async serveStaticFile(e,o){try{let t=$e(je(import.meta.url)),i=[P(t,"..","web","dist"),P(t,"..","web"),P(process.cwd(),"web","dist"),P(process.cwd(),"web")].find(v=>U(v));if(!i){o.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),o.end(`
12
+ `;e.response.write(t)}catch(t){y.error(`Failed to send to client ${e.id}:`,t),this.clients.delete(e.sessionId)}}broadcastToClients(e){for(let o of this.clients.values())this.sendToClient(o,e)}async start(){try{await this.startMCPProxy(),this.server=this.app.listen(this.port,()=>{y.info(`MCP Server listening on port ${this.port}`),y.info(`SSE endpoint: http://localhost:${this.port}/sse`),y.info(`Messages endpoint: http://localhost:${this.port}/messages`),y.info(`RPC endpoint: http://localhost:${this.port}/rpc`)}),this.emit("started")}catch(e){throw y.error("Failed to start MCP server:",e),e}}async startMCPProxy(){let e=ie(import.meta.url),o=j.dirname(e),t=null;for(let r=0;r<5;r++){let i=j.join(o,"mcpServerProxy.js"),c=await import("fs");if(c.existsSync(i)){t=i;break}let a=j.join(o,"dist","mcpServerProxy.js");if(c.existsSync(a)){t=a;break}o=j.dirname(o)}if(!t)throw new Error("Could not find mcpServerProxy.js in the project structure");y.info(`Starting MCP proxy from: ${t}`),this.mcpProxy=Re("node",[t],{stdio:["pipe","pipe","pipe"],env:{...process.env,MCP_SERVER_MODE:"true",XIAOZHI_CONFIG_DIR:process.env.XIAOZHI_CONFIG_DIR||process.cwd()}}),this.mcpProxy.on("error",r=>{y.error("MCP proxy error:",r)}),this.mcpProxy.on("exit",(r,i)=>{y.warn(`MCP proxy exited with code ${r}, signal ${i}`),this.mcpProxy=null}),this.mcpProxy.stderr&&this.mcpProxy.stderr.on("data",r=>{let i=r.toString().trim();i.includes("[ERROR]")||i.includes("Error:")||i.includes("Failed")?y.error("MCP proxy stderr:",i):y.info("MCP proxy output:",i)}),this.mcpProxy.stdout&&this.mcpProxy.stdout.on("data",r=>{this.handleProxyResponse(r)}),await new Promise((r,i)=>{let c=setTimeout(()=>{i(new Error("MCP proxy startup timeout"))},1e4),a=g(d=>{let m=d.toString();(m.includes("MCP proxy ready")||m.includes("started"))&&(clearTimeout(c),this.mcpProxy?.stdout?.removeListener("data",a),r())},"dataHandler");this.mcpProxy?.stdout?.on("data",a)}),y.info("MCP proxy started successfully")}async stop(){y.info("Stopping MCP server...");for(let e of this.clients.values())try{e.response.end()}catch{}this.clients.clear(),this.server&&(await new Promise(e=>{this.server.close(()=>e())}),this.server=null),this.mcpProxy&&(this.mcpProxy.kill("SIGTERM"),await new Promise(e=>{this.mcpProxy.on("exit",()=>e()),setTimeout(()=>{this.mcpProxy?.kill("SIGKILL"),e()},5e3)}),this.mcpProxy=null),this.emit("stopped"),y.info("MCP server stopped")}}});import{spawn as W}from"child_process";import u from"fs";import f from"path";import{fileURLToPath as I}from"url";import s from"chalk";import{Command as Ae}from"commander";import b from"ora";import be from"omelette";import{copyFileSync as he,existsSync as Z,readFileSync as ue,writeFileSync as ye}from"fs";import{dirname as Ce,resolve as B}from"path";import{fileURLToPath as ve}from"url";var Se=Ce(ve(import.meta.url)),k={heartbeatInterval:3e4,heartbeatTimeout:1e4,reconnectInterval:5e3},A=class n{static{g(this,"ConfigManager")}static instance;defaultConfigPath;config=null;constructor(){this.defaultConfigPath=B(Se,"xiaozhi.config.default.json")}getConfigFilePath(){let e=process.env.XIAOZHI_CONFIG_DIR||process.cwd();return B(e,"xiaozhi.config.json")}static getInstance(){return n.instance||(n.instance=new n),n.instance}configExists(){let e=this.getConfigFilePath();return Z(e)}initConfig(){if(!Z(this.defaultConfigPath))throw new Error("\u9ED8\u8BA4\u914D\u7F6E\u6587\u4EF6 xiaozhi.config.default.json \u4E0D\u5B58\u5728");if(this.configExists())throw new Error("\u914D\u7F6E\u6587\u4EF6 xiaozhi.config.json \u5DF2\u5B58\u5728\uFF0C\u65E0\u9700\u91CD\u590D\u521D\u59CB\u5316");let e=this.getConfigFilePath();he(this.defaultConfigPath,e),this.config=null}loadConfig(){if(!this.configExists())throw new Error("\u914D\u7F6E\u6587\u4EF6 xiaozhi.config.json \u4E0D\u5B58\u5728\uFF0C\u8BF7\u5148\u8FD0\u884C xiaozhi init \u521D\u59CB\u5316\u914D\u7F6E");try{let e=this.getConfigFilePath(),o=ue(e,"utf8"),t=JSON.parse(o);return this.validateConfig(t),t}catch(e){throw e instanceof SyntaxError?new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF: ${e.message}`):e}}validateConfig(e){if(!e||typeof e!="object")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1A\u6839\u5BF9\u8C61\u65E0\u6548");let o=e;if(o.mcpEndpoint===void 0||o.mcpEndpoint===null)throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u5B57\u6BB5\u65E0\u6548");if(typeof o.mcpEndpoint!="string")if(Array.isArray(o.mcpEndpoint)){if(o.mcpEndpoint.length===0)throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u6570\u7EC4\u4E0D\u80FD\u4E3A\u7A7A");for(let t of o.mcpEndpoint)if(typeof t!="string"||t.trim()==="")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u6570\u7EC4\u4E2D\u7684\u6BCF\u4E2A\u5143\u7D20\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32")}else throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u5FC5\u987B\u662F\u5B57\u7B26\u4E32\u6216\u5B57\u7B26\u4E32\u6570\u7EC4");if(!o.mcpServers||typeof o.mcpServers!="object")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers \u5B57\u6BB5\u65E0\u6548");for(let[t,r]of Object.entries(o.mcpServers)){if(!r||typeof r!="object")throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers.${t} \u65E0\u6548`);let i=r;if(i.url&&typeof i.url=="string"){if(i.type&&i.type!=="sse"&&i.type!=="streamable-http")throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers.${t}.type \u5FC5\u987B\u662F "sse" \u6216 "streamable-http"`)}else{if(!i.command||typeof i.command!="string")throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers.${t}.command \u65E0\u6548`);if(!Array.isArray(i.args))throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers.${t}.args \u5FC5\u987B\u662F\u6570\u7EC4`);if(i.env&&typeof i.env!="object")throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers.${t}.env \u5FC5\u987B\u662F\u5BF9\u8C61`)}}}getConfig(){return this.config||(this.config=this.loadConfig()),JSON.parse(JSON.stringify(this.config))}getMcpEndpoint(){let e=this.getConfig();return Array.isArray(e.mcpEndpoint)?e.mcpEndpoint[0]||"":e.mcpEndpoint}getMcpEndpoints(){let e=this.getConfig();return Array.isArray(e.mcpEndpoint)?[...e.mcpEndpoint]:e.mcpEndpoint?[e.mcpEndpoint]:[]}getMcpServers(){return this.getConfig().mcpServers}getMcpServerConfig(){return this.getConfig().mcpServerConfig||{}}getServerToolsConfig(e){return this.getMcpServerConfig()[e]?.tools||{}}isToolEnabled(e,o){return this.getServerToolsConfig(e)[o]?.enable!==!1}updateMcpEndpoint(e){if(Array.isArray(e)){if(e.length===0)throw new Error("MCP \u7AEF\u70B9\u6570\u7EC4\u4E0D\u80FD\u4E3A\u7A7A");for(let r of e)if(!r||typeof r!="string")throw new Error("MCP \u7AEF\u70B9\u6570\u7EC4\u4E2D\u7684\u6BCF\u4E2A\u5143\u7D20\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32")}else if(!e||typeof e!="string")throw new Error("MCP \u7AEF\u70B9\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let t={...this.getConfig(),mcpEndpoint:e};this.saveConfig(t)}addMcpEndpoint(e){if(!e||typeof e!="string")throw new Error("MCP \u7AEF\u70B9\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let o=this.getConfig(),t=this.getMcpEndpoints();if(t.includes(e))throw new Error(`MCP \u7AEF\u70B9 ${e} \u5DF2\u5B58\u5728`);let r=[...t,e],i={...o,mcpEndpoint:r};this.saveConfig(i)}removeMcpEndpoint(e){if(!e||typeof e!="string")throw new Error("MCP \u7AEF\u70B9\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let o=this.getConfig(),t=this.getMcpEndpoints();if(t.indexOf(e)===-1)throw new Error(`MCP \u7AEF\u70B9 ${e} \u4E0D\u5B58\u5728`);if(t.length===1)throw new Error("\u4E0D\u80FD\u5220\u9664\u6700\u540E\u4E00\u4E2A MCP \u7AEF\u70B9");let i=t.filter(a=>a!==e),c={...o,mcpEndpoint:i};this.saveConfig(c)}updateMcpServer(e,o){if(!e||typeof e!="string")throw new Error("\u670D\u52A1\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");if("type"in o&&o.type==="sse"){if(!o.url||typeof o.url!="string")throw new Error("SSE \u670D\u52A1\u914D\u7F6E\u7684 url \u5B57\u6BB5\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32")}else{let i=o;if(!i.command||typeof i.command!="string")throw new Error("\u670D\u52A1\u914D\u7F6E\u7684 command \u5B57\u6BB5\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");if(!Array.isArray(i.args))throw new Error("\u670D\u52A1\u914D\u7F6E\u7684 args \u5B57\u6BB5\u5FC5\u987B\u662F\u6570\u7EC4");if(i.env&&typeof i.env!="object")throw new Error("\u670D\u52A1\u914D\u7F6E\u7684 env \u5B57\u6BB5\u5FC5\u987B\u662F\u5BF9\u8C61")}let t=this.getConfig(),r={...t,mcpServers:{...t.mcpServers,[e]:o}};this.saveConfig(r)}removeMcpServer(e){if(!e||typeof e!="string")throw new Error("\u670D\u52A1\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let o=this.getConfig();if(!o.mcpServers[e])throw new Error(`\u670D\u52A1 ${e} \u4E0D\u5B58\u5728`);let t={...o.mcpServers};delete t[e];let r={...o,mcpServers:t};this.saveConfig(r)}updateServerToolsConfig(e,o){let r={...this.getConfig()};r.mcpServerConfig||(r.mcpServerConfig={}),r.mcpServerConfig[e]={tools:o},this.saveConfig(r)}setToolEnabled(e,o,t,r){let c={...this.getConfig()};c.mcpServerConfig||(c.mcpServerConfig={}),c.mcpServerConfig[e]||(c.mcpServerConfig[e]={tools:{}}),c.mcpServerConfig[e].tools[o]={enable:t,...r&&{description:r}},this.saveConfig(c)}saveConfig(e){try{this.validateConfig(e);let o=this.getConfigFilePath(),t=JSON.stringify(e,null,2);ye(o,t,"utf8"),this.config=e}catch(o){throw new Error(`\u4FDD\u5B58\u914D\u7F6E\u5931\u8D25: ${o instanceof Error?o.message:String(o)}`)}}reloadConfig(){this.config=null}getConfigPath(){return this.getConfigFilePath()}getDefaultConfigPath(){return this.defaultConfigPath}getConnectionConfig(){let o=this.getConfig().connection||{};return{heartbeatInterval:o.heartbeatInterval??k.heartbeatInterval,heartbeatTimeout:o.heartbeatTimeout??k.heartbeatTimeout,reconnectInterval:o.reconnectInterval??k.reconnectInterval}}getHeartbeatInterval(){return this.getConnectionConfig().heartbeatInterval}getHeartbeatTimeout(){return this.getConnectionConfig().heartbeatTimeout}getReconnectInterval(){return this.getConnectionConfig().reconnectInterval}updateConnectionConfig(e){let o=this.getConfig(),r={...o.connection||{},...e},i={...o,connection:r};this.saveConfig(i)}setHeartbeatInterval(e){if(e<=0)throw new Error("\u5FC3\u8DF3\u68C0\u6D4B\u95F4\u9694\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({heartbeatInterval:e})}setHeartbeatTimeout(e){if(e<=0)throw new Error("\u5FC3\u8DF3\u8D85\u65F6\u65F6\u95F4\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({heartbeatTimeout:e})}setReconnectInterval(e){if(e<=0)throw new Error("\u91CD\u8FDE\u95F4\u9694\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({reconnectInterval:e})}getModelScopeConfig(){return this.getConfig().modelscope||{}}getModelScopeApiKey(){return this.getModelScopeConfig().apiKey||process.env.MODELSCOPE_API_TOKEN}updateModelScopeConfig(e){let o=this.getConfig(),r={...o.modelscope||{},...e},i={...o,modelscope:r};this.saveConfig(i)}setModelScopeApiKey(e){if(!e||typeof e!="string")throw new Error("API Key \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");this.updateModelScopeConfig({apiKey:e})}getWebUIConfig(){return this.getConfig().webUI||{}}getWebUIPort(){return this.getWebUIConfig().port??9999}updateWebUIConfig(e){let o=this.getConfig(),r={...o.webUI||{},...e},i={...o,webUI:r};this.saveConfig(i)}setWebUIPort(e){if(!Number.isInteger(e)||e<=0||e>65535)throw new Error("\u7AEF\u53E3\u53F7\u5FC5\u987B\u662F 1-65535 \u4E4B\u95F4\u7684\u6574\u6570");this.updateWebUIConfig({port:e})}},l=A.getInstance();function we(){try{if(!l.configExists())return[];let n=l.getMcpServers();return Object.keys(n)}catch{return[]}}g(we,"getMcpServerNames");function Pe(n){try{if(!l.configExists())return[];let e=l.getServerToolsConfig(n);return Object.keys(e)}catch{return[]}}g(Pe,"getServerToolNames");function V(){let n=be("xiaozhi <command>");if(n.on("command",({reply:e})=>{e(["create","init","config","start","stop","status","attach","restart","mcp","completion"])}),n.on("complete",(e,{line:o,before:t,reply:r})=>{process.env.XIAOZHI_DEBUG_COMPLETION&&console.error(`Debug completion - line: "${o}", before: "${t}", fragment: "${e}"`);let i=o.trim().split(/\s+/),a=o!==o.trim()?i.length:i.length-1;if(i[1]==="mcp"){let d=i[2];if(a===2){let m=["list","server","tool"],h=i[2]||"",C=m.filter(v=>v.startsWith(h));r(C);return}if(a===3){switch(d){case"list":{let m=["--tools"],h=i[3]||"",C=m.filter(v=>v.startsWith(h));r(C);break}case"server":case"tool":{let m=we(),h=i[3]||"",C=m.filter(v=>v.startsWith(h));r(C);break}default:r([])}return}if(a===4&&d==="tool"){let m=i[3],h=Pe(m),C=i[4]||"",v=h.filter(E=>E.startsWith(C));r(v);return}if(a===5&&d==="tool"){let m=["enable","disable"],h=i[5]||"",C=m.filter(v=>v.startsWith(h));r(C);return}}if(a===2){switch(i[1]){case"create":r(["--template","-t"]);break;case"start":case"restart":r(["--daemon","-d"]);break;case"completion":r(["install","uninstall"]);break;default:r([])}return}r([])}),process.argv.includes("--completion")){try{console.log(n.setupShellInitFile())}catch(e){console.error("\u751F\u6210\u81EA\u52A8\u8865\u5168\u811A\u672C\u65F6\u51FA\u9519:",e)}process.exit(0)}process.argv.includes("--completion-fish")&&(console.log(n.setupShellInitFile("fish")),process.exit(0)),process.argv.includes("--compzsh")||process.argv.includes("--compbash"),n.init()}g(V,"setupAutoCompletion");function q(){console.log("\u{1F680} xiaozhi \u81EA\u52A8\u8865\u5168\u8BBE\u7F6E"),console.log(),console.log("\u8981\u542F\u7528\u81EA\u52A8\u8865\u5168\uFF0C\u8BF7\u6839\u636E\u4F60\u7684shell\u6267\u884C\u4EE5\u4E0B\u547D\u4EE4\uFF1A"),console.log(),console.log("\u{1F4DD} Zsh (\u63A8\u8350):"),console.log(" xiaozhi --completion >> ~/.xiaozhi-completion.zsh"),console.log(" echo 'source ~/.xiaozhi-completion.zsh' >> ~/.zshrc"),console.log(" source ~/.zshrc"),console.log(),console.log("\u{1F4DD} Bash:"),console.log(" xiaozhi --completion >> ~/.xiaozhi-completion.bash"),console.log(" echo 'source ~/.xiaozhi-completion.bash' >> ~/.bash_profile"),console.log(" source ~/.bash_profile"),console.log(),console.log("\u{1F4DD} Fish:"),console.log(" xiaozhi --completion-fish >> ~/.config/fish/completions/xiaozhi.fish"),console.log(),console.log("\u2728 \u8BBE\u7F6E\u5B8C\u6210\u540E\uFF0C\u4F60\u5C31\u53EF\u4EE5\u4F7F\u7528 Tab \u952E\u8FDB\u884C\u81EA\u52A8\u8865\u5168\u4E86\uFF01"),console.log(),console.log("\u{1F4A1} \u793A\u4F8B:"),console.log(" xiaozhi m<Tab> # \u2192 mcp"),console.log(" xiaozhi mcp l<Tab> # \u2192 list"),console.log(" xiaozhi mcp tool <Tab> # \u2192 \u663E\u793A\u6240\u6709\u670D\u52A1\u5668\u540D\u79F0")}g(q,"showCompletionHelp");z();import p from"chalk";import K from"cli-table3";import F from"ora";function Y(n){let e=0;for(let o of n)/[\u4e00-\u9fff\u3400-\u4dbf\uff00-\uffef]/.test(o)?e+=2:e+=1;return e}g(Y,"getDisplayWidth");function Q(n,e){if(Y(n)<=e)return n;if(e<=3)return"";let o="",t=0,r=!1;for(let i of n){let c=/[\u4e00-\u9fff\u3400-\u4dbf\uff00-\uffef]/.test(i)?2:1;if(t+c>e-3){if(!r)return"";o+="...";break}o+=i,t+=c,r=!0}return o}g(Q,"truncateToWidth");async function ee(n={}){let e=F("\u83B7\u53D6 MCP \u670D\u52A1\u5217\u8868...").start();try{let o=l.getMcpServers(),t=Object.keys(o);if(t.length===0){e.warn("\u672A\u914D\u7F6E\u4EFB\u4F55 MCP \u670D\u52A1"),console.log(p.yellow("\u{1F4A1} \u63D0\u793A: \u4F7F\u7528 'xiaozhi config' \u547D\u4EE4\u914D\u7F6E MCP \u670D\u52A1"));return}if(e.succeed(`\u627E\u5230 ${t.length} \u4E2A MCP \u670D\u52A1`),n.tools){console.log(),console.log(p.bold("MCP \u670D\u52A1\u5DE5\u5177\u5217\u8868:")),console.log();let r=8,i=[];for(let a of t){let d=l.getServerToolsConfig(a),m=Object.keys(d);i.push(...m)}for(let a of i){let d=Y(a);d>r&&(r=d)}r=Math.max(10,Math.min(r+2,30));let c=new K({head:[p.bold("MCP"),p.bold("\u5DE5\u5177\u540D\u79F0"),p.bold("\u72B6\u6001"),p.bold("\u63CF\u8FF0")],colWidths:[15,r,8,40],wordWrap:!0,style:{head:[],border:[]}});for(let a of t){let d=l.getServerToolsConfig(a),m=Object.keys(d);if(m.length===0)c.push([p.gray(a),p.gray("-"),p.gray("-"),p.gray("\u6682\u672A\u8BC6\u522B\u5230\u76F8\u5173\u5DE5\u5177")]);else{c.length>0&&c.push([{colSpan:4,content:""}]);for(let h of m){let C=d[h],v=C.enable?p.green("\u542F\u7528"):p.red("\u7981\u7528"),E=Q(C.description||"",32);c.push([a,h,v,E])}}}console.log(c.toString())}else{console.log(),console.log(p.bold("MCP \u670D\u52A1\u5217\u8868:")),console.log();for(let r of t){let i=o[r],c=l.getServerToolsConfig(r),a=Object.keys(c).length,d=Object.values(c).filter(m=>m.enable!==!1).length;console.log(`${p.cyan("\u2022")} ${p.bold(r)}`),"url"in i?("type"in i&&i.type==="sse"?console.log(` \u7C7B\u578B: ${p.gray("SSE")}`):console.log(` \u7C7B\u578B: ${p.gray("Streamable HTTP")}`),console.log(` URL: ${p.gray(i.url)}`)):console.log(` \u547D\u4EE4: ${p.gray(i.command)} ${p.gray(i.args.join(" "))}`),a>0?console.log(` \u5DE5\u5177: ${p.green(d)} \u542F\u7528 / ${p.yellow(a)} \u603B\u8BA1`):console.log(` \u5DE5\u5177: ${p.gray("\u672A\u626B\u63CF (\u8BF7\u5148\u542F\u52A8\u670D\u52A1)")}`),console.log()}}console.log(p.gray("\u{1F4A1} \u63D0\u793A:")),console.log(p.gray(" - \u4F7F\u7528 'xiaozhi mcp list --tools' \u67E5\u770B\u6240\u6709\u5DE5\u5177")),console.log(p.gray(" - \u4F7F\u7528 'xiaozhi mcp <\u670D\u52A1\u540D> list' \u67E5\u770B\u6307\u5B9A\u670D\u52A1\u7684\u5DE5\u5177")),console.log(p.gray(" - \u4F7F\u7528 'xiaozhi mcp <\u670D\u52A1\u540D> <\u5DE5\u5177\u540D> enable/disable' \u542F\u7528/\u7981\u7528\u5DE5\u5177"))}catch(o){e.fail("\u83B7\u53D6 MCP \u670D\u52A1\u5217\u8868\u5931\u8D25"),console.error(p.red(`\u9519\u8BEF: ${o instanceof Error?o.message:String(o)}`)),process.exit(1)}}g(ee,"listMcpServers");async function oe(n){let e=F(`\u83B7\u53D6 ${n} \u670D\u52A1\u7684\u5DE5\u5177\u5217\u8868...`).start();try{if(!l.getMcpServers()[n]){e.fail(`\u670D\u52A1 '${n}' \u4E0D\u5B58\u5728`),console.log(p.yellow("\u{1F4A1} \u63D0\u793A: \u4F7F\u7528 'xiaozhi mcp list' \u67E5\u770B\u6240\u6709\u53EF\u7528\u670D\u52A1"));return}let t=l.getServerToolsConfig(n),r=Object.keys(t);if(r.length===0){e.warn(`\u670D\u52A1 '${n}' \u6682\u65E0\u5DE5\u5177\u4FE1\u606F`),console.log(p.yellow("\u{1F4A1} \u63D0\u793A: \u8BF7\u5148\u542F\u52A8\u670D\u52A1\u4EE5\u626B\u63CF\u5DE5\u5177\u5217\u8868"));return}e.succeed(`\u670D\u52A1 '${n}' \u5171\u6709 ${r.length} \u4E2A\u5DE5\u5177`),console.log(),console.log(p.bold(`${n} \u670D\u52A1\u5DE5\u5177\u5217\u8868:`)),console.log();let i=new K({head:[p.bold("\u5DE5\u5177\u540D\u79F0"),p.bold("\u72B6\u6001"),p.bold("\u63CF\u8FF0")],colWidths:[30,8,50],wordWrap:!0,style:{head:[],border:[]}});for(let c of r){let a=t[c],d=a.enable?p.green("\u542F\u7528"):p.red("\u7981\u7528"),m=Q(a.description||"",40);i.push([c,d,m])}console.log(i.toString()),console.log(),console.log(p.gray("\u{1F4A1} \u63D0\u793A:")),console.log(p.gray(` - \u4F7F\u7528 'xiaozhi mcp ${n} <\u5DE5\u5177\u540D> enable' \u542F\u7528\u5DE5\u5177`)),console.log(p.gray(` - \u4F7F\u7528 'xiaozhi mcp ${n} <\u5DE5\u5177\u540D> disable' \u7981\u7528\u5DE5\u5177`))}catch(o){e.fail("\u83B7\u53D6\u5DE5\u5177\u5217\u8868\u5931\u8D25"),console.error(p.red(`\u9519\u8BEF: ${o instanceof Error?o.message:String(o)}`)),process.exit(1)}}g(oe,"listServerTools");async function te(n,e,o){let t=o?"\u542F\u7528":"\u7981\u7528",r=F(`${t}\u5DE5\u5177 ${n}/${e}...`).start();try{if(!l.getMcpServers()[n]){r.fail(`\u670D\u52A1 '${n}' \u4E0D\u5B58\u5728`),console.log(p.yellow("\u{1F4A1} \u63D0\u793A: \u4F7F\u7528 'xiaozhi mcp list' \u67E5\u770B\u6240\u6709\u53EF\u7528\u670D\u52A1"));return}let c=l.getServerToolsConfig(n);if(!c[e]){r.fail(`\u5DE5\u5177 '${e}' \u5728\u670D\u52A1 '${n}' \u4E2D\u4E0D\u5B58\u5728`),console.log(p.yellow(`\u{1F4A1} \u63D0\u793A: \u4F7F\u7528 'xiaozhi mcp ${n} list' \u67E5\u770B\u8BE5\u670D\u52A1\u7684\u6240\u6709\u5DE5\u5177`));return}l.setToolEnabled(n,e,o,c[e].description),r.succeed(`\u6210\u529F${t}\u5DE5\u5177 ${p.cyan(n)}/${p.cyan(e)}`),console.log(),console.log(p.gray("\u{1F4A1} \u63D0\u793A: \u5DE5\u5177\u72B6\u6001\u66F4\u6539\u5C06\u5728\u4E0B\u6B21\u542F\u52A8\u670D\u52A1\u65F6\u751F\u6548"))}catch(i){r.fail(`${t}\u5DE5\u5177\u5931\u8D25`),console.error(p.red(`\u9519\u8BEF: ${i instanceof Error?i.message:String(i)}`)),process.exit(1)}}g(te,"setToolEnabled");import{spawn as ne}from"child_process";import{existsSync as U}from"fs";import{readFile as re}from"fs/promises";import{createServer as Me}from"http";import{dirname as $e,join as P}from"path";import{parse as Te}from"url";import{fileURLToPath as je}from"url";import{WebSocketServer as Oe}from"ws";z();var T=class{static{g(this,"WebServer")}httpServer;wss;logger;port;clientInfo={status:"disconnected",mcpEndpoint:"",activeMCPServers:[]};heartbeatTimeout;HEARTBEAT_TIMEOUT=35e3;constructor(e){if(e===void 0)try{this.port=l.getWebUIPort()}catch{this.port=9999}else this.port=e;this.logger=new $,this.httpServer=Me((o,t)=>{this.handleHttpRequest(o,t)}),this.wss=new Oe({server:this.httpServer}),this.setupWebSocket()}async handleHttpRequest(e,o){let{pathname:t}=Te(e.url||"",!0);if(o.setHeader("Access-Control-Allow-Origin","*"),o.setHeader("Access-Control-Allow-Methods","GET, POST, PUT, OPTIONS"),o.setHeader("Access-Control-Allow-Headers","Content-Type"),e.method==="OPTIONS"){o.writeHead(200),o.end();return}try{if(e.method==="GET"&&!t?.startsWith("/api/")){await this.serveStaticFile(t||"/",o);return}if(t==="/api/config"&&e.method==="GET"){let r=l.getConfig();o.writeHead(200,{"Content-Type":"application/json"}),o.end(JSON.stringify(r))}else if(t==="/api/config"&&e.method==="PUT"){let r="";e.on("data",i=>{r+=i.toString()}),e.on("end",async()=>{try{let i=JSON.parse(r);this.updateConfig(i),this.broadcastConfigUpdate(i),o.writeHead(200,{"Content-Type":"application/json"}),o.end(JSON.stringify({success:!0})),this.logger.info("\u914D\u7F6E\u5DF2\u66F4\u65B0")}catch(i){o.writeHead(400,{"Content-Type":"application/json"}),o.end(JSON.stringify({error:i instanceof Error?i.message:String(i)}))}})}else t==="/api/status"&&e.method==="GET"?(o.writeHead(200,{"Content-Type":"application/json"}),o.end(JSON.stringify(this.clientInfo))):(o.writeHead(404),o.end("Not Found"))}catch(r){this.logger.error("HTTP request error:",r),o.writeHead(500,{"Content-Type":"application/json"}),o.end(JSON.stringify({error:"Internal Server Error"}))}}async serveStaticFile(e,o){try{let t=$e(je(import.meta.url)),i=[P(t,"..","web","dist"),P(t,"..","web"),P(process.cwd(),"web","dist"),P(process.cwd(),"web")].find(v=>U(v));if(!i){o.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),o.end(`
13
13
  <!DOCTYPE html>
14
14
  <html>
15
15
  <head>
@@ -29,13 +29,13 @@ data: ${JSON.stringify(o)}
29
29
  </div>
30
30
  </body>
31
31
  </html>
32
- `);return}let c=e;if(c==="/"&&(c="/index.html"),c.includes("..")){o.writeHead(403),o.end("Forbidden");return}let a=P(i,c);if(!U(a)){let v=P(i,"index.html");if(U(v)){let E=await re(v);o.writeHead(200,{"Content-Type":"text/html"}),o.end(E)}else o.writeHead(404),o.end("Not Found");return}let f=await re(a),d=a.split(".").pop()?.toLowerCase(),C={html:"text/html",js:"application/javascript",css:"text/css",json:"application/json",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",svg:"image/svg+xml",ico:"image/x-icon"}[d||""]||"application/octet-stream";o.writeHead(200,{"Content-Type":C}),o.end(f)}catch(t){this.logger.error("Serve static file error:",t),o.writeHead(500),o.end("Internal Server Error")}}setupWebSocket(){this.wss.on("connection",e=>{this.logger.debug("WebSocket client connected"),e.on("message",async o=>{try{let t=JSON.parse(o.toString());await this.handleWebSocketMessage(e,t)}catch(t){this.logger.error("WebSocket message error:",t),e.send(JSON.stringify({type:"error",error:t instanceof Error?t.message:String(t)}))}}),e.on("close",()=>{this.logger.debug("WebSocket client disconnected")}),this.sendInitialData(e)})}async handleWebSocketMessage(e,o){switch(o.type){case"getConfig":{let t=l.getConfig();e.send(JSON.stringify({type:"config",data:t}));break}case"updateConfig":this.updateConfig(o.config),this.broadcastConfigUpdate(o.config);break;case"getStatus":e.send(JSON.stringify({type:"status",data:this.clientInfo}));break;case"clientStatus":this.updateClientInfo(o.data),this.broadcastStatusUpdate();break;case"restartService":this.logger.info("\u6536\u5230\u624B\u52A8\u91CD\u542F\u670D\u52A1\u8BF7\u6C42"),this.broadcastRestartStatus("restarting"),setTimeout(async()=>{try{await this.restartService(),setTimeout(()=>{this.broadcastRestartStatus("completed")},5e3)}catch(t){this.logger.error(`\u624B\u52A8\u91CD\u542F\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`),this.broadcastRestartStatus("failed",t instanceof Error?t.message:"\u672A\u77E5\u9519\u8BEF")}},500);break}}async sendInitialData(e){let o=l.getConfig();e.send(JSON.stringify({type:"config",data:o})),e.send(JSON.stringify({type:"status",data:this.clientInfo}))}broadcastConfigUpdate(e){let o=JSON.stringify({type:"configUpdate",data:e});for(let t of this.wss.clients)t.readyState===1&&t.send(o)}broadcastRestartStatus(e,o){let t=JSON.stringify({type:"restartStatus",data:{status:e,error:o,timestamp:Date.now()}});for(let r of this.wss.clients)r.readyState===1&&r.send(t)}broadcastStatusUpdate(){let e=JSON.stringify({type:"statusUpdate",data:this.clientInfo});for(let o of this.wss.clients)o.readyState===1&&o.send(e)}updateClientInfo(e){this.clientInfo={...this.clientInfo,...e},e.lastHeartbeat&&(this.clientInfo.lastHeartbeat=Date.now()),e.status==="connected"&&this.resetHeartbeatTimeout()}resetHeartbeatTimeout(){this.heartbeatTimeout&&clearTimeout(this.heartbeatTimeout),this.heartbeatTimeout=setTimeout(()=>{this.logger.warn("\u5BA2\u6237\u7AEF\u5FC3\u8DF3\u8D85\u65F6\uFF0C\u6807\u8BB0\u4E3A\u65AD\u5F00\u8FDE\u63A5"),this.updateClientInfo({status:"disconnected"}),this.broadcastStatusUpdate()},this.HEARTBEAT_TIMEOUT)}updateConfig(e){e.mcpEndpoint!==l.getMcpEndpoint()&&l.updateMcpEndpoint(e.mcpEndpoint);let o=l.getMcpServers();for(let[t,r]of Object.entries(e.mcpServers))JSON.stringify(o[t])!==JSON.stringify(r)&&l.updateMcpServer(t,r);for(let t of Object.keys(o))t in e.mcpServers||l.removeMcpServer(t);if(e.connection&&l.updateConnectionConfig(e.connection),e.modelscope&&l.updateModelScopeConfig(e.modelscope),e.webUI&&l.updateWebUIConfig(e.webUI),e.mcpServerConfig)for(let[t,r]of Object.entries(e.mcpServerConfig))for(let[i,c]of Object.entries(r.tools))l.setToolEnabled(t,i,c.enable)}async restartService(){this.logger.info("\u6B63\u5728\u91CD\u542F MCP \u670D\u52A1..."),this.heartbeatTimeout&&(clearTimeout(this.heartbeatTimeout),this.heartbeatTimeout=void 0);try{let e=x();if(!e.running){this.logger.warn("MCP \u670D\u52A1\u672A\u8FD0\u884C\uFF0C\u5C1D\u8BD5\u542F\u52A8\u670D\u52A1"),ne("xiaozhi",["start","--daemon"],{detached:!0,stdio:"ignore",env:{...process.env,XIAOZHI_CONFIG_DIR:process.env.XIAOZHI_CONFIG_DIR||process.cwd()}}).unref(),this.logger.info("MCP \u670D\u52A1\u542F\u52A8\u547D\u4EE4\u5DF2\u53D1\u9001");return}let o=e.mode==="daemon",t=["restart"];o&&t.push("--daemon"),ne("xiaozhi",t,{detached:!0,stdio:"ignore",env:{...process.env,XIAOZHI_CONFIG_DIR:process.env.XIAOZHI_CONFIG_DIR||process.cwd()}}).unref(),this.logger.info("MCP \u670D\u52A1\u91CD\u542F\u547D\u4EE4\u5DF2\u53D1\u9001"),this.resetHeartbeatTimeout()}catch(e){throw this.logger.error(`\u91CD\u542F\u670D\u52A1\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`),this.resetHeartbeatTimeout(),e}}updateStatus(e){this.updateClientInfo(e),this.broadcastStatusUpdate()}start(){return new Promise((e,o)=>{this.httpServer.listen(this.port,()=>{this.logger.info(`Web server listening on http://localhost:${this.port}`),e()}).on("error",o)})}stop(){return new Promise(e=>{this.heartbeatTimeout&&(clearTimeout(this.heartbeatTimeout),this.heartbeatTimeout=void 0);for(let o of this.wss.clients)o.terminate();this.wss.close(()=>{this.httpServer.close(()=>{this.logger.info("Web server stopped"),e()}),setTimeout(()=>{this.logger.info("Web server force stopped"),e()},2e3)})})}};var S=new Ae,Fe="xiaozhi-mcp-service";function ge(){try{let n=I(import.meta.url),e=m.dirname(n),o=[m.join(e,"..","package.json"),m.join(e,"..","package.json"),m.join(e,"..","..","package.json"),m.join(e,"package.json")];for(let t of o)if(u.existsSync(t)){let r=JSON.parse(u.readFileSync(t,"utf8"));if(r.version)return r.version}return"unknown"}catch(n){return console.warn("\u65E0\u6CD5\u4ECE package.json \u8BFB\u53D6\u7248\u672C\u4FE1\u606F:",n),"unknown"}}g(ge,"getVersion");var G=g(()=>{let n=process.env.XIAOZHI_CONFIG_DIR||process.cwd();return m.join(n,`.${Fe}.pid`)},"getPidFile");function x(){try{let n=G();if(!u.existsSync(n))return{running:!1};let e=u.readFileSync(n,"utf8").trim(),[o,t,r]=e.split("|"),i=Number.parseInt(o);if(Number.isNaN(i))return u.unlinkSync(n),{running:!1};try{process.kill(i,0);let c=Number.parseInt(t),a=Ue(Date.now()-c);return{running:!0,pid:i,uptime:a,mode:r||"foreground"}}catch{return u.unlinkSync(n),{running:!1}}}catch{return{running:!1}}}g(x,"getServiceStatus");function Ue(n){let e=Math.floor(n/1e3),o=Math.floor(e/60),t=Math.floor(o/60),r=Math.floor(t/24);return r>0?`${r}\u5929 ${t%24}\u5C0F\u65F6 ${o%60}\u5206\u949F`:t>0?`${t}\u5C0F\u65F6 ${o%60}\u5206\u949F`:o>0?`${o}\u5206\u949F ${e%60}\u79D2`:`${e}\u79D2`}g(Ue,"formatUptime");function _(n,e){let o=`${n}|${Date.now()}|${e}`;u.writeFileSync(G(),o)}g(_,"savePidInfo");function O(){try{let n=G();u.existsSync(n)&&u.unlinkSync(n)}catch{}}g(O,"cleanupPidFile");function De(){if(!l.configExists())return console.error(s.red("\u274C \u9519\u8BEF: \u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728")),console.log(s.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u8FD0\u884C "xiaozhi init" \u521D\u59CB\u5316\u914D\u7F6E')),!1;try{let n=l.getMcpEndpoint();return!n||n.includes("<\u8BF7\u586B\u5199")?(console.error(s.red("\u274C \u9519\u8BEF: MCP \u7AEF\u70B9\u672A\u914D\u7F6E")),console.log(s.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u8FD0\u884C "xiaozhi config mcpEndpoint <your-endpoint-url>" \u8BBE\u7F6E\u7AEF\u70B9')),!1):!0}catch(n){return console.error(s.red(`\u274C \u9519\u8BEF: \u914D\u7F6E\u6587\u4EF6\u65E0\u6548 - ${n instanceof Error?n.message:String(n)}`)),console.log(s.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u8FD0\u884C "xiaozhi init" \u91CD\u65B0\u521D\u59CB\u5316\u914D\u7F6E')),!1}}g(De,"checkEnvironment");function He(){let n=m.dirname(I(import.meta.url)),e;return n.includes("js-demo/dist")?e=n:e=[m.join(n,"..","js-demo","dist"),m.join(n,"..","..","js-demo","dist"),m.join(n,"..","..","..","js-demo","dist"),m.join(process.cwd(),"js-demo","dist"),m.join(process.cwd(),"dist")].find(t=>u.existsSync(m.join(t,"adaptiveMCPPipe.js"))&&u.existsSync(m.join(t,"mcpServerProxy.js")))||n,{command:"node",args:["adaptiveMCPPipe.js","mcpServerProxy.js"],cwd:e}}g(He,"getServiceCommand");async function ae(){try{if(!l.configExists()){console.log(s.yellow("\u{1F4A1} \u63D0\u793A: \u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7 Web UI \u542F\u52A8"));return}let n=new T;await n.start();let e=l.getWebUIPort();console.log(s.green(`\u2705 Web UI \u5DF2\u542F\u52A8: http://localhost:${e}`));let{spawn:o}=await import("child_process"),t=`http://localhost:${e}`;try{process.platform==="darwin"?o("open",[t],{detached:!0,stdio:"ignore"}).unref():process.platform==="win32"?o("cmd",["/c","start",t],{detached:!0,stdio:"ignore"}).unref():o("xdg-open",[t],{detached:!0,stdio:"ignore"}).unref()}catch{}global.__webServer=n}catch(n){console.log(s.yellow(`\u26A0\uFE0F Web UI \u542F\u52A8\u5931\u8D25: ${n instanceof Error?n.message:String(n)}`))}}g(ae,"startWebUIInBackground");async function pe(n=!1,e=!1){let o=b("\u68C0\u67E5\u670D\u52A1\u72B6\u6001...").start();try{let t=x();if(t.running){o.fail(`\u670D\u52A1\u5DF2\u7ECF\u5728\u8FD0\u884C (PID: ${t.pid})`);return}if(o.text="\u68C0\u67E5\u73AF\u5883\u914D\u7F6E...",!De()){o.fail("\u73AF\u5883\u914D\u7F6E\u68C0\u67E5\u5931\u8D25");return}let{command:r,args:i,cwd:c}=He();if(o.text=`\u542F\u52A8\u670D\u52A1 (${n?"\u540E\u53F0\u6A21\u5F0F":"\u524D\u53F0\u6A21\u5F0F"})...`,n){let a=W(r,i,{cwd:c,detached:!0,stdio:["ignore","pipe","pipe"],env:{...process.env,XIAOZHI_CONFIG_DIR:process.cwd(),XIAOZHI_DAEMON:"true"}});_(a.pid,"daemon");let f=process.cwd();w.initLogFile(f),w.enableFileLogging(!0);let d=m.join(f,"xiaozhi.log"),h=u.createWriteStream(d,{flags:"a"});a.stdout?.pipe(h),a.stderr?.pipe(h),a.on("exit",(C,v)=>{C!==0&&C!==null&&w.error(`\u540E\u53F0\u670D\u52A1\u5F02\u5E38\u9000\u51FA (\u4EE3\u7801: ${C}, \u4FE1\u53F7: ${v})`),O()}),a.on("error",C=>{w.error(`\u540E\u53F0\u670D\u52A1\u542F\u52A8\u9519\u8BEF: ${C.message}`),O(),o.fail(`\u540E\u53F0\u670D\u52A1\u542F\u52A8\u5931\u8D25: ${C.message}`)}),a.unref(),o.succeed(`\u670D\u52A1\u5DF2\u5728\u540E\u53F0\u542F\u52A8 (PID: ${a.pid})`),console.log(s.gray(`\u65E5\u5FD7\u6587\u4EF6: ${d}`)),console.log(s.gray("\u4F7F\u7528 'xiaozhi attach' \u53EF\u4EE5\u67E5\u770B\u5B9E\u65F6\u65E5\u5FD7")),e&&await ae()}else{o.succeed("\u670D\u52A1\u542F\u52A8\u4E2D...");let a=W(r,i,{cwd:c,stdio:"inherit",env:{...process.env,XIAOZHI_CONFIG_DIR:process.cwd()}});_(a.pid,"foreground"),a.on("exit",(f,d)=>{O(),console.log(f!==0?s.red(`
33
- \u670D\u52A1\u5F02\u5E38\u9000\u51FA (\u4EE3\u7801: ${f}, \u4FE1\u53F7: ${d})`):s.green(`
32
+ `);return}let c=e;if(c==="/"&&(c="/index.html"),c.includes("..")){o.writeHead(403),o.end("Forbidden");return}let a=P(i,c);if(!U(a)){let v=P(i,"index.html");if(U(v)){let E=await re(v);o.writeHead(200,{"Content-Type":"text/html"}),o.end(E)}else o.writeHead(404),o.end("Not Found");return}let d=await re(a),m=a.split(".").pop()?.toLowerCase(),C={html:"text/html",js:"application/javascript",css:"text/css",json:"application/json",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",svg:"image/svg+xml",ico:"image/x-icon"}[m||""]||"application/octet-stream";o.writeHead(200,{"Content-Type":C}),o.end(d)}catch(t){this.logger.error("Serve static file error:",t),o.writeHead(500),o.end("Internal Server Error")}}setupWebSocket(){this.wss.on("connection",e=>{this.logger.debug("WebSocket client connected"),e.on("message",async o=>{try{let t=JSON.parse(o.toString());await this.handleWebSocketMessage(e,t)}catch(t){this.logger.error("WebSocket message error:",t),e.send(JSON.stringify({type:"error",error:t instanceof Error?t.message:String(t)}))}}),e.on("close",()=>{this.logger.debug("WebSocket client disconnected")}),this.sendInitialData(e)})}async handleWebSocketMessage(e,o){switch(o.type){case"getConfig":{let t=l.getConfig();e.send(JSON.stringify({type:"config",data:t}));break}case"updateConfig":this.updateConfig(o.config),this.broadcastConfigUpdate(o.config);break;case"getStatus":e.send(JSON.stringify({type:"status",data:this.clientInfo}));break;case"clientStatus":this.updateClientInfo(o.data),this.broadcastStatusUpdate();break;case"restartService":this.logger.info("\u6536\u5230\u624B\u52A8\u91CD\u542F\u670D\u52A1\u8BF7\u6C42"),this.broadcastRestartStatus("restarting"),setTimeout(async()=>{try{await this.restartService(),setTimeout(()=>{this.broadcastRestartStatus("completed")},5e3)}catch(t){this.logger.error(`\u624B\u52A8\u91CD\u542F\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`),this.broadcastRestartStatus("failed",t instanceof Error?t.message:"\u672A\u77E5\u9519\u8BEF")}},500);break}}async sendInitialData(e){let o=l.getConfig();e.send(JSON.stringify({type:"config",data:o})),e.send(JSON.stringify({type:"status",data:this.clientInfo}))}broadcastConfigUpdate(e){let o=JSON.stringify({type:"configUpdate",data:e});for(let t of this.wss.clients)t.readyState===1&&t.send(o)}broadcastRestartStatus(e,o){let t=JSON.stringify({type:"restartStatus",data:{status:e,error:o,timestamp:Date.now()}});for(let r of this.wss.clients)r.readyState===1&&r.send(t)}broadcastStatusUpdate(){let e=JSON.stringify({type:"statusUpdate",data:this.clientInfo});for(let o of this.wss.clients)o.readyState===1&&o.send(e)}updateClientInfo(e){this.clientInfo={...this.clientInfo,...e},e.lastHeartbeat&&(this.clientInfo.lastHeartbeat=Date.now()),e.status==="connected"&&this.resetHeartbeatTimeout()}resetHeartbeatTimeout(){this.heartbeatTimeout&&clearTimeout(this.heartbeatTimeout),this.heartbeatTimeout=setTimeout(()=>{this.logger.warn("\u5BA2\u6237\u7AEF\u5FC3\u8DF3\u8D85\u65F6\uFF0C\u6807\u8BB0\u4E3A\u65AD\u5F00\u8FDE\u63A5"),this.updateClientInfo({status:"disconnected"}),this.broadcastStatusUpdate()},this.HEARTBEAT_TIMEOUT)}updateConfig(e){e.mcpEndpoint!==l.getMcpEndpoint()&&l.updateMcpEndpoint(e.mcpEndpoint);let o=l.getMcpServers();for(let[t,r]of Object.entries(e.mcpServers))JSON.stringify(o[t])!==JSON.stringify(r)&&l.updateMcpServer(t,r);for(let t of Object.keys(o))t in e.mcpServers||l.removeMcpServer(t);if(e.connection&&l.updateConnectionConfig(e.connection),e.modelscope&&l.updateModelScopeConfig(e.modelscope),e.webUI&&l.updateWebUIConfig(e.webUI),e.mcpServerConfig)for(let[t,r]of Object.entries(e.mcpServerConfig))for(let[i,c]of Object.entries(r.tools))l.setToolEnabled(t,i,c.enable)}async restartService(){this.logger.info("\u6B63\u5728\u91CD\u542F MCP \u670D\u52A1..."),this.heartbeatTimeout&&(clearTimeout(this.heartbeatTimeout),this.heartbeatTimeout=void 0);try{let e=x();if(!e.running){this.logger.warn("MCP \u670D\u52A1\u672A\u8FD0\u884C\uFF0C\u5C1D\u8BD5\u542F\u52A8\u670D\u52A1"),ne("xiaozhi",["start","--daemon"],{detached:!0,stdio:"ignore",env:{...process.env,XIAOZHI_CONFIG_DIR:process.env.XIAOZHI_CONFIG_DIR||process.cwd()}}).unref(),this.logger.info("MCP \u670D\u52A1\u542F\u52A8\u547D\u4EE4\u5DF2\u53D1\u9001");return}let o=e.mode==="daemon",t=["restart"];o&&t.push("--daemon"),ne("xiaozhi",t,{detached:!0,stdio:"ignore",env:{...process.env,XIAOZHI_CONFIG_DIR:process.env.XIAOZHI_CONFIG_DIR||process.cwd()}}).unref(),this.logger.info("MCP \u670D\u52A1\u91CD\u542F\u547D\u4EE4\u5DF2\u53D1\u9001"),this.resetHeartbeatTimeout()}catch(e){throw this.logger.error(`\u91CD\u542F\u670D\u52A1\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`),this.resetHeartbeatTimeout(),e}}updateStatus(e){this.updateClientInfo(e),this.broadcastStatusUpdate()}start(){return new Promise((e,o)=>{this.httpServer.listen(this.port,()=>{this.logger.info(`Web server listening on http://localhost:${this.port}`),e()}).on("error",o)})}stop(){return new Promise(e=>{this.heartbeatTimeout&&(clearTimeout(this.heartbeatTimeout),this.heartbeatTimeout=void 0);for(let o of this.wss.clients)o.terminate();this.wss.close(()=>{this.httpServer.close(()=>{this.logger.info("Web server stopped"),e()}),setTimeout(()=>{this.logger.info("Web server force stopped"),e()},2e3)})})}};var S=new Ae,Fe="xiaozhi-mcp-service";function ge(){try{let n=I(import.meta.url),e=f.dirname(n),o=[f.join(e,"..","package.json"),f.join(e,"..","package.json"),f.join(e,"..","..","package.json"),f.join(e,"package.json")];for(let t of o)if(u.existsSync(t)){let r=JSON.parse(u.readFileSync(t,"utf8"));if(r.version)return r.version}return"unknown"}catch(n){return console.warn("\u65E0\u6CD5\u4ECE package.json \u8BFB\u53D6\u7248\u672C\u4FE1\u606F:",n),"unknown"}}g(ge,"getVersion");var G=g(()=>{let n=process.env.XIAOZHI_CONFIG_DIR||process.cwd();return f.join(n,`.${Fe}.pid`)},"getPidFile");function x(){try{let n=G();if(!u.existsSync(n))return{running:!1};let e=u.readFileSync(n,"utf8").trim(),[o,t,r]=e.split("|"),i=Number.parseInt(o);if(Number.isNaN(i))return u.unlinkSync(n),{running:!1};try{process.kill(i,0);let c=Number.parseInt(t),a=Ue(Date.now()-c);return{running:!0,pid:i,uptime:a,mode:r||"foreground"}}catch{return u.unlinkSync(n),{running:!1}}}catch{return{running:!1}}}g(x,"getServiceStatus");function Ue(n){let e=Math.floor(n/1e3),o=Math.floor(e/60),t=Math.floor(o/60),r=Math.floor(t/24);return r>0?`${r}\u5929 ${t%24}\u5C0F\u65F6 ${o%60}\u5206\u949F`:t>0?`${t}\u5C0F\u65F6 ${o%60}\u5206\u949F`:o>0?`${o}\u5206\u949F ${e%60}\u79D2`:`${e}\u79D2`}g(Ue,"formatUptime");function _(n,e){let o=`${n}|${Date.now()}|${e}`;u.writeFileSync(G(),o)}g(_,"savePidInfo");function O(){try{let n=G();u.existsSync(n)&&u.unlinkSync(n)}catch{}}g(O,"cleanupPidFile");function De(){if(!l.configExists())return console.error(s.red("\u274C \u9519\u8BEF: \u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728")),console.log(s.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u8FD0\u884C "xiaozhi init" \u521D\u59CB\u5316\u914D\u7F6E')),!1;try{let n=l.getMcpEndpoint();return!n||n.includes("<\u8BF7\u586B\u5199")?(console.error(s.red("\u274C \u9519\u8BEF: MCP \u7AEF\u70B9\u672A\u914D\u7F6E")),console.log(s.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u8FD0\u884C "xiaozhi config mcpEndpoint <your-endpoint-url>" \u8BBE\u7F6E\u7AEF\u70B9')),!1):!0}catch(n){return console.error(s.red(`\u274C \u9519\u8BEF: \u914D\u7F6E\u6587\u4EF6\u65E0\u6548 - ${n instanceof Error?n.message:String(n)}`)),console.log(s.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u8FD0\u884C "xiaozhi init" \u91CD\u65B0\u521D\u59CB\u5316\u914D\u7F6E')),!1}}g(De,"checkEnvironment");function He(){let n=f.dirname(I(import.meta.url)),e;return n.includes("js-demo/dist")?e=n:e=[f.join(n,"..","js-demo","dist"),f.join(n,"..","..","js-demo","dist"),f.join(n,"..","..","..","js-demo","dist"),f.join(process.cwd(),"js-demo","dist"),f.join(process.cwd(),"dist")].find(t=>u.existsSync(f.join(t,"adaptiveMCPPipe.js"))&&u.existsSync(f.join(t,"mcpServerProxy.js")))||n,{command:"node",args:["adaptiveMCPPipe.js","mcpServerProxy.js"],cwd:e}}g(He,"getServiceCommand");async function ae(){try{if(!l.configExists()){console.log(s.yellow("\u{1F4A1} \u63D0\u793A: \u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7 Web UI \u542F\u52A8"));return}let n=new T;await n.start();let e=l.getWebUIPort();console.log(s.green(`\u2705 Web UI \u5DF2\u542F\u52A8: http://localhost:${e}`));let{spawn:o}=await import("child_process"),t=`http://localhost:${e}`;try{process.platform==="darwin"?o("open",[t],{detached:!0,stdio:"ignore"}).unref():process.platform==="win32"?o("cmd",["/c","start",t],{detached:!0,stdio:"ignore"}).unref():o("xdg-open",[t],{detached:!0,stdio:"ignore"}).unref()}catch{}global.__webServer=n}catch(n){console.log(s.yellow(`\u26A0\uFE0F Web UI \u542F\u52A8\u5931\u8D25: ${n instanceof Error?n.message:String(n)}`))}}g(ae,"startWebUIInBackground");async function pe(n=!1,e=!1){let o=b("\u68C0\u67E5\u670D\u52A1\u72B6\u6001...").start();try{let t=x();if(t.running){o.fail(`\u670D\u52A1\u5DF2\u7ECF\u5728\u8FD0\u884C (PID: ${t.pid})`);return}if(o.text="\u68C0\u67E5\u73AF\u5883\u914D\u7F6E...",!De()){o.fail("\u73AF\u5883\u914D\u7F6E\u68C0\u67E5\u5931\u8D25");return}let{command:r,args:i,cwd:c}=He();if(o.text=`\u542F\u52A8\u670D\u52A1 (${n?"\u540E\u53F0\u6A21\u5F0F":"\u524D\u53F0\u6A21\u5F0F"})...`,n){let a=W(r,i,{cwd:c,detached:!0,stdio:["ignore","pipe","pipe"],env:{...process.env,XIAOZHI_CONFIG_DIR:process.cwd(),XIAOZHI_DAEMON:"true"}});_(a.pid,"daemon");let d=process.cwd();w.initLogFile(d),w.enableFileLogging(!0);let m=f.join(d,"xiaozhi.log"),h=u.createWriteStream(m,{flags:"a"});a.stdout?.pipe(h),a.stderr?.pipe(h),a.on("exit",(C,v)=>{C!==0&&C!==null&&w.error(`\u540E\u53F0\u670D\u52A1\u5F02\u5E38\u9000\u51FA (\u4EE3\u7801: ${C}, \u4FE1\u53F7: ${v})`),O()}),a.on("error",C=>{w.error(`\u540E\u53F0\u670D\u52A1\u542F\u52A8\u9519\u8BEF: ${C.message}`),O(),o.fail(`\u540E\u53F0\u670D\u52A1\u542F\u52A8\u5931\u8D25: ${C.message}`)}),a.unref(),o.succeed(`\u670D\u52A1\u5DF2\u5728\u540E\u53F0\u542F\u52A8 (PID: ${a.pid})`),console.log(s.gray(`\u65E5\u5FD7\u6587\u4EF6: ${m}`)),console.log(s.gray("\u4F7F\u7528 'xiaozhi attach' \u53EF\u4EE5\u67E5\u770B\u5B9E\u65F6\u65E5\u5FD7")),e&&await ae()}else{o.succeed("\u670D\u52A1\u542F\u52A8\u4E2D...");let a=W(r,i,{cwd:c,stdio:"inherit",env:{...process.env,XIAOZHI_CONFIG_DIR:process.cwd()}});_(a.pid,"foreground"),a.on("exit",(d,m)=>{O(),console.log(d!==0?s.red(`
33
+ \u670D\u52A1\u5F02\u5E38\u9000\u51FA (\u4EE3\u7801: ${d}, \u4FE1\u53F7: ${m})`):s.green(`
34
34
  \u670D\u52A1\u5DF2\u505C\u6B62`))}),e&&setTimeout(()=>{ae()},1e3),process.on("SIGINT",async()=>{if(console.log(s.yellow(`
35
- \u6B63\u5728\u505C\u6B62\u670D\u52A1...`)),a.kill("SIGTERM"),global.__webServer)try{await global.__webServer.stop(),console.log(s.green("Web UI \u5DF2\u505C\u6B62"))}catch{}}),process.on("SIGTERM",async()=>{if(a.kill("SIGTERM"),global.__webServer)try{await global.__webServer.stop()}catch{}})}}catch(t){o.fail(`\u542F\u52A8\u670D\u52A1\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`)}}g(pe,"startService");async function fe(){let n=b("\u68C0\u67E5\u670D\u52A1\u72B6\u6001...").start();try{let e=x();if(!e.running){n.warn("\u670D\u52A1\u672A\u5728\u8FD0\u884C");return}n.text=`\u505C\u6B62\u670D\u52A1 (PID: ${e.pid})...`;try{process.kill(e.pid,"SIGTERM");let o=0,t=30;for(;o<t;){await new Promise(r=>setTimeout(r,100));try{process.kill(e.pid,0),o++}catch{break}}try{process.kill(e.pid,0),n.text="\u5F3A\u5236\u505C\u6B62\u670D\u52A1...",process.kill(e.pid,"SIGKILL"),await new Promise(r=>setTimeout(r,500))}catch{}O(),n.succeed("\u670D\u52A1\u5DF2\u505C\u6B62")}catch(o){O(),n.fail(`\u505C\u6B62\u670D\u52A1\u5931\u8D25: ${o instanceof Error?o.message:String(o)}`)}}catch(e){n.fail(`\u505C\u6B62\u670D\u52A1\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`)}}g(fe,"stopService");async function We(){let n=b("\u68C0\u67E5\u670D\u52A1\u72B6\u6001...").start();try{let e=x();if(e.running){if(n.succeed("\u670D\u52A1\u72B6\u6001"),console.log(s.green("\u2705 \u670D\u52A1\u6B63\u5728\u8FD0\u884C")),console.log(s.gray(` PID: ${e.pid}`)),console.log(s.gray(` \u8FD0\u884C\u65F6\u95F4: ${e.uptime}`)),console.log(s.gray(` \u8FD0\u884C\u6A21\u5F0F: ${e.mode==="daemon"?"\u540E\u53F0\u6A21\u5F0F":"\u524D\u53F0\u6A21\u5F0F"}`)),e.mode==="daemon"){let o=m.join(process.cwd(),"xiaozhi.log");console.log(s.gray(` \u65E5\u5FD7\u6587\u4EF6: ${o}`))}}else n.succeed("\u670D\u52A1\u72B6\u6001"),console.log(s.red("\u274C \u670D\u52A1\u672A\u8FD0\u884C"))}catch(e){n.fail(`\u68C0\u67E5\u72B6\u6001\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`)}}g(We,"checkStatus");async function _e(){let n=b("\u68C0\u67E5\u670D\u52A1\u72B6\u6001...").start();try{let e=x();if(!e.running){n.fail("\u670D\u52A1\u672A\u5728\u8FD0\u884C");return}if(e.mode!=="daemon"){n.fail("\u670D\u52A1\u4E0D\u662F\u5728\u540E\u53F0\u6A21\u5F0F\u8FD0\u884C");return}n.succeed("\u8FDE\u63A5\u5230\u540E\u53F0\u670D\u52A1..."),console.log(s.green(`\u5DF2\u8FDE\u63A5\u5230\u670D\u52A1 (PID: ${e.pid})`)),console.log(s.gray("\u6309 Ctrl+C \u53EF\u4EE5\u65AD\u5F00\u8FDE\u63A5\uFF08\u4E0D\u4F1A\u505C\u6B62\u670D\u52A1\uFF09")),console.log(s.gray("=".repeat(50)));let o=m.join(process.cwd(),"xiaozhi.log");if(u.existsSync(o))if(process.platform==="win32"){let{spawn:t}=await import("child_process"),r=t("powershell",["-Command",`Get-Content -Path "${o}" -Wait`],{stdio:"inherit"});process.on("SIGINT",()=>{console.log(s.yellow(`
35
+ \u6B63\u5728\u505C\u6B62\u670D\u52A1...`)),a.kill("SIGTERM"),global.__webServer)try{await global.__webServer.stop(),console.log(s.green("Web UI \u5DF2\u505C\u6B62"))}catch{}}),process.on("SIGTERM",async()=>{if(a.kill("SIGTERM"),global.__webServer)try{await global.__webServer.stop()}catch{}})}}catch(t){o.fail(`\u542F\u52A8\u670D\u52A1\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`)}}g(pe,"startService");async function fe(){let n=b("\u68C0\u67E5\u670D\u52A1\u72B6\u6001...").start();try{let e=x();if(!e.running){n.warn("\u670D\u52A1\u672A\u5728\u8FD0\u884C");return}n.text=`\u505C\u6B62\u670D\u52A1 (PID: ${e.pid})...`;try{process.kill(e.pid,"SIGTERM");let o=0,t=30;for(;o<t;){await new Promise(r=>setTimeout(r,100));try{process.kill(e.pid,0),o++}catch{break}}try{process.kill(e.pid,0),n.text="\u5F3A\u5236\u505C\u6B62\u670D\u52A1...",process.kill(e.pid,"SIGKILL"),await new Promise(r=>setTimeout(r,500))}catch{}O(),n.succeed("\u670D\u52A1\u5DF2\u505C\u6B62")}catch(o){O(),n.fail(`\u505C\u6B62\u670D\u52A1\u5931\u8D25: ${o instanceof Error?o.message:String(o)}`)}}catch(e){n.fail(`\u505C\u6B62\u670D\u52A1\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`)}}g(fe,"stopService");async function We(){let n=b("\u68C0\u67E5\u670D\u52A1\u72B6\u6001...").start();try{let e=x();if(e.running){if(n.succeed("\u670D\u52A1\u72B6\u6001"),console.log(s.green("\u2705 \u670D\u52A1\u6B63\u5728\u8FD0\u884C")),console.log(s.gray(` PID: ${e.pid}`)),console.log(s.gray(` \u8FD0\u884C\u65F6\u95F4: ${e.uptime}`)),console.log(s.gray(` \u8FD0\u884C\u6A21\u5F0F: ${e.mode==="daemon"?"\u540E\u53F0\u6A21\u5F0F":"\u524D\u53F0\u6A21\u5F0F"}`)),e.mode==="daemon"){let o=f.join(process.cwd(),"xiaozhi.log");console.log(s.gray(` \u65E5\u5FD7\u6587\u4EF6: ${o}`))}}else n.succeed("\u670D\u52A1\u72B6\u6001"),console.log(s.red("\u274C \u670D\u52A1\u672A\u8FD0\u884C"))}catch(e){n.fail(`\u68C0\u67E5\u72B6\u6001\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`)}}g(We,"checkStatus");async function _e(){let n=b("\u68C0\u67E5\u670D\u52A1\u72B6\u6001...").start();try{let e=x();if(!e.running){n.fail("\u670D\u52A1\u672A\u5728\u8FD0\u884C");return}if(e.mode!=="daemon"){n.fail("\u670D\u52A1\u4E0D\u662F\u5728\u540E\u53F0\u6A21\u5F0F\u8FD0\u884C");return}n.succeed("\u8FDE\u63A5\u5230\u540E\u53F0\u670D\u52A1..."),console.log(s.green(`\u5DF2\u8FDE\u63A5\u5230\u670D\u52A1 (PID: ${e.pid})`)),console.log(s.gray("\u6309 Ctrl+C \u53EF\u4EE5\u65AD\u5F00\u8FDE\u63A5\uFF08\u4E0D\u4F1A\u505C\u6B62\u670D\u52A1\uFF09")),console.log(s.gray("=".repeat(50)));let o=f.join(process.cwd(),"xiaozhi.log");if(u.existsSync(o))if(process.platform==="win32"){let{spawn:t}=await import("child_process"),r=t("powershell",["-Command",`Get-Content -Path "${o}" -Wait`],{stdio:"inherit"});process.on("SIGINT",()=>{console.log(s.yellow(`
36
36
  \u65AD\u5F00\u8FDE\u63A5\uFF0C\u670D\u52A1\u7EE7\u7EED\u5728\u540E\u53F0\u8FD0\u884C`)),r.kill(),process.exit(0)}),r.on("exit",()=>{process.exit(0)})}else{let{spawn:t}=await import("child_process"),r=t("tail",["-f",o],{stdio:"inherit"});process.on("SIGINT",()=>{console.log(s.yellow(`
37
- \u65AD\u5F00\u8FDE\u63A5\uFF0C\u670D\u52A1\u7EE7\u7EED\u5728\u540E\u53F0\u8FD0\u884C`)),r.kill(),process.exit(0)}),r.on("exit",()=>{process.exit(0)})}else console.log(s.yellow("\u65E5\u5FD7\u6587\u4EF6\u4E0D\u5B58\u5728"))}catch(e){n.fail(`\u8FDE\u63A5\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`)}}g(_e,"attachService");async function Ge(n=!1,e=!1){console.log(s.blue("\u{1F504} \u91CD\u542F\u670D\u52A1...")),await fe(),await new Promise(o=>setTimeout(o,1e3)),await pe(n,e)}g(Ge,"restartService");async function Le(n,e=!1){let o=b("\u542F\u52A8 MCP Server \u6A21\u5F0F...").start();try{if(!l.configExists()){o.fail("\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728"),console.log(s.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u5148\u8FD0\u884C "xiaozhi init" \u521D\u59CB\u5316\u914D\u7F6E'));return}let{MCPServer:t}=await Promise.resolve().then(()=>(ce(),se));if(e){let r=I(import.meta.url),i=m.dirname(r),c=W("node",[m.join(i,"cli.js"),"start","--server",n.toString()],{detached:!0,stdio:["ignore","pipe","pipe"],env:{...process.env,XIAOZHI_CONFIG_DIR:process.cwd(),XIAOZHI_DAEMON:"true",MCP_SERVER_MODE:"true"}});_(c.pid,"daemon");let a=m.join(process.cwd(),"xiaozhi-mcp-server.log"),f=u.createWriteStream(a,{flags:"a"});c.stdout?.pipe(f),c.stderr?.pipe(f),c.unref(),o.succeed(`MCP Server \u5DF2\u5728\u540E\u53F0\u542F\u52A8 (PID: ${c.pid}, Port: ${n})`),console.log(s.gray(`\u65E5\u5FD7\u6587\u4EF6: ${a}`))}else{let r=new t(n),i=g(async()=>{console.log(s.yellow(`
38
- \u6B63\u5728\u505C\u6B62 MCP Server...`)),await r.stop(),process.exit(0)},"cleanup");process.on("SIGINT",i),process.on("SIGTERM",i),await r.start(),o.succeed("MCP Server \u5DF2\u542F\u52A8"),console.log(s.green(`\u2705 SSE endpoint: http://localhost:${n}/sse`)),console.log(s.green(`\u2705 Messages endpoint: http://localhost:${n}/messages`)),console.log(s.green(`\u2705 RPC endpoint: http://localhost:${n}/rpc`)),console.log(s.yellow("\u{1F4A1} \u63D0\u793A: \u6309 Ctrl+C \u505C\u6B62\u670D\u52A1"))}}catch(t){o.fail(`\u542F\u52A8 MCP Server \u5931\u8D25: ${t instanceof Error?t.message:String(t)}`)}}g(Le,"startMCPServerMode");function Je(){let n=ge();console.log(s.blue(`xiaozhi v${n}`)),console.log(s.gray("MCP Calculator Service CLI Tool")),console.log(s.gray("Built with Node.js and TypeScript")),console.log(s.gray(`Node.js: ${process.version}`)),console.log(s.gray(`Platform: ${process.platform} ${process.arch}`))}g(Je,"showDetailedInfo");async function Xe(){let n=b("\u521D\u59CB\u5316\u914D\u7F6E...").start();try{if(l.configExists()){n.warn("\u914D\u7F6E\u6587\u4EF6\u5DF2\u5B58\u5728"),console.log(s.yellow("\u5982\u9700\u91CD\u65B0\u521D\u59CB\u5316\uFF0C\u8BF7\u5148\u5220\u9664\u73B0\u6709\u7684 xiaozhi.config.json \u6587\u4EF6"));return}l.initConfig(),n.succeed("\u914D\u7F6E\u6587\u4EF6\u521D\u59CB\u5316\u6210\u529F"),console.log(s.green("\u2705 \u914D\u7F6E\u6587\u4EF6\u5DF2\u521B\u5EFA: xiaozhi.config.json")),console.log(s.yellow("\u{1F4DD} \u8BF7\u7F16\u8F91\u914D\u7F6E\u6587\u4EF6\u8BBE\u7F6E\u4F60\u7684 MCP \u7AEF\u70B9:")),console.log(s.gray(` \u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84: ${l.getConfigPath()}`)),console.log(s.yellow("\u{1F4A1} \u6216\u8005\u4F7F\u7528\u547D\u4EE4\u8BBE\u7F6E:")),console.log(s.gray(" xiaozhi config mcpEndpoint <your-endpoint-url>"))}catch(e){n.fail(`\u521D\u59CB\u5316\u914D\u7F6E\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`)}}g(Xe,"initConfig");function Ze(){let n=m.dirname(I(import.meta.url)),o=[m.join(n,"..","templates"),m.join(n,"templates"),m.join(n,"..","..","templates")].find(t=>u.existsSync(t));return o?u.readdirSync(o).filter(t=>{let r=m.join(o,t);return u.statSync(r).isDirectory()}):[]}g(Ze,"getAvailableTemplates");function le(n,e){let o=n.length,t=e.length,r=Array(o+1).fill(null).map(()=>Array(t+1).fill(0));for(let c=0;c<=o;c++)r[c][0]=c;for(let c=0;c<=t;c++)r[0][c]=c;for(let c=1;c<=o;c++)for(let a=1;a<=t;a++)n[c-1]===e[a-1]?r[c][a]=r[c-1][a-1]:r[c][a]=Math.min(r[c-1][a]+1,r[c][a-1]+1,r[c-1][a-1]+1);let i=Math.max(o,t);return i===0?1:(i-r[o][t])/i}g(le,"calculateSimilarity");function Be(n,e){if(e.length===0)return null;let o=e[0],t=le(n.toLowerCase(),o.toLowerCase());for(let r of e.slice(1)){let i=le(n.toLowerCase(),r.toLowerCase());i>t&&(t=i,o=r)}return t>.5?o:null}g(Be,"findSimilarTemplate");async function Ve(n){if(!process.stdin.isTTY)return console.log("n (\u975E\u4EA4\u4E92\u5F0F\u73AF\u5883)"),!1;let e=await import("readline");return new Promise(o=>{process.stdout.write(n);let t=e.createInterface({input:process.stdin,output:process.stdout}),r=g(i=>{let c=i.trim().toLowerCase();c==="y"||c==="yes"?(t.close(),o(!0)):c==="n"||c==="no"||c===""?(t.close(),o(!1)):process.stdout.write("\u8BF7\u8F93\u5165 y \u6216 n: ")},"handleInput");t.on("line",r),t.on("SIGINT",()=>{t.close(),o(!1)})})}g(Ve,"askUserConfirmation");function Ke(n){let e={mcpEndpoint:"<\u8BF7\u586B\u5199\u4F60\u7684\u63A5\u5165\u70B9\u5730\u5740\uFF08\u83B7\u53D6\u5730\u5740\u5728 xiaozhi.me\uFF09>",mcpServers:{}},o=m.join(n,"xiaozhi.config.json");u.writeFileSync(o,JSON.stringify(e,null,2),"utf8")}g(Ke,"createBasicConfig");async function Ye(n,e){let o=b("\u521D\u59CB\u5316\u9879\u76EE...").start();try{let t=m.join(process.cwd(),n);if(u.existsSync(t)){o.fail(`\u76EE\u5F55 "${n}" \u5DF2\u5B58\u5728`),console.log(s.yellow("\u{1F4A1} \u63D0\u793A: \u8BF7\u9009\u62E9\u4E0D\u540C\u7684\u9879\u76EE\u540D\u79F0\u6216\u5220\u9664\u73B0\u6709\u76EE\u5F55"));return}if(e.template){o.text="\u68C0\u67E5\u6A21\u677F...";let r=Ze();if(r.length===0){o.fail("\u627E\u4E0D\u5230 templates \u76EE\u5F55"),console.log(s.yellow("\u{1F4A1} \u63D0\u793A: \u8BF7\u786E\u4FDD xiaozhi-client \u6B63\u786E\u5B89\u88C5"));return}if(!r.includes(e.template)){o.fail(`\u6A21\u677F "${e.template}" \u4E0D\u5B58\u5728`);let h=Be(e.template,r);if(h)if(console.log(s.yellow(`\u{1F4A1} \u4F60\u662F\u60F3\u4F7F\u7528\u6A21\u677F "${h}" \u5417\uFF1F`)),await Ve(s.cyan("\u786E\u8BA4\u4F7F\u7528\u6B64\u6A21\u677F\uFF1F(y/n): ")))e.template=h;else{console.log(s.yellow("\u53EF\u7528\u7684\u6A21\u677F:"));for(let v of r)console.log(s.gray(` - ${v}`));return}else{console.log(s.yellow("\u53EF\u7528\u7684\u6A21\u677F:"));for(let C of r)console.log(s.gray(` - ${C}`));return}}let i=m.dirname(I(import.meta.url)),a=[m.join(i,"..","templates"),m.join(i,"templates"),m.join(i,"..","..","templates")].find(h=>u.existsSync(h)),f=m.join(a,e.template);o.text=`\u4ECE\u6A21\u677F "${e.template}" \u521B\u5EFA\u9879\u76EE "${n}"...`,de(f,t,["node_modules",".pnpm-debug.log","pnpm-lock.yaml"]);let d=m.join(t,"xiaozhi.log");u.existsSync(d)||u.writeFileSync(d,"","utf8"),o.succeed(`\u9879\u76EE "${n}" \u521B\u5EFA\u6210\u529F`),console.log(s.green("\u2705 \u9879\u76EE\u521B\u5EFA\u5B8C\u6210!")),console.log(s.yellow("\u{1F4DD} \u63A5\u4E0B\u6765\u7684\u6B65\u9AA4:")),console.log(s.gray(` cd ${n}`)),console.log(s.gray(" pnpm install # \u5B89\u88C5\u4F9D\u8D56")),console.log(s.gray(" # \u7F16\u8F91 xiaozhi.config.json \u8BBE\u7F6E\u4F60\u7684 MCP \u7AEF\u70B9")),console.log(s.gray(" xiaozhi start # \u542F\u52A8\u670D\u52A1"))}else{o.text=`\u521B\u5EFA\u57FA\u672C\u9879\u76EE "${n}"...`,u.mkdirSync(t,{recursive:!0}),Ke(t);let r=m.join(t,"xiaozhi.log");u.writeFileSync(r,"","utf8"),o.succeed(`\u9879\u76EE "${n}" \u521B\u5EFA\u6210\u529F`),console.log(s.green("\u2705 \u57FA\u672C\u9879\u76EE\u521B\u5EFA\u5B8C\u6210!")),console.log(s.yellow("\u{1F4DD} \u63A5\u4E0B\u6765\u7684\u6B65\u9AA4:")),console.log(s.gray(` cd ${n}`)),console.log(s.gray(" # \u7F16\u8F91 xiaozhi.config.json \u8BBE\u7F6E\u4F60\u7684 MCP \u7AEF\u70B9\u548C\u670D\u52A1")),console.log(s.gray(" xiaozhi start # \u542F\u52A8\u670D\u52A1")),console.log(s.yellow("\u{1F4A1} \u63D0\u793A: \u4F7F\u7528 --template \u9009\u9879\u53EF\u4EE5\u4ECE\u6A21\u677F\u521B\u5EFA\u9879\u76EE"))}}catch(t){o.fail(`\u521B\u5EFA\u9879\u76EE\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`)}}g(Ye,"createProject");function de(n,e,o=[]){u.existsSync(e)||u.mkdirSync(e,{recursive:!0});let t=u.readdirSync(n);for(let r of t){if(o.some(f=>r.includes(f)))continue;let i=m.join(n,r),c=m.join(e,r);u.statSync(i).isDirectory()?de(i,c,o):u.copyFileSync(i,c)}}g(de,"copyDirectory");async function Qe(){let n=b("\u542F\u52A8 UI \u670D\u52A1...").start();try{if(!l.configExists()){n.fail("\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728"),console.log(s.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u5148\u8FD0\u884C "xiaozhi init" \u521D\u59CB\u5316\u914D\u7F6E'));return}let e=new T;await e.start(),n.succeed("UI \u670D\u52A1\u5DF2\u542F\u52A8");let o=l.getWebUIPort();console.log(s.green(`\u2705 \u914D\u7F6E\u7BA1\u7406\u7F51\u9875\u5DF2\u542F\u52A8: http://localhost:${o}`)),console.log(s.yellow("\u{1F4A1} \u63D0\u793A: \u6309 Ctrl+C \u505C\u6B62\u670D\u52A1"));let{spawn:t}=await import("child_process"),r=`http://localhost:${o}`;try{process.platform==="darwin"?t("open",[r],{detached:!0,stdio:"ignore"}).unref():process.platform==="win32"?t("cmd",["/c","start",r],{detached:!0,stdio:"ignore"}).unref():t("xdg-open",[r],{detached:!0,stdio:"ignore"}).unref()}catch{}let i=!1;process.on("SIGINT",async()=>{i&&(console.log(s.red(`
37
+ \u65AD\u5F00\u8FDE\u63A5\uFF0C\u670D\u52A1\u7EE7\u7EED\u5728\u540E\u53F0\u8FD0\u884C`)),r.kill(),process.exit(0)}),r.on("exit",()=>{process.exit(0)})}else console.log(s.yellow("\u65E5\u5FD7\u6587\u4EF6\u4E0D\u5B58\u5728"))}catch(e){n.fail(`\u8FDE\u63A5\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`)}}g(_e,"attachService");async function Ge(n=!1,e=!1){console.log(s.blue("\u{1F504} \u91CD\u542F\u670D\u52A1...")),await fe(),await new Promise(o=>setTimeout(o,1e3)),await pe(n,e)}g(Ge,"restartService");async function Je(n,e=!1){let o=b("\u542F\u52A8 MCP Server \u6A21\u5F0F...").start();try{if(!l.configExists()){o.fail("\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728"),console.log(s.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u5148\u8FD0\u884C "xiaozhi init" \u521D\u59CB\u5316\u914D\u7F6E'));return}let{MCPServer:t}=await Promise.resolve().then(()=>(ce(),se));if(e){let r=I(import.meta.url),i=f.dirname(r),c=W("node",[f.join(i,"cli.js"),"start","--server",n.toString()],{detached:!0,stdio:["ignore","pipe","pipe"],env:{...process.env,XIAOZHI_CONFIG_DIR:process.cwd(),XIAOZHI_DAEMON:"true",MCP_SERVER_MODE:"true"}});_(c.pid,"daemon");let a=f.join(process.cwd(),"xiaozhi-mcp-server.log"),d=u.createWriteStream(a,{flags:"a"});c.stdout?.pipe(d),c.stderr?.pipe(d),c.unref(),o.succeed(`MCP Server \u5DF2\u5728\u540E\u53F0\u542F\u52A8 (PID: ${c.pid}, Port: ${n})`),console.log(s.gray(`\u65E5\u5FD7\u6587\u4EF6: ${a}`))}else{let r=new t(n),i=g(async()=>{console.log(s.yellow(`
38
+ \u6B63\u5728\u505C\u6B62 MCP Server...`)),await r.stop(),process.exit(0)},"cleanup");process.on("SIGINT",i),process.on("SIGTERM",i),await r.start(),o.succeed("MCP Server \u5DF2\u542F\u52A8"),console.log(s.green(`\u2705 SSE endpoint: http://localhost:${n}/sse`)),console.log(s.green(`\u2705 Messages endpoint: http://localhost:${n}/messages`)),console.log(s.green(`\u2705 RPC endpoint: http://localhost:${n}/rpc`)),console.log(s.yellow("\u{1F4A1} \u63D0\u793A: \u6309 Ctrl+C \u505C\u6B62\u670D\u52A1"))}}catch(t){o.fail(`\u542F\u52A8 MCP Server \u5931\u8D25: ${t instanceof Error?t.message:String(t)}`)}}g(Je,"startMCPServerMode");function Le(){let n=ge();console.log(s.blue(`xiaozhi v${n}`)),console.log(s.gray("MCP Calculator Service CLI Tool")),console.log(s.gray("Built with Node.js and TypeScript")),console.log(s.gray(`Node.js: ${process.version}`)),console.log(s.gray(`Platform: ${process.platform} ${process.arch}`))}g(Le,"showDetailedInfo");async function Xe(){let n=b("\u521D\u59CB\u5316\u914D\u7F6E...").start();try{if(l.configExists()){n.warn("\u914D\u7F6E\u6587\u4EF6\u5DF2\u5B58\u5728"),console.log(s.yellow("\u5982\u9700\u91CD\u65B0\u521D\u59CB\u5316\uFF0C\u8BF7\u5148\u5220\u9664\u73B0\u6709\u7684 xiaozhi.config.json \u6587\u4EF6"));return}l.initConfig(),n.succeed("\u914D\u7F6E\u6587\u4EF6\u521D\u59CB\u5316\u6210\u529F"),console.log(s.green("\u2705 \u914D\u7F6E\u6587\u4EF6\u5DF2\u521B\u5EFA: xiaozhi.config.json")),console.log(s.yellow("\u{1F4DD} \u8BF7\u7F16\u8F91\u914D\u7F6E\u6587\u4EF6\u8BBE\u7F6E\u4F60\u7684 MCP \u7AEF\u70B9:")),console.log(s.gray(` \u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84: ${l.getConfigPath()}`)),console.log(s.yellow("\u{1F4A1} \u6216\u8005\u4F7F\u7528\u547D\u4EE4\u8BBE\u7F6E:")),console.log(s.gray(" xiaozhi config mcpEndpoint <your-endpoint-url>"))}catch(e){n.fail(`\u521D\u59CB\u5316\u914D\u7F6E\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`)}}g(Xe,"initConfig");function Ze(){let n=f.dirname(I(import.meta.url)),o=[f.join(n,"..","templates"),f.join(n,"templates"),f.join(n,"..","..","templates")].find(t=>u.existsSync(t));return o?u.readdirSync(o).filter(t=>{let r=f.join(o,t);return u.statSync(r).isDirectory()}):[]}g(Ze,"getAvailableTemplates");function le(n,e){let o=n.length,t=e.length,r=Array(o+1).fill(null).map(()=>Array(t+1).fill(0));for(let c=0;c<=o;c++)r[c][0]=c;for(let c=0;c<=t;c++)r[0][c]=c;for(let c=1;c<=o;c++)for(let a=1;a<=t;a++)n[c-1]===e[a-1]?r[c][a]=r[c-1][a-1]:r[c][a]=Math.min(r[c-1][a]+1,r[c][a-1]+1,r[c-1][a-1]+1);let i=Math.max(o,t);return i===0?1:(i-r[o][t])/i}g(le,"calculateSimilarity");function Be(n,e){if(e.length===0)return null;let o=e[0],t=le(n.toLowerCase(),o.toLowerCase());for(let r of e.slice(1)){let i=le(n.toLowerCase(),r.toLowerCase());i>t&&(t=i,o=r)}return t>.5?o:null}g(Be,"findSimilarTemplate");async function Ve(n){if(!process.stdin.isTTY)return console.log("n (\u975E\u4EA4\u4E92\u5F0F\u73AF\u5883)"),!1;let e=await import("readline");return new Promise(o=>{process.stdout.write(n);let t=e.createInterface({input:process.stdin,output:process.stdout}),r=g(i=>{let c=i.trim().toLowerCase();c==="y"||c==="yes"?(t.close(),o(!0)):c==="n"||c==="no"||c===""?(t.close(),o(!1)):process.stdout.write("\u8BF7\u8F93\u5165 y \u6216 n: ")},"handleInput");t.on("line",r),t.on("SIGINT",()=>{t.close(),o(!1)})})}g(Ve,"askUserConfirmation");function qe(n){let e={mcpEndpoint:"<\u8BF7\u586B\u5199\u4F60\u7684\u63A5\u5165\u70B9\u5730\u5740\uFF08\u83B7\u53D6\u5730\u5740\u5728 xiaozhi.me\uFF09>",mcpServers:{}},o=f.join(n,"xiaozhi.config.json");u.writeFileSync(o,JSON.stringify(e,null,2),"utf8")}g(qe,"createBasicConfig");async function Ke(n,e){let o=b("\u521D\u59CB\u5316\u9879\u76EE...").start();try{let t=f.join(process.cwd(),n);if(u.existsSync(t)){o.fail(`\u76EE\u5F55 "${n}" \u5DF2\u5B58\u5728`),console.log(s.yellow("\u{1F4A1} \u63D0\u793A: \u8BF7\u9009\u62E9\u4E0D\u540C\u7684\u9879\u76EE\u540D\u79F0\u6216\u5220\u9664\u73B0\u6709\u76EE\u5F55"));return}if(e.template){o.text="\u68C0\u67E5\u6A21\u677F...";let r=Ze();if(r.length===0){o.fail("\u627E\u4E0D\u5230 templates \u76EE\u5F55"),console.log(s.yellow("\u{1F4A1} \u63D0\u793A: \u8BF7\u786E\u4FDD xiaozhi-client \u6B63\u786E\u5B89\u88C5"));return}if(!r.includes(e.template)){o.fail(`\u6A21\u677F "${e.template}" \u4E0D\u5B58\u5728`);let h=Be(e.template,r);if(h)if(console.log(s.yellow(`\u{1F4A1} \u4F60\u662F\u60F3\u4F7F\u7528\u6A21\u677F "${h}" \u5417\uFF1F`)),await Ve(s.cyan("\u786E\u8BA4\u4F7F\u7528\u6B64\u6A21\u677F\uFF1F(y/n): ")))e.template=h;else{console.log(s.yellow("\u53EF\u7528\u7684\u6A21\u677F:"));for(let v of r)console.log(s.gray(` - ${v}`));return}else{console.log(s.yellow("\u53EF\u7528\u7684\u6A21\u677F:"));for(let C of r)console.log(s.gray(` - ${C}`));return}}let i=f.dirname(I(import.meta.url)),a=[f.join(i,"..","templates"),f.join(i,"templates"),f.join(i,"..","..","templates")].find(h=>u.existsSync(h)),d=f.join(a,e.template);o.text=`\u4ECE\u6A21\u677F "${e.template}" \u521B\u5EFA\u9879\u76EE "${n}"...`,de(d,t,["node_modules",".pnpm-debug.log","pnpm-lock.yaml"]);let m=f.join(t,"xiaozhi.log");u.existsSync(m)||u.writeFileSync(m,"","utf8"),o.succeed(`\u9879\u76EE "${n}" \u521B\u5EFA\u6210\u529F`),console.log(s.green("\u2705 \u9879\u76EE\u521B\u5EFA\u5B8C\u6210!")),console.log(s.yellow("\u{1F4DD} \u63A5\u4E0B\u6765\u7684\u6B65\u9AA4:")),console.log(s.gray(` cd ${n}`)),console.log(s.gray(" pnpm install # \u5B89\u88C5\u4F9D\u8D56")),console.log(s.gray(" # \u7F16\u8F91 xiaozhi.config.json \u8BBE\u7F6E\u4F60\u7684 MCP \u7AEF\u70B9")),console.log(s.gray(" xiaozhi start # \u542F\u52A8\u670D\u52A1"))}else{o.text=`\u521B\u5EFA\u57FA\u672C\u9879\u76EE "${n}"...`,u.mkdirSync(t,{recursive:!0}),qe(t);let r=f.join(t,"xiaozhi.log");u.writeFileSync(r,"","utf8"),o.succeed(`\u9879\u76EE "${n}" \u521B\u5EFA\u6210\u529F`),console.log(s.green("\u2705 \u57FA\u672C\u9879\u76EE\u521B\u5EFA\u5B8C\u6210!")),console.log(s.yellow("\u{1F4DD} \u63A5\u4E0B\u6765\u7684\u6B65\u9AA4:")),console.log(s.gray(` cd ${n}`)),console.log(s.gray(" # \u7F16\u8F91 xiaozhi.config.json \u8BBE\u7F6E\u4F60\u7684 MCP \u7AEF\u70B9\u548C\u670D\u52A1")),console.log(s.gray(" xiaozhi start # \u542F\u52A8\u670D\u52A1")),console.log(s.yellow("\u{1F4A1} \u63D0\u793A: \u4F7F\u7528 --template \u9009\u9879\u53EF\u4EE5\u4ECE\u6A21\u677F\u521B\u5EFA\u9879\u76EE"))}}catch(t){o.fail(`\u521B\u5EFA\u9879\u76EE\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`)}}g(Ke,"createProject");function de(n,e,o=[]){u.existsSync(e)||u.mkdirSync(e,{recursive:!0});let t=u.readdirSync(n);for(let r of t){if(o.some(d=>r.includes(d)))continue;let i=f.join(n,r),c=f.join(e,r);u.statSync(i).isDirectory()?de(i,c,o):u.copyFileSync(i,c)}}g(de,"copyDirectory");async function Ye(){let n=b("\u542F\u52A8 UI \u670D\u52A1...").start();try{if(!l.configExists()){n.fail("\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728"),console.log(s.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u5148\u8FD0\u884C "xiaozhi init" \u521D\u59CB\u5316\u914D\u7F6E'));return}let e=new T;await e.start(),n.succeed("UI \u670D\u52A1\u5DF2\u542F\u52A8");let o=l.getWebUIPort();console.log(s.green(`\u2705 \u914D\u7F6E\u7BA1\u7406\u7F51\u9875\u5DF2\u542F\u52A8: http://localhost:${o}`)),console.log(s.yellow("\u{1F4A1} \u63D0\u793A: \u6309 Ctrl+C \u505C\u6B62\u670D\u52A1"));let{spawn:t}=await import("child_process"),r=`http://localhost:${o}`;try{process.platform==="darwin"?t("open",[r],{detached:!0,stdio:"ignore"}).unref():process.platform==="win32"?t("cmd",["/c","start",r],{detached:!0,stdio:"ignore"}).unref():t("xdg-open",[r],{detached:!0,stdio:"ignore"}).unref()}catch{}let i=!1;process.on("SIGINT",async()=>{i&&(console.log(s.red(`
39
39
  \u5F3A\u5236\u9000\u51FA...`)),process.exit(1)),i=!0,console.log(s.yellow(`
40
- \u6B63\u5728\u505C\u6B62 UI \u670D\u52A1...`));try{await e.stop(),console.log(s.green("UI \u670D\u52A1\u5DF2\u505C\u6B62"))}catch{console.log(s.red("\u505C\u6B62\u670D\u52A1\u65F6\u51FA\u9519\uFF0C\u5F3A\u5236\u9000\u51FA"))}process.exit(0)}),process.on("SIGTERM",async()=>{i=!0,await e.stop(),process.exit(0)})}catch(e){n.fail(`\u542F\u52A8 UI \u670D\u52A1\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`)}}g(Qe,"startUIService");async function qe(n,e){let o=b("\u66F4\u65B0\u914D\u7F6E...").start();try{if(!l.configExists()){o.fail("\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728"),console.log(s.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u5148\u8FD0\u884C "xiaozhi init" \u521D\u59CB\u5316\u914D\u7F6E'));return}if(e)switch(n){case"mcpEndpoint":l.updateMcpEndpoint(e),o.succeed(`MCP \u7AEF\u70B9\u5DF2\u66F4\u65B0\u4E3A: ${e}`);break;case"heartbeatInterval":{let t=Number.parseInt(e,10);if(Number.isNaN(t)||t<=0){o.fail("\u5FC3\u8DF3\u68C0\u6D4B\u95F4\u9694\u5FC5\u987B\u662F\u5927\u4E8E0\u7684\u6570\u5B57\uFF08\u6BEB\u79D2\uFF09");return}l.setHeartbeatInterval(t),o.succeed(`\u5FC3\u8DF3\u68C0\u6D4B\u95F4\u9694\u5DF2\u66F4\u65B0\u4E3A: ${t}ms`);break}case"heartbeatTimeout":{let t=Number.parseInt(e,10);if(Number.isNaN(t)||t<=0){o.fail("\u5FC3\u8DF3\u8D85\u65F6\u65F6\u95F4\u5FC5\u987B\u662F\u5927\u4E8E0\u7684\u6570\u5B57\uFF08\u6BEB\u79D2\uFF09");return}l.setHeartbeatTimeout(t),o.succeed(`\u5FC3\u8DF3\u8D85\u65F6\u65F6\u95F4\u5DF2\u66F4\u65B0\u4E3A: ${t}ms`);break}case"reconnectInterval":{let t=Number.parseInt(e,10);if(Number.isNaN(t)||t<=0){o.fail("\u91CD\u8FDE\u95F4\u9694\u5FC5\u987B\u662F\u5927\u4E8E0\u7684\u6570\u5B57\uFF08\u6BEB\u79D2\uFF09");return}l.setReconnectInterval(t),o.succeed(`\u91CD\u8FDE\u95F4\u9694\u5DF2\u66F4\u65B0\u4E3A: ${t}ms`);break}default:o.fail(`\u914D\u7F6E\u9879 ${n} \u4E0D\u652F\u6301\u901A\u8FC7\u547D\u4EE4\u884C\u8BBE\u7F6E`),console.log(s.yellow("\u652F\u6301\u8BBE\u7F6E\u7684\u914D\u7F6E\u9879: mcpEndpoint, heartbeatInterval, heartbeatTimeout, reconnectInterval"));return}else{o.text="\u8BFB\u53D6\u914D\u7F6E...";let t=l.getConfig();switch(n){case"mcpEndpoint":{o.succeed("\u914D\u7F6E\u4FE1\u606F");let r=l.getMcpEndpoints();r.length===0?console.log(s.yellow("\u672A\u914D\u7F6E\u4EFB\u4F55 MCP \u7AEF\u70B9")):r.length===1?console.log(s.green(`MCP \u7AEF\u70B9: ${r[0]}`)):(console.log(s.green(`MCP \u7AEF\u70B9 (${r.length} \u4E2A):`)),r.forEach((i,c)=>{console.log(s.gray(` ${c+1}. ${i}`))}));break}case"mcpServers":o.succeed("\u914D\u7F6E\u4FE1\u606F"),console.log(s.green("MCP \u670D\u52A1:"));for(let[r,i]of Object.entries(t.mcpServers))"type"in i&&i.type==="sse"?console.log(s.gray(` ${r}: [SSE] ${i.url}`)):console.log(s.gray(` ${r}: ${i.command} ${i.args.join(" ")}`));break;case"connection":{o.succeed("\u914D\u7F6E\u4FE1\u606F");let r=l.getConnectionConfig();console.log(s.green("\u8FDE\u63A5\u914D\u7F6E:")),console.log(s.gray(` \u5FC3\u8DF3\u68C0\u6D4B\u95F4\u9694: ${r.heartbeatInterval}ms`)),console.log(s.gray(` \u5FC3\u8DF3\u8D85\u65F6\u65F6\u95F4: ${r.heartbeatTimeout}ms`)),console.log(s.gray(` \u91CD\u8FDE\u95F4\u9694: ${r.reconnectInterval}ms`));break}case"heartbeatInterval":o.succeed("\u914D\u7F6E\u4FE1\u606F"),console.log(s.green(`\u5FC3\u8DF3\u68C0\u6D4B\u95F4\u9694: ${l.getHeartbeatInterval()}ms`));break;case"heartbeatTimeout":o.succeed("\u914D\u7F6E\u4FE1\u606F"),console.log(s.green(`\u5FC3\u8DF3\u8D85\u65F6\u65F6\u95F4: ${l.getHeartbeatTimeout()}ms`));break;case"reconnectInterval":o.succeed("\u914D\u7F6E\u4FE1\u606F"),console.log(s.green(`\u91CD\u8FDE\u95F4\u9694: ${l.getReconnectInterval()}ms`));break;default:o.fail(`\u672A\u77E5\u7684\u914D\u7F6E\u9879: ${n}`),console.log(s.yellow("\u652F\u6301\u7684\u914D\u7F6E\u9879: mcpEndpoint, mcpServers, connection, heartbeatInterval, heartbeatTimeout, reconnectInterval"));return}}}catch(t){o.fail(`\u914D\u7F6E\u64CD\u4F5C\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`)}}g(qe,"configCommand");function eo(){console.log(s.blue.bold("xiaozhi - MCP Calculator Service CLI")),console.log(),console.log(s.yellow("\u4F7F\u7528\u65B9\u6CD5:")),console.log(" xiaozhi <command> [options]"),console.log(),console.log(s.yellow("\u547D\u4EE4:")),console.log(" create <projectName> \u521B\u5EFA\u9879\u76EE"),console.log(" init \u521D\u59CB\u5316\u914D\u7F6E\u6587\u4EF6"),console.log(" config <key> [value] \u67E5\u770B\u6216\u8BBE\u7F6E\u914D\u7F6E"),console.log(" start [--daemon] [--ui] [--server] \u542F\u52A8\u670D\u52A1 (--daemon \u540E\u53F0\u8FD0\u884C, --ui \u540C\u65F6\u542F\u52A8 Web UI, --server MCP Server \u6A21\u5F0F)"),console.log(" stop \u505C\u6B62\u670D\u52A1"),console.log(" status \u68C0\u67E5\u670D\u52A1\u72B6\u6001"),console.log(" attach \u8FDE\u63A5\u5230\u540E\u53F0\u670D\u52A1\u67E5\u770B\u65E5\u5FD7"),console.log(" restart [--daemon] [--ui] \u91CD\u542F\u670D\u52A1 (--daemon \u540E\u53F0\u8FD0\u884C, --ui \u540C\u65F6\u542F\u52A8 Web UI)"),console.log(" ui \u542F\u52A8\u914D\u7F6E\u7BA1\u7406\u7F51\u9875"),console.log(" completion \u663E\u793A\u81EA\u52A8\u8865\u5168\u8BBE\u7F6E\u8BF4\u660E"),console.log(),console.log(s.yellow("\u9009\u9879:")),console.log(" -v, --version \u663E\u793A\u7248\u672C\u4FE1\u606F"),console.log(" -V \u663E\u793A\u8BE6\u7EC6\u4FE1\u606F"),console.log(" -h, --help \u663E\u793A\u5E2E\u52A9\u4FE1\u606F"),console.log(" -t, --template <name> \u6307\u5B9A\u6A21\u677F\u540D\u79F0\uFF08\u7528\u4E8E create \u547D\u4EE4\uFF09"),console.log(),console.log(s.yellow("\u9879\u76EE\u793A\u4F8B:")),console.log(" xiaozhi create my-app # \u521B\u5EFA\u57FA\u672C\u9879\u76EE"),console.log(" xiaozhi create my-app -t hello-world # \u4F7F\u7528 hello-world \u6A21\u677F"),console.log(" xiaozhi create my-app --template hello-world # \u540C\u4E0A\uFF0C\u5B8C\u6574\u9009\u9879\u540D"),console.log(),console.log(s.yellow("\u914D\u7F6E\u793A\u4F8B:")),console.log(" xiaozhi init # \u521D\u59CB\u5316\u914D\u7F6E"),console.log(" xiaozhi config mcpEndpoint # \u67E5\u770B MCP \u7AEF\u70B9"),console.log(" xiaozhi config mcpEndpoint wss://... # \u8BBE\u7F6E MCP \u7AEF\u70B9"),console.log(),console.log(s.yellow("\u670D\u52A1\u793A\u4F8B:")),console.log(" xiaozhi start # \u524D\u53F0\u542F\u52A8\u670D\u52A1"),console.log(" xiaozhi start --daemon # \u540E\u53F0\u542F\u52A8\u670D\u52A1"),console.log(" xiaozhi start --ui # \u542F\u52A8\u670D\u52A1\u5E76\u540C\u65F6\u542F\u52A8 Web UI"),console.log(" xiaozhi start -d -u # \u540E\u53F0\u542F\u52A8\u670D\u52A1\u5E76\u540C\u65F6\u542F\u52A8 Web UI"),console.log(" xiaozhi start --server # \u4EE5 MCP Server \u6A21\u5F0F\u542F\u52A8 (\u7AEF\u53E3 3000)"),console.log(" xiaozhi start -s 8080 # \u4EE5 MCP Server \u6A21\u5F0F\u542F\u52A8 (\u7AEF\u53E3 8080)"),console.log(" xiaozhi start -s -d # \u540E\u53F0\u8FD0\u884C MCP Server"),console.log(" xiaozhi status # \u68C0\u67E5\u670D\u52A1\u72B6\u6001"),console.log(" xiaozhi attach # \u67E5\u770B\u540E\u53F0\u670D\u52A1\u65E5\u5FD7"),console.log(" xiaozhi stop # \u505C\u6B62\u670D\u52A1"),console.log(),console.log(s.yellow("MCP \u7BA1\u7406\u793A\u4F8B:")),console.log(" xiaozhi mcp list # \u5217\u51FA\u6240\u6709 MCP \u670D\u52A1"),console.log(" xiaozhi mcp list --tools # \u5217\u51FA\u6240\u6709\u670D\u52A1\u7684\u5DE5\u5177"),console.log(" xiaozhi mcp server <name> # \u5217\u51FA\u6307\u5B9A\u670D\u52A1\u7684\u5DE5\u5177"),console.log(" xiaozhi mcp tool <server> <tool> enable # \u542F\u7528\u5DE5\u5177"),console.log(" xiaozhi mcp tool <server> <tool> disable # \u7981\u7528\u5DE5\u5177"),console.log(),console.log(s.yellow("\u81EA\u52A8\u8865\u5168:")),console.log(" xiaozhi completion # \u663E\u793A\u81EA\u52A8\u8865\u5168\u8BBE\u7F6E\u8BF4\u660E"),console.log(" # \u8BBE\u7F6E\u540E\u53EF\u4F7F\u7528 Tab \u952E\u8FDB\u884C\u547D\u4EE4\u3001\u53C2\u6570\u81EA\u52A8\u8865\u5168")}g(eo,"showHelp");S.name("xiaozhi").description("MCP Calculator Service CLI Tool").version(ge(),"-v, --version","\u663E\u793A\u7248\u672C\u4FE1\u606F").helpOption("-h, --help","\u663E\u793A\u5E2E\u52A9\u4FE1\u606F");S.command("create <projectName>").description("\u521B\u5EFA\u9879\u76EE").option("-t, --template <templateName>","\u4F7F\u7528\u6307\u5B9A\u6A21\u677F\u521B\u5EFA\u9879\u76EE").action(async(n,e)=>{await Ye(n,e)});S.command("init").description("\u521D\u59CB\u5316\u914D\u7F6E\u6587\u4EF6").action(async()=>{await Xe()});S.command("config <key> [value]").description("\u67E5\u770B\u6216\u8BBE\u7F6E\u914D\u7F6E").action(async(n,e)=>{await qe(n,e)});S.command("start").description("\u542F\u52A8\u670D\u52A1").option("-d, --daemon","\u5728\u540E\u53F0\u8FD0\u884C\u670D\u52A1").option("-u, --ui","\u540C\u65F6\u542F\u52A8 Web UI \u670D\u52A1").option("-s, --server [port]","\u4EE5 MCP Server \u6A21\u5F0F\u542F\u52A8 (\u53EF\u9009\u6307\u5B9A\u7AEF\u53E3\uFF0C\u9ED8\u8BA4 3000)").option("--stdio","\u4EE5 stdio \u6A21\u5F0F\u8FD0\u884C MCP Server (\u7528\u4E8E Cursor \u7B49\u5BA2\u6237\u7AEF)").action(async n=>{if(n.stdio){let{spawn:e}=await import("child_process"),o=I(import.meta.url),t=m.dirname(o),r=m.join(t,"mcpServerProxy.js");e("node",[r],{stdio:"inherit",env:{...process.env,XIAOZHI_CONFIG_DIR:process.env.XIAOZHI_CONFIG_DIR||process.cwd()}})}else if(n.server){let e=typeof n.server=="string"?Number.parseInt(n.server):3e3;await Le(e,n.daemon)}else await pe(n.daemon,n.ui)});S.command("stop").description("\u505C\u6B62\u670D\u52A1").action(async()=>{await fe()});S.command("status").description("\u68C0\u67E5\u670D\u52A1\u72B6\u6001").action(async()=>{await We()});S.command("attach").description("\u8FDE\u63A5\u5230\u540E\u53F0\u670D\u52A1\u67E5\u770B\u65E5\u5FD7").action(async()=>{await _e()});S.command("restart").description("\u91CD\u542F\u670D\u52A1").option("-d, --daemon","\u5728\u540E\u53F0\u8FD0\u884C\u670D\u52A1").option("-u, --ui","\u540C\u65F6\u542F\u52A8 Web UI \u670D\u52A1").action(async n=>{await Ge(n.daemon,n.ui)});var L=S.command("mcp").description("MCP \u670D\u52A1\u548C\u5DE5\u5177\u7BA1\u7406");L.command("list").description("\u5217\u51FA MCP \u670D\u52A1").option("--tools","\u663E\u793A\u6240\u6709\u670D\u52A1\u7684\u5DE5\u5177\u5217\u8868").action(async n=>{await ee(n)});L.command("server <serverName>").description("\u7BA1\u7406\u6307\u5B9A\u7684 MCP \u670D\u52A1").action(async n=>{await oe(n)});L.command("tool <serverName> <toolName> <action>").description("\u542F\u7528\u6216\u7981\u7528\u6307\u5B9A\u670D\u52A1\u7684\u5DE5\u5177").action(async(n,e,o)=>{o!=="enable"&&o!=="disable"&&(console.error(s.red("\u9519\u8BEF: \u64CD\u4F5C\u5FC5\u987B\u662F 'enable' \u6216 'disable'")),process.exit(1)),await te(n,e,o==="enable")});var N=S.command("endpoint").description("\u7BA1\u7406 MCP \u7AEF\u70B9");N.command("list").description("\u5217\u51FA\u6240\u6709 MCP \u7AEF\u70B9").action(async()=>{let n=b("\u8BFB\u53D6\u7AEF\u70B9\u914D\u7F6E...").start();try{let e=l.getMcpEndpoints();n.succeed("\u7AEF\u70B9\u5217\u8868"),e.length===0?console.log(s.yellow("\u672A\u914D\u7F6E\u4EFB\u4F55 MCP \u7AEF\u70B9")):(console.log(s.green(`\u5171 ${e.length} \u4E2A\u7AEF\u70B9:`)),e.forEach((o,t)=>{console.log(s.gray(` ${t+1}. ${o}`))}))}catch(e){n.fail(`\u8BFB\u53D6\u7AEF\u70B9\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`)}});N.command("add <url>").description("\u6DFB\u52A0\u65B0\u7684 MCP \u7AEF\u70B9").action(async n=>{let e=b("\u6DFB\u52A0\u7AEF\u70B9...").start();try{l.addMcpEndpoint(n),e.succeed(`\u6210\u529F\u6DFB\u52A0\u7AEF\u70B9: ${n}`);let o=l.getMcpEndpoints();console.log(s.gray(`\u5F53\u524D\u5171 ${o.length} \u4E2A\u7AEF\u70B9`))}catch(o){e.fail(`\u6DFB\u52A0\u7AEF\u70B9\u5931\u8D25: ${o instanceof Error?o.message:String(o)}`)}});N.command("remove <url>").description("\u79FB\u9664\u6307\u5B9A\u7684 MCP \u7AEF\u70B9").action(async n=>{let e=b("\u79FB\u9664\u7AEF\u70B9...").start();try{l.removeMcpEndpoint(n),e.succeed(`\u6210\u529F\u79FB\u9664\u7AEF\u70B9: ${n}`);let o=l.getMcpEndpoints();console.log(s.gray(`\u5F53\u524D\u5269\u4F59 ${o.length} \u4E2A\u7AEF\u70B9`))}catch(o){e.fail(`\u79FB\u9664\u7AEF\u70B9\u5931\u8D25: ${o instanceof Error?o.message:String(o)}`)}});N.command("set <urls...>").description("\u8BBE\u7F6E MCP \u7AEF\u70B9\uFF08\u53EF\u4EE5\u662F\u5355\u4E2A\u6216\u591A\u4E2A\uFF09").action(async n=>{let e=b("\u8BBE\u7F6E\u7AEF\u70B9...").start();try{if(n.length===1)l.updateMcpEndpoint(n[0]),e.succeed(`\u6210\u529F\u8BBE\u7F6E\u7AEF\u70B9: ${n[0]}`);else{l.updateMcpEndpoint(n),e.succeed(`\u6210\u529F\u8BBE\u7F6E ${n.length} \u4E2A\u7AEF\u70B9`);for(let[o,t]of n.entries())console.log(s.gray(` ${o+1}. ${t}`))}}catch(o){e.fail(`\u8BBE\u7F6E\u7AEF\u70B9\u5931\u8D25: ${o instanceof Error?o.message:String(o)}`)}});S.command("ui").description("\u542F\u52A8\u914D\u7F6E\u7BA1\u7406\u7F51\u9875").action(async()=>{await Qe()});S.command("completion").description("\u663E\u793A\u81EA\u52A8\u8865\u5168\u8BBE\u7F6E\u8BF4\u660E").action(async()=>{K()});S.option("-V","\u663E\u793A\u8BE6\u7EC6\u4FE1\u606F").action(n=>{n.V&&(Je(),process.exit(0))});V();process.argv.length<=2&&(eo(),process.exit(0));S.parse(process.argv);export{le as calculateSimilarity,De as checkEnvironment,Ue as formatUptime,x as getServiceStatus,ge as getVersion};
40
+ \u6B63\u5728\u505C\u6B62 UI \u670D\u52A1...`));try{await e.stop(),console.log(s.green("UI \u670D\u52A1\u5DF2\u505C\u6B62"))}catch{console.log(s.red("\u505C\u6B62\u670D\u52A1\u65F6\u51FA\u9519\uFF0C\u5F3A\u5236\u9000\u51FA"))}process.exit(0)}),process.on("SIGTERM",async()=>{i=!0,await e.stop(),process.exit(0)})}catch(e){n.fail(`\u542F\u52A8 UI \u670D\u52A1\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`)}}g(Ye,"startUIService");async function Qe(n,e){let o=b("\u66F4\u65B0\u914D\u7F6E...").start();try{if(!l.configExists()){o.fail("\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728"),console.log(s.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u5148\u8FD0\u884C "xiaozhi init" \u521D\u59CB\u5316\u914D\u7F6E'));return}if(e)switch(n){case"mcpEndpoint":l.updateMcpEndpoint(e),o.succeed(`MCP \u7AEF\u70B9\u5DF2\u66F4\u65B0\u4E3A: ${e}`);break;case"heartbeatInterval":{let t=Number.parseInt(e,10);if(Number.isNaN(t)||t<=0){o.fail("\u5FC3\u8DF3\u68C0\u6D4B\u95F4\u9694\u5FC5\u987B\u662F\u5927\u4E8E0\u7684\u6570\u5B57\uFF08\u6BEB\u79D2\uFF09");return}l.setHeartbeatInterval(t),o.succeed(`\u5FC3\u8DF3\u68C0\u6D4B\u95F4\u9694\u5DF2\u66F4\u65B0\u4E3A: ${t}ms`);break}case"heartbeatTimeout":{let t=Number.parseInt(e,10);if(Number.isNaN(t)||t<=0){o.fail("\u5FC3\u8DF3\u8D85\u65F6\u65F6\u95F4\u5FC5\u987B\u662F\u5927\u4E8E0\u7684\u6570\u5B57\uFF08\u6BEB\u79D2\uFF09");return}l.setHeartbeatTimeout(t),o.succeed(`\u5FC3\u8DF3\u8D85\u65F6\u65F6\u95F4\u5DF2\u66F4\u65B0\u4E3A: ${t}ms`);break}case"reconnectInterval":{let t=Number.parseInt(e,10);if(Number.isNaN(t)||t<=0){o.fail("\u91CD\u8FDE\u95F4\u9694\u5FC5\u987B\u662F\u5927\u4E8E0\u7684\u6570\u5B57\uFF08\u6BEB\u79D2\uFF09");return}l.setReconnectInterval(t),o.succeed(`\u91CD\u8FDE\u95F4\u9694\u5DF2\u66F4\u65B0\u4E3A: ${t}ms`);break}default:o.fail(`\u914D\u7F6E\u9879 ${n} \u4E0D\u652F\u6301\u901A\u8FC7\u547D\u4EE4\u884C\u8BBE\u7F6E`),console.log(s.yellow("\u652F\u6301\u8BBE\u7F6E\u7684\u914D\u7F6E\u9879: mcpEndpoint, heartbeatInterval, heartbeatTimeout, reconnectInterval"));return}else{o.text="\u8BFB\u53D6\u914D\u7F6E...";let t=l.getConfig();switch(n){case"mcpEndpoint":{o.succeed("\u914D\u7F6E\u4FE1\u606F");let r=l.getMcpEndpoints();r.length===0?console.log(s.yellow("\u672A\u914D\u7F6E\u4EFB\u4F55 MCP \u7AEF\u70B9")):r.length===1?console.log(s.green(`MCP \u7AEF\u70B9: ${r[0]}`)):(console.log(s.green(`MCP \u7AEF\u70B9 (${r.length} \u4E2A):`)),r.forEach((i,c)=>{console.log(s.gray(` ${c+1}. ${i}`))}));break}case"mcpServers":o.succeed("\u914D\u7F6E\u4FE1\u606F"),console.log(s.green("MCP \u670D\u52A1:"));for(let[r,i]of Object.entries(t.mcpServers))"type"in i&&i.type==="sse"?console.log(s.gray(` ${r}: [SSE] ${i.url}`)):console.log(s.gray(` ${r}: ${i.command} ${i.args.join(" ")}`));break;case"connection":{o.succeed("\u914D\u7F6E\u4FE1\u606F");let r=l.getConnectionConfig();console.log(s.green("\u8FDE\u63A5\u914D\u7F6E:")),console.log(s.gray(` \u5FC3\u8DF3\u68C0\u6D4B\u95F4\u9694: ${r.heartbeatInterval}ms`)),console.log(s.gray(` \u5FC3\u8DF3\u8D85\u65F6\u65F6\u95F4: ${r.heartbeatTimeout}ms`)),console.log(s.gray(` \u91CD\u8FDE\u95F4\u9694: ${r.reconnectInterval}ms`));break}case"heartbeatInterval":o.succeed("\u914D\u7F6E\u4FE1\u606F"),console.log(s.green(`\u5FC3\u8DF3\u68C0\u6D4B\u95F4\u9694: ${l.getHeartbeatInterval()}ms`));break;case"heartbeatTimeout":o.succeed("\u914D\u7F6E\u4FE1\u606F"),console.log(s.green(`\u5FC3\u8DF3\u8D85\u65F6\u65F6\u95F4: ${l.getHeartbeatTimeout()}ms`));break;case"reconnectInterval":o.succeed("\u914D\u7F6E\u4FE1\u606F"),console.log(s.green(`\u91CD\u8FDE\u95F4\u9694: ${l.getReconnectInterval()}ms`));break;default:o.fail(`\u672A\u77E5\u7684\u914D\u7F6E\u9879: ${n}`),console.log(s.yellow("\u652F\u6301\u7684\u914D\u7F6E\u9879: mcpEndpoint, mcpServers, connection, heartbeatInterval, heartbeatTimeout, reconnectInterval"));return}}}catch(t){o.fail(`\u914D\u7F6E\u64CD\u4F5C\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`)}}g(Qe,"configCommand");function eo(){console.log(s.blue.bold("xiaozhi - MCP Calculator Service CLI")),console.log(),console.log(s.yellow("\u4F7F\u7528\u65B9\u6CD5:")),console.log(" xiaozhi <command> [options]"),console.log(),console.log(s.yellow("\u547D\u4EE4:")),console.log(" create <projectName> \u521B\u5EFA\u9879\u76EE"),console.log(" init \u521D\u59CB\u5316\u914D\u7F6E\u6587\u4EF6"),console.log(" config <key> [value] \u67E5\u770B\u6216\u8BBE\u7F6E\u914D\u7F6E"),console.log(" start [--daemon] [--ui] [--server] \u542F\u52A8\u670D\u52A1 (--daemon \u540E\u53F0\u8FD0\u884C, --ui \u540C\u65F6\u542F\u52A8 Web UI, --server MCP Server \u6A21\u5F0F)"),console.log(" stop \u505C\u6B62\u670D\u52A1"),console.log(" status \u68C0\u67E5\u670D\u52A1\u72B6\u6001"),console.log(" attach \u8FDE\u63A5\u5230\u540E\u53F0\u670D\u52A1\u67E5\u770B\u65E5\u5FD7"),console.log(" restart [--daemon] [--ui] \u91CD\u542F\u670D\u52A1 (--daemon \u540E\u53F0\u8FD0\u884C, --ui \u540C\u65F6\u542F\u52A8 Web UI)"),console.log(" ui \u542F\u52A8\u914D\u7F6E\u7BA1\u7406\u7F51\u9875"),console.log(" completion \u663E\u793A\u81EA\u52A8\u8865\u5168\u8BBE\u7F6E\u8BF4\u660E"),console.log(),console.log(s.yellow("\u9009\u9879:")),console.log(" -v, --version \u663E\u793A\u7248\u672C\u4FE1\u606F"),console.log(" -V \u663E\u793A\u8BE6\u7EC6\u4FE1\u606F"),console.log(" -h, --help \u663E\u793A\u5E2E\u52A9\u4FE1\u606F"),console.log(" -t, --template <name> \u6307\u5B9A\u6A21\u677F\u540D\u79F0\uFF08\u7528\u4E8E create \u547D\u4EE4\uFF09"),console.log(),console.log(s.yellow("\u9879\u76EE\u793A\u4F8B:")),console.log(" xiaozhi create my-app # \u521B\u5EFA\u57FA\u672C\u9879\u76EE"),console.log(" xiaozhi create my-app -t hello-world # \u4F7F\u7528 hello-world \u6A21\u677F"),console.log(" xiaozhi create my-app --template hello-world # \u540C\u4E0A\uFF0C\u5B8C\u6574\u9009\u9879\u540D"),console.log(),console.log(s.yellow("\u914D\u7F6E\u793A\u4F8B:")),console.log(" xiaozhi init # \u521D\u59CB\u5316\u914D\u7F6E"),console.log(" xiaozhi config mcpEndpoint # \u67E5\u770B MCP \u7AEF\u70B9"),console.log(" xiaozhi config mcpEndpoint wss://... # \u8BBE\u7F6E MCP \u7AEF\u70B9"),console.log(),console.log(s.yellow("\u670D\u52A1\u793A\u4F8B:")),console.log(" xiaozhi start # \u524D\u53F0\u542F\u52A8\u670D\u52A1"),console.log(" xiaozhi start --daemon # \u540E\u53F0\u542F\u52A8\u670D\u52A1"),console.log(" xiaozhi start --ui # \u542F\u52A8\u670D\u52A1\u5E76\u540C\u65F6\u542F\u52A8 Web UI"),console.log(" xiaozhi start -d -u # \u540E\u53F0\u542F\u52A8\u670D\u52A1\u5E76\u540C\u65F6\u542F\u52A8 Web UI"),console.log(" xiaozhi start --server # \u4EE5 MCP Server \u6A21\u5F0F\u542F\u52A8 (\u7AEF\u53E3 3000)"),console.log(" xiaozhi start -s 8080 # \u4EE5 MCP Server \u6A21\u5F0F\u542F\u52A8 (\u7AEF\u53E3 8080)"),console.log(" xiaozhi start -s -d # \u540E\u53F0\u8FD0\u884C MCP Server"),console.log(" xiaozhi status # \u68C0\u67E5\u670D\u52A1\u72B6\u6001"),console.log(" xiaozhi attach # \u67E5\u770B\u540E\u53F0\u670D\u52A1\u65E5\u5FD7"),console.log(" xiaozhi stop # \u505C\u6B62\u670D\u52A1"),console.log(),console.log(s.yellow("MCP \u7BA1\u7406\u793A\u4F8B:")),console.log(" xiaozhi mcp list # \u5217\u51FA\u6240\u6709 MCP \u670D\u52A1"),console.log(" xiaozhi mcp list --tools # \u5217\u51FA\u6240\u6709\u670D\u52A1\u7684\u5DE5\u5177"),console.log(" xiaozhi mcp server <name> # \u5217\u51FA\u6307\u5B9A\u670D\u52A1\u7684\u5DE5\u5177"),console.log(" xiaozhi mcp tool <server> <tool> enable # \u542F\u7528\u5DE5\u5177"),console.log(" xiaozhi mcp tool <server> <tool> disable # \u7981\u7528\u5DE5\u5177"),console.log(),console.log(s.yellow("\u81EA\u52A8\u8865\u5168:")),console.log(" xiaozhi completion # \u663E\u793A\u81EA\u52A8\u8865\u5168\u8BBE\u7F6E\u8BF4\u660E"),console.log(" # \u8BBE\u7F6E\u540E\u53EF\u4F7F\u7528 Tab \u952E\u8FDB\u884C\u547D\u4EE4\u3001\u53C2\u6570\u81EA\u52A8\u8865\u5168")}g(eo,"showHelp");S.name("xiaozhi").description("MCP Calculator Service CLI Tool").version(ge(),"-v, --version","\u663E\u793A\u7248\u672C\u4FE1\u606F").helpOption("-h, --help","\u663E\u793A\u5E2E\u52A9\u4FE1\u606F");S.command("create <projectName>").description("\u521B\u5EFA\u9879\u76EE").option("-t, --template <templateName>","\u4F7F\u7528\u6307\u5B9A\u6A21\u677F\u521B\u5EFA\u9879\u76EE").action(async(n,e)=>{await Ke(n,e)});S.command("init").description("\u521D\u59CB\u5316\u914D\u7F6E\u6587\u4EF6").action(async()=>{await Xe()});S.command("config <key> [value]").description("\u67E5\u770B\u6216\u8BBE\u7F6E\u914D\u7F6E").action(async(n,e)=>{await Qe(n,e)});S.command("start").description("\u542F\u52A8\u670D\u52A1").option("-d, --daemon","\u5728\u540E\u53F0\u8FD0\u884C\u670D\u52A1").option("-u, --ui","\u540C\u65F6\u542F\u52A8 Web UI \u670D\u52A1").option("-s, --server [port]","\u4EE5 MCP Server \u6A21\u5F0F\u542F\u52A8 (\u53EF\u9009\u6307\u5B9A\u7AEF\u53E3\uFF0C\u9ED8\u8BA4 3000)").option("--stdio","\u4EE5 stdio \u6A21\u5F0F\u8FD0\u884C MCP Server (\u7528\u4E8E Cursor \u7B49\u5BA2\u6237\u7AEF)").action(async n=>{if(n.stdio){let{spawn:e}=await import("child_process"),o=I(import.meta.url),t=f.dirname(o),r=f.join(t,"mcpServerProxy.js");e("node",[r],{stdio:"inherit",env:{...process.env,XIAOZHI_CONFIG_DIR:process.env.XIAOZHI_CONFIG_DIR||process.cwd()}})}else if(n.server){let e=typeof n.server=="string"?Number.parseInt(n.server):3e3;await Je(e,n.daemon)}else await pe(n.daemon,n.ui)});S.command("stop").description("\u505C\u6B62\u670D\u52A1").action(async()=>{await fe()});S.command("status").description("\u68C0\u67E5\u670D\u52A1\u72B6\u6001").action(async()=>{await We()});S.command("attach").description("\u8FDE\u63A5\u5230\u540E\u53F0\u670D\u52A1\u67E5\u770B\u65E5\u5FD7").action(async()=>{await _e()});S.command("restart").description("\u91CD\u542F\u670D\u52A1").option("-d, --daemon","\u5728\u540E\u53F0\u8FD0\u884C\u670D\u52A1").option("-u, --ui","\u540C\u65F6\u542F\u52A8 Web UI \u670D\u52A1").action(async n=>{await Ge(n.daemon,n.ui)});var J=S.command("mcp").description("MCP \u670D\u52A1\u548C\u5DE5\u5177\u7BA1\u7406");J.command("list").description("\u5217\u51FA MCP \u670D\u52A1").option("--tools","\u663E\u793A\u6240\u6709\u670D\u52A1\u7684\u5DE5\u5177\u5217\u8868").action(async n=>{await ee(n)});J.command("server <serverName>").description("\u7BA1\u7406\u6307\u5B9A\u7684 MCP \u670D\u52A1").action(async n=>{await oe(n)});J.command("tool <serverName> <toolName> <action>").description("\u542F\u7528\u6216\u7981\u7528\u6307\u5B9A\u670D\u52A1\u7684\u5DE5\u5177").action(async(n,e,o)=>{o!=="enable"&&o!=="disable"&&(console.error(s.red("\u9519\u8BEF: \u64CD\u4F5C\u5FC5\u987B\u662F 'enable' \u6216 'disable'")),process.exit(1)),await te(n,e,o==="enable")});var N=S.command("endpoint").description("\u7BA1\u7406 MCP \u7AEF\u70B9");N.command("list").description("\u5217\u51FA\u6240\u6709 MCP \u7AEF\u70B9").action(async()=>{let n=b("\u8BFB\u53D6\u7AEF\u70B9\u914D\u7F6E...").start();try{let e=l.getMcpEndpoints();n.succeed("\u7AEF\u70B9\u5217\u8868"),e.length===0?console.log(s.yellow("\u672A\u914D\u7F6E\u4EFB\u4F55 MCP \u7AEF\u70B9")):(console.log(s.green(`\u5171 ${e.length} \u4E2A\u7AEF\u70B9:`)),e.forEach((o,t)=>{console.log(s.gray(` ${t+1}. ${o}`))}))}catch(e){n.fail(`\u8BFB\u53D6\u7AEF\u70B9\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`)}});N.command("add <url>").description("\u6DFB\u52A0\u65B0\u7684 MCP \u7AEF\u70B9").action(async n=>{let e=b("\u6DFB\u52A0\u7AEF\u70B9...").start();try{l.addMcpEndpoint(n),e.succeed(`\u6210\u529F\u6DFB\u52A0\u7AEF\u70B9: ${n}`);let o=l.getMcpEndpoints();console.log(s.gray(`\u5F53\u524D\u5171 ${o.length} \u4E2A\u7AEF\u70B9`))}catch(o){e.fail(`\u6DFB\u52A0\u7AEF\u70B9\u5931\u8D25: ${o instanceof Error?o.message:String(o)}`)}});N.command("remove <url>").description("\u79FB\u9664\u6307\u5B9A\u7684 MCP \u7AEF\u70B9").action(async n=>{let e=b("\u79FB\u9664\u7AEF\u70B9...").start();try{l.removeMcpEndpoint(n),e.succeed(`\u6210\u529F\u79FB\u9664\u7AEF\u70B9: ${n}`);let o=l.getMcpEndpoints();console.log(s.gray(`\u5F53\u524D\u5269\u4F59 ${o.length} \u4E2A\u7AEF\u70B9`))}catch(o){e.fail(`\u79FB\u9664\u7AEF\u70B9\u5931\u8D25: ${o instanceof Error?o.message:String(o)}`)}});N.command("set <urls...>").description("\u8BBE\u7F6E MCP \u7AEF\u70B9\uFF08\u53EF\u4EE5\u662F\u5355\u4E2A\u6216\u591A\u4E2A\uFF09").action(async n=>{let e=b("\u8BBE\u7F6E\u7AEF\u70B9...").start();try{if(n.length===1)l.updateMcpEndpoint(n[0]),e.succeed(`\u6210\u529F\u8BBE\u7F6E\u7AEF\u70B9: ${n[0]}`);else{l.updateMcpEndpoint(n),e.succeed(`\u6210\u529F\u8BBE\u7F6E ${n.length} \u4E2A\u7AEF\u70B9`);for(let[o,t]of n.entries())console.log(s.gray(` ${o+1}. ${t}`))}}catch(o){e.fail(`\u8BBE\u7F6E\u7AEF\u70B9\u5931\u8D25: ${o instanceof Error?o.message:String(o)}`)}});S.command("ui").description("\u542F\u52A8\u914D\u7F6E\u7BA1\u7406\u7F51\u9875").action(async()=>{await Ye()});S.command("completion").description("\u663E\u793A\u81EA\u52A8\u8865\u5168\u8BBE\u7F6E\u8BF4\u660E").action(async()=>{q()});S.option("-V","\u663E\u793A\u8BE6\u7EC6\u4FE1\u606F").action(n=>{n.V&&(Le(),process.exit(0))});V();process.argv.length<=2&&(eo(),process.exit(0));S.parse(process.argv);export{le as calculateSimilarity,De as checkEnvironment,Ue as formatUptime,x as getServiceStatus,ge as getVersion};
41
41
  //# sourceMappingURL=cli.js.map