grix-connector 4.11.11 → 4.11.13
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/dist/adapter/claude/claude-bridge-server.js +1 -1
- package/dist/adapter/claude/claude-tools.js +1 -1
- package/dist/adapter/claude/claude-worker-client.js +1 -1
- package/dist/adapter/claude/mcp-http-launcher.js +2 -2
- package/dist/adapter/claude/result-timeout.js +1 -1
- package/dist/adapter/codex/codex-bridge.js +8 -8
- package/dist/assets/dsh-bridge/grix-dsh-bridge-4.11.13.tgz +0 -0
- package/dist/assets/dsh-bridge/manifest.json +5 -5
- package/dist/core/access/allowlist-store.js +1 -1
- package/dist/core/file-ops/list-files.js +1 -1
- package/dist/grix.js +8 -8
- package/dist/log.js +2 -2
- package/dist/mcp/stream-http/config.js +1 -1
- package/dist/mcp/stream-http/connection-binding.js +1 -1
- package/dist/mcp/stream-http/tool-executor.js +1 -1
- package/dist/mcp/stream-http/tool-registry.js +1 -1
- package/dist/mcp/stream-http/tool-schemas.js +1 -1
- package/dist/runtime/duplicate-daemon.js +2 -2
- package/dist/runtime/startup-phases.js +1 -0
- package/dist/service/platform-adapter.js +18 -18
- package/dist/service/service-manager.js +2 -3
- package/package.json +1 -1
- package/dist/assets/dsh-bridge/grix-dsh-bridge-4.11.11.tgz +0 -0
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import{createHash as R}from"node:crypto";import l from"node:fs";import B from"node:os";import n from"node:path";import f from"node:process";import{mkdir as y}from"node:fs/promises";import{setTimeout as N}from"node:timers/promises";import{resolveRuntimePaths as w}from"../core/config/paths.js";import{inspectDaemonState as S}from"../runtime/service-state.js";import{isProcessRunning as M,runCommand as m,terminateProcessTree as W,waitForProcessExit as q}from"./process-control.js";import{isLockHolderIdentityVerified as C,readDaemonLock as _}from"../runtime/daemon-lock.js";import{ServiceInstallStore as O}from"./service-install-store.js";import{getPlatformServiceAdapter as U}from"./platform-adapter.js";import{captureLogCursor as v,formatLogDelta as L}from"./log-diagnostics.js";import{LAUNCHER_FILE as j,bootstrapVersionFromPackage as V,compareVersions as z,ensureLauncher as G,launcherPath as A,packagedLauncherPath as J,readLauncherTemplateVersion as X,readPackageVersionAt as E,readPointer as I,switchCurrent as K,versionEntry as $}from"../core/upgrade/version-store.js";import{buildServiceID as P,parseExecStartWords as Q,parseProgramArgumentsFromPlistXML as Y,resolveLinuxUserUnitPath as Z,resolveMacOSLaunchAgentPath as tt,resolveWindowsServiceRuntimeDir as et,resolveServiceInstallRecordPath as it,resolveServiceStderrPath as rt,resolveServiceStdoutPath as at}from"./service-paths.js";import{resolveWindowsStartupShortcutPath as st,resolveWindowsWrapperPath as b}from"./platform-adapter.js";import{readInstalledWrapperTemplate as ot}from"./windows-wrapper-migration.js";import{appendLegacyHealLog as nt,isLauncherStoreUsable as H,parseWrapperCliPath as ct,planLegacyStateHeal as dt}from"./legacy-state-heal.js";function lt(F){try{return l.realpathSync(F)}catch{return F}}class jt{adapter;platform;homeDir;uid;nodePath;cliPath;waitForExit;terminateTree;constructor(e){this.platform=e.platform??f.platform,this.homeDir=e.homeDir??B.homedir(),this.uid=e.uid??f.getuid?.()??0,this.nodePath=e.nodePath??f.execPath,this.cliPath=lt(e.cliPath),this.adapter=U(this.platform),this.waitForExit=e.processControl?.waitForExit??q,this.terminateTree=e.processControl?.terminateTree??W}normalizeRootDir(e){return n.resolve(String(e??"").trim())}resolveLocalServiceBaseDir(){if(this.platform==="darwin")return n.join(this.homeDir,"Library","Application Support","grix-connector");if(this.platform==="win32"){const e=String(f.env.LOCALAPPDATA??"").trim();return n.join(e&&n.isAbsolute(e)?e:n.join(this.homeDir,"AppData","Local"),"grix-connector")}return null}resolveServiceRuntimeDir(e){const t=this.resolveLocalServiceBaseDir();return t?this.platform==="win32"?et(this.normalizeRootDir(e),f.env,this.homeDir):n.join(t,"runtime"):null}resolveServiceCliPath(e){const t=this.resolveServiceRuntimeDir(e);return t?A(t):this.cliPath}resolveSourcePackageDir(){return n.dirname(n.dirname(this.cliPath))}async adoptLauncher(e){const t=this.normalizeRootDir(e),r=this.resolveServiceRuntimeDir(t);if(!r)return!1;const i=await this.createStore(t).load();return!i||i.cli_path===this.resolveServiceCliPath(t)&&H(r)?!1:(await this.refreshDescriptor(t,i),!0)}prepareServiceRuntime(e){const t=this.resolveServiceRuntimeDir(e);if(!t)return;const r=this.resolveSourcePackageDir();l.mkdirSync(t,{recursive:!0});const i=E(r);if(!i)throw new Error(`Cannot read package version at ${r} (entry ${this.cliPath}); refusing to install the service`);if(!G(t,r))throw new Error(`Package at ${r} does not ship ${j}; refusing to point the service at it`);const a=I(t,"current");if((!a||!l.existsSync($(t,a))||z(i,a)>0)&&(V(t,r,i),K(t,i)),this.platform==="win32"||this.platform==="darwin"){const s=n.join(r,"scripts","upgrade-guardian.mjs");if(l.existsSync(s)){const o=n.join(this.normalizeRootDir(e),"bin"),d=n.join(o,"upgrade-guardian.mjs"),c=n.join(o,"upgrade-guardian.fallback.mjs"),h=`${d}.tmp-${f.pid}`;l.mkdirSync(o,{recursive:!0});try{l.copyFileSync(s,h),l.renameSync(h,d),l.copyFileSync(s,c)}finally{l.rmSync(h,{force:!0})}}if(this.platform==="darwin"){const o=n.join(r,"scripts","upgrade-guardian.sh");if(l.existsSync(o)){const d=n.join(this.normalizeRootDir(e),"bin","upgrade-guardian.sh"),c=`${d}.tmp-${f.pid}`;try{l.copyFileSync(o,c),l.chmodSync(c,493),l.renameSync(c,d)}finally{l.rmSync(c,{force:!0})}}}}}buildDescriptor(e,t,r=""){const i=this.normalizeRootDir(e),a=this.resolveServiceCliPath(i);return{schema_version:1,platform:this.platform,service_id:P(i,this.platform),node_path:this.nodePath,cli_path:a,cli_hash:this.computeServiceHash(a)??"",definition_path:r,config_dir:t??"",installed_at:0,updated_at:0}}createStore(e){return new O(it(this.normalizeRootDir(e)))}toAdapterPayload(e,t){return{serviceID:e.service_id,nodePath:e.node_path,cliPath:e.cli_path,configDir:e.config_dir||void 0,rootDir:this.normalizeRootDir(t),environmentPath:this.buildServiceEnvironmentPath(e.node_path)}}async resolveServiceLogPaths(e){const t=this.resolveLocalServiceBaseDir();if(t){const r=n.join(this.platform==="darwin"?n.join(this.homeDir,"Library","Logs","grix-connector"):n.join(t,"logs"),P(this.normalizeRootDir(e),this.platform));return await y(r,{recursive:!0}),{stdoutPath:n.join(r,"daemon.out.log"),stderrPath:n.join(r,"daemon.err.log")}}return await y(n.join(e,"service"),{recursive:!0}),{stdoutPath:at(e),stderrPath:rt(e)}}buildServiceEnvironmentPath(e){const t=[n.dirname(e),...this.platform==="darwin"?["/opt/homebrew/bin"]:[],"/usr/local/bin","/usr/bin","/bin","/usr/sbin","/sbin"],r=String(f.env.PATH??"").split(n.delimiter).filter(s=>s&&n.isAbsolute(s)).filter(s=>!s.includes("/node_modules/.bin")).filter(s=>!s.includes("/node-gyp-bin")),i=[],a=new Set;for(const s of[...t,...r]){if(a.has(s))continue;if(a.add(s),[...i,s].join(n.delimiter).length>2048)break;i.push(s)}return i.join(n.delimiter)}toStartParams(e){return{serviceID:e.service_id,definitionPath:e.definition_path,uid:this.uid,homeDir:this.homeDir,runCommand:m}}toStopParams(e){return{serviceID:e.service_id,uid:this.uid,homeDir:this.homeDir,runCommand:m}}toRestartParams(e,t={}){return{serviceID:e.service_id,definitionPath:e.definition_path,uid:this.uid,homeDir:this.homeDir,runCommand:m,reloadDefinition:t.reloadDefinition===!0}}toUninstallParams(e){return{serviceID:e.service_id,definitionPath:e.definition_path,uid:this.uid,homeDir:this.homeDir,runCommand:m}}async loadDescriptor(e){const t=this.createStore(e),r=await t.load();if(!r)throw new Error("\u540E\u53F0\u670D\u52A1\u8FD8\u6CA1\u6709\u5B89\u88C5\uFF0C\u8BF7\u5148\u6267\u884C grix-connector start\uFF08\u4F1A\u81EA\u52A8\u5B89\u88C5\u5E76\u542F\u52A8\u670D\u52A1\uFF09\u3002");return{store:t,descriptor:r}}resolveServiceNodePath(e){return e.node_path&&l.existsSync(e.node_path)?e.node_path:this.nodePath}isDescriptorCurrent(e,t){if(t.node_path!==this.resolveServiceNodePath(t)||t.cli_path!==this.resolveServiceCliPath(e)||!t.cli_hash)return!1;const r=this.computeServiceHash(t.cli_path),i=this.computeServiceHash(this.cliPath);return r!==null&&i!==null&&r===t.cli_hash&&i===t.cli_hash}computeFileHash(e){try{const t=l.readFileSync(e);return R("sha256").update(t).digest("hex")}catch{return null}}computeServiceHash(e){return this.resolveLocalServiceBaseDir()?this.computeLauncherHash(e):this.computeFileHash(e)}computeLauncherHash(e){try{const t=this.resolveSourcePackageDir(),r=E(t)??"",i=n.basename(e)===j,a=i?n.dirname(e):null,s=i?e:J(t);if(!s)return null;const o=X(s);if(o<0)return null;let d=!0;if(a){const c=I(a,"current");d=!!c&&l.existsSync($(a,c))&&z(c,r)>=0}return d?R("sha256").update(`launcher:${o}`).update(`source:${r}`).digest("hex"):null}catch{return null}}computeRuntimeDirHash(e){try{const t=n.dirname(e),r=R("sha256"),i=s=>{const o=l.readdirSync(s,{withFileTypes:!0}).sort((d,c)=>d.name.localeCompare(c.name));for(const d of o){const c=n.join(s,d.name);r.update(n.relative(t,c)),d.isDirectory()?i(c):d.isFile()&&r.update(l.readFileSync(c))}};i(t);const a=n.join(n.dirname(t),"package.json");return l.existsSync(a)&&(r.update("package.json"),r.update(l.readFileSync(a))),r.digest("hex")}catch{return null}}async refreshDescriptor(e,t){const r=this.normalizeRootDir(e);await y(n.join(r,"service"),{recursive:!0}),this.prepareServiceRuntime(r);const i=this.resolveServiceCliPath(r),a={...t,platform:this.platform,service_id:t.service_id||P(r,this.platform),node_path:this.resolveServiceNodePath(t),cli_path:i,cli_hash:this.computeServiceHash(i)??"",config_dir:t.config_dir},s=await this.resolveServiceLogPaths(r),o=await this.adapter.install({...this.toAdapterPayload(a,r),stdoutPath:s.stdoutPath,stderrPath:s.stderrPath,homeDir:this.homeDir,uid:this.uid,runCommand:m}),d={...a,installed_at:t.installed_at,definition_path:o?.definitionPath||a.definition_path,updated_at:Date.now()};return await this.createStore(r).save(d),d}async resolveActiveDescriptor(e){return(await this.resolveActiveDescriptorState(e)).descriptor}async resolveActiveDescriptorState(e){const{descriptor:t}=await this.loadDescriptor(e);return this.isDescriptorCurrent(e,t)?{descriptor:t,definitionRewritten:!1}:{descriptor:await this.refreshDescriptor(e,t),definitionRewritten:!0}}async discoverConflictingServices(e){const t=this.normalizeRootDir(e),r=P(t,this.platform);return(await this.adapter.discoverServices({homeDir:this.homeDir,runCommand:m})).filter(a=>a.serviceID!==r)}async cleanupConflictingServices(e){const t=await this.discoverConflictingServices(e);if(t.length>0){const i=t.map(a=>a.serviceID).join(", ");console.log(`\u53D1\u73B0 ${t.length} \u4E2A\u6B8B\u7559\u670D\u52A1\uFF0C\u6B63\u5728\u68C0\u67E5: ${i}`)}let r=0;for(const i of t){if(await this.adapter.isServiceLoaded({serviceID:i.serviceID,uid:this.uid,homeDir:this.homeDir,runCommand:m})){console.log(`\u8DF3\u8FC7\u6B63\u5728\u8FD0\u884C\u7684\u670D\u52A1: ${i.serviceID}`);continue}try{await this.adapter.stop({serviceID:i.serviceID,uid:this.uid,homeDir:this.homeDir,runCommand:m})}catch{}try{await this.adapter.uninstall({serviceID:i.serviceID,definitionPath:i.definitionPath,uid:this.uid,homeDir:this.homeDir,runCommand:m}),r++}catch{}}return r}captureDaemonBaseline(e){return{status:S(e.daemonStatusFile),lock:_(e.daemonLockFile)}}isDaemonReady(e,t,r){const i=S(e.daemonStatusFile),a=_(e.daemonLockFile);if(!i.running||i.state!=="running"||i.pid<=0||!a||a.pid!==i.pid||!M(a.pid)||typeof a.root_dir!="string"||n.resolve(a.root_dir)!==n.resolve(e.rootDir)||typeof a.instance_id!="string"||a.instance_id.length===0||i.instance_id!==a.instance_id)return!1;const s=i.pid!==t.status.pid||i.state!==t.status.state||i.updated_at!==t.status.updated_at||i.instance_id!==t.status.instance_id,o=!t.lock||a.pid!==t.lock.pid||a.acquired_at!==t.lock.acquired_at||a.instance_id!==t.lock.instance_id,d=s&&o,c=t.status.state==="starting"&&t.status.instance_id===a.instance_id&&t.lock?.pid===a.pid&&t.lock.instance_id===a.instance_id&&i.instance_id===a.instance_id&&i.updated_at!==t.status.updated_at,h=t.lock?.pid===a.pid&&t.lock.instance_id===a.instance_id&&t.lock.acquired_at===a.acquired_at&&(t.status.pid!==a.pid||t.status.instance_id!==a.instance_id||t.status.state!=="running")&&i.pid===a.pid&&i.instance_id===a.instance_id&&i.state==="running"&&i.updated_at!==t.status.updated_at;return!C(a)&&!d&&!c&&!h?!1:r?d||c||h:!0}canForceTerminateDaemon(e,t){const r=_(e.daemonLockFile);return t>0&&r!==null&&r.pid===t&&typeof r.root_dir=="string"&&n.resolve(r.root_dir)===n.resolve(e.rootDir)&&C(r)}defaultDaemonStartTimeoutMs(){return this.platform==="darwin"?5e4:2e4}async waitForDaemonStarted(e,t={}){const r=t.timeoutMs??this.defaultDaemonStartTimeoutMs(),i=t.baseline??this.captureDaemonBaseline(e),a=t.requireNewDaemon??!1,s=t.stdoutLogFile??e.stdoutLogFile,o=t.stderrLogFile??e.stderrLogFile,d=t.stdoutLogCursor??v(s),c=t.stderrLogCursor??v(o),h=Date.now();for(;Date.now()-h<r;){if(this.isDaemonReady(e,i,a))return;const g=S(e.daemonStatusFile);if(g.state==="failed"&&(i.status.state!=="failed"||g.pid!==i.status.pid||g.updated_at!==i.status.updated_at||g.instance_id!==i.status.instance_id)){const x=_(e.daemonLockFile),T=["daemon start failed",`status=${JSON.stringify(g)}`,`lock=${x?JSON.stringify(x):"missing"}`,L("stderr",o,c),L("stdout",s,d)].filter(Boolean);throw new Error(T.join(`
|
|
2
|
-
`))}await
|
|
3
|
-
`))}readDefinitionCliPath(e,t){const r=t.service_id||P(e,this.platform),i=a=>{try{return l.readFileSync(a,"utf8")}catch{return null}};if(this.adapter.kind==="launchd"){const a=i(t.definition_path||tt(r,this.homeDir));return a?Y(a)[1]??null:null}if(this.adapter.kind==="systemd-user"){const a=i(t.definition_path||Z(r,this.homeDir));return a?Q(a)[1]??null:null}if(this.adapter.kind==="task-scheduler"){const a=i(b(r,this.homeDir));return a?ct(a):null}return null}observeLegacyState(e,t){const r=this.resolveServiceRuntimeDir(e),i=t?.service_id||P(e,this.platform);return{platform:this.platform,record:t,expectedLauncherPath:r?A(r):null,launcherStoreUsable:r?H(r):!1,nodePathExists:!!t?.node_path&&l.existsSync(t.node_path),cliPathExists:!!t?.cli_path&&l.existsSync(t.cli_path),definitionCliPath:t?this.readDefinitionCliPath(e,t):null,upgradePending:l.existsSync(n.join(e,"data","upgrade-pending.json")),windowsWrapperTemplate:this.platform==="win32"?ot(b(i,this.homeDir)):-1,windowsStartupShortcutExists:this.platform==="win32"&&l.existsSync(st(i,this.homeDir))}}async healLegacyState(e){const t=this.normalizeRootDir(e.rootDir),r=this.createStore(t),i=await r.load(),a=dt(this.observeLegacyState(t,i));if(!a.heal||!i)return{healed:!1,reasons:[]};const s=o=>{nt(t,o),console.log(`\u9057\u7559\u72B6\u6001\u81EA\u6108: ${o}`)};for(const o of a.reasons)s(`detected ${o}`);try{await this.stopServiceAndDaemon(t,i),s("stopped the legacy service and daemon")}catch(o){s(`stop failed (continuing): ${o instanceof Error?o.message:o}`)}try{await this.adapter.uninstall(this.toUninstallParams(i)),s("removed the legacy service definition")}catch(o){s(`uninstall failed (continuing): ${o instanceof Error?o.message:o}`)}return await r.clear(),s("cleared the install record; rebuilding via install"),{healed:!0,reasons:a.reasons,configDir:i.config_dir||void 0}}async install(e){const t=this.normalizeRootDir(e.rootDir);await this.cleanupConflictingServices(t),await y(n.join(t,"service"),{recursive:!0}),this.prepareServiceRuntime(t);const r=w(t),i=this.captureDaemonBaseline(r),a=this.buildDescriptor(t,e.configDir),s=await this.resolveServiceLogPaths(t),o=v(s.stdoutPath),d=v(s.stderrPath),c=await this.adapter.isServiceLoaded({serviceID:a.service_id,uid:this.uid,homeDir:this.homeDir,runCommand:m}),h=await this.adapter.install({...this.toAdapterPayload(a,t),stdoutPath:s.stdoutPath,stderrPath:s.stderrPath,homeDir:this.homeDir,uid:this.uid,runCommand:m}),p={...a,definition_path:h?.definitionPath??"",installed_at:Date.now(),updated_at:Date.now()};return await this.createStore(t).save(p),c?await this.adapter.restart(this.toRestartParams(p,{reloadDefinition:!0})):await this.adapter.start(this.toStartParams(p)),await this.waitForDaemonStarted(r,{baseline:i,requireNewDaemon:!0,stdoutLogFile:s.stdoutPath,stderrLogFile:s.stderrPath,stdoutLogCursor:o,stderrLogCursor:d}),this.status({rootDir:t})}async start(e){const t=this.normalizeRootDir(e.rootDir);await this.cleanupConflictingServices(t);const r=w(t),i=this.captureDaemonBaseline(r),a=i.status,s=v(r.stdoutLogFile),o=v(r.stderrLogFile),c=await this.createStore(t).load();if(a.running&&c&&this.isDescriptorCurrent(t,c)){if(a.state==="starting"){const u=i.lock;if(u!==null&&u.pid===a.pid&&typeof u.root_dir=="string"&&n.resolve(u.root_dir)===n.resolve(r.rootDir)&&typeof u.instance_id=="string"&&u.instance_id.length>0&&a.instance_id===u.instance_id&&C(u)){const k=await this.resolveServiceLogPaths(t);return await this.waitForDaemonStarted(r,{baseline:i,stdoutLogFile:k.stdoutPath,stderrLogFile:k.stderrPath,stdoutLogCursor:s,stderrLogCursor:o}),this.status({rootDir:t})}}if(this.isDaemonReady(r,i,!1))return this.status({rootDir:t})}let h,p=!1;if(c)this.isDescriptorCurrent(t,c)&&a.running?h=c:(h=await this.refreshDescriptor(t,c),p=!0);else{const u=await this.resolveActiveDescriptorState(t);h=u.descriptor,p=u.definitionRewritten}const D=await this.resolveServiceLogPaths(t);try{a.running?await this.adapter.restart(this.toRestartParams(h,{reloadDefinition:p})):await this.adapter.start(this.toStartParams(h))}catch(u){if(u instanceof Error&&u.message.includes("plist missing"))await this.adapter.install({...this.toAdapterPayload(h,t),stdoutPath:D.stdoutPath,stderrPath:D.stderrPath,homeDir:this.homeDir,uid:this.uid,runCommand:m}),await this.adapter.start(this.toStartParams(h));else throw u}return await this.waitForDaemonStarted(r,{baseline:i,requireNewDaemon:!0,stdoutLogFile:D.stdoutPath,stderrLogFile:D.stderrPath,stdoutLogCursor:s,stderrLogCursor:o}),this.status({rootDir:t})}async stopServiceAndDaemon(e,t){const r=w(e),i=S(r.daemonStatusFile);await this.adapter.stop(this.toStopParams(t)),!(!i.running||!i.pid||await this.waitForExit(i.pid,{timeoutMs:5e3}))&&this.canForceTerminateDaemon(r,i.pid)&&(await this.terminateTree(i.pid,{platform:this.platform,runCommandImpl:m}),await this.waitForExit(i.pid,{timeoutMs:5e3}))}async stop(e){const t=this.normalizeRootDir(e.rootDir),{descriptor:r}=await this.loadDescriptor(t);return await this.stopServiceAndDaemon(t,r),this.status({rootDir:t})}async restart(e){const t=this.normalizeRootDir(e.rootDir);await this.cleanupConflictingServices(t);const{descriptor:r,definitionRewritten:i}=await this.resolveActiveDescriptorState(t),a=w(t),s=this.captureDaemonBaseline(a),o=await this.resolveServiceLogPaths(t),d=v(o.stdoutPath),c=v(o.stderrPath);try{await this.adapter.restart(this.toRestartParams(r,{reloadDefinition:i}))}catch(h){if(h instanceof Error&&h.message.includes("plist missing"))await this.adapter.install({...this.toAdapterPayload(r,t),stdoutPath:o.stdoutPath,stderrPath:o.stderrPath,homeDir:this.homeDir,uid:this.uid,runCommand:m}),await this.adapter.start(this.toStartParams(r));else throw h}return await this.waitForDaemonStarted(a,{baseline:s,requireNewDaemon:!0,stdoutLogFile:o.stdoutPath,stderrLogFile:o.stderrPath,stdoutLogCursor:d,stderrLogCursor:c}),this.status({rootDir:t})}async uninstall(e){const t=this.normalizeRootDir(e.rootDir),r=this.createStore(t),i=await r.load();return i&&(await this.adapter.uninstall(this.toUninstallParams(i)),await r.clear()),this.status({rootDir:t})}async status(e){const t=this.normalizeRootDir(e.rootDir),i=await this.createStore(t).load(),a=w(t),s=S(a.daemonStatusFile);return i?{installed:!0,install_state:this.isDescriptorCurrent(t,i)?"current":"stale",service_kind:this.adapter.kind,service_id:i.service_id,definition_path:i.definition_path,root_dir:t,daemon_state:s.state,pid:s.pid,connection_state:s.connection_state,updated_at:s.updated_at,reason:s.reason}:{installed:!1,install_state:"missing",service_kind:this.adapter.kind,root_dir:t,daemon_state:s.state,pid:s.pid,reason:s.reason}}}export{jt as ServiceManager};
|
|
1
|
+
import{createHash as A}from"node:crypto";import l from"node:fs";import O from"node:os";import n from"node:path";import S from"node:process";import{mkdir as F}from"node:fs/promises";import{setTimeout as j}from"node:timers/promises";import{resolveRuntimePaths as y}from"../core/config/paths.js";import{inspectDaemonState as w}from"../runtime/service-state.js";import{isProcessRunning as E,runCommand as f,terminateProcessTree as U,waitForProcessExit as V}from"./process-control.js";import{isLockHolderIdentityVerified as R,readDaemonLock as L}from"../runtime/daemon-lock.js";import{ServiceInstallStore as J}from"./service-install-store.js";import{getPlatformServiceAdapter as X}from"./platform-adapter.js";import{captureLogCursor as _,formatLogDelta as $}from"./log-diagnostics.js";import{LAUNCHER_FILE as z,bootstrapVersionFromPackage as Y,compareVersions as I,ensureLauncher as K,launcherPath as T,packagedLauncherPath as Q,readLauncherTemplateVersion as Z,readPackageVersionAt as M,readPointer as H,switchCurrent as tt,versionEntry as N}from"../core/upgrade/version-store.js";import{buildServiceID as P,parseExecStartWords as et,parseProgramArgumentsFromPlistXML as it,resolveLinuxUserUnitPath as rt,resolveMacOSLaunchAgentPath as at,resolveWindowsServiceRuntimeDir as st,resolveServiceInstallRecordPath as ot,resolveServiceStderrPath as nt,resolveServiceStdoutPath as ct}from"./service-paths.js";import{resolveWindowsStartupShortcutPath as dt,resolveWindowsWrapperPath as b}from"./platform-adapter.js";import{readInstalledWrapperTemplate as lt}from"./windows-wrapper-migration.js";import{appendLegacyHealLog as ht,isLauncherStoreUsable as B,parseWrapperCliPath as ut,planLegacyStateHeal as mt}from"./legacy-state-heal.js";const pt=6e4;function ft(u=S.env){const e=String(u.GRIX_DAEMON_READY_TIMEOUT_MS??"").trim();return/^\d+$/.test(e)?Number(e):pt}function G(u,e,t){const i=e.pid!==u.status.pid||e.state!==u.status.state||e.updated_at!==u.status.updated_at||e.instance_id!==u.status.instance_id,r=!u.lock||t.pid!==u.lock.pid||t.acquired_at!==u.lock.acquired_at||t.instance_id!==u.lock.instance_id;return i&&r}function Dt(u){return u?`lock holder pid ${u.pid} ${E(u.pid)?"alive":"dead"}`:"lock holder: none"}function vt(u){try{return l.realpathSync(u)}catch{return u}}class Mt{adapter;platform;homeDir;uid;nodePath;cliPath;waitForExit;terminateTree;constructor(e){this.platform=e.platform??S.platform,this.homeDir=e.homeDir??O.homedir(),this.uid=e.uid??S.getuid?.()??0,this.nodePath=e.nodePath??S.execPath,this.cliPath=vt(e.cliPath),this.adapter=X(this.platform),this.waitForExit=e.processControl?.waitForExit??V,this.terminateTree=e.processControl?.terminateTree??U}normalizeRootDir(e){return n.resolve(String(e??"").trim())}resolveLocalServiceBaseDir(){if(this.platform==="darwin")return n.join(this.homeDir,"Library","Application Support","grix-connector");if(this.platform==="win32"){const e=String(S.env.LOCALAPPDATA??"").trim();return n.join(e&&n.isAbsolute(e)?e:n.join(this.homeDir,"AppData","Local"),"grix-connector")}return null}resolveServiceRuntimeDir(e){const t=this.resolveLocalServiceBaseDir();return t?this.platform==="win32"?st(this.normalizeRootDir(e),S.env,this.homeDir):n.join(t,"runtime"):null}resolveServiceCliPath(e){const t=this.resolveServiceRuntimeDir(e);return t?T(t):this.cliPath}resolveSourcePackageDir(){return n.dirname(n.dirname(this.cliPath))}async adoptLauncher(e){const t=this.normalizeRootDir(e),i=this.resolveServiceRuntimeDir(t);if(!i)return!1;const r=await this.createStore(t).load();return!r||r.cli_path===this.resolveServiceCliPath(t)&&B(i)?!1:(await this.refreshDescriptor(t,r),!0)}prepareServiceRuntime(e){const t=this.resolveServiceRuntimeDir(e);if(!t)return;const i=this.resolveSourcePackageDir();l.mkdirSync(t,{recursive:!0});const r=M(i);if(!r)throw new Error(`Cannot read package version at ${i} (entry ${this.cliPath}); refusing to install the service`);if(!K(t,i))throw new Error(`Package at ${i} does not ship ${z}; refusing to point the service at it`);const a=H(t,"current");if((!a||!l.existsSync(N(t,a))||I(r,a)>0)&&(Y(t,i,r),tt(t,r)),this.platform==="win32"||this.platform==="darwin"){const s=n.join(i,"scripts","upgrade-guardian.mjs");if(l.existsSync(s)){const o=n.join(this.normalizeRootDir(e),"bin"),d=n.join(o,"upgrade-guardian.mjs"),c=n.join(o,"upgrade-guardian.fallback.mjs"),h=`${d}.tmp-${S.pid}`;l.mkdirSync(o,{recursive:!0});try{l.copyFileSync(s,h),l.renameSync(h,d),l.copyFileSync(s,c)}finally{l.rmSync(h,{force:!0})}}if(this.platform==="darwin"){const o=n.join(i,"scripts","upgrade-guardian.sh");if(l.existsSync(o)){const d=n.join(this.normalizeRootDir(e),"bin","upgrade-guardian.sh"),c=`${d}.tmp-${S.pid}`;try{l.copyFileSync(o,c),l.chmodSync(c,493),l.renameSync(c,d)}finally{l.rmSync(c,{force:!0})}}}}}buildDescriptor(e,t,i=""){const r=this.normalizeRootDir(e),a=this.resolveServiceCliPath(r);return{schema_version:1,platform:this.platform,service_id:P(r,this.platform),node_path:this.nodePath,cli_path:a,cli_hash:this.computeServiceHash(a)??"",definition_path:i,config_dir:t??"",installed_at:0,updated_at:0}}createStore(e){return new J(ot(this.normalizeRootDir(e)))}toAdapterPayload(e,t){return{serviceID:e.service_id,nodePath:e.node_path,cliPath:e.cli_path,configDir:e.config_dir||void 0,rootDir:this.normalizeRootDir(t),environmentPath:this.buildServiceEnvironmentPath(e.node_path)}}async resolveServiceLogPaths(e){const t=this.resolveLocalServiceBaseDir();if(t){const i=n.join(this.platform==="darwin"?n.join(this.homeDir,"Library","Logs","grix-connector"):n.join(t,"logs"),P(this.normalizeRootDir(e),this.platform));return await F(i,{recursive:!0}),{stdoutPath:n.join(i,"daemon.out.log"),stderrPath:n.join(i,"daemon.err.log")}}return await F(n.join(e,"service"),{recursive:!0}),{stdoutPath:ct(e),stderrPath:nt(e)}}buildServiceEnvironmentPath(e){const t=[n.dirname(e),...this.platform==="darwin"?["/opt/homebrew/bin"]:[],"/usr/local/bin","/usr/bin","/bin","/usr/sbin","/sbin"],i=String(S.env.PATH??"").split(n.delimiter).filter(s=>s&&n.isAbsolute(s)).filter(s=>!s.includes("/node_modules/.bin")).filter(s=>!s.includes("/node-gyp-bin")),r=[],a=new Set;for(const s of[...t,...i]){if(a.has(s))continue;if(a.add(s),[...r,s].join(n.delimiter).length>2048)break;r.push(s)}return r.join(n.delimiter)}toStartParams(e){return{serviceID:e.service_id,definitionPath:e.definition_path,uid:this.uid,homeDir:this.homeDir,runCommand:f}}toStopParams(e){return{serviceID:e.service_id,uid:this.uid,homeDir:this.homeDir,runCommand:f}}toRestartParams(e,t={}){return{serviceID:e.service_id,definitionPath:e.definition_path,uid:this.uid,homeDir:this.homeDir,runCommand:f,reloadDefinition:t.reloadDefinition===!0}}toUninstallParams(e){return{serviceID:e.service_id,definitionPath:e.definition_path,uid:this.uid,homeDir:this.homeDir,runCommand:f}}async loadDescriptor(e){const t=this.createStore(e),i=await t.load();if(!i)throw new Error("\u540E\u53F0\u670D\u52A1\u8FD8\u6CA1\u6709\u5B89\u88C5\uFF0C\u8BF7\u5148\u6267\u884C grix-connector start\uFF08\u4F1A\u81EA\u52A8\u5B89\u88C5\u5E76\u542F\u52A8\u670D\u52A1\uFF09\u3002");return{store:t,descriptor:i}}resolveServiceNodePath(e){return e.node_path&&l.existsSync(e.node_path)?e.node_path:this.nodePath}isDescriptorCurrent(e,t){if(t.node_path!==this.resolveServiceNodePath(t)||t.cli_path!==this.resolveServiceCliPath(e)||!t.cli_hash)return!1;const i=this.computeServiceHash(t.cli_path),r=this.computeServiceHash(this.cliPath);return i!==null&&r!==null&&i===t.cli_hash&&r===t.cli_hash}computeFileHash(e){try{const t=l.readFileSync(e);return A("sha256").update(t).digest("hex")}catch{return null}}computeServiceHash(e){return this.resolveLocalServiceBaseDir()?this.computeLauncherHash(e):this.computeFileHash(e)}computeLauncherHash(e){try{const t=this.resolveSourcePackageDir(),i=M(t)??"",r=n.basename(e)===z,a=r?n.dirname(e):null,s=r?e:Q(t);if(!s)return null;const o=Z(s);if(o<0)return null;let d=!0;if(a){const c=H(a,"current");d=!!c&&l.existsSync(N(a,c))&&I(c,i)>=0}return d?A("sha256").update(`launcher:${o}`).update(`source:${i}`).digest("hex"):null}catch{return null}}computeRuntimeDirHash(e){try{const t=n.dirname(e),i=A("sha256"),r=s=>{const o=l.readdirSync(s,{withFileTypes:!0}).sort((d,c)=>d.name.localeCompare(c.name));for(const d of o){const c=n.join(s,d.name);i.update(n.relative(t,c)),d.isDirectory()?r(c):d.isFile()&&i.update(l.readFileSync(c))}};r(t);const a=n.join(n.dirname(t),"package.json");return l.existsSync(a)&&(i.update("package.json"),i.update(l.readFileSync(a))),i.digest("hex")}catch{return null}}async refreshDescriptor(e,t){const i=this.normalizeRootDir(e);await F(n.join(i,"service"),{recursive:!0}),this.prepareServiceRuntime(i);const r=this.resolveServiceCliPath(i),a={...t,platform:this.platform,service_id:t.service_id||P(i,this.platform),node_path:this.resolveServiceNodePath(t),cli_path:r,cli_hash:this.computeServiceHash(r)??"",config_dir:t.config_dir},s=await this.resolveServiceLogPaths(i),o=await this.adapter.install({...this.toAdapterPayload(a,i),stdoutPath:s.stdoutPath,stderrPath:s.stderrPath,homeDir:this.homeDir,uid:this.uid,runCommand:f}),d={...a,installed_at:t.installed_at,definition_path:o?.definitionPath||a.definition_path,updated_at:Date.now()};return await this.createStore(i).save(d),d}async resolveActiveDescriptor(e){return(await this.resolveActiveDescriptorState(e)).descriptor}async resolveActiveDescriptorState(e){const{descriptor:t}=await this.loadDescriptor(e);return this.isDescriptorCurrent(e,t)?{descriptor:t,definitionRewritten:!1}:{descriptor:await this.refreshDescriptor(e,t),definitionRewritten:!0}}async discoverConflictingServices(e){const t=this.normalizeRootDir(e),i=P(t,this.platform);return(await this.adapter.discoverServices({homeDir:this.homeDir,runCommand:f})).filter(a=>a.serviceID!==i)}async cleanupConflictingServices(e){const t=await this.discoverConflictingServices(e);if(t.length>0){const r=t.map(a=>a.serviceID).join(", ");console.log(`\u53D1\u73B0 ${t.length} \u4E2A\u6B8B\u7559\u670D\u52A1\uFF0C\u6B63\u5728\u68C0\u67E5: ${r}`)}let i=0;for(const r of t){if(await this.adapter.isServiceLoaded({serviceID:r.serviceID,uid:this.uid,homeDir:this.homeDir,runCommand:f})){console.log(`\u8DF3\u8FC7\u6B63\u5728\u8FD0\u884C\u7684\u670D\u52A1: ${r.serviceID}`);continue}try{await this.adapter.stop({serviceID:r.serviceID,uid:this.uid,homeDir:this.homeDir,runCommand:f})}catch{}try{await this.adapter.uninstall({serviceID:r.serviceID,definitionPath:r.definitionPath,uid:this.uid,homeDir:this.homeDir,runCommand:f}),i++}catch{}}return i}captureDaemonBaseline(e){return{status:w(e.daemonStatusFile),lock:L(e.daemonLockFile)}}readMatchedGeneration(e,t){const i=w(e.daemonStatusFile),r=L(e.daemonLockFile);return!i.running||!t.includes(i.state)||i.pid<=0||!r||r.pid!==i.pid||!E(r.pid)||typeof r.root_dir!="string"||n.resolve(r.root_dir)!==n.resolve(e.rootDir)||typeof r.instance_id!="string"||r.instance_id.length===0||i.instance_id!==r.instance_id?null:{inspection:i,lock:r}}isDaemonReady(e,t,i){const r=this.readMatchedGeneration(e,["running"]);if(!r)return!1;const{inspection:a,lock:s}=r,o=G(t,a,s),d=t.status.state==="starting"&&t.status.instance_id===s.instance_id&&t.lock?.pid===s.pid&&t.lock.instance_id===s.instance_id&&a.instance_id===s.instance_id&&a.updated_at!==t.status.updated_at,c=t.lock?.pid===s.pid&&t.lock.instance_id===s.instance_id&&t.lock.acquired_at===s.acquired_at&&(t.status.pid!==s.pid||t.status.instance_id!==s.instance_id||t.status.state!=="running")&&a.pid===s.pid&&a.instance_id===s.instance_id&&a.state==="running"&&a.updated_at!==t.status.updated_at;return!o&&!d&&!c&&!R(s)?!1:i?o||d||c:!0}findStartedGeneration(e,t,i,r){const a=this.readMatchedGeneration(e,["starting","running"]);if(!a)return null;const{inspection:s,lock:o}=a,d=t.lock?.pid===o.pid&&t.lock.instance_id===o.instance_id&&t.lock.acquired_at===o.acquired_at&&(t.status.pid!==o.pid||t.status.instance_id!==o.instance_id)&&s.updated_at!==t.status.updated_at;let c=G(t,s,o)||d;if(!c&&!i){const h=`${o.pid}:${o.instance_id}`;let p=r.get(h);p===void 0&&(p=R(o),r.set(h,p)),c=p}return c?{pid:o.pid,instance_id:o.instance_id,state:s.state}:null}diedHoldingLock(e,t){if(E(t.pid))return!1;const i=L(e.daemonLockFile);return i?.pid===t.pid&&i.instance_id===t.instance_id}canForceTerminateDaemon(e,t){const i=L(e.daemonLockFile);return t>0&&i!==null&&i.pid===t&&typeof i.root_dir=="string"&&n.resolve(i.root_dir)===n.resolve(e.rootDir)&&R(i)}defaultDaemonStartTimeoutMs(){return this.platform==="darwin"?5e4:this.platform==="win32"?45e3:2e4}async waitForDaemonStarted(e,t={}){const i=t.timeoutMs??this.defaultDaemonStartTimeoutMs(),r=t.readyTimeoutMs??ft(),a=t.baseline??this.captureDaemonBaseline(e),s=t.requireNewDaemon??!1,o=t.stdoutLogFile??e.stdoutLogFile,d=t.stderrLogFile??e.stderrLogFile,c=t.stdoutLogCursor??_(o),h=t.stderrLogCursor??_(d),p=new Map,v=(D,k=w(e.daemonStatusFile))=>{const x=L(e.daemonLockFile),q=[D,`status=${JSON.stringify(k)}`,`lock=${x?JSON.stringify(x):"missing"}`,Dt(x),$("stderr",d,h),$("stdout",o,c)].filter(Boolean);return new Error(q.join(`
|
|
2
|
+
`))},m=()=>{const D=w(e.daemonStatusFile);if(D.state==="failed"&&(a.status.state!=="failed"||D.pid!==a.status.pid||D.updated_at!==a.status.updated_at||D.instance_id!==a.status.instance_id))throw v("daemon start failed",D)},C=Date.now();let g=null;for(;Date.now()-C<i;){if(this.isDaemonReady(e,a,s))return;if(m(),g=this.findStartedGeneration(e,a,s,p),g)break;await j(100)}if(!g)throw v(`daemon start timeout (${i}ms)`);const W=Date.now()+r;for(;;){if(this.isDaemonReady(e,a,s))return;m();const D=this.findStartedGeneration(e,a,s,p);if(D)g=D;else if(this.diedHoldingLock(e,g))throw v(`daemon exited during startup (pid ${g.pid})`);if(Date.now()>=W){if(D){const k=Math.round((Date.now()-C)/1e3);console.warn(`Warning: daemon \u4ECD\u5728\u542F\u52A8\u4E2D(pid ${D.pid}\uFF0C\u5DF2 ${k}s)\uFF0C\u7A0D\u540E\u7528 grix-connector status \u67E5\u770B`);return}throw v(`daemon start timeout (${i}ms + ${r}ms)`)}await j(100)}}readDefinitionCliPath(e,t){const i=t.service_id||P(e,this.platform),r=a=>{try{return l.readFileSync(a,"utf8")}catch{return null}};if(this.adapter.kind==="launchd"){const a=r(t.definition_path||at(i,this.homeDir));return a?it(a)[1]??null:null}if(this.adapter.kind==="systemd-user"){const a=r(t.definition_path||rt(i,this.homeDir));return a?et(a)[1]??null:null}if(this.adapter.kind==="task-scheduler"){const a=r(b(i,this.homeDir));return a?ut(a):null}return null}observeLegacyState(e,t){const i=this.resolveServiceRuntimeDir(e),r=t?.service_id||P(e,this.platform);return{platform:this.platform,record:t,expectedLauncherPath:i?T(i):null,launcherStoreUsable:i?B(i):!1,nodePathExists:!!t?.node_path&&l.existsSync(t.node_path),cliPathExists:!!t?.cli_path&&l.existsSync(t.cli_path),definitionCliPath:t?this.readDefinitionCliPath(e,t):null,upgradePending:l.existsSync(n.join(e,"data","upgrade-pending.json")),windowsWrapperTemplate:this.platform==="win32"?lt(b(r,this.homeDir)):-1,windowsStartupShortcutExists:this.platform==="win32"&&l.existsSync(dt(r,this.homeDir))}}async healLegacyState(e){const t=this.normalizeRootDir(e.rootDir),i=this.createStore(t),r=await i.load(),a=mt(this.observeLegacyState(t,r));if(!a.heal||!r)return{healed:!1,reasons:[]};const s=o=>{ht(t,o),console.log(`\u9057\u7559\u72B6\u6001\u81EA\u6108: ${o}`)};for(const o of a.reasons)s(`detected ${o}`);try{await this.stopServiceAndDaemon(t,r),s("stopped the legacy service and daemon")}catch(o){s(`stop failed (continuing): ${o instanceof Error?o.message:o}`)}try{await this.adapter.uninstall(this.toUninstallParams(r)),s("removed the legacy service definition")}catch(o){s(`uninstall failed (continuing): ${o instanceof Error?o.message:o}`)}return await i.clear(),s("cleared the install record; rebuilding via install"),{healed:!0,reasons:a.reasons,configDir:r.config_dir||void 0}}async install(e){const t=this.normalizeRootDir(e.rootDir);await this.cleanupConflictingServices(t),await F(n.join(t,"service"),{recursive:!0}),this.prepareServiceRuntime(t);const i=y(t),r=this.captureDaemonBaseline(i),a=this.buildDescriptor(t,e.configDir),s=await this.resolveServiceLogPaths(t),o=_(s.stdoutPath),d=_(s.stderrPath),c=await this.adapter.isServiceLoaded({serviceID:a.service_id,uid:this.uid,homeDir:this.homeDir,runCommand:f}),h=await this.adapter.install({...this.toAdapterPayload(a,t),stdoutPath:s.stdoutPath,stderrPath:s.stderrPath,homeDir:this.homeDir,uid:this.uid,runCommand:f}),p={...a,definition_path:h?.definitionPath??"",installed_at:Date.now(),updated_at:Date.now()};return await this.createStore(t).save(p),c?await this.adapter.restart(this.toRestartParams(p,{reloadDefinition:!0})):await this.adapter.start(this.toStartParams(p)),await this.waitForDaemonStarted(i,{baseline:r,requireNewDaemon:!0,stdoutLogFile:s.stdoutPath,stderrLogFile:s.stderrPath,stdoutLogCursor:o,stderrLogCursor:d}),this.status({rootDir:t})}async start(e){const t=this.normalizeRootDir(e.rootDir);await this.cleanupConflictingServices(t);const i=y(t),r=this.captureDaemonBaseline(i),a=r.status,s=_(i.stdoutLogFile),o=_(i.stderrLogFile),c=await this.createStore(t).load();if(a.running&&c&&this.isDescriptorCurrent(t,c)){if(a.state==="starting"){const m=r.lock;if(m!==null&&m.pid===a.pid&&typeof m.root_dir=="string"&&n.resolve(m.root_dir)===n.resolve(i.rootDir)&&typeof m.instance_id=="string"&&m.instance_id.length>0&&a.instance_id===m.instance_id&&R(m)){const g=await this.resolveServiceLogPaths(t);return await this.waitForDaemonStarted(i,{baseline:r,stdoutLogFile:g.stdoutPath,stderrLogFile:g.stderrPath,stdoutLogCursor:s,stderrLogCursor:o}),this.status({rootDir:t})}}if(this.isDaemonReady(i,r,!1))return this.status({rootDir:t})}let h,p=!1;if(c)this.isDescriptorCurrent(t,c)&&a.running?h=c:(h=await this.refreshDescriptor(t,c),p=!0);else{const m=await this.resolveActiveDescriptorState(t);h=m.descriptor,p=m.definitionRewritten}const v=await this.resolveServiceLogPaths(t);try{a.running?await this.adapter.restart(this.toRestartParams(h,{reloadDefinition:p})):await this.adapter.start(this.toStartParams(h))}catch(m){if(m instanceof Error&&m.message.includes("plist missing"))await this.adapter.install({...this.toAdapterPayload(h,t),stdoutPath:v.stdoutPath,stderrPath:v.stderrPath,homeDir:this.homeDir,uid:this.uid,runCommand:f}),await this.adapter.start(this.toStartParams(h));else throw m}return await this.waitForDaemonStarted(i,{baseline:r,requireNewDaemon:!0,stdoutLogFile:v.stdoutPath,stderrLogFile:v.stderrPath,stdoutLogCursor:s,stderrLogCursor:o}),this.status({rootDir:t})}async stopServiceAndDaemon(e,t){const i=y(e),r=w(i.daemonStatusFile);await this.adapter.stop(this.toStopParams(t)),!(!r.running||!r.pid||await this.waitForExit(r.pid,{timeoutMs:5e3}))&&this.canForceTerminateDaemon(i,r.pid)&&(await this.terminateTree(r.pid,{platform:this.platform,runCommandImpl:f}),await this.waitForExit(r.pid,{timeoutMs:5e3}))}async stop(e){const t=this.normalizeRootDir(e.rootDir),{descriptor:i}=await this.loadDescriptor(t);return await this.stopServiceAndDaemon(t,i),this.status({rootDir:t})}async restart(e){const t=this.normalizeRootDir(e.rootDir);await this.cleanupConflictingServices(t);const{descriptor:i,definitionRewritten:r}=await this.resolveActiveDescriptorState(t),a=y(t),s=this.captureDaemonBaseline(a),o=await this.resolveServiceLogPaths(t),d=_(o.stdoutPath),c=_(o.stderrPath);try{await this.adapter.restart(this.toRestartParams(i,{reloadDefinition:r}))}catch(h){if(h instanceof Error&&h.message.includes("plist missing"))await this.adapter.install({...this.toAdapterPayload(i,t),stdoutPath:o.stdoutPath,stderrPath:o.stderrPath,homeDir:this.homeDir,uid:this.uid,runCommand:f}),await this.adapter.start(this.toStartParams(i));else throw h}return await this.waitForDaemonStarted(a,{baseline:s,requireNewDaemon:!0,stdoutLogFile:o.stdoutPath,stderrLogFile:o.stderrPath,stdoutLogCursor:d,stderrLogCursor:c}),this.status({rootDir:t})}async uninstall(e){const t=this.normalizeRootDir(e.rootDir),i=this.createStore(t),r=await i.load();return r&&(await this.adapter.uninstall(this.toUninstallParams(r)),await i.clear()),this.status({rootDir:t})}async status(e){const t=this.normalizeRootDir(e.rootDir),r=await this.createStore(t).load(),a=y(t),s=w(a.daemonStatusFile);return r?{installed:!0,install_state:this.isDescriptorCurrent(t,r)?"current":"stale",service_kind:this.adapter.kind,service_id:r.service_id,definition_path:r.definition_path,root_dir:t,daemon_state:s.state,pid:s.pid,connection_state:s.connection_state,updated_at:s.updated_at,reason:s.reason}:{installed:!1,install_state:"missing",service_kind:this.adapter.kind,root_dir:t,daemon_state:s.state,pid:s.pid,reason:s.reason}}}export{Mt as ServiceManager};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "grix-connector",
|
|
3
|
-
"version": "4.11.
|
|
3
|
+
"version": "4.11.13",
|
|
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",
|
|
Binary file
|