xiaozhi-client 1.0.9 → 1.1.0-beta.1

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.
package/README.md CHANGED
@@ -90,7 +90,7 @@ xiaozhi restart
90
90
  xiaozhi mcp list
91
91
 
92
92
  # 列出所有mcp所提供的tools
93
- xiaozhi mcp list --tools
93
+ xiaozhi mcp --tools
94
94
  ```
95
95
 
96
96
  ## 路线图
@@ -1,2 +1,2 @@
1
- var w=Object.defineProperty;var l=(r,o)=>w(r,"name",{value:o,configurable:!0});import M from"omelette";import{copyFileSync as S,existsSync as v,readFileSync as E,writeFileSync as x}from"fs";import{dirname as I,resolve as b}from"path";import{fileURLToPath as P}from"url";var T=I(P(import.meta.url)),u={heartbeatInterval:3e4,heartbeatTimeout:1e4,reconnectInterval:5e3},m=class r{static{l(this,"ConfigManager")}static instance;defaultConfigPath;config=null;constructor(){this.defaultConfigPath=b(T,"xiaozhi.config.default.json")}getConfigFilePath(){let o=process.env.XIAOZHI_CONFIG_DIR||process.cwd();return b(o,"xiaozhi.config.json")}static getInstance(){return r.instance||(r.instance=new r),r.instance}configExists(){let o=this.getConfigFilePath();return v(o)}initConfig(){if(!v(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 o=this.getConfigFilePath();S(this.defaultConfigPath,o),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 o=this.getConfigFilePath(),n=E(o,"utf8"),e=JSON.parse(n);return this.validateConfig(e),e}catch(o){throw o instanceof SyntaxError?new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF: ${o.message}`):o}}validateConfig(o){if(!o||typeof o!="object")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1A\u6839\u5BF9\u8C61\u65E0\u6548");let n=o;if(!n.mcpEndpoint||typeof n.mcpEndpoint!="string")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u5B57\u6BB5\u65E0\u6548");if(!n.mcpServers||typeof n.mcpServers!="object")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers \u5B57\u6BB5\u65E0\u6548");for(let[e,t]of Object.entries(n.mcpServers)){if(!t||typeof t!="object")throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers.${e} \u65E0\u6548`);let i=t;if(!i.command||typeof i.command!="string")throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers.${e}.command \u65E0\u6548`);if(!Array.isArray(i.args))throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers.${e}.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.${e}.env \u5FC5\u987B\u662F\u5BF9\u8C61`)}}getConfig(){return this.config||(this.config=this.loadConfig()),JSON.parse(JSON.stringify(this.config))}getMcpEndpoint(){return this.getConfig().mcpEndpoint}getMcpServers(){return this.getConfig().mcpServers}getMcpServerConfig(){return this.getConfig().mcpServerConfig||{}}getServerToolsConfig(o){return this.getMcpServerConfig()[o]?.tools||{}}isToolEnabled(o,n){return this.getServerToolsConfig(o)[n]?.enable!==!1}updateMcpEndpoint(o){if(!o||typeof o!="string")throw new Error("MCP \u7AEF\u70B9\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let e={...this.getConfig(),mcpEndpoint:o};this.saveConfig(e)}updateMcpServer(o,n){if(!o||typeof o!="string")throw new Error("\u670D\u52A1\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");if(!n.command||typeof n.command!="string")throw new Error("\u670D\u52A1\u914D\u7F6E\u7684 command \u5B57\u6BB5\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");if(!Array.isArray(n.args))throw new Error("\u670D\u52A1\u914D\u7F6E\u7684 args \u5B57\u6BB5\u5FC5\u987B\u662F\u6570\u7EC4");if(n.env&&typeof n.env!="object")throw new Error("\u670D\u52A1\u914D\u7F6E\u7684 env \u5B57\u6BB5\u5FC5\u987B\u662F\u5BF9\u8C61");let e=this.getConfig(),t={...e,mcpServers:{...e.mcpServers,[o]:n}};this.saveConfig(t)}removeMcpServer(o){if(!o||typeof o!="string")throw new Error("\u670D\u52A1\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let n=this.getConfig();if(!n.mcpServers[o])throw new Error(`\u670D\u52A1 ${o} \u4E0D\u5B58\u5728`);let e={...n.mcpServers};delete e[o];let t={...n,mcpServers:e};this.saveConfig(t)}updateServerToolsConfig(o,n){let t={...this.getConfig()};t.mcpServerConfig||(t.mcpServerConfig={}),t.mcpServerConfig[o]={tools:n},this.saveConfig(t)}setToolEnabled(o,n,e,t){let f={...this.getConfig()};f.mcpServerConfig||(f.mcpServerConfig={}),f.mcpServerConfig[o]||(f.mcpServerConfig[o]={tools:{}}),f.mcpServerConfig[o].tools[n]={enable:e,...t&&{description:t}},this.saveConfig(f)}saveConfig(o){try{this.validateConfig(o);let n=this.getConfigFilePath(),e=JSON.stringify(o,null,2);x(n,e,"utf8"),this.config=o}catch(n){throw new Error(`\u4FDD\u5B58\u914D\u7F6E\u5931\u8D25: ${n instanceof Error?n.message:String(n)}`)}}reloadConfig(){this.config=null}getConfigPath(){return this.getConfigFilePath()}getDefaultConfigPath(){return this.defaultConfigPath}getConnectionConfig(){let n=this.getConfig().connection||{};return{heartbeatInterval:n.heartbeatInterval??u.heartbeatInterval,heartbeatTimeout:n.heartbeatTimeout??u.heartbeatTimeout,reconnectInterval:n.reconnectInterval??u.reconnectInterval}}getHeartbeatInterval(){return this.getConnectionConfig().heartbeatInterval}getHeartbeatTimeout(){return this.getConnectionConfig().heartbeatTimeout}getReconnectInterval(){return this.getConnectionConfig().reconnectInterval}updateConnectionConfig(o){let n=this.getConfig(),t={...n.connection||{},...o},i={...n,connection:t};this.saveConfig(i)}setHeartbeatInterval(o){if(o<=0)throw new Error("\u5FC3\u8DF3\u68C0\u6D4B\u95F4\u9694\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({heartbeatInterval:o})}setHeartbeatTimeout(o){if(o<=0)throw new Error("\u5FC3\u8DF3\u8D85\u65F6\u65F6\u95F4\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({heartbeatTimeout:o})}setReconnectInterval(o){if(o<=0)throw new Error("\u91CD\u8FDE\u95F4\u9694\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({reconnectInterval:o})}},h=m.getInstance();function y(){try{if(!h.configExists())return[];let r=h.getMcpServers();return Object.keys(r)}catch{return[]}}l(y,"getMcpServerNames");function z(r){try{if(!h.configExists())return[];let o=h.getServerToolsConfig(r);return Object.keys(o)}catch{return[]}}l(z,"getServerToolNames");function D(){let r=M("xiaozhi <command>");if(r.on("command",({reply:o})=>{o(["create","init","config","start","stop","status","attach","restart","mcp","completion"])}),r.on("complete",(o,{line:n,before:e,reply:t})=>{process.env.XIAOZHI_DEBUG_COMPLETION&&console.error(`Debug completion - line: "${n}", before: "${e}", fragment: "${o}"`);let i=n.trim().split(/\s+/),p=n!==n.trim()?i.length:i.length-1;if(i[1]==="mcp"){let C=i[2];if(p===2){let c=["list","server","tool"],s=i[2]||"",g=c.filter(a=>a.startsWith(s));t(g);return}if(p===3){switch(C){case"list":{let c=["--tools"],s=i[3]||"",g=c.filter(a=>a.startsWith(s));t(g);break}case"server":case"tool":{let c=y(),s=i[3]||"",g=c.filter(a=>a.startsWith(s));t(g);break}default:t([])}return}if(p===4&&C==="tool"){let c=i[3],s=z(c),g=i[4]||"",a=s.filter(d=>d.startsWith(g));t(a);return}if(p===5&&C==="tool"){let c=["enable","disable"],s=i[5]||"",g=c.filter(a=>a.startsWith(s));t(g);return}}if(p===2){switch(i[1]){case"create":t(["--template","-t"]);break;case"start":case"restart":t(["--daemon","-d"]);break;case"completion":t(["install","uninstall"]);break;default:t([])}return}t([])}),process.argv.includes("--completion")){try{console.log(r.setupShellInitFile())}catch(o){console.error("\u751F\u6210\u81EA\u52A8\u8865\u5168\u811A\u672C\u65F6\u51FA\u9519:",o)}process.exit(0)}process.argv.includes("--completion-fish")&&(console.log(r.setupShellInitFile("fish")),process.exit(0)),process.argv.includes("--compzsh")||process.argv.includes("--compbash"),r.init()}l(D,"setupAutoCompletion");function H(){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")}l(H,"showCompletionHelp");export{D as setupAutoCompletion,H as showCompletionHelp};
1
+ var S=Object.defineProperty;var l=(r,o)=>S(r,"name",{value:o,configurable:!0});import z from"omelette";import{copyFileSync as b,existsSync as C,readFileSync as w,writeFileSync as x}from"fs";import{dirname as E,resolve as v}from"path";import{fileURLToPath as P}from"url";var M=E(P(import.meta.url)),u=class r{static{l(this,"ConfigManager")}static instance;defaultConfigPath;config=null;constructor(){this.defaultConfigPath=v(M,"xiaozhi.config.default.json")}getConfigFilePath(){let o=process.env.XIAOZHI_CONFIG_DIR||process.cwd();return v(o,"xiaozhi.config.json")}static getInstance(){return r.instance||(r.instance=new r),r.instance}configExists(){let o=this.getConfigFilePath();return C(o)}initConfig(){if(!C(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 o=this.getConfigFilePath();b(this.defaultConfigPath,o),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 o=this.getConfigFilePath(),t=w(o,"utf8"),e=JSON.parse(t);return this.validateConfig(e),e}catch(o){throw o instanceof SyntaxError?new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF: ${o.message}`):o}}validateConfig(o){if(!o||typeof o!="object")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1A\u6839\u5BF9\u8C61\u65E0\u6548");let t=o;if(!t.mcpEndpoint||typeof t.mcpEndpoint!="string")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u5B57\u6BB5\u65E0\u6548");if(!t.mcpServers||typeof t.mcpServers!="object")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers \u5B57\u6BB5\u65E0\u6548");for(let[e,n]of Object.entries(t.mcpServers)){if(!n||typeof n!="object")throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers.${e} \u65E0\u6548`);let f=n;if(!f.command||typeof f.command!="string")throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers.${e}.command \u65E0\u6548`);if(!Array.isArray(f.args))throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers.${e}.args \u5FC5\u987B\u662F\u6570\u7EC4`);if(f.env&&typeof f.env!="object")throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers.${e}.env \u5FC5\u987B\u662F\u5BF9\u8C61`)}}getConfig(){return this.config||(this.config=this.loadConfig()),JSON.parse(JSON.stringify(this.config))}getMcpEndpoint(){return this.getConfig().mcpEndpoint}getMcpServers(){return this.getConfig().mcpServers}getMcpServerConfig(){return this.getConfig().mcpServerConfig||{}}getServerToolsConfig(o){return this.getMcpServerConfig()[o]?.tools||{}}isToolEnabled(o,t){return this.getServerToolsConfig(o)[t]?.enable!==!1}updateMcpEndpoint(o){if(!o||typeof o!="string")throw new Error("MCP \u7AEF\u70B9\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let e={...this.getConfig(),mcpEndpoint:o};this.saveConfig(e)}updateMcpServer(o,t){if(!o||typeof o!="string")throw new Error("\u670D\u52A1\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");if(!t.command||typeof t.command!="string")throw new Error("\u670D\u52A1\u914D\u7F6E\u7684 command \u5B57\u6BB5\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");if(!Array.isArray(t.args))throw new Error("\u670D\u52A1\u914D\u7F6E\u7684 args \u5B57\u6BB5\u5FC5\u987B\u662F\u6570\u7EC4");if(t.env&&typeof t.env!="object")throw new Error("\u670D\u52A1\u914D\u7F6E\u7684 env \u5B57\u6BB5\u5FC5\u987B\u662F\u5BF9\u8C61");let e=this.getConfig(),n={...e,mcpServers:{...e.mcpServers,[o]:t}};this.saveConfig(n)}removeMcpServer(o){if(!o||typeof o!="string")throw new Error("\u670D\u52A1\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let t=this.getConfig();if(!t.mcpServers[o])throw new Error(`\u670D\u52A1 ${o} \u4E0D\u5B58\u5728`);let e={...t.mcpServers};delete e[o];let n={...t,mcpServers:e};this.saveConfig(n)}updateServerToolsConfig(o,t){let n={...this.getConfig()};n.mcpServerConfig||(n.mcpServerConfig={}),n.mcpServerConfig[o]={tools:t},this.saveConfig(n)}setToolEnabled(o,t,e,n){let i={...this.getConfig()};i.mcpServerConfig||(i.mcpServerConfig={}),i.mcpServerConfig[o]||(i.mcpServerConfig[o]={tools:{}}),i.mcpServerConfig[o].tools[t]={enable:e,...n&&{description:n}},this.saveConfig(i)}saveConfig(o){try{this.validateConfig(o);let t=this.getConfigFilePath(),e=JSON.stringify(o,null,2);x(t,e,"utf8"),this.config=o}catch(t){throw new Error(`\u4FDD\u5B58\u914D\u7F6E\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`)}}reloadConfig(){this.config=null}getConfigPath(){return this.getConfigFilePath()}getDefaultConfigPath(){return this.defaultConfigPath}},m=u.getInstance();function y(){try{if(!m.configExists())return[];let r=m.getMcpServers();return Object.keys(r)}catch{return[]}}l(y,"getMcpServerNames");function T(r){try{if(!m.configExists())return[];let o=m.getServerToolsConfig(r);return Object.keys(o)}catch{return[]}}l(T,"getServerToolNames");function J(){let r=z("xiaozhi");r.on("complete",(o,{line:t,before:e,reply:n})=>{let f=t.trim(),i=f.split(/\s+/),h=t!==f?i.length:i.length-1;if(h===1){let p=["create","init","config","start","stop","status","attach","restart","mcp","completion"],s=i[1]||"",c=p.filter(g=>g.startsWith(s));n(c);return}if(h===2){switch(i[1]){case"create":n(["--template","-t"]);break;case"start":case"restart":n(["--daemon","-d"]);break;case"completion":n(["install","uninstall"]);break;case"mcp":{let s=["list","server","tool"],c=i[2]||"",g=s.filter(a=>a.startsWith(c));n(g);break}default:n([])}return}if(i[1]==="mcp"){let p=i[2];if(h===3){switch(p){case"list":{let s=["--tools"],c=i[3]||"",g=s.filter(a=>a.startsWith(c));n(g);break}case"server":case"tool":{let s=y(),c=i[3]||"",g=s.filter(a=>a.startsWith(c));n(g);break}default:n([])}return}if(h===4&&p==="tool"){let s=i[3],c=T(s),g=i[4]||"",a=c.filter(d=>d.startsWith(g));n(a);return}if(h===5&&p==="tool"){let s=["enable","disable"],c=i[5]||"",g=s.filter(a=>a.startsWith(c));n(g);return}}n([])}),process.argv.includes("--completion")&&(console.log(r.setupShellInitFile()),process.exit(0)),process.argv.includes("--completion-fish")&&(console.log(r.setupShellInitFile("fish")),process.exit(0)),process.argv.includes("--compzsh")||process.argv.includes("--compbash"),r.init()}l(J,"setupAutoCompletion");function D(){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")}l(D,"showCompletionHelp");export{J as setupAutoCompletion,D as showCompletionHelp};
2
2
  //# sourceMappingURL=autoCompletion.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/autoCompletion.ts","../src/configManager.ts"],"sourcesContent":["import omelette from \"omelette\";\nimport { configManager } from \"./configManager\";\n\n/**\n * 自动补全功能模块\n */\n\n/**\n * 获取所有可用的MCP服务器名称\n */\nfunction getMcpServerNames(): string[] {\n try {\n if (!configManager.configExists()) {\n return [];\n }\n const mcpServers = configManager.getMcpServers();\n return Object.keys(mcpServers);\n } catch (error) {\n return [];\n }\n}\n\n/**\n * 获取指定服务器的工具名称\n */\nfunction getServerToolNames(serverName: string): string[] {\n try {\n if (!configManager.configExists()) {\n return [];\n }\n const toolsConfig = configManager.getServerToolsConfig(serverName);\n return Object.keys(toolsConfig);\n } catch (error) {\n return [];\n }\n}\n\n/**\n * 设置自动补全功能\n */\nexport function setupAutoCompletion(): void {\n // 创建 omelette 实例,使用简单的模板\n const completion = omelette(\"xiaozhi <command>\");\n\n // 处理主命令补全\n completion.on(\"command\", ({ reply }) => {\n reply([\n \"create\",\n \"init\",\n \"config\",\n \"start\",\n \"stop\",\n \"status\",\n \"attach\",\n \"restart\",\n \"mcp\",\n \"completion\",\n ]);\n });\n\n // 处理复杂的多级命令补全\n completion.on(\"complete\", (fragment, { line, before, reply }) => {\n // 调试信息\n if (process.env.XIAOZHI_DEBUG_COMPLETION) {\n console.error(\n `Debug completion - line: \"${line}\", before: \"${before}\", fragment: \"${fragment}\"`\n );\n }\n\n const parts = line.trim().split(/\\s+/);\n const endsWithSpace = line !== line.trim();\n const currentIndex = endsWithSpace ? parts.length : parts.length - 1;\n\n // MCP 相关的补全\n if (parts[1] === \"mcp\") {\n const subcommand = parts[2];\n\n if (currentIndex === 2) {\n // mcp 子命令\n const subcommands = [\"list\", \"server\", \"tool\"];\n const current = parts[2] || \"\";\n const matches = subcommands.filter((cmd) => cmd.startsWith(current));\n reply(matches);\n return;\n }\n\n if (currentIndex === 3) {\n switch (subcommand) {\n case \"list\": {\n const options = [\"--tools\"];\n const current = parts[3] || \"\";\n const matches = options.filter((opt) => opt.startsWith(current));\n reply(matches);\n break;\n }\n case \"server\":\n case \"tool\": {\n const serverNames = getMcpServerNames();\n const current = parts[3] || \"\";\n const matches = serverNames.filter((name) =>\n name.startsWith(current)\n );\n reply(matches);\n break;\n }\n default:\n reply([]);\n }\n return;\n }\n\n if (currentIndex === 4 && subcommand === \"tool\") {\n const serverName = parts[3];\n const toolNames = getServerToolNames(serverName);\n const current = parts[4] || \"\";\n const matches = toolNames.filter((name) => name.startsWith(current));\n reply(matches);\n return;\n }\n\n if (currentIndex === 5 && subcommand === \"tool\") {\n const actions = [\"enable\", \"disable\"];\n const current = parts[5] || \"\";\n const matches = actions.filter((action) => action.startsWith(current));\n reply(matches);\n return;\n }\n }\n\n // 其他命令的子参数补全\n if (currentIndex === 2) {\n const command = parts[1];\n switch (command) {\n case \"create\":\n reply([\"--template\", \"-t\"]);\n break;\n case \"start\":\n case \"restart\":\n reply([\"--daemon\", \"-d\"]);\n break;\n case \"completion\":\n reply([\"install\", \"uninstall\"]);\n break;\n default:\n reply([]);\n }\n return;\n }\n\n // 默认情况\n reply([]);\n });\n\n // 处理补全相关的命令行参数\n if (process.argv.includes(\"--completion\")) {\n // 输出补全脚本供shell使用\n try {\n console.log(completion.setupShellInitFile());\n } catch (error) {\n console.error(\"生成自动补全脚本时出错:\", error);\n }\n process.exit(0);\n }\n\n if (process.argv.includes(\"--completion-fish\")) {\n // Fish shell 补全\n console.log(completion.setupShellInitFile(\"fish\"));\n process.exit(0);\n }\n\n if (\n process.argv.includes(\"--compzsh\") ||\n process.argv.includes(\"--compbash\")\n ) {\n // 处理实际的补全请求 - 这些是omelette内部使用的参数\n // 不需要手动处理,让omelette自己处理\n }\n\n // 初始化补全\n completion.init();\n}\n\n/**\n * 显示自动补全安装说明\n */\nexport function showCompletionHelp(): void {\n console.log(\"🚀 xiaozhi 自动补全设置\");\n console.log();\n console.log(\"要启用自动补全,请根据你的shell执行以下命令:\");\n console.log();\n console.log(\"📝 Zsh (推荐):\");\n console.log(\" xiaozhi --completion >> ~/.xiaozhi-completion.zsh\");\n console.log(\" echo 'source ~/.xiaozhi-completion.zsh' >> ~/.zshrc\");\n console.log(\" source ~/.zshrc\");\n console.log();\n console.log(\"📝 Bash:\");\n console.log(\" xiaozhi --completion >> ~/.xiaozhi-completion.bash\");\n console.log(\" echo 'source ~/.xiaozhi-completion.bash' >> ~/.bash_profile\");\n console.log(\" source ~/.bash_profile\");\n console.log();\n console.log(\"📝 Fish:\");\n console.log(\n \" xiaozhi --completion-fish >> ~/.config/fish/completions/xiaozhi.fish\"\n );\n console.log();\n console.log(\"✨ 设置完成后,你就可以使用 Tab 键进行自动补全了!\");\n console.log();\n console.log(\"💡 示例:\");\n console.log(\" xiaozhi m<Tab> # → mcp\");\n console.log(\" xiaozhi mcp l<Tab> # → list\");\n console.log(\" xiaozhi mcp tool <Tab> # → 显示所有服务器名称\");\n}\n","import { copyFileSync, existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\n// 在 ESM 中,需要从 import.meta.url 获取当前文件目录\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\n// 默认连接配置\nconst DEFAULT_CONNECTION_CONFIG: Required<ConnectionConfig> = {\n heartbeatInterval: 30000, // 30秒心跳间隔\n heartbeatTimeout: 10000, // 10秒心跳超时\n reconnectInterval: 5000, // 5秒重连间隔\n};\n\n// 配置文件接口定义\nexport interface MCPServerConfig {\n command: string;\n args: string[];\n env?: Record<string, string>;\n}\n\nexport interface MCPToolConfig {\n description?: string;\n enable: boolean;\n}\n\nexport interface MCPServerToolsConfig {\n tools: Record<string, MCPToolConfig>;\n}\n\nexport interface ConnectionConfig {\n heartbeatInterval?: number; // 心跳检测间隔(毫秒),默认30000\n heartbeatTimeout?: number; // 心跳超时时间(毫秒),默认10000\n reconnectInterval?: number; // 重连间隔(毫秒),默认5000\n}\n\nexport interface AppConfig {\n mcpEndpoint: string;\n mcpServers: Record<string, MCPServerConfig>;\n mcpServerConfig?: Record<string, MCPServerToolsConfig>;\n connection?: ConnectionConfig; // 连接配置(可选,用于向后兼容)\n}\n\n/**\n * 配置管理类\n * 负责管理应用配置,提供只读访问和安全的配置更新功能\n */\nexport class ConfigManager {\n private static instance: ConfigManager;\n private defaultConfigPath: string;\n private config: AppConfig | null = null;\n\n private constructor() {\n this.defaultConfigPath = resolve(__dirname, \"xiaozhi.config.default.json\");\n }\n\n /**\n * 获取配置文件路径(动态计算)\n */\n private getConfigFilePath(): string {\n // 配置文件路径 - 优先使用环境变量指定的目录,否则使用当前工作目录\n const configDir = process.env.XIAOZHI_CONFIG_DIR || process.cwd();\n return resolve(configDir, \"xiaozhi.config.json\");\n }\n\n /**\n * 获取配置管理器单例实例\n */\n public static getInstance(): ConfigManager {\n if (!ConfigManager.instance) {\n ConfigManager.instance = new ConfigManager();\n }\n return ConfigManager.instance;\n }\n\n /**\n * 检查配置文件是否存在\n */\n public configExists(): boolean {\n const configPath = this.getConfigFilePath();\n return existsSync(configPath);\n }\n\n /**\n * 初始化配置文件\n * 从 config.default.json 复制到 config.json\n */\n public initConfig(): void {\n if (!existsSync(this.defaultConfigPath)) {\n throw new Error(\"默认配置文件 xiaozhi.config.default.json 不存在\");\n }\n\n if (this.configExists()) {\n throw new Error(\"配置文件 xiaozhi.config.json 已存在,无需重复初始化\");\n }\n\n const configPath = this.getConfigFilePath();\n copyFileSync(this.defaultConfigPath, configPath);\n this.config = null; // 重置缓存\n }\n\n /**\n * 加载配置文件\n */\n private loadConfig(): AppConfig {\n if (!this.configExists()) {\n throw new Error(\n \"配置文件 xiaozhi.config.json 不存在,请先运行 xiaozhi init 初始化配置\"\n );\n }\n\n try {\n const configPath = this.getConfigFilePath();\n const configData = readFileSync(configPath, \"utf8\");\n const config = JSON.parse(configData) as AppConfig;\n\n // 验证配置结构\n this.validateConfig(config);\n\n return config;\n } catch (error) {\n if (error instanceof SyntaxError) {\n throw new Error(`配置文件格式错误: ${error.message}`);\n }\n throw error;\n }\n }\n\n /**\n * 验证配置文件结构\n */\n private validateConfig(config: unknown): void {\n if (!config || typeof config !== \"object\") {\n throw new Error(\"配置文件格式错误:根对象无效\");\n }\n\n const configObj = config as Record<string, unknown>;\n\n if (!configObj.mcpEndpoint || typeof configObj.mcpEndpoint !== \"string\") {\n throw new Error(\"配置文件格式错误:mcpEndpoint 字段无效\");\n }\n\n if (!configObj.mcpServers || typeof configObj.mcpServers !== \"object\") {\n throw new Error(\"配置文件格式错误:mcpServers 字段无效\");\n }\n\n // 验证每个 MCP 服务配置\n for (const [serverName, serverConfig] of Object.entries(\n configObj.mcpServers as Record<string, unknown>\n )) {\n if (!serverConfig || typeof serverConfig !== \"object\") {\n throw new Error(`配置文件格式错误:mcpServers.${serverName} 无效`);\n }\n\n const sc = serverConfig as Record<string, unknown>;\n if (!sc.command || typeof sc.command !== \"string\") {\n throw new Error(\n `配置文件格式错误:mcpServers.${serverName}.command 无效`\n );\n }\n\n if (!Array.isArray(sc.args)) {\n throw new Error(\n `配置文件格式错误:mcpServers.${serverName}.args 必须是数组`\n );\n }\n\n if (sc.env && typeof sc.env !== \"object\") {\n throw new Error(\n `配置文件格式错误:mcpServers.${serverName}.env 必须是对象`\n );\n }\n }\n }\n\n /**\n * 获取配置(只读)\n */\n public getConfig(): Readonly<AppConfig> {\n if (!this.config) {\n this.config = this.loadConfig();\n }\n\n // 返回深度只读副本\n return JSON.parse(JSON.stringify(this.config));\n }\n\n /**\n * 获取 MCP 端点\n */\n public getMcpEndpoint(): string {\n const config = this.getConfig();\n return config.mcpEndpoint;\n }\n\n /**\n * 获取 MCP 服务配置\n */\n public getMcpServers(): Readonly<Record<string, MCPServerConfig>> {\n const config = this.getConfig();\n return config.mcpServers;\n }\n\n /**\n * 获取 MCP 服务工具配置\n */\n public getMcpServerConfig(): Readonly<Record<string, MCPServerToolsConfig>> {\n const config = this.getConfig();\n return config.mcpServerConfig || {};\n }\n\n /**\n * 获取指定服务的工具配置\n */\n public getServerToolsConfig(\n serverName: string\n ): Readonly<Record<string, MCPToolConfig>> {\n const serverConfig = this.getMcpServerConfig();\n return serverConfig[serverName]?.tools || {};\n }\n\n /**\n * 检查工具是否启用\n */\n public isToolEnabled(serverName: string, toolName: string): boolean {\n const toolsConfig = this.getServerToolsConfig(serverName);\n const toolConfig = toolsConfig[toolName];\n return toolConfig?.enable !== false; // 默认启用\n }\n\n /**\n * 更新 MCP 端点\n */\n public updateMcpEndpoint(endpoint: string): void {\n if (!endpoint || typeof endpoint !== \"string\") {\n throw new Error(\"MCP 端点必须是非空字符串\");\n }\n\n const config = this.getConfig();\n const newConfig = { ...config, mcpEndpoint: endpoint };\n this.saveConfig(newConfig);\n }\n\n /**\n * 更新 MCP 服务配置\n */\n public updateMcpServer(\n serverName: string,\n serverConfig: MCPServerConfig\n ): void {\n if (!serverName || typeof serverName !== \"string\") {\n throw new Error(\"服务名称必须是非空字符串\");\n }\n\n // 验证服务配置\n if (!serverConfig.command || typeof serverConfig.command !== \"string\") {\n throw new Error(\"服务配置的 command 字段必须是非空字符串\");\n }\n\n if (!Array.isArray(serverConfig.args)) {\n throw new Error(\"服务配置的 args 字段必须是数组\");\n }\n\n if (serverConfig.env && typeof serverConfig.env !== \"object\") {\n throw new Error(\"服务配置的 env 字段必须是对象\");\n }\n\n const config = this.getConfig();\n const newConfig = {\n ...config,\n mcpServers: {\n ...config.mcpServers,\n [serverName]: serverConfig,\n },\n };\n this.saveConfig(newConfig);\n }\n\n /**\n * 删除 MCP 服务配置\n */\n public removeMcpServer(serverName: string): void {\n if (!serverName || typeof serverName !== \"string\") {\n throw new Error(\"服务名称必须是非空字符串\");\n }\n\n const config = this.getConfig();\n if (!config.mcpServers[serverName]) {\n throw new Error(`服务 ${serverName} 不存在`);\n }\n\n const newMcpServers = { ...config.mcpServers };\n delete newMcpServers[serverName];\n\n const newConfig = {\n ...config,\n mcpServers: newMcpServers,\n };\n this.saveConfig(newConfig);\n }\n\n /**\n * 更新服务工具配置\n */\n public updateServerToolsConfig(\n serverName: string,\n toolsConfig: Record<string, MCPToolConfig>\n ): void {\n const config = this.getConfig();\n const newConfig = { ...config };\n\n // 确保 mcpServerConfig 存在\n if (!newConfig.mcpServerConfig) {\n newConfig.mcpServerConfig = {};\n }\n\n // 更新指定服务的工具配置\n newConfig.mcpServerConfig[serverName] = {\n tools: toolsConfig,\n };\n\n this.saveConfig(newConfig);\n }\n\n /**\n * 设置工具启用状态\n */\n public setToolEnabled(\n serverName: string,\n toolName: string,\n enabled: boolean,\n description?: string\n ): void {\n const config = this.getConfig();\n const newConfig = { ...config };\n\n // 确保 mcpServerConfig 存在\n if (!newConfig.mcpServerConfig) {\n newConfig.mcpServerConfig = {};\n }\n\n // 确保服务配置存在\n if (!newConfig.mcpServerConfig[serverName]) {\n newConfig.mcpServerConfig[serverName] = { tools: {} };\n }\n\n // 更新工具配置\n newConfig.mcpServerConfig[serverName].tools[toolName] = {\n enable: enabled,\n ...(description && { description }),\n };\n\n this.saveConfig(newConfig);\n }\n\n /**\n * 保存配置到文件\n */\n private saveConfig(config: AppConfig): void {\n try {\n // 验证配置\n this.validateConfig(config);\n\n // 格式化 JSON 并保存\n const configPath = this.getConfigFilePath();\n const configJson = JSON.stringify(config, null, 2);\n writeFileSync(configPath, configJson, \"utf8\");\n\n // 更新缓存\n this.config = config;\n } catch (error) {\n throw new Error(\n `保存配置失败: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n /**\n * 重新加载配置(清除缓存)\n */\n public reloadConfig(): void {\n this.config = null;\n }\n\n /**\n * 获取配置文件路径\n */\n public getConfigPath(): string {\n return this.getConfigFilePath();\n }\n\n /**\n * 获取默认配置文件路径\n */\n public getDefaultConfigPath(): string {\n return this.defaultConfigPath;\n }\n\n /**\n * 获取连接配置(包含默认值)\n */\n public getConnectionConfig(): Required<ConnectionConfig> {\n const config = this.getConfig();\n const connectionConfig = config.connection || {};\n\n return {\n heartbeatInterval:\n connectionConfig.heartbeatInterval ??\n DEFAULT_CONNECTION_CONFIG.heartbeatInterval,\n heartbeatTimeout:\n connectionConfig.heartbeatTimeout ??\n DEFAULT_CONNECTION_CONFIG.heartbeatTimeout,\n reconnectInterval:\n connectionConfig.reconnectInterval ??\n DEFAULT_CONNECTION_CONFIG.reconnectInterval,\n };\n }\n\n /**\n * 获取心跳检测间隔(毫秒)\n */\n public getHeartbeatInterval(): number {\n return this.getConnectionConfig().heartbeatInterval;\n }\n\n /**\n * 获取心跳超时时间(毫秒)\n */\n public getHeartbeatTimeout(): number {\n return this.getConnectionConfig().heartbeatTimeout;\n }\n\n /**\n * 获取重连间隔(毫秒)\n */\n public getReconnectInterval(): number {\n return this.getConnectionConfig().reconnectInterval;\n }\n\n /**\n * 更新连接配置\n */\n public updateConnectionConfig(\n connectionConfig: Partial<ConnectionConfig>\n ): void {\n const config = this.getConfig();\n const currentConnectionConfig = config.connection || {};\n\n const newConnectionConfig = {\n ...currentConnectionConfig,\n ...connectionConfig,\n };\n\n const newConfig = {\n ...config,\n connection: newConnectionConfig,\n };\n\n this.saveConfig(newConfig);\n }\n\n /**\n * 设置心跳检测间隔\n */\n public setHeartbeatInterval(interval: number): void {\n if (interval <= 0) {\n throw new Error(\"心跳检测间隔必须大于0\");\n }\n this.updateConnectionConfig({ heartbeatInterval: interval });\n }\n\n /**\n * 设置心跳超时时间\n */\n public setHeartbeatTimeout(timeout: number): void {\n if (timeout <= 0) {\n throw new Error(\"心跳超时时间必须大于0\");\n }\n this.updateConnectionConfig({ heartbeatTimeout: timeout });\n }\n\n /**\n * 设置重连间隔\n */\n public setReconnectInterval(interval: number): void {\n if (interval <= 0) {\n throw new Error(\"重连间隔必须大于0\");\n }\n this.updateConnectionConfig({ reconnectInterval: interval });\n }\n}\n\n// 导出单例实例\nexport const configManager = ConfigManager.getInstance();\n"],"mappings":"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","names":["omelette","copyFileSync","existsSync","readFileSync","writeFileSync","dirname","resolve","fileURLToPath","__dirname","dirname","fileURLToPath","DEFAULT_CONNECTION_CONFIG","ConfigManager","_ConfigManager","__name","resolve","configDir","configPath","existsSync","copyFileSync","configData","readFileSync","config","error","configObj","serverName","serverConfig","sc","toolName","endpoint","newConfig","newMcpServers","toolsConfig","enabled","description","configJson","writeFileSync","connectionConfig","newConnectionConfig","interval","timeout","configManager","getMcpServerNames","configManager","mcpServers","__name","getServerToolNames","serverName","toolsConfig","setupAutoCompletion","completion","omelette","reply","fragment","line","before","parts","currentIndex","subcommand","subcommands","current","matches","cmd","options","opt","serverNames","name","toolNames","actions","action","error","showCompletionHelp"]}
1
+ {"version":3,"sources":["../src/autoCompletion.ts","../src/configManager.ts"],"sourcesContent":["import omelette from \"omelette\";\nimport { configManager } from \"./configManager\";\n\n/**\n * 自动补全功能模块\n */\n\n/**\n * 获取所有可用的MCP服务器名称\n */\nfunction getMcpServerNames(): string[] {\n try {\n if (!configManager.configExists()) {\n return [];\n }\n const mcpServers = configManager.getMcpServers();\n return Object.keys(mcpServers);\n } catch (error) {\n return [];\n }\n}\n\n/**\n * 获取指定服务器的工具名称\n */\nfunction getServerToolNames(serverName: string): string[] {\n try {\n if (!configManager.configExists()) {\n return [];\n }\n const toolsConfig = configManager.getServerToolsConfig(serverName);\n return Object.keys(toolsConfig);\n } catch (error) {\n return [];\n }\n}\n\n/**\n * 设置自动补全功能\n */\nexport function setupAutoCompletion(): void {\n // 创建 omelette 实例,使用简单的模板\n const completion = omelette(\"xiaozhi\");\n\n // 使用全局事件处理所有补全\n completion.on(\"complete\", (fragment, { line, before, reply }) => {\n // 处理行尾空格的情况\n const trimmedLine = line.trim();\n const parts = trimmedLine.split(/\\s+/);\n\n // 如果原始行以空格结尾,说明用户想要补全下一个参数\n const endsWithSpace = line !== trimmedLine;\n const currentIndex = endsWithSpace ? parts.length : parts.length - 1;\n\n // 主命令补全\n if (currentIndex === 1) {\n const commands = [\n \"create\",\n \"init\",\n \"config\",\n \"start\",\n \"stop\",\n \"status\",\n \"attach\",\n \"restart\",\n \"mcp\",\n \"completion\",\n ];\n\n const current = parts[1] || \"\";\n const matches = commands.filter((cmd) => cmd.startsWith(current));\n reply(matches);\n return;\n }\n\n // 子命令补全\n if (currentIndex === 2) {\n const command = parts[1];\n\n switch (command) {\n case \"create\":\n reply([\"--template\", \"-t\"]);\n break;\n case \"start\":\n case \"restart\":\n reply([\"--daemon\", \"-d\"]);\n break;\n case \"completion\":\n reply([\"install\", \"uninstall\"]);\n break;\n case \"mcp\": {\n const subcommands = [\"list\", \"server\", \"tool\"];\n const current = parts[2] || \"\";\n const matches = subcommands.filter((cmd) => cmd.startsWith(current));\n reply(matches);\n break;\n }\n default:\n reply([]);\n }\n return;\n }\n\n // MCP 相关的进一步补全\n if (parts[1] === \"mcp\") {\n const subcommand = parts[2];\n\n if (currentIndex === 3) {\n switch (subcommand) {\n case \"list\": {\n const options = [\"--tools\"];\n const current = parts[3] || \"\";\n const matches = options.filter((opt) => opt.startsWith(current));\n reply(matches);\n break;\n }\n case \"server\":\n case \"tool\": {\n const serverNames = getMcpServerNames();\n const current = parts[3] || \"\";\n const matches = serverNames.filter((name) =>\n name.startsWith(current)\n );\n reply(matches);\n break;\n }\n default:\n reply([]);\n }\n return;\n }\n\n if (currentIndex === 4 && subcommand === \"tool\") {\n const serverName = parts[3];\n const toolNames = getServerToolNames(serverName);\n const current = parts[4] || \"\";\n const matches = toolNames.filter((name) => name.startsWith(current));\n reply(matches);\n return;\n }\n\n if (currentIndex === 5 && subcommand === \"tool\") {\n const actions = [\"enable\", \"disable\"];\n const current = parts[5] || \"\";\n const matches = actions.filter((action) => action.startsWith(current));\n reply(matches);\n return;\n }\n }\n\n // 默认情况\n reply([]);\n });\n\n // 处理补全相关的命令行参数\n if (process.argv.includes(\"--completion\")) {\n // 输出补全脚本供shell使用\n console.log(completion.setupShellInitFile());\n process.exit(0);\n }\n\n if (process.argv.includes(\"--completion-fish\")) {\n // Fish shell 补全\n console.log(completion.setupShellInitFile(\"fish\"));\n process.exit(0);\n }\n\n if (\n process.argv.includes(\"--compzsh\") ||\n process.argv.includes(\"--compbash\")\n ) {\n // 处理实际的补全请求 - 这些是omelette内部使用的参数\n // 不需要手动处理,让omelette自己处理\n }\n\n // 初始化补全\n completion.init();\n}\n\n/**\n * 显示自动补全安装说明\n */\nexport function showCompletionHelp(): void {\n console.log(\"🚀 xiaozhi 自动补全设置\");\n console.log();\n console.log(\"要启用自动补全,请根据你的shell执行以下命令:\");\n console.log();\n console.log(\"📝 Zsh (推荐):\");\n console.log(\" xiaozhi --completion >> ~/.xiaozhi-completion.zsh\");\n console.log(\" echo 'source ~/.xiaozhi-completion.zsh' >> ~/.zshrc\");\n console.log(\" source ~/.zshrc\");\n console.log();\n console.log(\"📝 Bash:\");\n console.log(\" xiaozhi --completion >> ~/.xiaozhi-completion.bash\");\n console.log(\" echo 'source ~/.xiaozhi-completion.bash' >> ~/.bash_profile\");\n console.log(\" source ~/.bash_profile\");\n console.log();\n console.log(\"📝 Fish:\");\n console.log(\n \" xiaozhi --completion-fish >> ~/.config/fish/completions/xiaozhi.fish\"\n );\n console.log();\n console.log(\"✨ 设置完成后,你就可以使用 Tab 键进行自动补全了!\");\n console.log();\n console.log(\"💡 示例:\");\n console.log(\" xiaozhi m<Tab> # → mcp\");\n console.log(\" xiaozhi mcp l<Tab> # → list\");\n console.log(\" xiaozhi mcp tool <Tab> # → 显示所有服务器名称\");\n}\n","import { copyFileSync, existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\n// 在 ESM 中,需要从 import.meta.url 获取当前文件目录\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\n// 配置文件接口定义\nexport interface MCPServerConfig {\n command: string;\n args: string[];\n env?: Record<string, string>;\n}\n\nexport interface MCPToolConfig {\n description?: string;\n enable: boolean;\n}\n\nexport interface MCPServerToolsConfig {\n tools: Record<string, MCPToolConfig>;\n}\n\nexport interface AppConfig {\n mcpEndpoint: string;\n mcpServers: Record<string, MCPServerConfig>;\n mcpServerConfig?: Record<string, MCPServerToolsConfig>;\n}\n\n/**\n * 配置管理类\n * 负责管理应用配置,提供只读访问和安全的配置更新功能\n */\nexport class ConfigManager {\n private static instance: ConfigManager;\n private defaultConfigPath: string;\n private config: AppConfig | null = null;\n\n private constructor() {\n this.defaultConfigPath = resolve(__dirname, \"xiaozhi.config.default.json\");\n }\n\n /**\n * 获取配置文件路径(动态计算)\n */\n private getConfigFilePath(): string {\n // 配置文件路径 - 优先使用环境变量指定的目录,否则使用当前工作目录\n const configDir = process.env.XIAOZHI_CONFIG_DIR || process.cwd();\n return resolve(configDir, \"xiaozhi.config.json\");\n }\n\n /**\n * 获取配置管理器单例实例\n */\n public static getInstance(): ConfigManager {\n if (!ConfigManager.instance) {\n ConfigManager.instance = new ConfigManager();\n }\n return ConfigManager.instance;\n }\n\n /**\n * 检查配置文件是否存在\n */\n public configExists(): boolean {\n const configPath = this.getConfigFilePath();\n return existsSync(configPath);\n }\n\n /**\n * 初始化配置文件\n * 从 config.default.json 复制到 config.json\n */\n public initConfig(): void {\n if (!existsSync(this.defaultConfigPath)) {\n throw new Error(\"默认配置文件 xiaozhi.config.default.json 不存在\");\n }\n\n if (this.configExists()) {\n throw new Error(\"配置文件 xiaozhi.config.json 已存在,无需重复初始化\");\n }\n\n const configPath = this.getConfigFilePath();\n copyFileSync(this.defaultConfigPath, configPath);\n this.config = null; // 重置缓存\n }\n\n /**\n * 加载配置文件\n */\n private loadConfig(): AppConfig {\n if (!this.configExists()) {\n throw new Error(\n \"配置文件 xiaozhi.config.json 不存在,请先运行 xiaozhi init 初始化配置\"\n );\n }\n\n try {\n const configPath = this.getConfigFilePath();\n const configData = readFileSync(configPath, \"utf8\");\n const config = JSON.parse(configData) as AppConfig;\n\n // 验证配置结构\n this.validateConfig(config);\n\n return config;\n } catch (error) {\n if (error instanceof SyntaxError) {\n throw new Error(`配置文件格式错误: ${error.message}`);\n }\n throw error;\n }\n }\n\n /**\n * 验证配置文件结构\n */\n private validateConfig(config: unknown): void {\n if (!config || typeof config !== \"object\") {\n throw new Error(\"配置文件格式错误:根对象无效\");\n }\n\n const configObj = config as Record<string, unknown>;\n\n if (!configObj.mcpEndpoint || typeof configObj.mcpEndpoint !== \"string\") {\n throw new Error(\"配置文件格式错误:mcpEndpoint 字段无效\");\n }\n\n if (!configObj.mcpServers || typeof configObj.mcpServers !== \"object\") {\n throw new Error(\"配置文件格式错误:mcpServers 字段无效\");\n }\n\n // 验证每个 MCP 服务配置\n for (const [serverName, serverConfig] of Object.entries(\n configObj.mcpServers as Record<string, unknown>\n )) {\n if (!serverConfig || typeof serverConfig !== \"object\") {\n throw new Error(`配置文件格式错误:mcpServers.${serverName} 无效`);\n }\n\n const sc = serverConfig as Record<string, unknown>;\n if (!sc.command || typeof sc.command !== \"string\") {\n throw new Error(\n `配置文件格式错误:mcpServers.${serverName}.command 无效`\n );\n }\n\n if (!Array.isArray(sc.args)) {\n throw new Error(\n `配置文件格式错误:mcpServers.${serverName}.args 必须是数组`\n );\n }\n\n if (sc.env && typeof sc.env !== \"object\") {\n throw new Error(\n `配置文件格式错误:mcpServers.${serverName}.env 必须是对象`\n );\n }\n }\n }\n\n /**\n * 获取配置(只读)\n */\n public getConfig(): Readonly<AppConfig> {\n if (!this.config) {\n this.config = this.loadConfig();\n }\n\n // 返回深度只读副本\n return JSON.parse(JSON.stringify(this.config));\n }\n\n /**\n * 获取 MCP 端点\n */\n public getMcpEndpoint(): string {\n const config = this.getConfig();\n return config.mcpEndpoint;\n }\n\n /**\n * 获取 MCP 服务配置\n */\n public getMcpServers(): Readonly<Record<string, MCPServerConfig>> {\n const config = this.getConfig();\n return config.mcpServers;\n }\n\n /**\n * 获取 MCP 服务工具配置\n */\n public getMcpServerConfig(): Readonly<Record<string, MCPServerToolsConfig>> {\n const config = this.getConfig();\n return config.mcpServerConfig || {};\n }\n\n /**\n * 获取指定服务的工具配置\n */\n public getServerToolsConfig(\n serverName: string\n ): Readonly<Record<string, MCPToolConfig>> {\n const serverConfig = this.getMcpServerConfig();\n return serverConfig[serverName]?.tools || {};\n }\n\n /**\n * 检查工具是否启用\n */\n public isToolEnabled(serverName: string, toolName: string): boolean {\n const toolsConfig = this.getServerToolsConfig(serverName);\n const toolConfig = toolsConfig[toolName];\n return toolConfig?.enable !== false; // 默认启用\n }\n\n /**\n * 更新 MCP 端点\n */\n public updateMcpEndpoint(endpoint: string): void {\n if (!endpoint || typeof endpoint !== \"string\") {\n throw new Error(\"MCP 端点必须是非空字符串\");\n }\n\n const config = this.getConfig();\n const newConfig = { ...config, mcpEndpoint: endpoint };\n this.saveConfig(newConfig);\n }\n\n /**\n * 更新 MCP 服务配置\n */\n public updateMcpServer(\n serverName: string,\n serverConfig: MCPServerConfig\n ): void {\n if (!serverName || typeof serverName !== \"string\") {\n throw new Error(\"服务名称必须是非空字符串\");\n }\n\n // 验证服务配置\n if (!serverConfig.command || typeof serverConfig.command !== \"string\") {\n throw new Error(\"服务配置的 command 字段必须是非空字符串\");\n }\n\n if (!Array.isArray(serverConfig.args)) {\n throw new Error(\"服务配置的 args 字段必须是数组\");\n }\n\n if (serverConfig.env && typeof serverConfig.env !== \"object\") {\n throw new Error(\"服务配置的 env 字段必须是对象\");\n }\n\n const config = this.getConfig();\n const newConfig = {\n ...config,\n mcpServers: {\n ...config.mcpServers,\n [serverName]: serverConfig,\n },\n };\n this.saveConfig(newConfig);\n }\n\n /**\n * 删除 MCP 服务配置\n */\n public removeMcpServer(serverName: string): void {\n if (!serverName || typeof serverName !== \"string\") {\n throw new Error(\"服务名称必须是非空字符串\");\n }\n\n const config = this.getConfig();\n if (!config.mcpServers[serverName]) {\n throw new Error(`服务 ${serverName} 不存在`);\n }\n\n const newMcpServers = { ...config.mcpServers };\n delete newMcpServers[serverName];\n\n const newConfig = {\n ...config,\n mcpServers: newMcpServers,\n };\n this.saveConfig(newConfig);\n }\n\n /**\n * 更新服务工具配置\n */\n public updateServerToolsConfig(\n serverName: string,\n toolsConfig: Record<string, MCPToolConfig>\n ): void {\n const config = this.getConfig();\n const newConfig = { ...config };\n\n // 确保 mcpServerConfig 存在\n if (!newConfig.mcpServerConfig) {\n newConfig.mcpServerConfig = {};\n }\n\n // 更新指定服务的工具配置\n newConfig.mcpServerConfig[serverName] = {\n tools: toolsConfig,\n };\n\n this.saveConfig(newConfig);\n }\n\n /**\n * 设置工具启用状态\n */\n public setToolEnabled(\n serverName: string,\n toolName: string,\n enabled: boolean,\n description?: string\n ): void {\n const config = this.getConfig();\n const newConfig = { ...config };\n\n // 确保 mcpServerConfig 存在\n if (!newConfig.mcpServerConfig) {\n newConfig.mcpServerConfig = {};\n }\n\n // 确保服务配置存在\n if (!newConfig.mcpServerConfig[serverName]) {\n newConfig.mcpServerConfig[serverName] = { tools: {} };\n }\n\n // 更新工具配置\n newConfig.mcpServerConfig[serverName].tools[toolName] = {\n enable: enabled,\n ...(description && { description }),\n };\n\n this.saveConfig(newConfig);\n }\n\n /**\n * 保存配置到文件\n */\n private saveConfig(config: AppConfig): void {\n try {\n // 验证配置\n this.validateConfig(config);\n\n // 格式化 JSON 并保存\n const configPath = this.getConfigFilePath();\n const configJson = JSON.stringify(config, null, 2);\n writeFileSync(configPath, configJson, \"utf8\");\n\n // 更新缓存\n this.config = config;\n } catch (error) {\n throw new Error(\n `保存配置失败: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n /**\n * 重新加载配置(清除缓存)\n */\n public reloadConfig(): void {\n this.config = null;\n }\n\n /**\n * 获取配置文件路径\n */\n public getConfigPath(): string {\n return this.getConfigFilePath();\n }\n\n /**\n * 获取默认配置文件路径\n */\n public getDefaultConfigPath(): string {\n return this.defaultConfigPath;\n }\n}\n\n// 导出单例实例\nexport const configManager = ConfigManager.getInstance();\n"],"mappings":"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","names":["omelette","copyFileSync","existsSync","readFileSync","writeFileSync","dirname","resolve","fileURLToPath","__dirname","dirname","fileURLToPath","ConfigManager","_ConfigManager","__name","resolve","configDir","configPath","existsSync","copyFileSync","configData","readFileSync","config","error","configObj","serverName","serverConfig","sc","toolName","endpoint","newConfig","newMcpServers","toolsConfig","enabled","description","configJson","writeFileSync","configManager","getMcpServerNames","configManager","mcpServers","__name","getServerToolNames","serverName","toolsConfig","setupAutoCompletion","completion","omelette","fragment","line","before","reply","trimmedLine","parts","currentIndex","commands","current","matches","cmd","subcommands","subcommand","options","opt","serverNames","name","toolNames","actions","action","showCompletionHelp"]}
package/dist/cli.js CHANGED
@@ -1,9 +1,8 @@
1
1
  #!/usr/bin/env node
2
- var Y=Object.defineProperty;var a=(t,o)=>Y(t,"name",{value:o,configurable:!0});import{spawn as U}from"child_process";import u from"fs";import go from"os";import f from"path";import{fileURLToPath as I}from"url";import r from"chalk";import{Command as fo}from"commander";import w from"ora";import io from"omelette";import{copyFileSync as K,existsSync as R,readFileSync as Q,writeFileSync as oo}from"fs";import{dirname as eo,resolve as D}from"path";import{fileURLToPath as to}from"url";var no=eo(to(import.meta.url)),M={heartbeatInterval:3e4,heartbeatTimeout:1e4,reconnectInterval:5e3},z=class t{static{a(this,"ConfigManager")}static instance;defaultConfigPath;config=null;constructor(){this.defaultConfigPath=D(no,"xiaozhi.config.default.json")}getConfigFilePath(){let o=process.env.XIAOZHI_CONFIG_DIR||process.cwd();return D(o,"xiaozhi.config.json")}static getInstance(){return t.instance||(t.instance=new t),t.instance}configExists(){let o=this.getConfigFilePath();return R(o)}initConfig(){if(!R(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 o=this.getConfigFilePath();K(this.defaultConfigPath,o),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 o=this.getConfigFilePath(),e=Q(o,"utf8"),n=JSON.parse(e);return this.validateConfig(n),n}catch(o){throw o instanceof SyntaxError?new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF: ${o.message}`):o}}validateConfig(o){if(!o||typeof o!="object")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1A\u6839\u5BF9\u8C61\u65E0\u6548");let e=o;if(!e.mcpEndpoint||typeof e.mcpEndpoint!="string")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u5B57\u6BB5\u65E0\u6548");if(!e.mcpServers||typeof e.mcpServers!="object")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers \u5B57\u6BB5\u65E0\u6548");for(let[n,i]of Object.entries(e.mcpServers)){if(!i||typeof i!="object")throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers.${n} \u65E0\u6548`);let c=i;if(!c.command||typeof c.command!="string")throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers.${n}.command \u65E0\u6548`);if(!Array.isArray(c.args))throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers.${n}.args \u5FC5\u987B\u662F\u6570\u7EC4`);if(c.env&&typeof c.env!="object")throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers.${n}.env \u5FC5\u987B\u662F\u5BF9\u8C61`)}}getConfig(){return this.config||(this.config=this.loadConfig()),JSON.parse(JSON.stringify(this.config))}getMcpEndpoint(){return this.getConfig().mcpEndpoint}getMcpServers(){return this.getConfig().mcpServers}getMcpServerConfig(){return this.getConfig().mcpServerConfig||{}}getServerToolsConfig(o){return this.getMcpServerConfig()[o]?.tools||{}}isToolEnabled(o,e){return this.getServerToolsConfig(o)[e]?.enable!==!1}updateMcpEndpoint(o){if(!o||typeof o!="string")throw new Error("MCP \u7AEF\u70B9\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let n={...this.getConfig(),mcpEndpoint:o};this.saveConfig(n)}updateMcpServer(o,e){if(!o||typeof o!="string")throw new Error("\u670D\u52A1\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");if(!e.command||typeof e.command!="string")throw new Error("\u670D\u52A1\u914D\u7F6E\u7684 command \u5B57\u6BB5\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");if(!Array.isArray(e.args))throw new Error("\u670D\u52A1\u914D\u7F6E\u7684 args \u5B57\u6BB5\u5FC5\u987B\u662F\u6570\u7EC4");if(e.env&&typeof e.env!="object")throw new Error("\u670D\u52A1\u914D\u7F6E\u7684 env \u5B57\u6BB5\u5FC5\u987B\u662F\u5BF9\u8C61");let n=this.getConfig(),i={...n,mcpServers:{...n.mcpServers,[o]:e}};this.saveConfig(i)}removeMcpServer(o){if(!o||typeof o!="string")throw new Error("\u670D\u52A1\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let e=this.getConfig();if(!e.mcpServers[o])throw new Error(`\u670D\u52A1 ${o} \u4E0D\u5B58\u5728`);let n={...e.mcpServers};delete n[o];let i={...e,mcpServers:n};this.saveConfig(i)}updateServerToolsConfig(o,e){let i={...this.getConfig()};i.mcpServerConfig||(i.mcpServerConfig={}),i.mcpServerConfig[o]={tools:e},this.saveConfig(i)}setToolEnabled(o,e,n,i){let s={...this.getConfig()};s.mcpServerConfig||(s.mcpServerConfig={}),s.mcpServerConfig[o]||(s.mcpServerConfig[o]={tools:{}}),s.mcpServerConfig[o].tools[e]={enable:n,...i&&{description:i}},this.saveConfig(s)}saveConfig(o){try{this.validateConfig(o);let e=this.getConfigFilePath(),n=JSON.stringify(o,null,2);oo(e,n,"utf8"),this.config=o}catch(e){throw new Error(`\u4FDD\u5B58\u914D\u7F6E\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`)}}reloadConfig(){this.config=null}getConfigPath(){return this.getConfigFilePath()}getDefaultConfigPath(){return this.defaultConfigPath}getConnectionConfig(){let e=this.getConfig().connection||{};return{heartbeatInterval:e.heartbeatInterval??M.heartbeatInterval,heartbeatTimeout:e.heartbeatTimeout??M.heartbeatTimeout,reconnectInterval:e.reconnectInterval??M.reconnectInterval}}getHeartbeatInterval(){return this.getConnectionConfig().heartbeatInterval}getHeartbeatTimeout(){return this.getConnectionConfig().heartbeatTimeout}getReconnectInterval(){return this.getConnectionConfig().reconnectInterval}updateConnectionConfig(o){let e=this.getConfig(),i={...e.connection||{},...o},c={...e,connection:i};this.saveConfig(c)}setHeartbeatInterval(o){if(o<=0)throw new Error("\u5FC3\u8DF3\u68C0\u6D4B\u95F4\u9694\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({heartbeatInterval:o})}setHeartbeatTimeout(o){if(o<=0)throw new Error("\u5FC3\u8DF3\u8D85\u65F6\u65F6\u95F4\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({heartbeatTimeout:o})}setReconnectInterval(o){if(o<=0)throw new Error("\u91CD\u8FDE\u95F4\u9694\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({reconnectInterval:o})}},p=z.getInstance();function ro(){try{if(!p.configExists())return[];let t=p.getMcpServers();return Object.keys(t)}catch{return[]}}a(ro,"getMcpServerNames");function so(t){try{if(!p.configExists())return[];let o=p.getServerToolsConfig(t);return Object.keys(o)}catch{return[]}}a(so,"getServerToolNames");function O(){let t=io("xiaozhi <command>");if(t.on("command",({reply:o})=>{o(["create","init","config","start","stop","status","attach","restart","mcp","completion"])}),t.on("complete",(o,{line:e,before:n,reply:i})=>{process.env.XIAOZHI_DEBUG_COMPLETION&&console.error(`Debug completion - line: "${e}", before: "${n}", fragment: "${o}"`);let c=e.trim().split(/\s+/),l=e!==e.trim()?c.length:c.length-1;if(c[1]==="mcp"){let h=c[2];if(l===2){let m=["list","server","tool"],d=c[2]||"",y=m.filter(C=>C.startsWith(d));i(y);return}if(l===3){switch(h){case"list":{let m=["--tools"],d=c[3]||"",y=m.filter(C=>C.startsWith(d));i(y);break}case"server":case"tool":{let m=ro(),d=c[3]||"",y=m.filter(C=>C.startsWith(d));i(y);break}default:i([])}return}if(l===4&&h==="tool"){let m=c[3],d=so(m),y=c[4]||"",C=d.filter(T=>T.startsWith(y));i(C);return}if(l===5&&h==="tool"){let m=["enable","disable"],d=c[5]||"",y=m.filter(C=>C.startsWith(d));i(y);return}}if(l===2){switch(c[1]){case"create":i(["--template","-t"]);break;case"start":case"restart":i(["--daemon","-d"]);break;case"completion":i(["install","uninstall"]);break;default:i([])}return}i([])}),process.argv.includes("--completion")){try{console.log(t.setupShellInitFile())}catch(o){console.error("\u751F\u6210\u81EA\u52A8\u8865\u5168\u811A\u672C\u65F6\u51FA\u9519:",o)}process.exit(0)}process.argv.includes("--completion-fish")&&(console.log(t.setupShellInitFile("fish")),process.exit(0)),process.argv.includes("--compzsh")||process.argv.includes("--compbash"),t.init()}a(O,"setupAutoCompletion");function N(){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")}a(N,"showCompletionHelp");import P from"fs";import co from"path";import S from"chalk";import{createConsola as lo}from"consola";function ao(t){let o=t.getFullYear(),e=String(t.getMonth()+1).padStart(2,"0"),n=String(t.getDate()).padStart(2,"0"),i=String(t.getHours()).padStart(2,"0"),c=String(t.getMinutes()).padStart(2,"0"),s=String(t.getSeconds()).padStart(2,"0");return`${o}-${e}-${n} ${i}:${c}:${s}`}a(ao,"formatDateTime");var j=class{static{a(this,"Logger")}logFilePath=null;writeStream=null;consolaInstance;constructor(){this.consolaInstance=lo({formatOptions:{date:!1,colors:!0,compact:!0},fancy:!1}),this.consolaInstance.setReporters([{log:a(o=>{let e={info:"INFO",success:"SUCCESS",warn:"WARN",error:"ERROR",debug:"DEBUG",log:"LOG"},n={info:S.blue,success:S.green,warn:S.yellow,error:S.red,debug:S.gray,log:a(m=>m,"log")},i=e[o.type]||o.type.toUpperCase(),c=n[o.type]||(m=>m),s=ao(new Date),l=c(`[${i}]`),h=`[${s}] ${l} ${o.args.join(" ")}`;console.error(h)},"log")}])}initLogFile(o){this.logFilePath=co.join(o,"xiaozhi.log"),P.existsSync(this.logFilePath)||P.writeFileSync(this.logFilePath,""),this.writeStream=P.createWriteStream(this.logFilePath,{flags:"a",encoding:"utf8"})}logToFile(o,e,...n){if(this.writeStream){let c=`[${new Date().toISOString()}] [${o.toUpperCase()}] ${e}`,s=n.length>0?`${c} ${n.map(l=>typeof l=="object"?JSON.stringify(l):String(l)).join(" ")}`:c;this.writeStream.write(`${s}
3
- `)}}enableFileLogging(o){o&&!this.writeStream&&this.logFilePath?this.writeStream=P.createWriteStream(this.logFilePath,{flags:"a",encoding:"utf8"}):!o&&this.writeStream&&(this.writeStream.end(),this.writeStream=null)}info(o,...e){this.consolaInstance.info(o,...e),this.logToFile("info",o,...e)}success(o,...e){this.consolaInstance.success(o,...e),this.logToFile("success",o,...e)}warn(o,...e){this.consolaInstance.warn(o,...e),this.logToFile("warn",o,...e)}error(o,...e){this.consolaInstance.error(o,...e),this.logToFile("error",o,...e)}debug(o,...e){this.consolaInstance.debug(o,...e),this.logToFile("debug",o,...e)}log(o,...e){this.consolaInstance.log(o,...e),this.logToFile("log",o,...e)}withTag(o){return this}close(){this.writeStream&&(this.writeStream.end(),this.writeStream=null)}},x=new j;import g from"chalk";import A from"cli-table3";import k from"ora";function L(t){let o=0;for(let e of t)/[\u4e00-\u9fff\u3400-\u4dbf\uff00-\uffef]/.test(e)?o+=2:o+=1;return o}a(L,"getDisplayWidth");function W(t,o){if(L(t)<=o)return t;if(o<=3)return"";let e="",n=0,i=!1;for(let c of t){let s=/[\u4e00-\u9fff\u3400-\u4dbf\uff00-\uffef]/.test(c)?2:1;if(n+s>o-3){if(!i)return"";e+="...";break}e+=c,n+=s,i=!0}return e}a(W,"truncateToWidth");async function G(t={}){let o=k("\u83B7\u53D6 MCP \u670D\u52A1\u5217\u8868...").start();try{let e=p.getMcpServers(),n=Object.keys(e);if(n.length===0){o.warn("\u672A\u914D\u7F6E\u4EFB\u4F55 MCP \u670D\u52A1"),console.log(g.yellow("\u{1F4A1} \u63D0\u793A: \u4F7F\u7528 'xiaozhi config' \u547D\u4EE4\u914D\u7F6E MCP \u670D\u52A1"));return}if(o.succeed(`\u627E\u5230 ${n.length} \u4E2A MCP \u670D\u52A1`),t.tools){console.log(),console.log(g.bold("MCP \u670D\u52A1\u5DE5\u5177\u5217\u8868:")),console.log();let i=8,c=[];for(let l of n){let h=p.getServerToolsConfig(l),m=Object.keys(h);c.push(...m)}for(let l of c){let h=L(l);h>i&&(i=h)}i=Math.max(10,Math.min(i+2,30));let s=new A({head:[g.bold("MCP"),g.bold("\u5DE5\u5177\u540D\u79F0"),g.bold("\u72B6\u6001"),g.bold("\u63CF\u8FF0")],colWidths:[15,i,8,40],wordWrap:!0,style:{head:[],border:[]}});for(let l of n){let h=p.getServerToolsConfig(l),m=Object.keys(h);if(m.length===0)s.push([g.gray(l),g.gray("(\u65E0\u5DE5\u5177)"),g.gray("-"),g.gray("\u8BF7\u5148\u542F\u52A8\u670D\u52A1\u626B\u63CF\u5DE5\u5177")]);else{s.length>0&&s.push([{colSpan:4,content:""}]);for(let d of m){let y=h[d],C=y.enable?g.green("\u542F\u7528"):g.red("\u7981\u7528"),T=W(y.description||"",32);s.push([l,d,C,T])}}}console.log(s.toString())}else{console.log(),console.log(g.bold("MCP \u670D\u52A1\u5217\u8868:")),console.log();for(let i of n){let c=e[i],s=p.getServerToolsConfig(i),l=Object.keys(s).length,h=Object.values(s).filter(m=>m.enable!==!1).length;console.log(`${g.cyan("\u2022")} ${g.bold(i)}`),console.log(` \u547D\u4EE4: ${g.gray(c.command)} ${g.gray(c.args.join(" "))}`),l>0?console.log(` \u5DE5\u5177: ${g.green(h)} \u542F\u7528 / ${g.yellow(l)} \u603B\u8BA1`):console.log(` \u5DE5\u5177: ${g.gray("\u672A\u626B\u63CF (\u8BF7\u5148\u542F\u52A8\u670D\u52A1)")}`),console.log()}}console.log(g.gray("\u{1F4A1} \u63D0\u793A:")),console.log(g.gray(" - \u4F7F\u7528 'xiaozhi mcp list --tools' \u67E5\u770B\u6240\u6709\u5DE5\u5177")),console.log(g.gray(" - \u4F7F\u7528 'xiaozhi mcp <\u670D\u52A1\u540D> list' \u67E5\u770B\u6307\u5B9A\u670D\u52A1\u7684\u5DE5\u5177")),console.log(g.gray(" - \u4F7F\u7528 'xiaozhi mcp <\u670D\u52A1\u540D> <\u5DE5\u5177\u540D> enable/disable' \u542F\u7528/\u7981\u7528\u5DE5\u5177"))}catch(e){o.fail("\u83B7\u53D6 MCP \u670D\u52A1\u5217\u8868\u5931\u8D25"),console.error(g.red(`\u9519\u8BEF: ${e instanceof Error?e.message:String(e)}`)),process.exit(1)}}a(G,"listMcpServers");async function H(t){let o=k(`\u83B7\u53D6 ${t} \u670D\u52A1\u7684\u5DE5\u5177\u5217\u8868...`).start();try{if(!p.getMcpServers()[t]){o.fail(`\u670D\u52A1 '${t}' \u4E0D\u5B58\u5728`),console.log(g.yellow("\u{1F4A1} \u63D0\u793A: \u4F7F\u7528 'xiaozhi mcp list' \u67E5\u770B\u6240\u6709\u53EF\u7528\u670D\u52A1"));return}let n=p.getServerToolsConfig(t),i=Object.keys(n);if(i.length===0){o.warn(`\u670D\u52A1 '${t}' \u6682\u65E0\u5DE5\u5177\u4FE1\u606F`),console.log(g.yellow("\u{1F4A1} \u63D0\u793A: \u8BF7\u5148\u542F\u52A8\u670D\u52A1\u4EE5\u626B\u63CF\u5DE5\u5177\u5217\u8868"));return}o.succeed(`\u670D\u52A1 '${t}' \u5171\u6709 ${i.length} \u4E2A\u5DE5\u5177`),console.log(),console.log(g.bold(`${t} \u670D\u52A1\u5DE5\u5177\u5217\u8868:`)),console.log();let c=new A({head:[g.bold("\u5DE5\u5177\u540D\u79F0"),g.bold("\u72B6\u6001"),g.bold("\u63CF\u8FF0")],colWidths:[30,8,50],wordWrap:!0,style:{head:[],border:[]}});for(let s of i){let l=n[s],h=l.enable?g.green("\u542F\u7528"):g.red("\u7981\u7528"),m=W(l.description||"",40);c.push([s,h,m])}console.log(c.toString()),console.log(),console.log(g.gray("\u{1F4A1} \u63D0\u793A:")),console.log(g.gray(` - \u4F7F\u7528 'xiaozhi mcp ${t} <\u5DE5\u5177\u540D> enable' \u542F\u7528\u5DE5\u5177`)),console.log(g.gray(` - \u4F7F\u7528 'xiaozhi mcp ${t} <\u5DE5\u5177\u540D> disable' \u7981\u7528\u5DE5\u5177`))}catch(e){o.fail("\u83B7\u53D6\u5DE5\u5177\u5217\u8868\u5931\u8D25"),console.error(g.red(`\u9519\u8BEF: ${e instanceof Error?e.message:String(e)}`)),process.exit(1)}}a(H,"listServerTools");async function _(t,o,e){let n=e?"\u542F\u7528":"\u7981\u7528",i=k(`${n}\u5DE5\u5177 ${t}/${o}...`).start();try{if(!p.getMcpServers()[t]){i.fail(`\u670D\u52A1 '${t}' \u4E0D\u5B58\u5728`),console.log(g.yellow("\u{1F4A1} \u63D0\u793A: \u4F7F\u7528 'xiaozhi mcp list' \u67E5\u770B\u6240\u6709\u53EF\u7528\u670D\u52A1"));return}let s=p.getServerToolsConfig(t);if(!s[o]){i.fail(`\u5DE5\u5177 '${o}' \u5728\u670D\u52A1 '${t}' \u4E2D\u4E0D\u5B58\u5728`),console.log(g.yellow(`\u{1F4A1} \u63D0\u793A: \u4F7F\u7528 'xiaozhi mcp ${t} list' \u67E5\u770B\u8BE5\u670D\u52A1\u7684\u6240\u6709\u5DE5\u5177`));return}p.setToolEnabled(t,o,e,s[o].description),i.succeed(`\u6210\u529F${n}\u5DE5\u5177 ${g.cyan(t)}/${g.cyan(o)}`),console.log(),console.log(g.gray("\u{1F4A1} \u63D0\u793A: \u5DE5\u5177\u72B6\u6001\u66F4\u6539\u5C06\u5728\u4E0B\u6B21\u542F\u52A8\u670D\u52A1\u65F6\u751F\u6548"))}catch(c){i.fail(`${n}\u5DE5\u5177\u5931\u8D25`),console.error(g.red(`\u9519\u8BEF: ${c instanceof Error?c.message:String(c)}`)),process.exit(1)}}a(_,"setToolEnabled");var b=new fo,po="xiaozhi-mcp-service";function B(){try{let t=I(import.meta.url),o=f.dirname(t),e=[f.join(o,"..","package.json"),f.join(o,"..","package.json"),f.join(o,"..","..","package.json"),f.join(o,"package.json")];for(let n of e)if(u.existsSync(n)){let i=JSON.parse(u.readFileSync(n,"utf8"));if(i.version)return i.version}return"unknown"}catch(t){return console.warn("\u65E0\u6CD5\u4ECE package.json \u8BFB\u53D6\u7248\u672C\u4FE1\u606F:",t),"unknown"}}a(B,"getVersion");var v=f.join(go.tmpdir(),`${po}.pid`);function E(){try{if(!u.existsSync(v))return{running:!1};let t=u.readFileSync(v,"utf8").trim(),[o,e,n]=t.split("|"),i=Number.parseInt(o);if(Number.isNaN(i))return u.unlinkSync(v),{running:!1};try{process.kill(i,0);let c=Number.parseInt(e),s=mo(Date.now()-c);return{running:!0,pid:i,uptime:s,mode:n||"foreground"}}catch{return u.unlinkSync(v),{running:!1}}}catch{return{running:!1}}}a(E,"getServiceStatus");function mo(t){let o=Math.floor(t/1e3),e=Math.floor(o/60),n=Math.floor(e/60),i=Math.floor(n/24);return i>0?`${i}\u5929 ${n%24}\u5C0F\u65F6 ${e%60}\u5206\u949F`:n>0?`${n}\u5C0F\u65F6 ${e%60}\u5206\u949F`:e>0?`${e}\u5206\u949F ${o%60}\u79D2`:`${o}\u79D2`}a(mo,"formatUptime");function J(t,o){let e=`${t}|${Date.now()}|${o}`;u.writeFileSync(v,e)}a(J,"savePidInfo");function $(){try{u.existsSync(v)&&u.unlinkSync(v)}catch{}}a($,"cleanupPidFile");function uo(){if(!p.configExists())return console.error(r.red("\u274C \u9519\u8BEF: \u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728")),console.log(r.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u8FD0\u884C "xiaozhi init" \u521D\u59CB\u5316\u914D\u7F6E')),!1;try{let t=p.getMcpEndpoint();return!t||t.includes("<\u8BF7\u586B\u5199")?(console.error(r.red("\u274C \u9519\u8BEF: MCP \u7AEF\u70B9\u672A\u914D\u7F6E")),console.log(r.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u8FD0\u884C "xiaozhi config mcpEndpoint <your-endpoint-url>" \u8BBE\u7F6E\u7AEF\u70B9')),!1):!0}catch(t){return console.error(r.red(`\u274C \u9519\u8BEF: \u914D\u7F6E\u6587\u4EF6\u65E0\u6548 - ${t instanceof Error?t.message:String(t)}`)),console.log(r.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u8FD0\u884C "xiaozhi init" \u91CD\u65B0\u521D\u59CB\u5316\u914D\u7F6E')),!1}}a(uo,"checkEnvironment");function ho(){let t=f.dirname(I(import.meta.url)),o;return t.includes("js-demo/dist")?o=t:o=[f.join(t,"..","js-demo","dist"),f.join(t,"..","..","js-demo","dist"),f.join(t,"..","..","..","js-demo","dist"),f.join(process.cwd(),"js-demo","dist"),f.join(process.cwd(),"dist")].find(n=>u.existsSync(f.join(n,"mcpPipe.js"))&&u.existsSync(f.join(n,"mcpServerProxy.js")))||t,{command:"node",args:["mcpPipe.js","mcpServerProxy.js"],cwd:o}}a(ho,"getServiceCommand");async function V(t=!1){let o=w("\u68C0\u67E5\u670D\u52A1\u72B6\u6001...").start();try{let e=E();if(e.running){o.fail(`\u670D\u52A1\u5DF2\u7ECF\u5728\u8FD0\u884C (PID: ${e.pid})`);return}if(o.text="\u68C0\u67E5\u73AF\u5883\u914D\u7F6E...",!uo()){o.fail("\u73AF\u5883\u914D\u7F6E\u68C0\u67E5\u5931\u8D25");return}let{command:n,args:i,cwd:c}=ho();if(o.text=`\u542F\u52A8\u670D\u52A1 (${t?"\u540E\u53F0\u6A21\u5F0F":"\u524D\u53F0\u6A21\u5F0F"})...`,t){let s=U(n,i,{cwd:c,detached:!0,stdio:["ignore","pipe","pipe"],env:{...process.env,XIAOZHI_CONFIG_DIR:process.cwd(),XIAOZHI_DAEMON:"true"}});J(s.pid,"daemon");let l=process.cwd();x.initLogFile(l),x.enableFileLogging(!0);let h=f.join(l,"xiaozhi.log"),m=u.createWriteStream(h,{flags:"a"});s.stdout?.pipe(m),s.stderr?.pipe(m),s.on("exit",(d,y)=>{d!==0&&d!==null&&x.error(`\u540E\u53F0\u670D\u52A1\u5F02\u5E38\u9000\u51FA (\u4EE3\u7801: ${d}, \u4FE1\u53F7: ${y})`),$()}),s.on("error",d=>{x.error(`\u540E\u53F0\u670D\u52A1\u542F\u52A8\u9519\u8BEF: ${d.message}`),$(),o.fail(`\u540E\u53F0\u670D\u52A1\u542F\u52A8\u5931\u8D25: ${d.message}`)}),s.unref(),o.succeed(`\u670D\u52A1\u5DF2\u5728\u540E\u53F0\u542F\u52A8 (PID: ${s.pid})`),console.log(r.gray(`\u65E5\u5FD7\u6587\u4EF6: ${h}`)),console.log(r.gray("\u4F7F\u7528 'xiaozhi attach' \u53EF\u4EE5\u67E5\u770B\u5B9E\u65F6\u65E5\u5FD7"))}else{o.succeed("\u670D\u52A1\u542F\u52A8\u4E2D...");let s=U(n,i,{cwd:c,stdio:"inherit",env:{...process.env,XIAOZHI_CONFIG_DIR:process.cwd()}});J(s.pid,"foreground"),s.on("exit",(l,h)=>{$(),console.log(l!==0?r.red(`
4
- \u670D\u52A1\u5F02\u5E38\u9000\u51FA (\u4EE3\u7801: ${l}, \u4FE1\u53F7: ${h})`):r.green(`
2
+ var K=Object.defineProperty;var a=(e,o)=>K(e,"name",{value:o,configurable:!0});import{spawn as G}from"child_process";import p from"fs";import J from"os";import f from"path";import{fileURLToPath as P}from"url";import r from"chalk";import{Command as ro}from"commander";import b from"ora";import to from"omelette";import{copyFileSync as Y,existsSync as T,readFileSync as q,writeFileSync as Q}from"fs";import{dirname as oo,resolve as k}from"path";import{fileURLToPath as eo}from"url";var no=oo(eo(import.meta.url)),E=class e{static{a(this,"ConfigManager")}static instance;defaultConfigPath;config=null;constructor(){this.defaultConfigPath=k(no,"xiaozhi.config.default.json")}getConfigFilePath(){let o=process.env.XIAOZHI_CONFIG_DIR||process.cwd();return k(o,"xiaozhi.config.json")}static getInstance(){return e.instance||(e.instance=new e),e.instance}configExists(){let o=this.getConfigFilePath();return T(o)}initConfig(){if(!T(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 o=this.getConfigFilePath();Y(this.defaultConfigPath,o),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 o=this.getConfigFilePath(),n=q(o,"utf8"),t=JSON.parse(n);return this.validateConfig(t),t}catch(o){throw o instanceof SyntaxError?new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF: ${o.message}`):o}}validateConfig(o){if(!o||typeof o!="object")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1A\u6839\u5BF9\u8C61\u65E0\u6548");let n=o;if(!n.mcpEndpoint||typeof n.mcpEndpoint!="string")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u5B57\u6BB5\u65E0\u6548");if(!n.mcpServers||typeof n.mcpServers!="object")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers \u5B57\u6BB5\u65E0\u6548");for(let[t,i]of Object.entries(n.mcpServers)){if(!i||typeof i!="object")throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers.${t} \u65E0\u6548`);let c=i;if(!c.command||typeof c.command!="string")throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers.${t}.command \u65E0\u6548`);if(!Array.isArray(c.args))throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers.${t}.args \u5FC5\u987B\u662F\u6570\u7EC4`);if(c.env&&typeof c.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(){return this.getConfig().mcpEndpoint}getMcpServers(){return this.getConfig().mcpServers}getMcpServerConfig(){return this.getConfig().mcpServerConfig||{}}getServerToolsConfig(o){return this.getMcpServerConfig()[o]?.tools||{}}isToolEnabled(o,n){return this.getServerToolsConfig(o)[n]?.enable!==!1}updateMcpEndpoint(o){if(!o||typeof o!="string")throw new Error("MCP \u7AEF\u70B9\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let t={...this.getConfig(),mcpEndpoint:o};this.saveConfig(t)}updateMcpServer(o,n){if(!o||typeof o!="string")throw new Error("\u670D\u52A1\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");if(!n.command||typeof n.command!="string")throw new Error("\u670D\u52A1\u914D\u7F6E\u7684 command \u5B57\u6BB5\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");if(!Array.isArray(n.args))throw new Error("\u670D\u52A1\u914D\u7F6E\u7684 args \u5B57\u6BB5\u5FC5\u987B\u662F\u6570\u7EC4");if(n.env&&typeof n.env!="object")throw new Error("\u670D\u52A1\u914D\u7F6E\u7684 env \u5B57\u6BB5\u5FC5\u987B\u662F\u5BF9\u8C61");let t=this.getConfig(),i={...t,mcpServers:{...t.mcpServers,[o]:n}};this.saveConfig(i)}removeMcpServer(o){if(!o||typeof o!="string")throw new Error("\u670D\u52A1\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let n=this.getConfig();if(!n.mcpServers[o])throw new Error(`\u670D\u52A1 ${o} \u4E0D\u5B58\u5728`);let t={...n.mcpServers};delete t[o];let i={...n,mcpServers:t};this.saveConfig(i)}updateServerToolsConfig(o,n){let i={...this.getConfig()};i.mcpServerConfig||(i.mcpServerConfig={}),i.mcpServerConfig[o]={tools:n},this.saveConfig(i)}setToolEnabled(o,n,t,i){let s={...this.getConfig()};s.mcpServerConfig||(s.mcpServerConfig={}),s.mcpServerConfig[o]||(s.mcpServerConfig[o]={tools:{}}),s.mcpServerConfig[o].tools[n]={enable:t,...i&&{description:i}},this.saveConfig(s)}saveConfig(o){try{this.validateConfig(o);let n=this.getConfigFilePath(),t=JSON.stringify(o,null,2);Q(n,t,"utf8"),this.config=o}catch(n){throw new Error(`\u4FDD\u5B58\u914D\u7F6E\u5931\u8D25: ${n instanceof Error?n.message:String(n)}`)}}reloadConfig(){this.config=null}getConfigPath(){return this.getConfigFilePath()}getDefaultConfigPath(){return this.defaultConfigPath}},m=E.getInstance();function io(){try{if(!m.configExists())return[];let e=m.getMcpServers();return Object.keys(e)}catch{return[]}}a(io,"getMcpServerNames");function so(e){try{if(!m.configExists())return[];let o=m.getServerToolsConfig(e);return Object.keys(o)}catch{return[]}}a(so,"getServerToolNames");function I(){let e=to("xiaozhi");e.on("complete",(o,{line:n,before:t,reply:i})=>{let c=n.trim(),s=c.split(/\s+/),d=n!==c?s.length:s.length-1;if(d===1){let u=["create","init","config","start","stop","status","attach","restart","mcp","completion"],h=s[1]||"",y=u.filter(C=>C.startsWith(h));i(y);return}if(d===2){switch(s[1]){case"create":i(["--template","-t"]);break;case"start":case"restart":i(["--daemon","-d"]);break;case"completion":i(["install","uninstall"]);break;case"mcp":{let h=["list","server","tool"],y=s[2]||"",C=h.filter(S=>S.startsWith(y));i(C);break}default:i([])}return}if(s[1]==="mcp"){let u=s[2];if(d===3){switch(u){case"list":{let h=["--tools"],y=s[3]||"",C=h.filter(S=>S.startsWith(y));i(C);break}case"server":case"tool":{let h=io(),y=s[3]||"",C=h.filter(S=>S.startsWith(y));i(C);break}default:i([])}return}if(d===4&&u==="tool"){let h=s[3],y=so(h),C=s[4]||"",S=y.filter(X=>X.startsWith(C));i(S);return}if(d===5&&u==="tool"){let h=["enable","disable"],y=s[5]||"",C=h.filter(S=>S.startsWith(y));i(C);return}}i([])}),process.argv.includes("--completion")&&(console.log(e.setupShellInitFile()),process.exit(0)),process.argv.includes("--completion-fish")&&(console.log(e.setupShellInitFile("fish")),process.exit(0)),process.argv.includes("--compzsh")||process.argv.includes("--compbash"),e.init()}a(I,"setupAutoCompletion");function D(){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")}a(D,"showCompletionHelp");import l from"chalk";import O from"cli-table3";import M from"ora";function R(e){let o=0;for(let n of e)/[\u4e00-\u9fff\u3400-\u4dbf\uff00-\uffef]/.test(n)?o+=2:o+=1;return o}a(R,"getDisplayWidth");function F(e,o){if(R(e)<=o)return e;if(o<=3)return"";let n="",t=0,i=!1;for(let c of e){let s=/[\u4e00-\u9fff\u3400-\u4dbf\uff00-\uffef]/.test(c)?2:1;if(t+s>o-3){if(!i)return"";n+="...";break}n+=c,t+=s,i=!0}return n}a(F,"truncateToWidth");async function A(e={}){let o=M("\u83B7\u53D6 MCP \u670D\u52A1\u5217\u8868...").start();try{let n=m.getMcpServers(),t=Object.keys(n);if(t.length===0){o.warn("\u672A\u914D\u7F6E\u4EFB\u4F55 MCP \u670D\u52A1"),console.log(l.yellow("\u{1F4A1} \u63D0\u793A: \u4F7F\u7528 'xiaozhi config' \u547D\u4EE4\u914D\u7F6E MCP \u670D\u52A1"));return}if(o.succeed(`\u627E\u5230 ${t.length} \u4E2A MCP \u670D\u52A1`),e.tools){console.log(),console.log(l.bold("MCP \u670D\u52A1\u5DE5\u5177\u5217\u8868:")),console.log();let i=8,c=[];for(let g of t){let d=m.getServerToolsConfig(g),u=Object.keys(d);c.push(...u)}for(let g of c){let d=R(g);d>i&&(i=d)}i=Math.max(10,Math.min(i+2,30));let s=new O({head:[l.bold("MCP"),l.bold("\u5DE5\u5177\u540D\u79F0"),l.bold("\u72B6\u6001"),l.bold("\u63CF\u8FF0")],colWidths:[15,i,8,40],wordWrap:!0,style:{head:[],border:[]}});for(let g of t){let d=m.getServerToolsConfig(g),u=Object.keys(d);if(u.length===0)s.push([l.gray(g),l.gray("(\u65E0\u5DE5\u5177)"),l.gray("-"),l.gray("\u8BF7\u5148\u542F\u52A8\u670D\u52A1\u626B\u63CF\u5DE5\u5177")]);else{s.length>0&&s.push([{colSpan:4,content:""}]);for(let h of u){let y=d[h],C=y.enable?l.green("\u542F\u7528"):l.red("\u7981\u7528"),S=F(y.description||"",32);s.push([g,h,C,S])}}}console.log(s.toString())}else{console.log(),console.log(l.bold("MCP \u670D\u52A1\u5217\u8868:")),console.log();for(let i of t){let c=n[i],s=m.getServerToolsConfig(i),g=Object.keys(s).length,d=Object.values(s).filter(u=>u.enable!==!1).length;console.log(`${l.cyan("\u2022")} ${l.bold(i)}`),console.log(` \u547D\u4EE4: ${l.gray(c.command)} ${l.gray(c.args.join(" "))}`),g>0?console.log(` \u5DE5\u5177: ${l.green(d)} \u542F\u7528 / ${l.yellow(g)} \u603B\u8BA1`):console.log(` \u5DE5\u5177: ${l.gray("\u672A\u626B\u63CF (\u8BF7\u5148\u542F\u52A8\u670D\u52A1)")}`),console.log()}}console.log(l.gray("\u{1F4A1} \u63D0\u793A:")),console.log(l.gray(" - \u4F7F\u7528 'xiaozhi mcp list --tools' \u67E5\u770B\u6240\u6709\u5DE5\u5177")),console.log(l.gray(" - \u4F7F\u7528 'xiaozhi mcp <\u670D\u52A1\u540D> list' \u67E5\u770B\u6307\u5B9A\u670D\u52A1\u7684\u5DE5\u5177")),console.log(l.gray(" - \u4F7F\u7528 'xiaozhi mcp <\u670D\u52A1\u540D> <\u5DE5\u5177\u540D> enable/disable' \u542F\u7528/\u7981\u7528\u5DE5\u5177"))}catch(n){o.fail("\u83B7\u53D6 MCP \u670D\u52A1\u5217\u8868\u5931\u8D25"),console.error(l.red(`\u9519\u8BEF: ${n instanceof Error?n.message:String(n)}`)),process.exit(1)}}a(A,"listMcpServers");async function W(e){let o=M(`\u83B7\u53D6 ${e} \u670D\u52A1\u7684\u5DE5\u5177\u5217\u8868...`).start();try{if(!m.getMcpServers()[e]){o.fail(`\u670D\u52A1 '${e}' \u4E0D\u5B58\u5728`),console.log(l.yellow("\u{1F4A1} \u63D0\u793A: \u4F7F\u7528 'xiaozhi mcp list' \u67E5\u770B\u6240\u6709\u53EF\u7528\u670D\u52A1"));return}let t=m.getServerToolsConfig(e),i=Object.keys(t);if(i.length===0){o.warn(`\u670D\u52A1 '${e}' \u6682\u65E0\u5DE5\u5177\u4FE1\u606F`),console.log(l.yellow("\u{1F4A1} \u63D0\u793A: \u8BF7\u5148\u542F\u52A8\u670D\u52A1\u4EE5\u626B\u63CF\u5DE5\u5177\u5217\u8868"));return}o.succeed(`\u670D\u52A1 '${e}' \u5171\u6709 ${i.length} \u4E2A\u5DE5\u5177`),console.log(),console.log(l.bold(`${e} \u670D\u52A1\u5DE5\u5177\u5217\u8868:`)),console.log();let c=new O({head:[l.bold("\u5DE5\u5177\u540D\u79F0"),l.bold("\u72B6\u6001"),l.bold("\u63CF\u8FF0")],colWidths:[30,8,50],wordWrap:!0,style:{head:[],border:[]}});for(let s of i){let g=t[s],d=g.enable?l.green("\u542F\u7528"):l.red("\u7981\u7528"),u=F(g.description||"",40);c.push([s,d,u])}console.log(c.toString()),console.log(),console.log(l.gray("\u{1F4A1} \u63D0\u793A:")),console.log(l.gray(` - \u4F7F\u7528 'xiaozhi mcp ${e} <\u5DE5\u5177\u540D> enable' \u542F\u7528\u5DE5\u5177`)),console.log(l.gray(` - \u4F7F\u7528 'xiaozhi mcp ${e} <\u5DE5\u5177\u540D> disable' \u7981\u7528\u5DE5\u5177`))}catch(n){o.fail("\u83B7\u53D6\u5DE5\u5177\u5217\u8868\u5931\u8D25"),console.error(l.red(`\u9519\u8BEF: ${n instanceof Error?n.message:String(n)}`)),process.exit(1)}}a(W,"listServerTools");async function L(e,o,n){let t=n?"\u542F\u7528":"\u7981\u7528",i=M(`${t}\u5DE5\u5177 ${e}/${o}...`).start();try{if(!m.getMcpServers()[e]){i.fail(`\u670D\u52A1 '${e}' \u4E0D\u5B58\u5728`),console.log(l.yellow("\u{1F4A1} \u63D0\u793A: \u4F7F\u7528 'xiaozhi mcp list' \u67E5\u770B\u6240\u6709\u53EF\u7528\u670D\u52A1"));return}let s=m.getServerToolsConfig(e);if(!s[o]){i.fail(`\u5DE5\u5177 '${o}' \u5728\u670D\u52A1 '${e}' \u4E2D\u4E0D\u5B58\u5728`),console.log(l.yellow(`\u{1F4A1} \u63D0\u793A: \u4F7F\u7528 'xiaozhi mcp ${e} list' \u67E5\u770B\u8BE5\u670D\u52A1\u7684\u6240\u6709\u5DE5\u5177`));return}m.setToolEnabled(e,o,n,s[o].description),i.succeed(`\u6210\u529F${t}\u5DE5\u5177 ${l.cyan(e)}/${l.cyan(o)}`),console.log(),console.log(l.gray("\u{1F4A1} \u63D0\u793A: \u5DE5\u5177\u72B6\u6001\u66F4\u6539\u5C06\u5728\u4E0B\u6B21\u542F\u52A8\u670D\u52A1\u65F6\u751F\u6548"))}catch(c){i.fail(`${t}\u5DE5\u5177\u5931\u8D25`),console.error(l.red(`\u9519\u8BEF: ${c instanceof Error?c.message:String(c)}`)),process.exit(1)}}a(L,"setToolEnabled");var w=new ro,H="xiaozhi-mcp-service";function V(){try{let e=P(import.meta.url),o=f.dirname(e),n=[f.join(o,"..","package.json"),f.join(o,"..","package.json"),f.join(o,"..","..","package.json"),f.join(o,"package.json")];for(let t of n)if(p.existsSync(t)){let i=JSON.parse(p.readFileSync(t,"utf8"));if(i.version)return i.version}return"unknown"}catch(e){return console.warn("Warning: Could not read version from package.json:",e),"unknown"}}a(V,"getVersion");var v=f.join(J.tmpdir(),`${H}.pid`),x=f.join(J.tmpdir(),`${H}.log`);function $(){try{if(!p.existsSync(v))return{running:!1};let e=p.readFileSync(v,"utf8").trim(),[o,n,t]=e.split("|"),i=Number.parseInt(o);if(Number.isNaN(i))return p.unlinkSync(v),{running:!1};try{process.kill(i,0);let c=Number.parseInt(n),s=co(Date.now()-c);return{running:!0,pid:i,uptime:s,mode:t||"foreground"}}catch{return p.unlinkSync(v),{running:!1}}}catch{return{running:!1}}}a($,"getServiceStatus");function co(e){let o=Math.floor(e/1e3),n=Math.floor(o/60),t=Math.floor(n/60),i=Math.floor(t/24);return i>0?`${i}\u5929 ${t%24}\u5C0F\u65F6 ${n%60}\u5206\u949F`:t>0?`${t}\u5C0F\u65F6 ${n%60}\u5206\u949F`:n>0?`${n}\u5206\u949F ${o%60}\u79D2`:`${o}\u79D2`}a(co,"formatUptime");function _(e,o){let n=`${e}|${Date.now()}|${o}`;p.writeFileSync(v,n)}a(_,"savePidInfo");function z(){try{p.existsSync(v)&&p.unlinkSync(v)}catch{}}a(z,"cleanupPidFile");function lo(){if(!m.configExists())return console.error(r.red("\u274C \u9519\u8BEF: \u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728")),console.log(r.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u8FD0\u884C "xiaozhi init" \u521D\u59CB\u5316\u914D\u7F6E')),!1;try{let e=m.getMcpEndpoint();return!e||e.includes("<\u8BF7\u586B\u5199")?(console.error(r.red("\u274C \u9519\u8BEF: MCP \u7AEF\u70B9\u672A\u914D\u7F6E")),console.log(r.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u8FD0\u884C "xiaozhi config mcpEndpoint <your-endpoint-url>" \u8BBE\u7F6E\u7AEF\u70B9')),!1):!0}catch(e){return console.error(r.red(`\u274C \u9519\u8BEF: \u914D\u7F6E\u6587\u4EF6\u65E0\u6548 - ${e instanceof Error?e.message:String(e)}`)),console.log(r.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u8FD0\u884C "xiaozhi init" \u91CD\u65B0\u521D\u59CB\u5316\u914D\u7F6E')),!1}}a(lo,"checkEnvironment");function ao(){let e=f.dirname(P(import.meta.url)),o;return e.includes("js-demo/dist")?o=e:o=[f.join(e,"..","js-demo","dist"),f.join(e,"..","..","js-demo","dist"),f.join(e,"..","..","..","js-demo","dist"),f.join(process.cwd(),"js-demo","dist"),f.join(process.cwd(),"dist")].find(t=>p.existsSync(f.join(t,"mcpPipe.js"))&&p.existsSync(f.join(t,"mcpServerProxy.js")))||e,{command:"node",args:["mcpPipe.js","mcpServerProxy.js"],cwd:o}}a(ao,"getServiceCommand");async function U(e=!1){let o=b("\u68C0\u67E5\u670D\u52A1\u72B6\u6001...").start();try{let n=$();if(n.running){o.fail(`\u670D\u52A1\u5DF2\u7ECF\u5728\u8FD0\u884C (PID: ${n.pid})`);return}if(o.text="\u68C0\u67E5\u73AF\u5883\u914D\u7F6E...",!lo()){o.fail("\u73AF\u5883\u914D\u7F6E\u68C0\u67E5\u5931\u8D25");return}let{command:t,args:i,cwd:c}=ao();if(o.text=`\u542F\u52A8\u670D\u52A1 (${e?"\u540E\u53F0\u6A21\u5F0F":"\u524D\u53F0\u6A21\u5F0F"})...`,e){let s=G(t,i,{cwd:c,detached:!0,stdio:["ignore","pipe","pipe"],env:{...process.env,XIAOZHI_CONFIG_DIR:process.cwd()}});_(s.pid,"daemon");let g=p.createWriteStream(x,{flags:"a"});s.stdout?.pipe(g),s.stderr?.pipe(g),s.unref(),o.succeed(`\u670D\u52A1\u5DF2\u5728\u540E\u53F0\u542F\u52A8 (PID: ${s.pid})`),console.log(r.gray(`\u65E5\u5FD7\u6587\u4EF6: ${x}`)),console.log(r.gray("\u4F7F\u7528 'xiaozhi attach' \u53EF\u4EE5\u67E5\u770B\u5B9E\u65F6\u65E5\u5FD7"))}else{o.succeed("\u670D\u52A1\u542F\u52A8\u4E2D...");let s=G(t,i,{cwd:c,stdio:"inherit",env:{...process.env,XIAOZHI_CONFIG_DIR:process.cwd()}});_(s.pid,"foreground"),s.on("exit",(g,d)=>{z(),console.log(g!==0?r.red(`
3
+ \u670D\u52A1\u5F02\u5E38\u9000\u51FA (\u4EE3\u7801: ${g}, \u4FE1\u53F7: ${d})`):r.green(`
5
4
  \u670D\u52A1\u5DF2\u505C\u6B62`))}),process.on("SIGINT",()=>{console.log(r.yellow(`
6
- \u6B63\u5728\u505C\u6B62\u670D\u52A1...`)),s.kill("SIGTERM")}),process.on("SIGTERM",()=>{s.kill("SIGTERM")})}}catch(e){o.fail(`\u542F\u52A8\u670D\u52A1\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`)}}a(V,"startService");async function X(){let t=w("\u68C0\u67E5\u670D\u52A1\u72B6\u6001...").start();try{let o=E();if(!o.running){t.warn("\u670D\u52A1\u672A\u5728\u8FD0\u884C");return}t.text=`\u505C\u6B62\u670D\u52A1 (PID: ${o.pid})...`;try{process.kill(o.pid,"SIGTERM");let e=0,n=30;for(;e<n;){await new Promise(i=>setTimeout(i,100));try{process.kill(o.pid,0),e++}catch{break}}try{process.kill(o.pid,0),t.text="\u5F3A\u5236\u505C\u6B62\u670D\u52A1...",process.kill(o.pid,"SIGKILL"),await new Promise(i=>setTimeout(i,500))}catch{}$(),t.succeed("\u670D\u52A1\u5DF2\u505C\u6B62")}catch(e){$(),t.fail(`\u505C\u6B62\u670D\u52A1\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`)}}catch(o){t.fail(`\u505C\u6B62\u670D\u52A1\u5931\u8D25: ${o instanceof Error?o.message:String(o)}`)}}a(X,"stopService");async function yo(){let t=w("\u68C0\u67E5\u670D\u52A1\u72B6\u6001...").start();try{let o=E();if(o.running){if(t.succeed("\u670D\u52A1\u72B6\u6001"),console.log(r.green("\u2705 \u670D\u52A1\u6B63\u5728\u8FD0\u884C")),console.log(r.gray(` PID: ${o.pid}`)),console.log(r.gray(` \u8FD0\u884C\u65F6\u95F4: ${o.uptime}`)),console.log(r.gray(` \u8FD0\u884C\u6A21\u5F0F: ${o.mode==="daemon"?"\u540E\u53F0\u6A21\u5F0F":"\u524D\u53F0\u6A21\u5F0F"}`)),o.mode==="daemon"){let e=f.join(process.cwd(),"xiaozhi.log");console.log(r.gray(` \u65E5\u5FD7\u6587\u4EF6: ${e}`))}}else t.succeed("\u670D\u52A1\u72B6\u6001"),console.log(r.red("\u274C \u670D\u52A1\u672A\u8FD0\u884C"))}catch(o){t.fail(`\u68C0\u67E5\u72B6\u6001\u5931\u8D25: ${o instanceof Error?o.message:String(o)}`)}}a(yo,"checkStatus");async function Co(){let t=w("\u68C0\u67E5\u670D\u52A1\u72B6\u6001...").start();try{let o=E();if(!o.running){t.fail("\u670D\u52A1\u672A\u5728\u8FD0\u884C");return}if(o.mode!=="daemon"){t.fail("\u670D\u52A1\u4E0D\u662F\u5728\u540E\u53F0\u6A21\u5F0F\u8FD0\u884C");return}t.succeed("\u8FDE\u63A5\u5230\u540E\u53F0\u670D\u52A1..."),console.log(r.green(`\u5DF2\u8FDE\u63A5\u5230\u670D\u52A1 (PID: ${o.pid})`)),console.log(r.gray("\u6309 Ctrl+C \u53EF\u4EE5\u65AD\u5F00\u8FDE\u63A5\uFF08\u4E0D\u4F1A\u505C\u6B62\u670D\u52A1\uFF09")),console.log(r.gray("=".repeat(50)));let e=f.join(process.cwd(),"xiaozhi.log");if(u.existsSync(e))if(process.platform==="win32"){let{spawn:n}=await import("child_process"),i=n("powershell",["-Command",`Get-Content -Path "${e}" -Wait`],{stdio:"inherit"});process.on("SIGINT",()=>{console.log(r.yellow(`
7
- \u65AD\u5F00\u8FDE\u63A5\uFF0C\u670D\u52A1\u7EE7\u7EED\u5728\u540E\u53F0\u8FD0\u884C`)),i.kill(),process.exit(0)}),i.on("exit",()=>{process.exit(0)})}else{let{spawn:n}=await import("child_process"),i=n("tail",["-f",e],{stdio:"inherit"});process.on("SIGINT",()=>{console.log(r.yellow(`
8
- \u65AD\u5F00\u8FDE\u63A5\uFF0C\u670D\u52A1\u7EE7\u7EED\u5728\u540E\u53F0\u8FD0\u884C`)),i.kill(),process.exit(0)}),i.on("exit",()=>{process.exit(0)})}else console.log(r.yellow("\u65E5\u5FD7\u6587\u4EF6\u4E0D\u5B58\u5728"))}catch(o){t.fail(`\u8FDE\u63A5\u5931\u8D25: ${o instanceof Error?o.message:String(o)}`)}}a(Co,"attachService");async function bo(t=!1){console.log(r.blue("\u{1F504} \u91CD\u542F\u670D\u52A1...")),await X(),await new Promise(o=>setTimeout(o,1e3)),await V(t)}a(bo,"restartService");function vo(){let t=B();console.log(r.blue(`xiaozhi v${t}`)),console.log(r.gray("MCP Calculator Service CLI Tool")),console.log(r.gray("Built with Node.js and TypeScript")),console.log(r.gray(`Node.js: ${process.version}`)),console.log(r.gray(`Platform: ${process.platform} ${process.arch}`))}a(vo,"showDetailedInfo");async function wo(){let t=w("\u521D\u59CB\u5316\u914D\u7F6E...").start();try{if(p.configExists()){t.warn("\u914D\u7F6E\u6587\u4EF6\u5DF2\u5B58\u5728"),console.log(r.yellow("\u5982\u9700\u91CD\u65B0\u521D\u59CB\u5316\uFF0C\u8BF7\u5148\u5220\u9664\u73B0\u6709\u7684 xiaozhi.config.json \u6587\u4EF6"));return}p.initConfig(),t.succeed("\u914D\u7F6E\u6587\u4EF6\u521D\u59CB\u5316\u6210\u529F"),console.log(r.green("\u2705 \u914D\u7F6E\u6587\u4EF6\u5DF2\u521B\u5EFA: xiaozhi.config.json")),console.log(r.yellow("\u{1F4DD} \u8BF7\u7F16\u8F91\u914D\u7F6E\u6587\u4EF6\u8BBE\u7F6E\u4F60\u7684 MCP \u7AEF\u70B9:")),console.log(r.gray(` \u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84: ${p.getConfigPath()}`)),console.log(r.yellow("\u{1F4A1} \u6216\u8005\u4F7F\u7528\u547D\u4EE4\u8BBE\u7F6E:")),console.log(r.gray(" xiaozhi config mcpEndpoint <your-endpoint-url>"))}catch(o){t.fail(`\u521D\u59CB\u5316\u914D\u7F6E\u5931\u8D25: ${o instanceof Error?o.message:String(o)}`)}}a(wo,"initConfig");function So(){let t=f.dirname(I(import.meta.url)),e=[f.join(t,"..","templates"),f.join(t,"templates"),f.join(t,"..","..","templates")].find(n=>u.existsSync(n));return e?u.readdirSync(e).filter(n=>{let i=f.join(e,n);return u.statSync(i).isDirectory()}):[]}a(So,"getAvailableTemplates");function Z(t,o){let e=t.length,n=o.length,i=Array(e+1).fill(null).map(()=>Array(n+1).fill(0));for(let s=0;s<=e;s++)i[s][0]=s;for(let s=0;s<=n;s++)i[0][s]=s;for(let s=1;s<=e;s++)for(let l=1;l<=n;l++)t[s-1]===o[l-1]?i[s][l]=i[s-1][l-1]:i[s][l]=Math.min(i[s-1][l]+1,i[s][l-1]+1,i[s-1][l-1]+1);let c=Math.max(e,n);return c===0?1:(c-i[e][n])/c}a(Z,"calculateSimilarity");function xo(t,o){if(o.length===0)return null;let e=o[0],n=Z(t.toLowerCase(),e.toLowerCase());for(let i of o.slice(1)){let c=Z(t.toLowerCase(),i.toLowerCase());c>n&&(n=c,e=i)}return n>.5?e:null}a(xo,"findSimilarTemplate");async function $o(t){if(!process.stdin.isTTY)return console.log("n (\u975E\u4EA4\u4E92\u5F0F\u73AF\u5883)"),!1;let o=await import("readline");return new Promise(e=>{process.stdout.write(t);let n=o.createInterface({input:process.stdin,output:process.stdout}),i=a(c=>{let s=c.trim().toLowerCase();s==="y"||s==="yes"?(n.close(),e(!0)):s==="n"||s==="no"||s===""?(n.close(),e(!1)):process.stdout.write("\u8BF7\u8F93\u5165 y \u6216 n: ")},"handleInput");n.on("line",i),n.on("SIGINT",()=>{n.close(),e(!1)})})}a($o,"askUserConfirmation");function Po(t){let o={mcpEndpoint:"<\u8BF7\u586B\u5199\u4F60\u7684\u63A5\u5165\u70B9\u5730\u5740\uFF08\u83B7\u53D6\u5730\u5740\u5728 xiaozhi.me\uFF09>",mcpServers:{}},e=f.join(t,"xiaozhi.config.json");u.writeFileSync(e,JSON.stringify(o,null,2),"utf8")}a(Po,"createBasicConfig");async function Io(t,o){let e=w("\u521D\u59CB\u5316\u9879\u76EE...").start();try{let n=f.join(process.cwd(),t);if(u.existsSync(n)){e.fail(`\u76EE\u5F55 "${t}" \u5DF2\u5B58\u5728`),console.log(r.yellow("\u{1F4A1} \u63D0\u793A: \u8BF7\u9009\u62E9\u4E0D\u540C\u7684\u9879\u76EE\u540D\u79F0\u6216\u5220\u9664\u73B0\u6709\u76EE\u5F55"));return}if(o.template){e.text="\u68C0\u67E5\u6A21\u677F...";let i=So();if(i.length===0){e.fail("\u627E\u4E0D\u5230 templates \u76EE\u5F55"),console.log(r.yellow("\u{1F4A1} \u63D0\u793A: \u8BF7\u786E\u4FDD xiaozhi-client \u6B63\u786E\u5B89\u88C5"));return}if(!i.includes(o.template)){e.fail(`\u6A21\u677F "${o.template}" \u4E0D\u5B58\u5728`);let d=xo(o.template,i);if(d)if(console.log(r.yellow(`\u{1F4A1} \u4F60\u662F\u60F3\u4F7F\u7528\u6A21\u677F "${d}" \u5417\uFF1F`)),await $o(r.cyan("\u786E\u8BA4\u4F7F\u7528\u6B64\u6A21\u677F\uFF1F(y/n): ")))o.template=d;else{console.log(r.yellow("\u53EF\u7528\u7684\u6A21\u677F:"));for(let C of i)console.log(r.gray(` - ${C}`));return}else{console.log(r.yellow("\u53EF\u7528\u7684\u6A21\u677F:"));for(let y of i)console.log(r.gray(` - ${y}`));return}}let c=f.dirname(I(import.meta.url)),l=[f.join(c,"..","templates"),f.join(c,"templates"),f.join(c,"..","..","templates")].find(d=>u.existsSync(d)),h=f.join(l,o.template);e.text=`\u4ECE\u6A21\u677F "${o.template}" \u521B\u5EFA\u9879\u76EE "${t}"...`,q(h,n,["node_modules",".pnpm-debug.log","pnpm-lock.yaml"]);let m=f.join(n,"xiaozhi.log");u.existsSync(m)||u.writeFileSync(m,"","utf8"),e.succeed(`\u9879\u76EE "${t}" \u521B\u5EFA\u6210\u529F`),console.log(r.green("\u2705 \u9879\u76EE\u521B\u5EFA\u5B8C\u6210!")),console.log(r.yellow("\u{1F4DD} \u63A5\u4E0B\u6765\u7684\u6B65\u9AA4:")),console.log(r.gray(` cd ${t}`)),console.log(r.gray(" pnpm install # \u5B89\u88C5\u4F9D\u8D56")),console.log(r.gray(" # \u7F16\u8F91 xiaozhi.config.json \u8BBE\u7F6E\u4F60\u7684 MCP \u7AEF\u70B9")),console.log(r.gray(" xiaozhi start # \u542F\u52A8\u670D\u52A1"))}else{e.text=`\u521B\u5EFA\u57FA\u672C\u9879\u76EE "${t}"...`,u.mkdirSync(n,{recursive:!0}),Po(n);let i=f.join(n,"xiaozhi.log");u.writeFileSync(i,"","utf8"),e.succeed(`\u9879\u76EE "${t}" \u521B\u5EFA\u6210\u529F`),console.log(r.green("\u2705 \u57FA\u672C\u9879\u76EE\u521B\u5EFA\u5B8C\u6210!")),console.log(r.yellow("\u{1F4DD} \u63A5\u4E0B\u6765\u7684\u6B65\u9AA4:")),console.log(r.gray(` cd ${t}`)),console.log(r.gray(" # \u7F16\u8F91 xiaozhi.config.json \u8BBE\u7F6E\u4F60\u7684 MCP \u7AEF\u70B9\u548C\u670D\u52A1")),console.log(r.gray(" xiaozhi start # \u542F\u52A8\u670D\u52A1")),console.log(r.yellow("\u{1F4A1} \u63D0\u793A: \u4F7F\u7528 --template \u9009\u9879\u53EF\u4EE5\u4ECE\u6A21\u677F\u521B\u5EFA\u9879\u76EE"))}}catch(n){e.fail(`\u521B\u5EFA\u9879\u76EE\u5931\u8D25: ${n instanceof Error?n.message:String(n)}`)}}a(Io,"createProject");function q(t,o,e=[]){u.existsSync(o)||u.mkdirSync(o,{recursive:!0});let n=u.readdirSync(t);for(let i of n){if(e.some(h=>i.includes(h)))continue;let c=f.join(t,i),s=f.join(o,i);u.statSync(c).isDirectory()?q(c,s,e):u.copyFileSync(c,s)}}a(q,"copyDirectory");async function Eo(t,o){let e=w("\u66F4\u65B0\u914D\u7F6E...").start();try{if(!p.configExists()){e.fail("\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728"),console.log(r.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u5148\u8FD0\u884C "xiaozhi init" \u521D\u59CB\u5316\u914D\u7F6E'));return}if(o)switch(t){case"mcpEndpoint":p.updateMcpEndpoint(o),e.succeed(`MCP \u7AEF\u70B9\u5DF2\u66F4\u65B0\u4E3A: ${o}`);break;case"heartbeatInterval":{let n=Number.parseInt(o,10);if(Number.isNaN(n)||n<=0){e.fail("\u5FC3\u8DF3\u68C0\u6D4B\u95F4\u9694\u5FC5\u987B\u662F\u5927\u4E8E0\u7684\u6570\u5B57\uFF08\u6BEB\u79D2\uFF09");return}p.setHeartbeatInterval(n),e.succeed(`\u5FC3\u8DF3\u68C0\u6D4B\u95F4\u9694\u5DF2\u66F4\u65B0\u4E3A: ${n}ms`);break}case"heartbeatTimeout":{let n=Number.parseInt(o,10);if(Number.isNaN(n)||n<=0){e.fail("\u5FC3\u8DF3\u8D85\u65F6\u65F6\u95F4\u5FC5\u987B\u662F\u5927\u4E8E0\u7684\u6570\u5B57\uFF08\u6BEB\u79D2\uFF09");return}p.setHeartbeatTimeout(n),e.succeed(`\u5FC3\u8DF3\u8D85\u65F6\u65F6\u95F4\u5DF2\u66F4\u65B0\u4E3A: ${n}ms`);break}case"reconnectInterval":{let n=Number.parseInt(o,10);if(Number.isNaN(n)||n<=0){e.fail("\u91CD\u8FDE\u95F4\u9694\u5FC5\u987B\u662F\u5927\u4E8E0\u7684\u6570\u5B57\uFF08\u6BEB\u79D2\uFF09");return}p.setReconnectInterval(n),e.succeed(`\u91CD\u8FDE\u95F4\u9694\u5DF2\u66F4\u65B0\u4E3A: ${n}ms`);break}default:e.fail(`\u914D\u7F6E\u9879 ${t} \u4E0D\u652F\u6301\u901A\u8FC7\u547D\u4EE4\u884C\u8BBE\u7F6E`),console.log(r.yellow("\u652F\u6301\u8BBE\u7F6E\u7684\u914D\u7F6E\u9879: mcpEndpoint, heartbeatInterval, heartbeatTimeout, reconnectInterval"));return}else{e.text="\u8BFB\u53D6\u914D\u7F6E...";let n=p.getConfig();switch(t){case"mcpEndpoint":e.succeed("\u914D\u7F6E\u4FE1\u606F"),console.log(r.green(`MCP \u7AEF\u70B9: ${n.mcpEndpoint}`));break;case"mcpServers":e.succeed("\u914D\u7F6E\u4FE1\u606F"),console.log(r.green("MCP \u670D\u52A1:"));for(let[i,c]of Object.entries(n.mcpServers))console.log(r.gray(` ${i}: ${c.command} ${c.args.join(" ")}`));break;case"connection":{e.succeed("\u914D\u7F6E\u4FE1\u606F");let i=p.getConnectionConfig();console.log(r.green("\u8FDE\u63A5\u914D\u7F6E:")),console.log(r.gray(` \u5FC3\u8DF3\u68C0\u6D4B\u95F4\u9694: ${i.heartbeatInterval}ms`)),console.log(r.gray(` \u5FC3\u8DF3\u8D85\u65F6\u65F6\u95F4: ${i.heartbeatTimeout}ms`)),console.log(r.gray(` \u91CD\u8FDE\u95F4\u9694: ${i.reconnectInterval}ms`));break}case"heartbeatInterval":e.succeed("\u914D\u7F6E\u4FE1\u606F"),console.log(r.green(`\u5FC3\u8DF3\u68C0\u6D4B\u95F4\u9694: ${p.getHeartbeatInterval()}ms`));break;case"heartbeatTimeout":e.succeed("\u914D\u7F6E\u4FE1\u606F"),console.log(r.green(`\u5FC3\u8DF3\u8D85\u65F6\u65F6\u95F4: ${p.getHeartbeatTimeout()}ms`));break;case"reconnectInterval":e.succeed("\u914D\u7F6E\u4FE1\u606F"),console.log(r.green(`\u91CD\u8FDE\u95F4\u9694: ${p.getReconnectInterval()}ms`));break;default:e.fail(`\u672A\u77E5\u7684\u914D\u7F6E\u9879: ${t}`),console.log(r.yellow("\u652F\u6301\u7684\u914D\u7F6E\u9879: mcpEndpoint, mcpServers, connection, heartbeatInterval, heartbeatTimeout, reconnectInterval"));return}}}catch(n){e.fail(`\u914D\u7F6E\u64CD\u4F5C\u5931\u8D25: ${n instanceof Error?n.message:String(n)}`)}}a(Eo,"configCommand");function To(){console.log(r.blue.bold("xiaozhi - MCP Calculator Service CLI")),console.log(),console.log(r.yellow("\u4F7F\u7528\u65B9\u6CD5:")),console.log(" xiaozhi <command> [options]"),console.log(),console.log(r.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] \u542F\u52A8\u670D\u52A1 (--daemon \u540E\u53F0\u8FD0\u884C)"),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] \u91CD\u542F\u670D\u52A1 (--daemon \u540E\u53F0\u8FD0\u884C)"),console.log(" completion \u663E\u793A\u81EA\u52A8\u8865\u5168\u8BBE\u7F6E\u8BF4\u660E"),console.log(),console.log(r.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(r.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(r.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(r.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 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(r.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(r.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")}a(To,"showHelp");b.name("xiaozhi").description("MCP Calculator Service CLI Tool").version(B(),"-v, --version","\u663E\u793A\u7248\u672C\u4FE1\u606F").helpOption("-h, --help","\u663E\u793A\u5E2E\u52A9\u4FE1\u606F");b.command("create <projectName>").description("\u521B\u5EFA\u9879\u76EE").option("-t, --template <templateName>","\u4F7F\u7528\u6307\u5B9A\u6A21\u677F\u521B\u5EFA\u9879\u76EE").action(async(t,o)=>{await Io(t,o)});b.command("init").description("\u521D\u59CB\u5316\u914D\u7F6E\u6587\u4EF6").action(async()=>{await wo()});b.command("config <key> [value]").description("\u67E5\u770B\u6216\u8BBE\u7F6E\u914D\u7F6E").action(async(t,o)=>{await Eo(t,o)});b.command("start").description("\u542F\u52A8\u670D\u52A1").option("-d, --daemon","\u5728\u540E\u53F0\u8FD0\u884C\u670D\u52A1").action(async t=>{await V(t.daemon)});b.command("stop").description("\u505C\u6B62\u670D\u52A1").action(async()=>{await X()});b.command("status").description("\u68C0\u67E5\u670D\u52A1\u72B6\u6001").action(async()=>{await yo()});b.command("attach").description("\u8FDE\u63A5\u5230\u540E\u53F0\u670D\u52A1\u67E5\u770B\u65E5\u5FD7").action(async()=>{await Co()});b.command("restart").description("\u91CD\u542F\u670D\u52A1").option("-d, --daemon","\u5728\u540E\u53F0\u8FD0\u884C\u670D\u52A1").action(async t=>{await bo(t.daemon)});var F=b.command("mcp").description("MCP \u670D\u52A1\u548C\u5DE5\u5177\u7BA1\u7406");F.command("list").description("\u5217\u51FA MCP \u670D\u52A1").option("--tools","\u663E\u793A\u6240\u6709\u670D\u52A1\u7684\u5DE5\u5177\u5217\u8868").action(async t=>{await G(t)});F.command("server <serverName>").description("\u7BA1\u7406\u6307\u5B9A\u7684 MCP \u670D\u52A1").action(async t=>{await H(t)});F.command("tool <serverName> <toolName> <action>").description("\u542F\u7528\u6216\u7981\u7528\u6307\u5B9A\u670D\u52A1\u7684\u5DE5\u5177").action(async(t,o,e)=>{e!=="enable"&&e!=="disable"&&(console.error(r.red("\u9519\u8BEF: \u64CD\u4F5C\u5FC5\u987B\u662F 'enable' \u6216 'disable'")),process.exit(1)),await _(t,o,e==="enable")});b.command("completion").description("\u663E\u793A\u81EA\u52A8\u8865\u5168\u8BBE\u7F6E\u8BF4\u660E").action(async()=>{N()});b.option("-V","\u663E\u793A\u8BE6\u7EC6\u4FE1\u606F").action(t=>{t.V&&(vo(),process.exit(0))});O();process.argv.length<=2&&(To(),process.exit(0));b.parse(process.argv);export{Z as calculateSimilarity,uo as checkEnvironment,mo as formatUptime,E as getServiceStatus,B as getVersion};
5
+ \u6B63\u5728\u505C\u6B62\u670D\u52A1...`)),s.kill("SIGTERM")}),process.on("SIGTERM",()=>{s.kill("SIGTERM")})}}catch(n){o.fail(`\u542F\u52A8\u670D\u52A1\u5931\u8D25: ${n instanceof Error?n.message:String(n)}`)}}a(U,"startService");async function Z(){let e=b("\u68C0\u67E5\u670D\u52A1\u72B6\u6001...").start();try{let o=$();if(!o.running){e.warn("\u670D\u52A1\u672A\u5728\u8FD0\u884C");return}e.text=`\u505C\u6B62\u670D\u52A1 (PID: ${o.pid})...`;try{process.kill(o.pid,"SIGTERM");let n=0,t=30;for(;n<t;){await new Promise(i=>setTimeout(i,100));try{process.kill(o.pid,0),n++}catch{break}}try{process.kill(o.pid,0),e.text="\u5F3A\u5236\u505C\u6B62\u670D\u52A1...",process.kill(o.pid,"SIGKILL"),await new Promise(i=>setTimeout(i,500))}catch{}z(),e.succeed("\u670D\u52A1\u5DF2\u505C\u6B62")}catch(n){z(),e.fail(`\u505C\u6B62\u670D\u52A1\u5931\u8D25: ${n instanceof Error?n.message:String(n)}`)}}catch(o){e.fail(`\u505C\u6B62\u670D\u52A1\u5931\u8D25: ${o instanceof Error?o.message:String(o)}`)}}a(Z,"stopService");async function go(){let e=b("\u68C0\u67E5\u670D\u52A1\u72B6\u6001...").start();try{let o=$();o.running?(e.succeed("\u670D\u52A1\u72B6\u6001"),console.log(r.green("\u2705 \u670D\u52A1\u6B63\u5728\u8FD0\u884C")),console.log(r.gray(` PID: ${o.pid}`)),console.log(r.gray(` \u8FD0\u884C\u65F6\u95F4: ${o.uptime}`)),console.log(r.gray(` \u8FD0\u884C\u6A21\u5F0F: ${o.mode==="daemon"?"\u540E\u53F0\u6A21\u5F0F":"\u524D\u53F0\u6A21\u5F0F"}`)),o.mode==="daemon"&&console.log(r.gray(` \u65E5\u5FD7\u6587\u4EF6: ${x}`))):(e.succeed("\u670D\u52A1\u72B6\u6001"),console.log(r.red("\u274C \u670D\u52A1\u672A\u8FD0\u884C")))}catch(o){e.fail(`\u68C0\u67E5\u72B6\u6001\u5931\u8D25: ${o instanceof Error?o.message:String(o)}`)}}a(go,"checkStatus");async function fo(){let e=b("\u68C0\u67E5\u670D\u52A1\u72B6\u6001...").start();try{let o=$();if(!o.running){e.fail("\u670D\u52A1\u672A\u5728\u8FD0\u884C");return}if(o.mode!=="daemon"){e.fail("\u670D\u52A1\u4E0D\u662F\u5728\u540E\u53F0\u6A21\u5F0F\u8FD0\u884C");return}if(e.succeed("\u8FDE\u63A5\u5230\u540E\u53F0\u670D\u52A1..."),console.log(r.green(`\u5DF2\u8FDE\u63A5\u5230\u670D\u52A1 (PID: ${o.pid})`)),console.log(r.gray("\u6309 Ctrl+C \u53EF\u4EE5\u65AD\u5F00\u8FDE\u63A5\uFF08\u4E0D\u4F1A\u505C\u6B62\u670D\u52A1\uFF09")),console.log(r.gray("=".repeat(50))),p.existsSync(x))if(process.platform==="win32"){let{spawn:n}=await import("child_process"),t=n("powershell",["-Command",`Get-Content -Path "${x}" -Wait`],{stdio:"inherit"});process.on("SIGINT",()=>{console.log(r.yellow(`
6
+ \u65AD\u5F00\u8FDE\u63A5\uFF0C\u670D\u52A1\u7EE7\u7EED\u5728\u540E\u53F0\u8FD0\u884C`)),t.kill(),process.exit(0)}),t.on("exit",()=>{process.exit(0)})}else{let{spawn:n}=await import("child_process"),t=n("tail",["-f",x],{stdio:"inherit"});process.on("SIGINT",()=>{console.log(r.yellow(`
7
+ \u65AD\u5F00\u8FDE\u63A5\uFF0C\u670D\u52A1\u7EE7\u7EED\u5728\u540E\u53F0\u8FD0\u884C`)),t.kill(),process.exit(0)}),t.on("exit",()=>{process.exit(0)})}else console.log(r.yellow("\u65E5\u5FD7\u6587\u4EF6\u4E0D\u5B58\u5728"))}catch(o){e.fail(`\u8FDE\u63A5\u5931\u8D25: ${o instanceof Error?o.message:String(o)}`)}}a(fo,"attachService");async function po(e=!1){console.log(r.blue("\u{1F504} \u91CD\u542F\u670D\u52A1...")),await Z(),await new Promise(o=>setTimeout(o,1e3)),await U(e)}a(po,"restartService");function mo(){let e=V();console.log(r.blue(`xiaozhi v${e}`)),console.log(r.gray("MCP Calculator Service CLI Tool")),console.log(r.gray("Built with Node.js and TypeScript")),console.log(r.gray(`Node.js: ${process.version}`)),console.log(r.gray(`Platform: ${process.platform} ${process.arch}`))}a(mo,"showDetailedInfo");async function uo(){let e=b("\u521D\u59CB\u5316\u914D\u7F6E...").start();try{if(m.configExists()){e.warn("\u914D\u7F6E\u6587\u4EF6\u5DF2\u5B58\u5728"),console.log(r.yellow("\u5982\u9700\u91CD\u65B0\u521D\u59CB\u5316\uFF0C\u8BF7\u5148\u5220\u9664\u73B0\u6709\u7684 xiaozhi.config.json \u6587\u4EF6"));return}m.initConfig(),e.succeed("\u914D\u7F6E\u6587\u4EF6\u521D\u59CB\u5316\u6210\u529F"),console.log(r.green("\u2705 \u914D\u7F6E\u6587\u4EF6\u5DF2\u521B\u5EFA: xiaozhi.config.json")),console.log(r.yellow("\u{1F4DD} \u8BF7\u7F16\u8F91\u914D\u7F6E\u6587\u4EF6\u8BBE\u7F6E\u4F60\u7684 MCP \u7AEF\u70B9:")),console.log(r.gray(` \u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84: ${m.getConfigPath()}`)),console.log(r.yellow("\u{1F4A1} \u6216\u8005\u4F7F\u7528\u547D\u4EE4\u8BBE\u7F6E:")),console.log(r.gray(" xiaozhi config mcpEndpoint <your-endpoint-url>"))}catch(o){e.fail(`\u521D\u59CB\u5316\u914D\u7F6E\u5931\u8D25: ${o instanceof Error?o.message:String(o)}`)}}a(uo,"initConfig");function ho(){let e=f.dirname(P(import.meta.url)),n=[f.join(e,"..","templates"),f.join(e,"templates"),f.join(e,"..","..","templates")].find(t=>p.existsSync(t));return n?p.readdirSync(n).filter(t=>{let i=f.join(n,t);return p.statSync(i).isDirectory()}):[]}a(ho,"getAvailableTemplates");function N(e,o){let n=e.length,t=o.length,i=Array(n+1).fill(null).map(()=>Array(t+1).fill(0));for(let s=0;s<=n;s++)i[s][0]=s;for(let s=0;s<=t;s++)i[0][s]=s;for(let s=1;s<=n;s++)for(let g=1;g<=t;g++)e[s-1]===o[g-1]?i[s][g]=i[s-1][g-1]:i[s][g]=Math.min(i[s-1][g]+1,i[s][g-1]+1,i[s-1][g-1]+1);let c=Math.max(n,t);return c===0?1:(c-i[n][t])/c}a(N,"calculateSimilarity");function yo(e,o){if(o.length===0)return null;let n=o[0],t=N(e.toLowerCase(),n.toLowerCase());for(let i of o.slice(1)){let c=N(e.toLowerCase(),i.toLowerCase());c>t&&(t=c,n=i)}return t>.5?n:null}a(yo,"findSimilarTemplate");async function Co(e){if(!process.stdin.isTTY)return console.log("n (\u975E\u4EA4\u4E92\u5F0F\u73AF\u5883)"),!1;let o=await import("readline");return new Promise(n=>{process.stdout.write(e);let t=o.createInterface({input:process.stdin,output:process.stdout}),i=a(c=>{let s=c.trim().toLowerCase();s==="y"||s==="yes"?(t.close(),n(!0)):s==="n"||s==="no"||s===""?(t.close(),n(!1)):process.stdout.write("\u8BF7\u8F93\u5165 y \u6216 n: ")},"handleInput");t.on("line",i),t.on("SIGINT",()=>{t.close(),n(!1)})})}a(Co,"askUserConfirmation");function wo(e){let o={mcpEndpoint:"<\u8BF7\u586B\u5199\u4F60\u7684\u63A5\u5165\u70B9\u5730\u5740\uFF08\u83B7\u53D6\u5730\u5740\u5728 xiaozhi.me\uFF09>",mcpServers:{}},n=f.join(e,"xiaozhi.config.json");p.writeFileSync(n,JSON.stringify(o,null,2),"utf8")}a(wo,"createBasicConfig");async function So(e,o){let n=b("\u521D\u59CB\u5316\u9879\u76EE...").start();try{let t=f.join(process.cwd(),e);if(p.existsSync(t)){n.fail(`\u76EE\u5F55 "${e}" \u5DF2\u5B58\u5728`),console.log(r.yellow("\u{1F4A1} \u63D0\u793A: \u8BF7\u9009\u62E9\u4E0D\u540C\u7684\u9879\u76EE\u540D\u79F0\u6216\u5220\u9664\u73B0\u6709\u76EE\u5F55"));return}if(o.template){n.text="\u68C0\u67E5\u6A21\u677F...";let i=ho();if(i.length===0){n.fail("\u627E\u4E0D\u5230 templates \u76EE\u5F55"),console.log(r.yellow("\u{1F4A1} \u63D0\u793A: \u8BF7\u786E\u4FDD xiaozhi-client \u6B63\u786E\u5B89\u88C5"));return}if(!i.includes(o.template)){n.fail(`\u6A21\u677F "${o.template}" \u4E0D\u5B58\u5728`);let u=yo(o.template,i);if(u)if(console.log(r.yellow(`\u{1F4A1} \u4F60\u662F\u60F3\u4F7F\u7528\u6A21\u677F "${u}" \u5417\uFF1F`)),await Co(r.cyan("\u786E\u8BA4\u4F7F\u7528\u6B64\u6A21\u677F\uFF1F(y/n): ")))o.template=u;else{console.log(r.yellow("\u53EF\u7528\u7684\u6A21\u677F:"));for(let y of i)console.log(r.gray(` - ${y}`));return}else{console.log(r.yellow("\u53EF\u7528\u7684\u6A21\u677F:"));for(let h of i)console.log(r.gray(` - ${h}`));return}}let c=f.dirname(P(import.meta.url)),g=[f.join(c,"..","templates"),f.join(c,"templates"),f.join(c,"..","..","templates")].find(u=>p.existsSync(u)),d=f.join(g,o.template);n.text=`\u4ECE\u6A21\u677F "${o.template}" \u521B\u5EFA\u9879\u76EE "${e}"...`,B(d,t,["node_modules",".pnpm-debug.log","pnpm-lock.yaml"]),n.succeed(`\u9879\u76EE "${e}" \u521B\u5EFA\u6210\u529F`),console.log(r.green("\u2705 \u9879\u76EE\u521B\u5EFA\u5B8C\u6210!")),console.log(r.yellow("\u{1F4DD} \u63A5\u4E0B\u6765\u7684\u6B65\u9AA4:")),console.log(r.gray(` cd ${e}`)),console.log(r.gray(" pnpm install # \u5B89\u88C5\u4F9D\u8D56")),console.log(r.gray(" # \u7F16\u8F91 xiaozhi.config.json \u8BBE\u7F6E\u4F60\u7684 MCP \u7AEF\u70B9")),console.log(r.gray(" xiaozhi start # \u542F\u52A8\u670D\u52A1"))}else n.text=`\u521B\u5EFA\u57FA\u672C\u9879\u76EE "${e}"...`,p.mkdirSync(t,{recursive:!0}),wo(t),n.succeed(`\u9879\u76EE "${e}" \u521B\u5EFA\u6210\u529F`),console.log(r.green("\u2705 \u57FA\u672C\u9879\u76EE\u521B\u5EFA\u5B8C\u6210!")),console.log(r.yellow("\u{1F4DD} \u63A5\u4E0B\u6765\u7684\u6B65\u9AA4:")),console.log(r.gray(` cd ${e}`)),console.log(r.gray(" # \u7F16\u8F91 xiaozhi.config.json \u8BBE\u7F6E\u4F60\u7684 MCP \u7AEF\u70B9\u548C\u670D\u52A1")),console.log(r.gray(" xiaozhi start # \u542F\u52A8\u670D\u52A1")),console.log(r.yellow("\u{1F4A1} \u63D0\u793A: \u4F7F\u7528 --template \u9009\u9879\u53EF\u4EE5\u4ECE\u6A21\u677F\u521B\u5EFA\u9879\u76EE"))}catch(t){n.fail(`\u521B\u5EFA\u9879\u76EE\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`)}}a(So,"createProject");function B(e,o,n=[]){p.existsSync(o)||p.mkdirSync(o,{recursive:!0});let t=p.readdirSync(e);for(let i of t){if(n.some(d=>i.includes(d)))continue;let c=f.join(e,i),s=f.join(o,i);p.statSync(c).isDirectory()?B(c,s,n):p.copyFileSync(c,s)}}a(B,"copyDirectory");async function vo(e,o){let n=b("\u66F4\u65B0\u914D\u7F6E...").start();try{if(!m.configExists()){n.fail("\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728"),console.log(r.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u5148\u8FD0\u884C "xiaozhi init" \u521D\u59CB\u5316\u914D\u7F6E'));return}if(o)switch(e){case"mcpEndpoint":m.updateMcpEndpoint(o),n.succeed(`MCP \u7AEF\u70B9\u5DF2\u66F4\u65B0\u4E3A: ${o}`);break;default:n.fail(`\u914D\u7F6E\u9879 ${e} \u4E0D\u652F\u6301\u901A\u8FC7\u547D\u4EE4\u884C\u8BBE\u7F6E`),console.log(r.yellow("\u652F\u6301\u8BBE\u7F6E\u7684\u914D\u7F6E\u9879: mcpEndpoint"));return}else{n.text="\u8BFB\u53D6\u914D\u7F6E...";let t=m.getConfig();switch(e){case"mcpEndpoint":n.succeed("\u914D\u7F6E\u4FE1\u606F"),console.log(r.green(`MCP \u7AEF\u70B9: ${t.mcpEndpoint}`));break;case"mcpServers":n.succeed("\u914D\u7F6E\u4FE1\u606F"),console.log(r.green("MCP \u670D\u52A1:"));for(let[i,c]of Object.entries(t.mcpServers))console.log(r.gray(` ${i}: ${c.command} ${c.args.join(" ")}`));break;default:n.fail(`\u672A\u77E5\u7684\u914D\u7F6E\u9879: ${e}`),console.log(r.yellow("\u652F\u6301\u7684\u914D\u7F6E\u9879: mcpEndpoint, mcpServers"));return}}}catch(t){n.fail(`\u914D\u7F6E\u64CD\u4F5C\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`)}}a(vo,"configCommand");function bo(){console.log(r.blue.bold("xiaozhi - MCP Calculator Service CLI")),console.log(),console.log(r.yellow("\u4F7F\u7528\u65B9\u6CD5:")),console.log(" xiaozhi <command> [options]"),console.log(),console.log(r.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] \u542F\u52A8\u670D\u52A1 (--daemon \u540E\u53F0\u8FD0\u884C)"),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] \u91CD\u542F\u670D\u52A1 (--daemon \u540E\u53F0\u8FD0\u884C)"),console.log(" completion \u663E\u793A\u81EA\u52A8\u8865\u5168\u8BBE\u7F6E\u8BF4\u660E"),console.log(),console.log(r.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(r.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(r.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(r.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 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(r.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(r.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")}a(bo,"showHelp");w.name("xiaozhi").description("MCP Calculator Service CLI Tool").version(V(),"-v, --version","\u663E\u793A\u7248\u672C\u4FE1\u606F").helpOption("-h, --help","\u663E\u793A\u5E2E\u52A9\u4FE1\u606F");w.command("create <projectName>").description("\u521B\u5EFA\u9879\u76EE").option("-t, --template <templateName>","\u4F7F\u7528\u6307\u5B9A\u6A21\u677F\u521B\u5EFA\u9879\u76EE").action(async(e,o)=>{await So(e,o)});w.command("init").description("\u521D\u59CB\u5316\u914D\u7F6E\u6587\u4EF6").action(async()=>{await uo()});w.command("config <key> [value]").description("\u67E5\u770B\u6216\u8BBE\u7F6E\u914D\u7F6E").action(async(e,o)=>{await vo(e,o)});w.command("start").description("\u542F\u52A8\u670D\u52A1").option("-d, --daemon","\u5728\u540E\u53F0\u8FD0\u884C\u670D\u52A1").action(async e=>{await U(e.daemon)});w.command("stop").description("\u505C\u6B62\u670D\u52A1").action(async()=>{await Z()});w.command("status").description("\u68C0\u67E5\u670D\u52A1\u72B6\u6001").action(async()=>{await go()});w.command("attach").description("\u8FDE\u63A5\u5230\u540E\u53F0\u670D\u52A1\u67E5\u770B\u65E5\u5FD7").action(async()=>{await fo()});w.command("restart").description("\u91CD\u542F\u670D\u52A1").option("-d, --daemon","\u5728\u540E\u53F0\u8FD0\u884C\u670D\u52A1").action(async e=>{await po(e.daemon)});var j=w.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 e=>{await A(e)});j.command("server <serverName>").description("\u7BA1\u7406\u6307\u5B9A\u7684 MCP \u670D\u52A1").action(async e=>{await W(e)});j.command("tool <serverName> <toolName> <action>").description("\u542F\u7528\u6216\u7981\u7528\u6307\u5B9A\u670D\u52A1\u7684\u5DE5\u5177").action(async(e,o,n)=>{n!=="enable"&&n!=="disable"&&(console.error(r.red("\u9519\u8BEF: \u64CD\u4F5C\u5FC5\u987B\u662F 'enable' \u6216 'disable'")),process.exit(1)),await L(e,o,n==="enable")});w.command("completion").description("\u663E\u793A\u81EA\u52A8\u8865\u5168\u8BBE\u7F6E\u8BF4\u660E").action(async()=>{D()});w.option("-V","\u663E\u793A\u8BE6\u7EC6\u4FE1\u606F").action(e=>{e.V&&(mo(),process.exit(0))});I();process.argv.length<=2&&(bo(),process.exit(0));w.parse(process.argv);export{N as calculateSimilarity,lo as checkEnvironment,co as formatUptime,$ as getServiceStatus,V as getVersion};
9
8
  //# sourceMappingURL=cli.js.map