grix-connector 3.5.1 → 3.5.3

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.
Files changed (34) hide show
  1. package/dist/adapter/claude/claude-bridge-server.js +1 -1
  2. package/dist/adapter/claude/claude-tools.js +1 -1
  3. package/dist/adapter/claude/claude-worker-client.js +1 -1
  4. package/dist/adapter/claude/mcp-http-launcher.js +2 -2
  5. package/dist/adapter/claude/result-timeout.js +1 -1
  6. package/dist/adapter/codex/codex-bridge.js +8 -8
  7. package/dist/bridge/bridge.js +4 -4
  8. package/dist/core/access/allowlist-store.js +1 -1
  9. package/dist/core/admin/admin-server.js +1 -1
  10. package/dist/core/file-ops/list-files.js +1 -1
  11. package/dist/core/installer/registry.js +1 -1
  12. package/dist/core/proxy/compat/anthropic/forwarder.js +1 -1
  13. package/dist/core/proxy/compat/codex-anthropic/forwarder.js +1 -1
  14. package/dist/core/proxy/compat/codex-gemini/forwarder.js +1 -1
  15. package/dist/core/proxy/compat/codex-openai/forwarder.js +1 -1
  16. package/dist/core/proxy/compat/gemini/forwarder.js +1 -1
  17. package/dist/core/proxy/gateway-route.js +1 -0
  18. package/dist/core/proxy/index.js +1 -1
  19. package/dist/core/proxy/proxy-manager.js +5 -5
  20. package/dist/core/proxy/relay-credential.js +1 -0
  21. package/dist/core/proxy/relay-hosts.js +1 -1
  22. package/dist/core/proxy/relay-orchestration.js +1 -1
  23. package/dist/core/proxy/routing/registry.js +1 -1
  24. package/dist/core/proxy/routing/resolver.js +1 -1
  25. package/dist/core/proxy/server/mitm-proxy.js +5 -3
  26. package/dist/grix.js +6 -6
  27. package/dist/log.js +2 -2
  28. package/dist/mcp/stream-http/config.js +1 -1
  29. package/dist/mcp/stream-http/connection-binding.js +1 -1
  30. package/dist/mcp/stream-http/tool-executor.js +1 -1
  31. package/dist/mcp/stream-http/tool-registry.js +1 -1
  32. package/dist/mcp/stream-http/tool-schemas.js +1 -1
  33. package/dist/service/platform-adapter.js +8 -8
  34. package/package.json +1 -1
@@ -1 +1 @@
1
- const r=3e4;class c{connectionManager;onDisconnected;bindings=new Map;constructor(n,i){this.connectionManager=n,this.onDisconnected=i}async bind(n,i){if(this.bindings.has(n))throw new Error(`Session ${n} is already bound to a connection`);const e=await this.connectWithTimeout(i),t=[],s=e.onDisconnected(()=>{this.removeBinding(n),this.onDisconnected(n)});return t.push(s),this.bindings.set(n,{sessionId:n,handle:e,subscriptions:t}),e}getHandle(n){return this.bindings.get(n)?.handle}unbind(n){const i=this.bindings.get(n);if(i){this.bindings.delete(n);for(const e of i.subscriptions)e();i.handle.disconnect()}}unbindAll(){const n=[...this.bindings.keys()];for(const i of n)this.unbind(i)}connectWithTimeout(n){return new Promise((i,e)=>{let t=!1;const s=setTimeout(()=>{t||(t=!0,e(new Error("Connection bind timeout after 30000ms")))},3e4);this.connectionManager.connect({agentId:n.agentId,apiKey:n.apiKey,url:n.wsUrl,clientType:n.clientType,capabilities:["agent_invoke"],adapterHint:`${n.clientType}/base`},{maxRetries:0}).then(o=>{t?o.disconnect():(t=!0,clearTimeout(s),i(o))}).catch(o=>{t||(t=!0,clearTimeout(s),e(o))})})}removeBinding(n){const i=this.bindings.get(n);if(i){this.bindings.delete(n);for(const e of i.subscriptions)e()}}}export{c as ConnectionBindingImpl};
1
+ const a=3e4;class c{connectionManager;onDisconnected;bindings=new Map;constructor(n,i){this.connectionManager=n,this.onDisconnected=i}async bind(n,i){if(this.bindings.has(n))throw new Error(`Session ${n} is already bound to a connection`);const e=await this.connectWithTimeout(i),t=[],s=e.onDisconnected(()=>{this.removeBinding(n),this.onDisconnected(n)});return t.push(s),this.bindings.set(n,{sessionId:n,handle:e,subscriptions:t}),e}getHandle(n){return this.bindings.get(n)?.handle}unbind(n){const i=this.bindings.get(n);if(i){this.bindings.delete(n);for(const e of i.subscriptions)e();i.handle.disconnect()}}unbindAll(){const n=[...this.bindings.keys()];for(const i of n)this.unbind(i)}connectWithTimeout(n){return new Promise((i,e)=>{let t=!1;const s=setTimeout(()=>{t||(t=!0,e(new Error("Connection bind timeout after 30000ms")))},3e4);this.connectionManager.connect({agentId:n.agentId,apiKey:n.apiKey,url:n.wsUrl,clientType:n.clientType,capabilities:["agent_invoke"],adapterHint:`${n.clientType}/base`},{maxRetries:0}).then(o=>{t?o.disconnect():(t=!0,clearTimeout(s),i(o))}).catch(o=>{t||(t=!0,clearTimeout(s),e(o))})})}removeBinding(n){const i=this.bindings.get(n);if(i){this.bindings.delete(n);for(const e of i.subscriptions)e()}}}export{c as ConnectionBindingImpl};
@@ -1 +1 @@
1
- import{toolCallToInvoke as i}from"../../core/mcp/tools.js";import{ToolRegistryImpl as l}from"./tool-registry.js";import{validateToolArgs as a}from"./tool-schemas.js";import{isEventTool as p,executeEventTool as d}from"./event-tool-executor.js";class y{registry;constructor(){this.registry=new l}async execute(t,e,r,n){if(!this.registry.hasTool(e))return this.errorResult(`\u672A\u77E5\u5DE5\u5177: ${e}`);const s=a(e,r);if(!s.valid)return this.errorResult(`\u53C2\u6570\u6821\u9A8C\u5931\u8D25: ${s.error}`);if(t.status!=="ready")return this.errorResult(`\u8FDE\u63A5\u4E0D\u53EF\u7528: \u5F53\u524D\u72B6\u6001\u4E3A ${t.status}`);if(p(e))return this.executeEventTool(t,e,r);const o=i(e,r);try{const u=await t.agentInvoke(o.action,o.params,n);return this.normalizeResult(u)}catch(u){const c=u instanceof Error?u.message:String(u);return c.toLowerCase().includes("timeout")?this.errorResult(`\u8C03\u7528\u8D85\u65F6: ${c}`):this.errorResult(`\u8C03\u7528\u5931\u8D25: ${c}`)}}normalizeResult(t){if(t==null||typeof t!="object")return this.successResult(t??null);const e=t,r=typeof e.code=="number"?e.code:0;if(r===0){const s="data"in e?e.data:null;return this.successResult(s??null)}const n=typeof e.msg=="string"?e.msg:"\u672A\u77E5\u9519\u8BEF";return this.errorResult(`\u4E0A\u6E38\u9519\u8BEF [code=${r}]: ${n}`)}successResult(t){return{content:[{type:"text",text:JSON.stringify(t)}],isError:!1}}errorResult(t){return{content:[{type:"text",text:t}],isError:!0}}async executeEventTool(t,e,r){return e==="grix_access_control"?this.executeAccessControl(t,r):d(t,e,r)}async executeAccessControl(t,e){const r=String(e.action??""),n={pair_approve:"pair_approve",pair_deny:"pair_deny",allow_sender:"sender_allow",remove_sender:"sender_remove",set_policy:"policy_set"}[r];if(!n)return this.errorResult(`\u672A\u77E5 access_control action: ${r}`);const s={};e.code!=null&&(s.code=e.code),e.sender_id!=null&&(s.sender_id=e.sender_id),e.policy!=null&&(s.policy=e.policy);try{const o=await t.agentInvoke("claude_access_control",{verb:n,payload:s},3e4);return this.successResult(o)}catch(o){const u=o instanceof Error?o.message:String(o);return this.errorResult(`access_control \u8C03\u7528\u5931\u8D25: ${u}`)}}}export{y as ToolExecutorImpl};
1
+ import{toolCallToInvoke as i}from"../../core/mcp/tools.js";import{ToolRegistryImpl as l}from"./tool-registry.js";import{validateToolArgs as a}from"./tool-schemas.js";import{isEventTool as p,executeEventTool as d}from"./event-tool-executor.js";class y{registry;constructor(){this.registry=new l}async execute(r,e,t,n){if(!this.registry.hasTool(e))return this.errorResult(`\u672A\u77E5\u5DE5\u5177: ${e}`);const s=a(e,t);if(!s.valid)return this.errorResult(`\u53C2\u6570\u6821\u9A8C\u5931\u8D25: ${s.error}`);if(r.status!=="ready")return this.errorResult(`\u8FDE\u63A5\u4E0D\u53EF\u7528: \u5F53\u524D\u72B6\u6001\u4E3A ${r.status}`);if(p(e))return this.executeEventTool(r,e,t);const o=i(e,t);try{const u=await r.agentInvoke(o.action,o.params,n);return this.normalizeResult(u)}catch(u){const c=u instanceof Error?u.message:String(u);return c.toLowerCase().includes("timeout")?this.errorResult(`\u8C03\u7528\u8D85\u65F6: ${c}`):this.errorResult(`\u8C03\u7528\u5931\u8D25: ${c}`)}}normalizeResult(r){if(r==null||typeof r!="object")return this.successResult(r??null);const e=r,t=typeof e.code=="number"?e.code:0;if(t===0){const s="data"in e?e.data:null;return this.successResult(s??null)}const n=typeof e.msg=="string"?e.msg:"\u672A\u77E5\u9519\u8BEF";return this.errorResult(`\u4E0A\u6E38\u9519\u8BEF [code=${t}]: ${n}`)}successResult(r){return{content:[{type:"text",text:JSON.stringify(r)}],isError:!1}}errorResult(r){return{content:[{type:"text",text:r}],isError:!0}}async executeEventTool(r,e,t){return e==="grix_access_control"?this.executeAccessControl(r,t):d(r,e,t)}async executeAccessControl(r,e){const t=String(e.action??""),n={pair_approve:"pair_approve",pair_deny:"pair_deny",allow_sender:"sender_allow",remove_sender:"sender_remove",set_policy:"policy_set"}[t];if(!n)return this.errorResult(`\u672A\u77E5 access_control action: ${t}`);const s={};e.code!=null&&(s.code=e.code),e.sender_id!=null&&(s.sender_id=e.sender_id),e.policy!=null&&(s.policy=e.policy);try{const o=await r.agentInvoke("claude_access_control",{verb:n,payload:s},3e4);return this.successResult(o)}catch(o){const u=o instanceof Error?o.message:String(o);return this.errorResult(`access_control \u8C03\u7528\u5931\u8D25: ${u}`)}}}export{y as ToolExecutorImpl};
@@ -1 +1 @@
1
- import{TOOLS as s,EVENT_TOOLS as t}from"../../core/mcp/tools.js";const e=new Set(["grix_query","grix_group","grix_message_send","grix_message_unsend","grix_admin"]),r=new Set(["grix_reply","grix_complete","grix_event_ack","grix_composing","grix_access_control","grix_status"]);class a{tools;toolMap;constructor(){this.tools=[...s.filter(o=>e.has(o.name)),...t.filter(o=>r.has(o.name))],this.toolMap=new Map(this.tools.map(o=>[o.name,o]))}getTools(){return this.tools}getTool(o){return this.toolMap.get(o)}hasTool(o){return this.toolMap.has(o)}}export{a as ToolRegistryImpl};
1
+ import{TOOLS as o,EVENT_TOOLS as s}from"../../core/mcp/tools.js";const e=new Set(["grix_query","grix_group","grix_message_send","grix_message_unsend","grix_admin"]),r=new Set(["grix_reply","grix_complete","grix_event_ack","grix_composing","grix_access_control","grix_status"]);class a{tools;toolMap;constructor(){this.tools=[...o.filter(t=>e.has(t.name)),...s.filter(t=>r.has(t.name))],this.toolMap=new Map(this.tools.map(t=>[t.name,t]))}getTools(){return this.tools}getTool(t){return this.toolMap.get(t)}hasTool(t){return this.toolMap.has(t)}}export{a as ToolRegistryImpl};
@@ -1 +1 @@
1
- const o={required:["action"],properties:{action:{type:"string",enum:["contact_search","session_search","message_history","message_search"]},id:{type:"string"},keyword:{type:"string",maxLength:200},limit:{type:"integer",minimum:1,maximum:100},offset:{type:"integer",minimum:0},sessionId:{type:"string"},beforeId:{type:"string"}}},a={required:["action"],properties:{action:{type:"string",enum:["create","detail","leave","add_members","remove_members","update_member_role","update_all_members_muted","update_member_speaking","dissolve"]},sessionId:{type:"string"},name:{type:"string",maxLength:128},memberIds:{type:"array",items:{type:"string"},maxItems:100},memberTypes:{type:"array",items:{type:"integer",enum:[1,2]}},memberId:{type:"string"},role:{type:"integer",enum:[1,2]},memberType:{type:"integer"},allMembersMuted:{type:"boolean"},isSpeakMuted:{type:"boolean"},canSpeakWhenAllMuted:{type:"boolean"}}},p={required:["sessionId","content"],properties:{sessionId:{type:"string"},content:{type:"string",maxLength:1e4},msgType:{type:"integer"},quotedMessageId:{type:"string"},threadId:{type:"string"}}},m={required:["sessionId","msgId"],properties:{sessionId:{type:"string"},msgId:{type:"string"}}},g={required:["action"],properties:{action:{type:"string",enum:["create_agent","list_categories","create_category","update_category","assign_category","rotate_api_key"]},agentName:{type:"string"},introduction:{type:"string"},isMain:{type:"boolean"},agentId:{type:"string"},categoryId:{type:"string"},name:{type:"string"},parentId:{type:"string"},sortOrder:{type:"integer"}}},y={required:["session_id","text"],properties:{event_id:{type:"string"},session_id:{type:"string"},text:{type:"string",maxLength:5e4},quoted_message_id:{type:"string"},is_final:{type:"boolean"}}},d={required:["event_id","status"],properties:{event_id:{type:"string"},status:{type:"string",enum:["responded","canceled","failed"]},msg:{type:"string",maxLength:500}}},c={required:["event_id"],properties:{event_id:{type:"string"},session_id:{type:"string"}}},l={required:["session_id","active"],properties:{session_id:{type:"string"},active:{type:"boolean"},event_id:{type:"string"}}},_={required:["action"],properties:{action:{type:"string",enum:["pair_approve","pair_deny","allow_sender","remove_sender","set_policy"]},code:{type:"string"},sender_id:{type:"string"},policy:{type:"string",enum:["allowlist","open","disabled"]}}},f={required:[],properties:{}},C={grix_query:o,grix_group:a,grix_message_send:p,grix_message_unsend:m,grix_admin:g,grix_reply:y,grix_complete:d,grix_event_ack:c,grix_composing:l,grix_access_control:_,grix_status:f};function B(u,t){const e=C[u];if(!e)return{valid:!1,error:`\u672A\u77E5\u5DE5\u5177: ${u}`};for(const i of e.required)if(t[i]===void 0||t[i]===null)return{valid:!1,error:`\u7F3A\u5C11\u5FC5\u586B\u53C2\u6570: ${i}`};for(const[i,r]of Object.entries(t)){if(r==null)continue;const n=e.properties[i];if(!n)continue;const s=$(i,r,n);if(s)return{valid:!1,error:s}}return{valid:!0}}function $(u,t,e){switch(e.type){case"string":if(typeof t!="string")return`\u53C2\u6570 ${u} \u7C7B\u578B\u9519\u8BEF: \u671F\u671B string\uFF0C\u5B9E\u9645 ${typeof t}`;if(e.maxLength!==void 0&&t.length>e.maxLength)return`\u53C2\u6570 ${u} \u8D85\u8FC7\u6700\u5927\u957F\u5EA6 ${e.maxLength}\uFF0C\u5B9E\u9645 ${t.length}`;if(e.enum&&!e.enum.includes(t))return`\u53C2\u6570 ${u} \u503C "${t}" \u4E0D\u5728\u5141\u8BB8\u8303\u56F4 [${e.enum.join(", ")}]`;break;case"integer":if(typeof t!="number"||!Number.isInteger(t))return`\u53C2\u6570 ${u} \u7C7B\u578B\u9519\u8BEF: \u671F\u671B integer\uFF0C\u5B9E\u9645 ${typeof t=="number"?"\u6D6E\u70B9\u6570":typeof t}`;if(e.minimum!==void 0&&t<e.minimum)return`\u53C2\u6570 ${u} \u503C ${t} \u5C0F\u4E8E\u6700\u5C0F\u503C ${e.minimum}`;if(e.maximum!==void 0&&t>e.maximum)return`\u53C2\u6570 ${u} \u503C ${t} \u5927\u4E8E\u6700\u5927\u503C ${e.maximum}`;if(e.enum&&!e.enum.includes(t))return`\u53C2\u6570 ${u} \u503C ${t} \u4E0D\u5728\u5141\u8BB8\u8303\u56F4 [${e.enum.join(", ")}]`;break;case"boolean":if(typeof t!="boolean")return`\u53C2\u6570 ${u} \u7C7B\u578B\u9519\u8BEF: \u671F\u671B boolean\uFF0C\u5B9E\u9645 ${typeof t}`;break;case"array":if(!Array.isArray(t))return`\u53C2\u6570 ${u} \u7C7B\u578B\u9519\u8BEF: \u671F\u671B array\uFF0C\u5B9E\u9645 ${typeof t}`;if(e.maxItems!==void 0&&t.length>e.maxItems)return`\u53C2\u6570 ${u} \u8D85\u8FC7\u6700\u5927\u5143\u7D20\u6570 ${e.maxItems}\uFF0C\u5B9E\u9645 ${t.length}`;if(e.items)for(let i=0;i<t.length;i++){const r=t[i];if(e.items.type==="string"&&typeof r!="string")return`\u53C2\u6570 ${u}[${i}] \u7C7B\u578B\u9519\u8BEF: \u671F\u671B string\uFF0C\u5B9E\u9645 ${typeof r}`;if(e.items.type==="integer"){if(typeof r!="number"||!Number.isInteger(r))return`\u53C2\u6570 ${u}[${i}] \u7C7B\u578B\u9519\u8BEF: \u671F\u671B integer\uFF0C\u5B9E\u9645 ${typeof r}`;if(e.items.enum&&!e.items.enum.includes(r))return`\u53C2\u6570 ${u}[${i}] \u503C ${r} \u4E0D\u5728\u5141\u8BB8\u8303\u56F4 [${e.items.enum.join(", ")}]`}}break}}export{B as validateToolArgs};
1
+ const o={required:["action"],properties:{action:{type:"string",enum:["contact_search","session_search","message_history","message_search"]},id:{type:"string"},keyword:{type:"string",maxLength:200},limit:{type:"integer",minimum:1,maximum:100},offset:{type:"integer",minimum:0},sessionId:{type:"string"},beforeId:{type:"string"}}},a={required:["action"],properties:{action:{type:"string",enum:["create","detail","leave","add_members","remove_members","update_member_role","update_all_members_muted","update_member_speaking","dissolve"]},sessionId:{type:"string"},name:{type:"string",maxLength:128},memberIds:{type:"array",items:{type:"string"},maxItems:100},memberTypes:{type:"array",items:{type:"integer",enum:[1,2]}},memberId:{type:"string"},role:{type:"integer",enum:[1,2]},memberType:{type:"integer"},allMembersMuted:{type:"boolean"},isSpeakMuted:{type:"boolean"},canSpeakWhenAllMuted:{type:"boolean"}}},p={required:["sessionId","content"],properties:{sessionId:{type:"string"},content:{type:"string",maxLength:1e4},msgType:{type:"integer"},quotedMessageId:{type:"string"},threadId:{type:"string"}}},m={required:["sessionId","msgId"],properties:{sessionId:{type:"string"},msgId:{type:"string"}}},g={required:["action"],properties:{action:{type:"string",enum:["create_agent","list_categories","create_category","update_category","assign_category","rotate_api_key"]},agentName:{type:"string"},introduction:{type:"string"},isMain:{type:"boolean"},agentId:{type:"string"},categoryId:{type:"string"},name:{type:"string"},parentId:{type:"string"},sortOrder:{type:"integer"}}},y={required:["session_id","text"],properties:{event_id:{type:"string"},session_id:{type:"string"},text:{type:"string",maxLength:5e4},quoted_message_id:{type:"string"},is_final:{type:"boolean"}}},d={required:["event_id","status"],properties:{event_id:{type:"string"},status:{type:"string",enum:["responded","canceled","failed"]},msg:{type:"string",maxLength:500}}},c={required:["event_id"],properties:{event_id:{type:"string"},session_id:{type:"string"}}},l={required:["session_id","active"],properties:{session_id:{type:"string"},active:{type:"boolean"},event_id:{type:"string"}}},_={required:["action"],properties:{action:{type:"string",enum:["pair_approve","pair_deny","allow_sender","remove_sender","set_policy"]},code:{type:"string"},sender_id:{type:"string"},policy:{type:"string",enum:["allowlist","open","disabled"]}}},f={required:[],properties:{}},C={grix_query:o,grix_group:a,grix_message_send:p,grix_message_unsend:m,grix_admin:g,grix_reply:y,grix_complete:d,grix_event_ack:c,grix_composing:l,grix_access_control:_,grix_status:f};function B(r,t){const e=C[r];if(!e)return{valid:!1,error:`\u672A\u77E5\u5DE5\u5177: ${r}`};for(const i of e.required)if(t[i]===void 0||t[i]===null)return{valid:!1,error:`\u7F3A\u5C11\u5FC5\u586B\u53C2\u6570: ${i}`};for(const[i,u]of Object.entries(t)){if(u==null)continue;const n=e.properties[i];if(!n)continue;const s=$(i,u,n);if(s)return{valid:!1,error:s}}return{valid:!0}}function $(r,t,e){switch(e.type){case"string":if(typeof t!="string")return`\u53C2\u6570 ${r} \u7C7B\u578B\u9519\u8BEF: \u671F\u671B string\uFF0C\u5B9E\u9645 ${typeof t}`;if(e.maxLength!==void 0&&t.length>e.maxLength)return`\u53C2\u6570 ${r} \u8D85\u8FC7\u6700\u5927\u957F\u5EA6 ${e.maxLength}\uFF0C\u5B9E\u9645 ${t.length}`;if(e.enum&&!e.enum.includes(t))return`\u53C2\u6570 ${r} \u503C "${t}" \u4E0D\u5728\u5141\u8BB8\u8303\u56F4 [${e.enum.join(", ")}]`;break;case"integer":if(typeof t!="number"||!Number.isInteger(t))return`\u53C2\u6570 ${r} \u7C7B\u578B\u9519\u8BEF: \u671F\u671B integer\uFF0C\u5B9E\u9645 ${typeof t=="number"?"\u6D6E\u70B9\u6570":typeof t}`;if(e.minimum!==void 0&&t<e.minimum)return`\u53C2\u6570 ${r} \u503C ${t} \u5C0F\u4E8E\u6700\u5C0F\u503C ${e.minimum}`;if(e.maximum!==void 0&&t>e.maximum)return`\u53C2\u6570 ${r} \u503C ${t} \u5927\u4E8E\u6700\u5927\u503C ${e.maximum}`;if(e.enum&&!e.enum.includes(t))return`\u53C2\u6570 ${r} \u503C ${t} \u4E0D\u5728\u5141\u8BB8\u8303\u56F4 [${e.enum.join(", ")}]`;break;case"boolean":if(typeof t!="boolean")return`\u53C2\u6570 ${r} \u7C7B\u578B\u9519\u8BEF: \u671F\u671B boolean\uFF0C\u5B9E\u9645 ${typeof t}`;break;case"array":if(!Array.isArray(t))return`\u53C2\u6570 ${r} \u7C7B\u578B\u9519\u8BEF: \u671F\u671B array\uFF0C\u5B9E\u9645 ${typeof t}`;if(e.maxItems!==void 0&&t.length>e.maxItems)return`\u53C2\u6570 ${r} \u8D85\u8FC7\u6700\u5927\u5143\u7D20\u6570 ${e.maxItems}\uFF0C\u5B9E\u9645 ${t.length}`;if(e.items)for(let i=0;i<t.length;i++){const u=t[i];if(e.items.type==="string"&&typeof u!="string")return`\u53C2\u6570 ${r}[${i}] \u7C7B\u578B\u9519\u8BEF: \u671F\u671B string\uFF0C\u5B9E\u9645 ${typeof u}`;if(e.items.type==="integer"){if(typeof u!="number"||!Number.isInteger(u))return`\u53C2\u6570 ${r}[${i}] \u7C7B\u578B\u9519\u8BEF: \u671F\u671B integer\uFF0C\u5B9E\u9645 ${typeof u}`;if(e.items.enum&&!e.items.enum.includes(u))return`\u53C2\u6570 ${r}[${i}] \u503C ${u} \u4E0D\u5728\u5141\u8BB8\u8303\u56F4 [${e.items.enum.join(", ")}]`}}break}}export{B as validateToolArgs};
@@ -1,4 +1,4 @@
1
- import{existsSync as E,readFileSync as O}from"node:fs";import{mkdir as P,readdir as v,readFile as g,rm as h,stat as U,writeFile as w}from"node:fs/promises";import l from"node:os";import u from"node:path";import{isProcessRunning as C,runCommand as d,spawnDetached as F,isWindowsElevated as H,killProcessesByCommandLine as _}from"./process-control.js";import{getServicePrefix as A,parseConfigDirFromPlistXML as G,parseConfigDirFromSystemdUnit as V,resolveBareDaemonMarkerPath as y,resolveLinuxUserUnitPath as X,resolveMacOSLaunchAgentPath as Q}from"./service-paths.js";function p(t){return String(t??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function T(t){return`'${String(t??"").replace(/'/g,"'\\''")}'`}function j(t){return[t.nodePath,t.cliPath,...t.configDir?["--config-dir",t.configDir]:[]]}function z(t){const e=j(t);return`<?xml version="1.0" encoding="UTF-8"?>
1
+ import{existsSync as N,readFileSync as O}from"node:fs";import{mkdir as P,readdir as C,readFile as g,rm as h,stat as H,writeFile as w}from"node:fs/promises";import l from"node:os";import u from"node:path";import{isProcessRunning as v,runCommand as d,spawnDetached as R,isWindowsElevated as G,killProcessesByCommandLine as _}from"./process-control.js";import{getServicePrefix as A,parseConfigDirFromPlistXML as V,parseConfigDirFromSystemdUnit as X,resolveBareDaemonMarkerPath as y,resolveLinuxUserUnitPath as Q,resolveMacOSLaunchAgentPath as z}from"./service-paths.js";function p(t){return String(t??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function T(t){return`'${String(t??"").replace(/'/g,"'\\''")}'`}function j(t){return[t.nodePath,t.cliPath,...t.configDir?["--config-dir",t.configDir]:[]]}function J(t){const e=j(t);return`<?xml version="1.0" encoding="UTF-8"?>
2
2
  <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
3
  <plist version="1.0">
4
4
  <dict>
@@ -26,7 +26,7 @@ ${t.environmentPath?` <key>EnvironmentVariables</key>
26
26
  <string>${p(t.stderrPath)}</string>
27
27
  </dict>
28
28
  </plist>
29
- `}function J(t){const e=j(t).map(r=>T(r)).join(" ");return`[Unit]
29
+ `}function K(t){const e=j(t).map(r=>T(r)).join(" ");return`[Unit]
30
30
  Description=grix-connector daemon (${t.serviceID})
31
31
  After=network.target
32
32
 
@@ -42,7 +42,7 @@ StandardError=append:${t.stderrPath}
42
42
  [Install]
43
43
  WantedBy=default.target
44
44
  `}function k(t,e){const r=t.replace(/[^a-zA-Z0-9._-]/g,"_");return u.join(e,".grix",`${r}-wrapper.vbs`)}function I(t,e){const r=t.replace(/[^a-zA-Z0-9._-]/g,"_"),n=u.join(e,"AppData","Roaming","Microsoft","Windows","Start Menu","Programs","Startup");return u.join(n,`${r}.lnk`)}function S(t){return String(t??"").replace(/"/g,'""')}function Z(t,e){const r=u.join(u.dirname(t),u.basename(e).replace(/\.lnk$/,"-create.vbs")),n=["Option Explicit","Dim shell, shortcut",'Set shell = CreateObject("WScript.Shell")',`Set shortcut = shell.CreateShortcut("${S(e)}")`,'shortcut.TargetPath = "wscript.exe"',`shortcut.Arguments = "//B //NoLogo \\"${S(t)}\\""`,"shortcut.WindowStyle = 7","shortcut.Save",""].join(`\r
45
- `);return{path:r,content:n}}async function q(t){const{wrapperPath:e,shortcutPath:r,runCommand:n}=t,a=Z(e,r);for(let i=1;i<=3;i+=1){try{await w(a.path,a.content,"utf8"),await n("wscript.exe",[a.path,"//B","//NoLogo"])}catch{}finally{await h(a.path,{force:!0}).catch(()=>{})}if(E(r))return!0}return console.warn(`Warning: failed to create Windows logon-autostart shortcut at ${r}. The daemon will NOT start automatically after the next reboot/logon. Check Controlled Folder Access / antivirus blocking writes to the Startup folder, or create the shortcut manually.`),!1}async function K(t){try{const e=await t("whoami",["/user","/fo","csv","/nh"],{allowFailure:!0}),r=String(e?.stdout??"").match(/"(S-1-[0-9-]+)"/);if(r)return r[1]}catch{}return null}function Y(t){const e=`//B //NoLogo "${t.wrapperPath}"`;return`<?xml version="1.0" encoding="UTF-16"?>
45
+ `);return{path:r,content:n}}async function q(t){const{wrapperPath:e,shortcutPath:r,runCommand:n}=t,a=Z(e,r);for(let i=1;i<=3;i+=1){try{await w(a.path,a.content,"utf8"),await n("wscript.exe",[a.path,"//B","//NoLogo"])}catch{}finally{await h(a.path,{force:!0}).catch(()=>{})}if(N(r))return!0}return console.warn(`Warning: failed to create Windows logon-autostart shortcut at ${r}. The daemon will NOT start automatically after the next reboot/logon. Check Controlled Folder Access / antivirus blocking writes to the Startup folder, or create the shortcut manually.`),!1}async function Y(t){try{const e=await t("whoami",["/user","/fo","csv","/nh"],{allowFailure:!0}),r=String(e?.stdout??"").match(/"(S-1-[0-9-]+)"/);if(r)return r[1]}catch{}return null}function tt(t){const e=`//B //NoLogo "${t.wrapperPath}"`;return`<?xml version="1.0" encoding="UTF-16"?>
46
46
  <Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
47
47
  <RegistrationInfo>
48
48
  <Description>grix-connector daemon autostart</Description>
@@ -85,12 +85,12 @@ WantedBy=default.target
85
85
  </Exec>
86
86
  </Actions>
87
87
  </Task>
88
- `}async function tt(t){const{serviceID:e,wrapperPath:r,runCommand:n}=t,a=await K(n)??l.userInfo().username,i=u.join(u.dirname(r),`${e}-task.xml`);try{const o=Y({userId:a,wrapperPath:r});return await w(i,"\uFEFF"+o,"utf16le"),await n("schtasks",["/Create","/TN",e,"/XML",i,"/F"]),!0}catch{return!1}finally{await h(i,{force:!0}).catch(()=>{})}}function et(t){const e=[`"${S(t.nodePath)}"`,`"${S(t.cliPath)}"`,...t.configDir?["--config-dir",`"${S(t.configDir)}"`]:[]].join(" ");return["Option Explicit","Dim shell, command, delayMs, rapidCount",`command = "${S(e)}"`,'Set shell = CreateObject("WScript.Shell")',"delayMs = 5000","rapidCount = 0","Do"," shell.Run command, 0, True"," rapidCount = rapidCount + 1"," If rapidCount >= 10 Then"," WScript.Sleep 300000"," rapidCount = 0"," Else"," WScript.Sleep delayMs"," End If","Loop",""].join(`\r
89
- `)}function b(t){return`gui/${t??0}`}function N(t){const e=String(t?.stdout??"").trim();return String(t?.stderr??"").trim()||e||`exit=${Number(t?.exitCode??-1)}`}function R(t,e){if(Number(t?.exitCode??0)!==0)throw new Error(`${e}: ${N(t)}`)}function rt(){return{platform:"darwin",kind:"launchd",async install({serviceID:t,nodePath:e,cliPath:r,configDir:n,stdoutPath:a,stderrPath:i,environmentPath:s="",homeDir:o=l.homedir()}){const c=Q(t,o);return await P(u.dirname(c),{recursive:!0}),await w(c,z({serviceID:t,nodePath:e,cliPath:r,configDir:n,stdoutPath:a,stderrPath:i,environmentPath:s}),{encoding:"utf8",mode:384}),{definitionPath:c}},async start({serviceID:t,definitionPath:e,runCommand:r=d,uid:n=process.getuid?.()??0}){const a=b(n);let i=await r("launchctl",["bootstrap",a,e],{allowFailure:!0});Number(i?.exitCode??0)!==0&&(await r("launchctl",["bootout",`${a}/${t}`],{allowFailure:!0}),i=await r("launchctl",["bootstrap",a,e],{allowFailure:!0}),R(i,`launchctl bootstrap ${a}`));const s=await r("launchctl",["kickstart","-k",`${a}/${t}`],{allowFailure:!0});if(Number(s?.exitCode??0)!==0){const o=Number(i?.exitCode??0)===0?"":`, bootstrap=${N(i)}`;throw new Error(`launchctl start failed for ${a}/${t}: ${N(s)}${o}`)}},async stop({serviceID:t,runCommand:e=d,uid:r=process.getuid?.()??0}){const n=b(r);await e("launchctl",["bootout",`${n}/${t}`],{allowFailure:!0})},async restart({serviceID:t,definitionPath:e,runCommand:r=d,uid:n=process.getuid?.()??0}){const a=b(n);await r("launchctl",["bootout",`${a}/${t}`],{allowFailure:!0});for(let o=0;o<20&&(await r("launchctl",["print",`${a}/${t}`],{allowFailure:!0})).exitCode===0;o+=1)await new Promise(m=>setTimeout(m,250));try{await U(e)}catch{throw new Error(`launchd plist missing: ${e}`)}const i=await r("launchctl",["bootstrap",a,e],{allowFailure:!0});R(i,`launchctl bootstrap ${a}`);const s=await r("launchctl",["kickstart","-k",`${a}/${t}`],{allowFailure:!0});R(s,`launchctl kickstart ${a}/${t}`)},async uninstall({serviceID:t,definitionPath:e,runCommand:r=d,uid:n=process.getuid?.()??0}){const a=b(n);await r("launchctl",["bootout",`${a}/${t}`],{allowFailure:!0}),await h(e,{force:!0})},async discoverServices({homeDir:t=l.homedir()}={}){const e=u.join(t,"Library","LaunchAgents"),r=await v(e).catch(()=>[]),n=A("darwin"),a=[];for(const i of r){if(!i.startsWith(n)||!i.endsWith(".plist"))continue;const s=i.slice(0,-6),o=u.join(e,i);let c=null;try{const m=await g(o,"utf8");c=G(m)}catch{}a.push({serviceID:s,definitionPath:o,configDir:c})}return a},async isServiceLoaded({serviceID:t,runCommand:e=d,uid:r=process.getuid?.()??0}){const n=b(r),a=await e("launchctl",["print",`${n}/${t}`],{allowFailure:!0});return Number(a?.exitCode??1)===0}}}function nt(){return{platform:"win32",kind:"task-scheduler",async install({serviceID:t,nodePath:e,cliPath:r,configDir:n,runCommand:a=d,homeDir:i=l.homedir()}){const s=k(t,i);await P(u.dirname(s),{recursive:!0}),await w(s,et({nodePath:e,cliPath:r,configDir:n}),"utf8");let o=!1;H()&&(o=await tt({serviceID:t,wrapperPath:s,runCommand:a}));const c=I(t,i);return o?await h(c,{force:!0}).catch(()=>{}):await q({wrapperPath:s,shortcutPath:c,runCommand:a}),{definitionPath:o?`task:${t}`:`startup:${t}`}},async start({serviceID:t,definitionPath:e,runCommand:r=d,homeDir:n=l.homedir()}){const a=k(t,n);if(e.startsWith("task:"))try{await r("schtasks",["/Run","/TN",t]);return}catch{}F("wscript.exe",["//B","//NoLogo",a])},async stop({serviceID:t,runCommand:e=d,homeDir:r=l.homedir()}){await e("schtasks",["/End","/TN",t],{allowFailure:!0});const n=`${t}-wrapper.vbs`;await _(n,{platform:"win32"})},async restart({serviceID:t,definitionPath:e,runCommand:r=d,homeDir:n=l.homedir()}){await r("schtasks",["/End","/TN",t],{allowFailure:!0});const a=`${t}-wrapper.vbs`;await _(a,{platform:"win32"});const i=k(t,n);if(e?.startsWith("task:"))try{await r("schtasks",["/Run","/TN",t]);return}catch{}F("wscript.exe",["//B","//NoLogo",i])},async uninstall({serviceID:t,runCommand:e=d,homeDir:r=l.homedir()}){await e("schtasks",["/Delete","/TN",t,"/F"],{allowFailure:!0});const n=k(t,r);await h(n,{force:!0});const a=I(t,r);await h(a,{force:!0})},async discoverServices({homeDir:t=l.homedir(),runCommand:e=d}={}){const r=A("win32"),n=await e("schtasks",["/Query","/FO","CSV","/NH"],{allowFailure:!0}),a=[];if(Number(n?.exitCode??-1)===0){const o=String(n.stdout??"").split(/\r?\n/);for(const c of o){const m=c.match(/^"([^"]+)"/);if(!m)continue;const f=m[1];if(!f.startsWith(r))continue;let W=null;try{const x=k(f,t),D=(await g(x,"utf8")).match(/--config-dir\s+""([^""]+)""/);D&&(W=D[1])}catch{}a.push({serviceID:f,definitionPath:`task:${f}`,configDir:W})}}const i=u.join(t,"AppData","Roaming","Microsoft","Windows","Start Menu","Programs","Startup"),s=await v(i).catch(()=>[]);for(const o of s){if(!o.startsWith(r)||!o.endsWith(".lnk"))continue;const c=o.slice(0,-4);if(a.some(f=>f.serviceID===c))continue;let m=null;try{const f=k(c,t),x=(await g(f,"utf8")).match(/--config-dir\s+""([^""]+)""/);x&&(m=x[1])}catch{}a.push({serviceID:c,definitionPath:`startup:${c}`,configDir:m})}return a},async isServiceLoaded({serviceID:t,runCommand:e=d}){const r=await e("schtasks",["/Query","/TN",t,"/NH"],{allowFailure:!0});return Number(r?.exitCode??1)===0}}}function at(){return{platform:"linux",kind:"systemd-user",async install({serviceID:t,nodePath:e,cliPath:r,configDir:n,stdoutPath:a,stderrPath:i,homeDir:s=l.homedir(),runCommand:o=d}){const c=X(t,s);return await P(u.dirname(c),{recursive:!0}),await w(c,J({serviceID:t,nodePath:e,cliPath:r,configDir:n,stdoutPath:a,stderrPath:i}),{encoding:"utf8",mode:384}),await o("systemctl",["--user","daemon-reload"]),await o("systemctl",["--user","enable",`${t}.service`]),{definitionPath:c}},async start({serviceID:t,runCommand:e=d}){await e("systemctl",["--user","start",`${t}.service`])},async stop({serviceID:t,runCommand:e=d}){await e("systemctl",["--user","stop",`${t}.service`],{allowFailure:!0})},async restart({serviceID:t,runCommand:e=d}){await e("systemctl",["--user","restart",`${t}.service`])},async uninstall({serviceID:t,definitionPath:e,runCommand:r=d}){await r("systemctl",["--user","stop",`${t}.service`],{allowFailure:!0}),await r("systemctl",["--user","disable",`${t}.service`],{allowFailure:!0}),await h(e,{force:!0}),await r("systemctl",["--user","daemon-reload"])},async discoverServices({homeDir:t=l.homedir()}={}){const e=u.join(t,".config","systemd","user"),r=await v(e).catch(()=>[]),n=A("linux"),a=[];for(const i of r){if(!i.startsWith(n)||!i.endsWith(".service"))continue;const s=i.slice(0,-8),o=u.join(e,i);let c=null;try{const m=await g(o,"utf8");c=V(m)}catch{}a.push({serviceID:s,definitionPath:o,configDir:c})}return a},async isServiceLoaded({serviceID:t,runCommand:e=d}){const r=await e("systemctl",["--user","is-active",`${t}.service`],{allowFailure:!0});return String(r?.stdout??"").trim()==="active"}}}function $(t){try{const e=O(t,"utf8"),r=JSON.parse(e);if(r&&typeof r.service_id=="string"&&typeof r.node_path=="string"&&typeof r.cli_path=="string"&&typeof r.root_dir=="string")return r}catch{}return null}function it(t){return u.join(t,"daemon.lock.json")}function L(t){const e=it(t);try{const r=O(e,"utf8"),n=JSON.parse(r);if(typeof n?.pid=="number")return n.pid}catch{}return 0}function B(t){return u.join(t,".profile")}function ot(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function st(t){const e=[T(t.nodePath),T(t.cliPath)];t.configDir&&e.push("--config-dir",T(t.configDir));const r=e.join(" ");return`${r} status >/dev/null 2>&1 || (nohup ${r} start >/dev/null 2>&1 &)`}function ct(t,e){return`# >>> grix-connector autostart [${t}] >>>
88
+ `}async function et(t){const{serviceID:e,wrapperPath:r,runCommand:n}=t,a=await Y(n)??l.userInfo().username,i=u.join(u.dirname(r),`${e}-task.xml`);try{const o=tt({userId:a,wrapperPath:r});return await w(i,"\uFEFF"+o,"utf16le"),await n("schtasks",["/Create","/TN",e,"/XML",i,"/F"]),!0}catch{return!1}finally{await h(i,{force:!0}).catch(()=>{})}}function rt(t){const e=[`"${S(t.nodePath)}"`,`"${S(t.cliPath)}"`,...t.configDir?["--config-dir",`"${S(t.configDir)}"`]:[]].join(" ");return["Option Explicit","Dim shell, command, delayMs, rapidCount",`command = "${S(e)}"`,'Set shell = CreateObject("WScript.Shell")',"delayMs = 5000","rapidCount = 0","Do"," shell.Run command, 0, True"," rapidCount = rapidCount + 1"," If rapidCount >= 10 Then"," WScript.Sleep 300000"," rapidCount = 0"," Else"," WScript.Sleep delayMs"," End If","Loop",""].join(`\r
89
+ `)}function b(t){return`gui/${t??0}`}function L(t){const e=String(t?.stdout??"").trim();return String(t?.stderr??"").trim()||e||`exit=${Number(t?.exitCode??-1)}`}function F(t,e){if(Number(t?.exitCode??0)!==0)throw new Error(`${e}: ${L(t)}`)}function B(t){return Number(t?.exitCode??0)===0?!1:L(t).includes("Could not find service")}function nt(){return{platform:"darwin",kind:"launchd",async install({serviceID:t,nodePath:e,cliPath:r,configDir:n,stdoutPath:a,stderrPath:i,environmentPath:s="",homeDir:o=l.homedir()}){const c=z(t,o);return await P(u.dirname(c),{recursive:!0}),await w(c,J({serviceID:t,nodePath:e,cliPath:r,configDir:n,stdoutPath:a,stderrPath:i,environmentPath:s}),{encoding:"utf8",mode:384}),{definitionPath:c}},async start({serviceID:t,definitionPath:e,runCommand:r=d,uid:n=process.getuid?.()??0}){const a=b(n);let i=await r("launchctl",["bootstrap",a,e],{allowFailure:!0});Number(i?.exitCode??0)!==0&&(await r("launchctl",["bootout",`${a}/${t}`],{allowFailure:!0}),i=await r("launchctl",["bootstrap",a,e],{allowFailure:!0}),F(i,`launchctl bootstrap ${a}`));const s=await r("launchctl",["kickstart","-k",`${a}/${t}`],{allowFailure:!0});if(Number(s?.exitCode??0)!==0&&!B(s)){const o=Number(i?.exitCode??0)===0?"":`, bootstrap=${L(i)}`;throw new Error(`launchctl start failed for ${a}/${t}: ${L(s)}${o}`)}},async stop({serviceID:t,runCommand:e=d,uid:r=process.getuid?.()??0}){const n=b(r);await e("launchctl",["bootout",`${n}/${t}`],{allowFailure:!0})},async restart({serviceID:t,definitionPath:e,runCommand:r=d,uid:n=process.getuid?.()??0}){const a=b(n);await r("launchctl",["bootout",`${a}/${t}`],{allowFailure:!0});for(let o=0;o<20&&(await r("launchctl",["print",`${a}/${t}`],{allowFailure:!0})).exitCode===0;o+=1)await new Promise(m=>setTimeout(m,250));try{await H(e)}catch{throw new Error(`launchd plist missing: ${e}`)}const i=await r("launchctl",["bootstrap",a,e],{allowFailure:!0});F(i,`launchctl bootstrap ${a}`);const s=await r("launchctl",["kickstart","-k",`${a}/${t}`],{allowFailure:!0});B(s)||F(s,`launchctl kickstart ${a}/${t}`)},async uninstall({serviceID:t,definitionPath:e,runCommand:r=d,uid:n=process.getuid?.()??0}){const a=b(n);await r("launchctl",["bootout",`${a}/${t}`],{allowFailure:!0}),await h(e,{force:!0})},async discoverServices({homeDir:t=l.homedir()}={}){const e=u.join(t,"Library","LaunchAgents"),r=await C(e).catch(()=>[]),n=A("darwin"),a=[];for(const i of r){if(!i.startsWith(n)||!i.endsWith(".plist"))continue;const s=i.slice(0,-6),o=u.join(e,i);let c=null;try{const m=await g(o,"utf8");c=V(m)}catch{}a.push({serviceID:s,definitionPath:o,configDir:c})}return a},async isServiceLoaded({serviceID:t,runCommand:e=d,uid:r=process.getuid?.()??0}){const n=b(r),a=await e("launchctl",["print",`${n}/${t}`],{allowFailure:!0});return Number(a?.exitCode??1)===0}}}function at(){return{platform:"win32",kind:"task-scheduler",async install({serviceID:t,nodePath:e,cliPath:r,configDir:n,runCommand:a=d,homeDir:i=l.homedir()}){const s=k(t,i);await P(u.dirname(s),{recursive:!0}),await w(s,rt({nodePath:e,cliPath:r,configDir:n}),"utf8");let o=!1;G()&&(o=await et({serviceID:t,wrapperPath:s,runCommand:a}));const c=I(t,i);return o?await h(c,{force:!0}).catch(()=>{}):await q({wrapperPath:s,shortcutPath:c,runCommand:a}),{definitionPath:o?`task:${t}`:`startup:${t}`}},async start({serviceID:t,definitionPath:e,runCommand:r=d,homeDir:n=l.homedir()}){const a=k(t,n);if(e.startsWith("task:"))try{await r("schtasks",["/Run","/TN",t]);return}catch{}R("wscript.exe",["//B","//NoLogo",a])},async stop({serviceID:t,runCommand:e=d,homeDir:r=l.homedir()}){await e("schtasks",["/End","/TN",t],{allowFailure:!0});const n=`${t}-wrapper.vbs`;await _(n,{platform:"win32"})},async restart({serviceID:t,definitionPath:e,runCommand:r=d,homeDir:n=l.homedir()}){await r("schtasks",["/End","/TN",t],{allowFailure:!0});const a=`${t}-wrapper.vbs`;await _(a,{platform:"win32"});const i=k(t,n);if(e?.startsWith("task:"))try{await r("schtasks",["/Run","/TN",t]);return}catch{}R("wscript.exe",["//B","//NoLogo",i])},async uninstall({serviceID:t,runCommand:e=d,homeDir:r=l.homedir()}){await e("schtasks",["/Delete","/TN",t,"/F"],{allowFailure:!0});const n=k(t,r);await h(n,{force:!0});const a=I(t,r);await h(a,{force:!0})},async discoverServices({homeDir:t=l.homedir(),runCommand:e=d}={}){const r=A("win32"),n=await e("schtasks",["/Query","/FO","CSV","/NH"],{allowFailure:!0}),a=[];if(Number(n?.exitCode??-1)===0){const o=String(n.stdout??"").split(/\r?\n/);for(const c of o){const m=c.match(/^"([^"]+)"/);if(!m)continue;const f=m[1];if(!f.startsWith(r))continue;let E=null;try{const x=k(f,t),D=(await g(x,"utf8")).match(/--config-dir\s+""([^""]+)""/);D&&(E=D[1])}catch{}a.push({serviceID:f,definitionPath:`task:${f}`,configDir:E})}}const i=u.join(t,"AppData","Roaming","Microsoft","Windows","Start Menu","Programs","Startup"),s=await C(i).catch(()=>[]);for(const o of s){if(!o.startsWith(r)||!o.endsWith(".lnk"))continue;const c=o.slice(0,-4);if(a.some(f=>f.serviceID===c))continue;let m=null;try{const f=k(c,t),x=(await g(f,"utf8")).match(/--config-dir\s+""([^""]+)""/);x&&(m=x[1])}catch{}a.push({serviceID:c,definitionPath:`startup:${c}`,configDir:m})}return a},async isServiceLoaded({serviceID:t,runCommand:e=d}){const r=await e("schtasks",["/Query","/TN",t,"/NH"],{allowFailure:!0});return Number(r?.exitCode??1)===0}}}function it(){return{platform:"linux",kind:"systemd-user",async install({serviceID:t,nodePath:e,cliPath:r,configDir:n,stdoutPath:a,stderrPath:i,homeDir:s=l.homedir(),runCommand:o=d}){const c=Q(t,s);return await P(u.dirname(c),{recursive:!0}),await w(c,K({serviceID:t,nodePath:e,cliPath:r,configDir:n,stdoutPath:a,stderrPath:i}),{encoding:"utf8",mode:384}),await o("systemctl",["--user","daemon-reload"]),await o("systemctl",["--user","enable",`${t}.service`]),{definitionPath:c}},async start({serviceID:t,runCommand:e=d}){await e("systemctl",["--user","start",`${t}.service`])},async stop({serviceID:t,runCommand:e=d}){await e("systemctl",["--user","stop",`${t}.service`],{allowFailure:!0})},async restart({serviceID:t,runCommand:e=d}){await e("systemctl",["--user","restart",`${t}.service`])},async uninstall({serviceID:t,definitionPath:e,runCommand:r=d}){await r("systemctl",["--user","stop",`${t}.service`],{allowFailure:!0}),await r("systemctl",["--user","disable",`${t}.service`],{allowFailure:!0}),await h(e,{force:!0}),await r("systemctl",["--user","daemon-reload"])},async discoverServices({homeDir:t=l.homedir()}={}){const e=u.join(t,".config","systemd","user"),r=await C(e).catch(()=>[]),n=A("linux"),a=[];for(const i of r){if(!i.startsWith(n)||!i.endsWith(".service"))continue;const s=i.slice(0,-8),o=u.join(e,i);let c=null;try{const m=await g(o,"utf8");c=X(m)}catch{}a.push({serviceID:s,definitionPath:o,configDir:c})}return a},async isServiceLoaded({serviceID:t,runCommand:e=d}){const r=await e("systemctl",["--user","is-active",`${t}.service`],{allowFailure:!0});return String(r?.stdout??"").trim()==="active"}}}function $(t){try{const e=O(t,"utf8"),r=JSON.parse(e);if(r&&typeof r.service_id=="string"&&typeof r.node_path=="string"&&typeof r.cli_path=="string"&&typeof r.root_dir=="string")return r}catch{}return null}function ot(t){return u.join(t,"daemon.lock.json")}function W(t){const e=ot(t);try{const r=O(e,"utf8"),n=JSON.parse(r);if(typeof n?.pid=="number")return n.pid}catch{}return 0}function M(t){return u.join(t,".profile")}function st(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function ct(t){const e=[T(t.nodePath),T(t.cliPath)];t.configDir&&e.push("--config-dir",T(t.configDir));const r=e.join(" ");return`${r} status >/dev/null 2>&1 || (nohup ${r} start >/dev/null 2>&1 &)`}function ut(t,e){return`# >>> grix-connector autostart [${t}] >>>
90
90
  ${e}
91
91
  # <<< grix-connector autostart [${t}] <<<
92
- `}function M(t){const e=ot(t);return new RegExp(`(?:^|\\n)# >>> grix-connector autostart \\[${e}\\] >>>\\n[\\s\\S]*?\\n# <<< grix-connector autostart \\[${e}\\] <<<\\n?`,"m")}async function ut(t,e,r){let n="";try{n=await g(t,"utf8")}catch{}const a=ct(e,r),i=M(e);let s;if(i.test(n))s=n.replace(i,`
92
+ `}function U(t){const e=st(t);return new RegExp(`(?:^|\\n)# >>> grix-connector autostart \\[${e}\\] >>>\\n[\\s\\S]*?\\n# <<< grix-connector autostart \\[${e}\\] <<<\\n?`,"m")}async function lt(t,e,r){let n="";try{n=await g(t,"utf8")}catch{}const a=ut(e,r),i=U(e);let s;if(i.test(n))s=n.replace(i,`
93
93
  ${a}`).replace(/^\n+/,"");else{const o=n.length===0||n.endsWith(`
94
94
  `)?"":`
95
- `;s=`${n}${o}${a}`}s!==n&&(await P(u.dirname(t),{recursive:!0}),await w(t,s,{encoding:"utf8"}))}async function lt(t,e){let r="";try{r=await g(t,"utf8")}catch{return}const n=M(e);if(!n.test(r))return;const a=r.replace(n,"").replace(/^\n+/,"");await w(t,a,{encoding:"utf8"})}function dt(){return{platform:"linux",kind:"bare-daemon",async install({serviceID:t,nodePath:e,cliPath:r,configDir:n,stdoutPath:a,stderrPath:i,homeDir:s=l.homedir()}){const o=y(t,s);await P(u.dirname(o),{recursive:!0});const c=u.resolve(u.dirname(u.dirname(a||i||o))),m={schema_version:1,service_id:t,node_path:e,cli_path:r,config_dir:n??"",root_dir:c,stdout_path:a,stderr_path:i,installed_at:Date.now()};await w(o,`${JSON.stringify(m,null,2)}
96
- `,{encoding:"utf8",mode:384});const f=st({nodePath:e,cliPath:r,configDir:n??""});return await ut(B(s),t,f),{definitionPath:o}},async start({serviceID:t,homeDir:e=l.homedir()}){const r=y(t,e),n=$(r);if(!n)throw new Error(`bare-daemon marker missing: ${r}`);const a=[n.cli_path];n.config_dir&&a.push("--config-dir",n.config_dir),F(n.node_path,a)},async stop({serviceID:t,homeDir:e=l.homedir()}){const r=y(t,e),n=$(r);if(!n)return;const a=L(n.root_dir);if(a>0&&C(a))try{process.kill(a,"SIGTERM")}catch{}},async restart(t){await this.stop(t);const e=Date.now()+5e3,r=y(t.serviceID,t.homeDir??l.homedir()),n=$(r);for(;n&&Date.now()<e;){const a=L(n.root_dir);if(a<=0||!C(a))break;await new Promise(i=>setTimeout(i,100))}await this.start(t)},async uninstall({serviceID:t,homeDir:e=l.homedir()}){const r=y(t,e),n=$(r);if(n){const a=L(n.root_dir);if(a>0&&C(a))try{process.kill(a,"SIGTERM")}catch{}}await h(r,{force:!0}),await lt(B(e),t)},async discoverServices({homeDir:t=l.homedir()}={}){const e=u.join(t,".grix","service"),r=await v(e).catch(()=>[]),n=A("linux"),a=[];for(const i of r){if(!i.startsWith(n)||!i.endsWith(".bare.json"))continue;const s=i.slice(0,-10),o=u.join(e,i),c=$(o);a.push({serviceID:s,definitionPath:o,configDir:c?.config_dir||null})}return a},async isServiceLoaded({serviceID:t,homeDir:e=l.homedir()}){const r=y(t,e),n=$(r);if(!n)return!1;const a=L(n.root_dir);return a>0&&C(a)}}}function mt(t=process.getuid?.()??0){if(process.env.GRIX_FORCE_BARE_DAEMON==="1")return!1;const e=process.env.XDG_RUNTIME_DIR;return!!(e&&E(u.join(e,"bus"))||E(`/run/user/${t}/bus`))}function St(t=process.platform,e={}){return t==="darwin"?rt():t==="win32"?nt():e.systemdUserAvailable??mt()?at():dt()}export{St as getPlatformServiceAdapter,mt as isSystemdUserBusAvailable,lt as removeProfileAutostart,ut as upsertProfileAutostart};
95
+ `;s=`${n}${o}${a}`}s!==n&&(await P(u.dirname(t),{recursive:!0}),await w(t,s,{encoding:"utf8"}))}async function dt(t,e){let r="";try{r=await g(t,"utf8")}catch{return}const n=U(e);if(!n.test(r))return;const a=r.replace(n,"").replace(/^\n+/,"");await w(t,a,{encoding:"utf8"})}function mt(){return{platform:"linux",kind:"bare-daemon",async install({serviceID:t,nodePath:e,cliPath:r,configDir:n,stdoutPath:a,stderrPath:i,homeDir:s=l.homedir()}){const o=y(t,s);await P(u.dirname(o),{recursive:!0});const c=u.resolve(u.dirname(u.dirname(a||i||o))),m={schema_version:1,service_id:t,node_path:e,cli_path:r,config_dir:n??"",root_dir:c,stdout_path:a,stderr_path:i,installed_at:Date.now()};await w(o,`${JSON.stringify(m,null,2)}
96
+ `,{encoding:"utf8",mode:384});const f=ct({nodePath:e,cliPath:r,configDir:n??""});return await lt(M(s),t,f),{definitionPath:o}},async start({serviceID:t,homeDir:e=l.homedir()}){const r=y(t,e),n=$(r);if(!n)throw new Error(`bare-daemon marker missing: ${r}`);const a=[n.cli_path];n.config_dir&&a.push("--config-dir",n.config_dir),R(n.node_path,a)},async stop({serviceID:t,homeDir:e=l.homedir()}){const r=y(t,e),n=$(r);if(!n)return;const a=W(n.root_dir);if(a>0&&v(a))try{process.kill(a,"SIGTERM")}catch{}},async restart(t){await this.stop(t);const e=Date.now()+5e3,r=y(t.serviceID,t.homeDir??l.homedir()),n=$(r);for(;n&&Date.now()<e;){const a=W(n.root_dir);if(a<=0||!v(a))break;await new Promise(i=>setTimeout(i,100))}await this.start(t)},async uninstall({serviceID:t,homeDir:e=l.homedir()}){const r=y(t,e),n=$(r);if(n){const a=W(n.root_dir);if(a>0&&v(a))try{process.kill(a,"SIGTERM")}catch{}}await h(r,{force:!0}),await dt(M(e),t)},async discoverServices({homeDir:t=l.homedir()}={}){const e=u.join(t,".grix","service"),r=await C(e).catch(()=>[]),n=A("linux"),a=[];for(const i of r){if(!i.startsWith(n)||!i.endsWith(".bare.json"))continue;const s=i.slice(0,-10),o=u.join(e,i),c=$(o);a.push({serviceID:s,definitionPath:o,configDir:c?.config_dir||null})}return a},async isServiceLoaded({serviceID:t,homeDir:e=l.homedir()}){const r=y(t,e),n=$(r);if(!n)return!1;const a=W(n.root_dir);return a>0&&v(a)}}}function ft(t=process.getuid?.()??0){if(process.env.GRIX_FORCE_BARE_DAEMON==="1")return!1;const e=process.env.XDG_RUNTIME_DIR;return!!(e&&N(u.join(e,"bus"))||N(`/run/user/${t}/bus`))}function $t(t=process.platform,e={}){return t==="darwin"?nt():t==="win32"?at():e.systemdUserAvailable??ft()?it():mt()}export{$t as getPlatformServiceAdapter,ft as isSystemdUserBusAvailable,dt as removeProfileAutostart,lt as upsertProfileAutostart};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "grix-connector",
3
- "version": "3.5.1",
3
+ "version": "3.5.3",
4
4
  "description": "Connect local AI coding agents (Claude, Codex, Gemini, Qwen, DeepSeek, Cursor, OpenCode, Pi, OpenHuman, Reasonix) to the Grix scheduling platform. Also serves as an OpenClaw plugin for Grix channel transport.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",