grix-connector 4.0.2 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapter/acp/acp-adapter.js +3 -3
- package/dist/adapter/acp/session-activity.js +1 -1
- package/dist/adapter/claude/claude-bridge-server.js +1 -0
- package/dist/adapter/claude/claude-tools.js +1 -0
- package/dist/adapter/claude/claude-worker-client.js +1 -0
- package/dist/adapter/claude/mcp-http-launcher.js +2 -0
- package/dist/adapter/claude/result-timeout.js +1 -0
- package/dist/adapter/deepseek/deepseek-adapter.js +6 -0
- package/dist/adapter/deepseek/index.js +1 -0
- package/dist/adapter/qwen/index.js +1 -0
- package/dist/adapter/qwen/qwen-adapter.js +4 -0
- package/dist/aibot/client.js +1 -0
- package/dist/aibot/index.js +1 -0
- package/dist/aibot/types.js +0 -0
- package/dist/assets/dsh-bridge/grix-dsh-bridge-4.2.0.tgz +0 -0
- package/dist/assets/dsh-bridge/manifest.json +5 -5
- package/dist/audit/adapters/agy/agy-audit-adapter.js +1 -1
- package/dist/audit/adapters/agy/agy-gen-metadata.js +1 -0
- package/dist/bridge/bridge.js +7 -7
- package/dist/bridge/lifecycle-barrier.js +1 -1
- package/dist/core/access/allowlist-gate.js +1 -0
- package/dist/core/access/allowlist-store.js +1 -0
- package/dist/core/access/index.js +1 -0
- package/dist/core/aibot/connection-manager.js +1 -1
- package/dist/core/config/agent-config-repository.js +2 -0
- package/dist/core/file-ops/handler.js +1 -0
- package/dist/core/file-ops/list-files.js +1 -0
- package/dist/core/file-ops/types.js +0 -0
- package/dist/core/installer/npm-registry.js +4 -4
- package/dist/core/runtime/health.js +1 -1
- package/dist/core/skill-sync/skill-syncer.js +1 -1
- package/dist/core/upgrade/npm-upgrader.js +2 -2
- package/dist/core/upgrade/upgrade-checker.js +1 -1
- package/dist/default-skills/grix-agent-dispatch/SKILL.md +9 -9
- package/dist/grix.js +7 -7
- package/dist/log.js +3 -0
- package/dist/main.js +31 -0
- package/dist/manager.js +1 -2
- package/dist/mcp/stream-http/config.js +1 -0
- package/dist/mcp/stream-http/connection-binding.js +1 -0
- package/dist/mcp/stream-http/event-tool-executor.js +1 -0
- package/dist/mcp/stream-http/gateway.js +1 -0
- package/dist/mcp/stream-http/index.js +1 -0
- package/dist/mcp/stream-http/security.js +1 -0
- package/dist/mcp/stream-http/session-manager.js +1 -0
- package/dist/mcp/stream-http/tool-executor.js +1 -0
- package/dist/mcp/stream-http/tool-registry.js +1 -0
- package/dist/mcp/stream-http/tool-schemas.js +1 -0
- package/dist/service/platform-adapter.js +25 -24
- package/dist/service/process-control.js +1 -1
- package/dist/service/service-manager.js +3 -3
- package/dist/service/service-paths.js +2 -2
- package/dist/service/windows-wrapper-migration.js +1 -0
- package/dist/session/index.js +1 -0
- package/dist/session/manager.js +1 -0
- package/dist/transport/index.js +1 -0
- package/dist/transport/json-rpc.js +3 -0
- package/openclaw-plugin/audit-recorder-worker.js +496 -54
- package/package.json +2 -1
- package/scripts/install-guardian.mjs +35 -19
- package/scripts/upgrade-guardian.mjs +1345 -0
- package/scripts/upgrade-guardian.sh +100 -75
- package/dist/assets/dsh-bridge/grix-dsh-bridge-4.0.2.tgz +0 -0
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{createHash as C}from"node:crypto";import u from"node:fs";import j from"node:os";import o from"node:path";import g from"node:process";import{mkdir as S}from"node:fs/promises";import{setTimeout as z}from"node:timers/promises";import{resolveRuntimePaths as P}from"../core/config/paths.js";import{inspectDaemonState as v}from"../runtime/service-state.js";import{isProcessRunning as I,runCommand as l,terminateProcessTree as x,waitForProcessExit as A}from"./process-control.js";import{isLockHolderIdentityVerified as L,readDaemonLock as _}from"../runtime/daemon-lock.js";import{ServiceInstallStore as B}from"./service-install-store.js";import{getPlatformServiceAdapter as E}from"./platform-adapter.js";import{captureLogCursor as D,formatLogDelta as w}from"./log-diagnostics.js";import{buildServiceID as y,resolveServiceInstallRecordPath as N,resolveServiceStderrPath as T,resolveServiceStdoutPath as H}from"./service-paths.js";class it{adapter;platform;homeDir;uid;nodePath;cliPath;waitForExit;terminateTree;constructor(e){this.platform=e.platform??g.platform,this.homeDir=e.homeDir??j.homedir(),this.uid=e.uid??g.getuid?.()??0,this.nodePath=e.nodePath??g.execPath,this.cliPath=e.cliPath,this.adapter=E(this.platform),this.waitForExit=e.processControl?.waitForExit??A,this.terminateTree=e.processControl?.terminateTree??x}normalizeRootDir(e){return o.resolve(String(e??"").trim())}resolveLocalServiceBaseDir(){if(this.platform==="darwin")return o.join(this.homeDir,"Library","Application Support","grix-connector");if(this.platform==="win32"){const e=String(g.env.LOCALAPPDATA??"").trim();return o.join(e&&o.isAbsolute(e)?e:o.join(this.homeDir,"AppData","Local"),"grix-connector")}return null}resolveServiceCliPath(){const e=this.resolveLocalServiceBaseDir();return e?o.join(e,"runtime","dist",o.basename(this.cliPath)):this.cliPath}prepareServiceRuntime(){const e=this.resolveLocalServiceBaseDir();if(!e)return;const t=o.dirname(this.cliPath),s=o.dirname(t),r=o.join(e,"runtime"),i=o.join(r,"dist"),a=o.join(r,"node_modules");u.mkdirSync(r,{recursive:!0}),u.rmSync(i,{recursive:!0,force:!0}),u.cpSync(t,i,{recursive:!0,force:!0});const n=o.join(s,"package.json");u.existsSync(n)&&u.copyFileSync(n,o.join(r,"package.json"));const c=o.join(s,"node_modules");u.existsSync(c)&&(u.rmSync(a,{recursive:!0,force:!0}),u.symlinkSync(u.realpathSync(c),a,this.platform==="win32"?"junction":"dir"))}buildDescriptor(e,t,s=""){const r=this.normalizeRootDir(e),i=this.resolveServiceCliPath();return{schema_version:1,platform:this.platform,service_id:y(r,this.platform),node_path:this.nodePath,cli_path:i,cli_hash:this.computeServiceHash(i)??"",definition_path:s,config_dir:t??"",installed_at:0,updated_at:0}}createStore(e){return new B(N(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()}}async resolveServiceLogPaths(e){const t=this.resolveLocalServiceBaseDir();if(t){const s=o.join(this.platform==="darwin"?o.join(this.homeDir,"Library","Logs","grix-connector"):o.join(t,"logs"),y(this.normalizeRootDir(e),this.platform));return await S(s,{recursive:!0}),{stdoutPath:o.join(s,"daemon.out.log"),stderrPath:o.join(s,"daemon.err.log")}}return await S(o.join(e,"service"),{recursive:!0}),{stdoutPath:H(e),stderrPath:T(e)}}buildServiceEnvironmentPath(){const e=[o.dirname(this.nodePath),"/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin","/usr/sbin","/sbin"],t=String(g.env.PATH??"").split(o.delimiter).filter(i=>i&&o.isAbsolute(i)).filter(i=>!i.includes("/node_modules/.bin")).filter(i=>!i.includes("/node-gyp-bin")),s=[],r=new Set;for(const i of[...e,...t]){if(r.has(i))continue;if(r.add(i),[...s,i].join(o.delimiter).length>2048)break;s.push(i)}return s.join(o.delimiter)}toStartParams(e){return{serviceID:e.service_id,definitionPath:e.definition_path,uid:this.uid,homeDir:this.homeDir,runCommand:l}}toStopParams(e){return{serviceID:e.service_id,uid:this.uid,homeDir:this.homeDir,runCommand:l}}toRestartParams(e){return{serviceID:e.service_id,definitionPath:e.definition_path,uid:this.uid,homeDir:this.homeDir,runCommand:l}}toUninstallParams(e){return{serviceID:e.service_id,definitionPath:e.definition_path,uid:this.uid,homeDir:this.homeDir,runCommand:l}}async loadDescriptor(e){const t=this.createStore(e),s=await t.load();if(!s)throw new Error("\u540E\u53F0\u670D\u52A1\u8FD8\u6CA1\u6709\u5B89\u88C5\uFF0C\u8BF7\u5148\u6267\u884C service install\u3002");return{store:t,descriptor:s}}isDescriptorCurrent(e){if(e.node_path!==this.nodePath||e.cli_path!==this.resolveServiceCliPath()||!e.cli_hash)return!1;const t=this.computeServiceHash(e.cli_path),s=this.computeServiceHash(this.cliPath);return t!==null&&s!==null&&t===e.cli_hash&&s===e.cli_hash}computeFileHash(e){try{const t=u.readFileSync(e);return C("sha256").update(t).digest("hex")}catch{return null}}computeServiceHash(e){if(!this.resolveLocalServiceBaseDir())return this.computeFileHash(e);try{const t=o.dirname(e),s=C("sha256"),r=i=>{const a=u.readdirSync(i,{withFileTypes:!0}).sort((n,c)=>n.name.localeCompare(c.name));for(const n of a){const c=o.join(i,n.name);s.update(o.relative(t,c)),n.isDirectory()?r(c):n.isFile()&&s.update(u.readFileSync(c))}};return r(t),s.digest("hex")}catch{return null}}async refreshDescriptor(e,t){const s=this.normalizeRootDir(e);await S(o.join(s,"service"),{recursive:!0}),this.prepareServiceRuntime();const r=this.resolveServiceCliPath(),i={...t,platform:this.platform,service_id:t.service_id||y(s,this.platform),node_path:this.nodePath,cli_path:r,cli_hash:this.computeServiceHash(r)??"",config_dir:t.config_dir},a=await this.resolveServiceLogPaths(s),n=await this.adapter.install({...this.toAdapterPayload(i,s),stdoutPath:a.stdoutPath,stderrPath:a.stderrPath,homeDir:this.homeDir,uid:this.uid,runCommand:l}),c={...i,installed_at:t.installed_at,definition_path:n?.definitionPath||i.definition_path,updated_at:Date.now()};return await this.createStore(s).save(c),c}async resolveActiveDescriptor(e){const{descriptor:t}=await this.loadDescriptor(e);return this.isDescriptorCurrent(t)?t:this.refreshDescriptor(e,t)}async discoverConflictingServices(e){const t=this.normalizeRootDir(e),s=y(t,this.platform);return(await this.adapter.discoverServices({homeDir:this.homeDir,runCommand:l})).filter(i=>i.serviceID!==s)}async cleanupConflictingServices(e){const t=await this.discoverConflictingServices(e);if(t.length>0){const r=t.map(i=>i.serviceID).join(", ");console.log(`\u53D1\u73B0 ${t.length} \u4E2A\u6B8B\u7559\u670D\u52A1\uFF0C\u6B63\u5728\u68C0\u67E5: ${r}`)}let s=0;for(const r of t){if(await this.adapter.isServiceLoaded({serviceID:r.serviceID,uid:this.uid,homeDir:this.homeDir,runCommand:l})){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:l})}catch{}try{await this.adapter.uninstall({serviceID:r.serviceID,definitionPath:r.definitionPath,uid:this.uid,homeDir:this.homeDir,runCommand:l}),s++}catch{}}return s}captureDaemonBaseline(e){return{status:v(e.daemonStatusFile),lock:_(e.daemonLockFile)}}isDaemonReady(e,t,s){const r=v(e.daemonStatusFile),i=_(e.daemonLockFile);if(!r.running||r.state!=="running"||r.pid<=0||!i||i.pid!==r.pid||!I(i.pid)||typeof i.root_dir!="string"||o.resolve(i.root_dir)!==o.resolve(e.rootDir)||typeof i.instance_id!="string"||i.instance_id.length===0||r.instance_id!==i.instance_id)return!1;const a=r.pid!==t.status.pid||r.state!==t.status.state||r.updated_at!==t.status.updated_at||r.instance_id!==t.status.instance_id,n=!t.lock||i.pid!==t.lock.pid||i.acquired_at!==t.lock.acquired_at||i.instance_id!==t.lock.instance_id,c=a&&n,d=t.status.state==="starting"&&t.status.instance_id===i.instance_id&&t.lock?.pid===i.pid&&t.lock.instance_id===i.instance_id&&r.instance_id===i.instance_id&&r.updated_at!==t.status.updated_at,m=t.lock?.pid===i.pid&&t.lock.instance_id===i.instance_id&&t.lock.acquired_at===i.acquired_at&&(t.status.pid!==i.pid||t.status.instance_id!==i.instance_id||t.status.state!=="running")&&r.pid===i.pid&&r.instance_id===i.instance_id&&r.state==="running"&&r.updated_at!==t.status.updated_at;return!L(i)&&!c&&!d&&!m?!1:s?c||d||m:!0}canForceTerminateDaemon(e,t){const s=_(e.daemonLockFile);return t>0&&s!==null&&s.pid===t&&typeof s.root_dir=="string"&&o.resolve(s.root_dir)===o.resolve(e.rootDir)&&L(s)}defaultDaemonStartTimeoutMs(){return this.platform==="darwin"?5e4:2e4}async waitForDaemonStarted(e,t={}){const s=t.timeoutMs??this.defaultDaemonStartTimeoutMs(),r=t.baseline??this.captureDaemonBaseline(e),i=t.requireNewDaemon??!1,a=t.stdoutLogFile??e.stdoutLogFile,n=t.stderrLogFile??e.stderrLogFile,c=t.stdoutLogCursor??D(a),d=t.stderrLogCursor??D(n),m=Date.now();for(;Date.now()-m<s;){if(this.isDaemonReady(e,r,i))return;const f=v(e.daemonStatusFile);if(f.state==="failed"&&(r.status.state!=="failed"||f.pid!==r.status.pid||f.updated_at!==r.status.updated_at||f.instance_id!==r.status.instance_id)){const k=_(e.daemonLockFile),R=["daemon start failed",`status=${JSON.stringify(f)}`,`lock=${k?JSON.stringify(k):"missing"}`,w("stderr",n,d),w("stdout",a,c)].filter(Boolean);throw new Error(R.join(`
|
|
2
|
-
`))}await z(100)}const
|
|
3
|
-
`))}async install(
|
|
1
|
+
import{createHash as C}from"node:crypto";import l from"node:fs";import j from"node:os";import a from"node:path";import D from"node:process";import{mkdir as w}from"node:fs/promises";import{setTimeout as z}from"node:timers/promises";import{resolveRuntimePaths as P}from"../core/config/paths.js";import{inspectDaemonState as S}from"../runtime/service-state.js";import{isProcessRunning as x,runCommand as p,terminateProcessTree as I,waitForProcessExit as A}from"./process-control.js";import{isLockHolderIdentityVerified as F,readDaemonLock as _}from"../runtime/daemon-lock.js";import{ServiceInstallStore as E}from"./service-install-store.js";import{getPlatformServiceAdapter as T}from"./platform-adapter.js";import{captureLogCursor as v,formatLogDelta as y}from"./log-diagnostics.js";import{buildServiceID as L,resolveWindowsServiceRuntimeDir as b,resolveServiceInstallRecordPath as B,resolveServiceStderrPath as N,resolveServiceStdoutPath as H}from"./service-paths.js";class rt{adapter;platform;homeDir;uid;nodePath;cliPath;waitForExit;terminateTree;constructor(i){this.platform=i.platform??D.platform,this.homeDir=i.homeDir??j.homedir(),this.uid=i.uid??D.getuid?.()??0,this.nodePath=i.nodePath??D.execPath,this.cliPath=i.cliPath,this.adapter=T(this.platform),this.waitForExit=i.processControl?.waitForExit??A,this.terminateTree=i.processControl?.terminateTree??I}normalizeRootDir(i){return a.resolve(String(i??"").trim())}resolveLocalServiceBaseDir(){if(this.platform==="darwin")return a.join(this.homeDir,"Library","Application Support","grix-connector");if(this.platform==="win32"){const i=String(D.env.LOCALAPPDATA??"").trim();return a.join(i&&a.isAbsolute(i)?i:a.join(this.homeDir,"AppData","Local"),"grix-connector")}return null}resolveServiceRuntimeDir(i){const t=this.resolveLocalServiceBaseDir();return t?this.platform==="win32"?b(this.normalizeRootDir(i),D.env,this.homeDir):a.join(t,"runtime"):null}resolveServiceCliPath(i){const t=this.resolveServiceRuntimeDir(i);return t?a.join(t,"dist",a.basename(this.cliPath)):this.cliPath}prepareServiceRuntime(i){const t=this.resolveServiceRuntimeDir(i);if(!t)return;const s=a.dirname(this.cliPath),r=a.dirname(s),e=a.join(t,"dist"),o=a.join(t,"node_modules");l.mkdirSync(t,{recursive:!0}),l.rmSync(e,{recursive:!0,force:!0}),l.cpSync(s,e,{recursive:!0,force:!0});const n=a.join(r,"package.json");l.existsSync(n)&&l.copyFileSync(n,a.join(t,"package.json"));const c=a.join(r,"node_modules");if(l.existsSync(c)&&(l.rmSync(o,{recursive:!0,force:!0}),l.cpSync(c,o,{recursive:!0,force:!0})),this.platform==="win32"||this.platform==="darwin"){const d=a.join(r,"scripts","upgrade-guardian.mjs");if(l.existsSync(d)){const u=a.join(this.normalizeRootDir(i),"bin"),m=a.join(u,"upgrade-guardian.mjs"),h=a.join(u,"upgrade-guardian.fallback.mjs"),g=`${m}.tmp-${D.pid}`;l.mkdirSync(u,{recursive:!0});try{l.copyFileSync(d,g),l.renameSync(g,m),l.copyFileSync(d,h)}finally{l.rmSync(g,{force:!0})}}if(this.platform==="darwin"){const u=a.join(r,"scripts","upgrade-guardian.sh");if(l.existsSync(u)){const m=a.join(this.normalizeRootDir(i),"bin","upgrade-guardian.sh"),h=`${m}.tmp-${D.pid}`;try{l.copyFileSync(u,h),l.chmodSync(h,493),l.renameSync(h,m)}finally{l.rmSync(h,{force:!0})}}}}}buildDescriptor(i,t,s=""){const r=this.normalizeRootDir(i),e=this.resolveServiceCliPath(r);return{schema_version:1,platform:this.platform,service_id:L(r,this.platform),node_path:this.nodePath,cli_path:e,cli_hash:this.computeServiceHash(e)??"",definition_path:s,config_dir:t??"",installed_at:0,updated_at:0}}createStore(i){return new E(B(this.normalizeRootDir(i)))}toAdapterPayload(i,t){return{serviceID:i.service_id,nodePath:i.node_path,cliPath:i.cli_path,configDir:i.config_dir||void 0,rootDir:this.normalizeRootDir(t),environmentPath:this.buildServiceEnvironmentPath()}}async resolveServiceLogPaths(i){const t=this.resolveLocalServiceBaseDir();if(t){const s=a.join(this.platform==="darwin"?a.join(this.homeDir,"Library","Logs","grix-connector"):a.join(t,"logs"),L(this.normalizeRootDir(i),this.platform));return await w(s,{recursive:!0}),{stdoutPath:a.join(s,"daemon.out.log"),stderrPath:a.join(s,"daemon.err.log")}}return await w(a.join(i,"service"),{recursive:!0}),{stdoutPath:H(i),stderrPath:N(i)}}buildServiceEnvironmentPath(){const i=[a.dirname(this.nodePath),"/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin","/usr/sbin","/sbin"],t=String(D.env.PATH??"").split(a.delimiter).filter(e=>e&&a.isAbsolute(e)).filter(e=>!e.includes("/node_modules/.bin")).filter(e=>!e.includes("/node-gyp-bin")),s=[],r=new Set;for(const e of[...i,...t]){if(r.has(e))continue;if(r.add(e),[...s,e].join(a.delimiter).length>2048)break;s.push(e)}return s.join(a.delimiter)}toStartParams(i){return{serviceID:i.service_id,definitionPath:i.definition_path,uid:this.uid,homeDir:this.homeDir,runCommand:p}}toStopParams(i){return{serviceID:i.service_id,uid:this.uid,homeDir:this.homeDir,runCommand:p}}toRestartParams(i){return{serviceID:i.service_id,definitionPath:i.definition_path,uid:this.uid,homeDir:this.homeDir,runCommand:p}}toUninstallParams(i){return{serviceID:i.service_id,definitionPath:i.definition_path,uid:this.uid,homeDir:this.homeDir,runCommand:p}}async loadDescriptor(i){const t=this.createStore(i),s=await t.load();if(!s)throw new Error("\u540E\u53F0\u670D\u52A1\u8FD8\u6CA1\u6709\u5B89\u88C5\uFF0C\u8BF7\u5148\u6267\u884C service install\u3002");return{store:t,descriptor:s}}isDescriptorCurrent(i,t){if(t.node_path!==this.nodePath||t.cli_path!==this.resolveServiceCliPath(i)||!t.cli_hash)return!1;const s=this.computeServiceHash(t.cli_path),r=this.computeServiceHash(this.cliPath);return s!==null&&r!==null&&s===t.cli_hash&&r===t.cli_hash}computeFileHash(i){try{const t=l.readFileSync(i);return C("sha256").update(t).digest("hex")}catch{return null}}computeServiceHash(i){if(!this.resolveLocalServiceBaseDir())return this.computeFileHash(i);try{const t=a.dirname(i),s=C("sha256"),r=e=>{const o=l.readdirSync(e,{withFileTypes:!0}).sort((n,c)=>n.name.localeCompare(c.name));for(const n of o){const c=a.join(e,n.name);s.update(a.relative(t,c)),n.isDirectory()?r(c):n.isFile()&&s.update(l.readFileSync(c))}};return r(t),s.digest("hex")}catch{return null}}async refreshDescriptor(i,t){const s=this.normalizeRootDir(i);await w(a.join(s,"service"),{recursive:!0}),this.prepareServiceRuntime(s);const r=this.resolveServiceCliPath(s),e={...t,platform:this.platform,service_id:t.service_id||L(s,this.platform),node_path:this.nodePath,cli_path:r,cli_hash:this.computeServiceHash(r)??"",config_dir:t.config_dir},o=await this.resolveServiceLogPaths(s),n=await this.adapter.install({...this.toAdapterPayload(e,s),stdoutPath:o.stdoutPath,stderrPath:o.stderrPath,homeDir:this.homeDir,uid:this.uid,runCommand:p}),c={...e,installed_at:t.installed_at,definition_path:n?.definitionPath||e.definition_path,updated_at:Date.now()};return await this.createStore(s).save(c),c}async resolveActiveDescriptor(i){const{descriptor:t}=await this.loadDescriptor(i);return this.isDescriptorCurrent(i,t)?t:this.refreshDescriptor(i,t)}async discoverConflictingServices(i){const t=this.normalizeRootDir(i),s=L(t,this.platform);return(await this.adapter.discoverServices({homeDir:this.homeDir,runCommand:p})).filter(e=>e.serviceID!==s)}async cleanupConflictingServices(i){const t=await this.discoverConflictingServices(i);if(t.length>0){const r=t.map(e=>e.serviceID).join(", ");console.log(`\u53D1\u73B0 ${t.length} \u4E2A\u6B8B\u7559\u670D\u52A1\uFF0C\u6B63\u5728\u68C0\u67E5: ${r}`)}let s=0;for(const r of t){if(await this.adapter.isServiceLoaded({serviceID:r.serviceID,uid:this.uid,homeDir:this.homeDir,runCommand:p})){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:p})}catch{}try{await this.adapter.uninstall({serviceID:r.serviceID,definitionPath:r.definitionPath,uid:this.uid,homeDir:this.homeDir,runCommand:p}),s++}catch{}}return s}captureDaemonBaseline(i){return{status:S(i.daemonStatusFile),lock:_(i.daemonLockFile)}}isDaemonReady(i,t,s){const r=S(i.daemonStatusFile),e=_(i.daemonLockFile);if(!r.running||r.state!=="running"||r.pid<=0||!e||e.pid!==r.pid||!x(e.pid)||typeof e.root_dir!="string"||a.resolve(e.root_dir)!==a.resolve(i.rootDir)||typeof e.instance_id!="string"||e.instance_id.length===0||r.instance_id!==e.instance_id)return!1;const o=r.pid!==t.status.pid||r.state!==t.status.state||r.updated_at!==t.status.updated_at||r.instance_id!==t.status.instance_id,n=!t.lock||e.pid!==t.lock.pid||e.acquired_at!==t.lock.acquired_at||e.instance_id!==t.lock.instance_id,c=o&&n,d=t.status.state==="starting"&&t.status.instance_id===e.instance_id&&t.lock?.pid===e.pid&&t.lock.instance_id===e.instance_id&&r.instance_id===e.instance_id&&r.updated_at!==t.status.updated_at,u=t.lock?.pid===e.pid&&t.lock.instance_id===e.instance_id&&t.lock.acquired_at===e.acquired_at&&(t.status.pid!==e.pid||t.status.instance_id!==e.instance_id||t.status.state!=="running")&&r.pid===e.pid&&r.instance_id===e.instance_id&&r.state==="running"&&r.updated_at!==t.status.updated_at;return!F(e)&&!c&&!d&&!u?!1:s?c||d||u:!0}canForceTerminateDaemon(i,t){const s=_(i.daemonLockFile);return t>0&&s!==null&&s.pid===t&&typeof s.root_dir=="string"&&a.resolve(s.root_dir)===a.resolve(i.rootDir)&&F(s)}defaultDaemonStartTimeoutMs(){return this.platform==="darwin"?5e4:2e4}async waitForDaemonStarted(i,t={}){const s=t.timeoutMs??this.defaultDaemonStartTimeoutMs(),r=t.baseline??this.captureDaemonBaseline(i),e=t.requireNewDaemon??!1,o=t.stdoutLogFile??i.stdoutLogFile,n=t.stderrLogFile??i.stderrLogFile,c=t.stdoutLogCursor??v(o),d=t.stderrLogCursor??v(n),u=Date.now();for(;Date.now()-u<s;){if(this.isDaemonReady(i,r,e))return;const f=S(i.daemonStatusFile);if(f.state==="failed"&&(r.status.state!=="failed"||f.pid!==r.status.pid||f.updated_at!==r.status.updated_at||f.instance_id!==r.status.instance_id)){const k=_(i.daemonLockFile),R=["daemon start failed",`status=${JSON.stringify(f)}`,`lock=${k?JSON.stringify(k):"missing"}`,y("stderr",n,d),y("stdout",o,c)].filter(Boolean);throw new Error(R.join(`
|
|
2
|
+
`))}await z(100)}const m=_(i.daemonLockFile),h=S(i.daemonStatusFile),g=[`daemon start timeout (${s}ms)`,`status=${JSON.stringify(h)}`,`lock=${m?JSON.stringify(m):"missing"}`,y("stderr",n,d),y("stdout",o,c)].filter(Boolean);throw new Error(g.join(`
|
|
3
|
+
`))}async install(i){const t=this.normalizeRootDir(i.rootDir);await this.cleanupConflictingServices(t),await w(a.join(t,"service"),{recursive:!0}),this.prepareServiceRuntime(t);const s=P(t),r=this.captureDaemonBaseline(s),e=this.buildDescriptor(t,i.configDir),o=await this.resolveServiceLogPaths(t),n=v(o.stdoutPath),c=v(o.stderrPath),d=await this.adapter.isServiceLoaded({serviceID:e.service_id,uid:this.uid,homeDir:this.homeDir,runCommand:p}),u=await this.adapter.install({...this.toAdapterPayload(e,t),stdoutPath:o.stdoutPath,stderrPath:o.stderrPath,homeDir:this.homeDir,uid:this.uid,runCommand:p}),m={...e,definition_path:u?.definitionPath??"",installed_at:Date.now(),updated_at:Date.now()};return await this.createStore(t).save(m),d?await this.adapter.restart(this.toRestartParams(m)):await this.adapter.start(this.toStartParams(m)),await this.waitForDaemonStarted(s,{baseline:r,requireNewDaemon:!0,stdoutLogFile:o.stdoutPath,stderrLogFile:o.stderrPath,stdoutLogCursor:n,stderrLogCursor:c}),this.status({rootDir:t})}async start(i){const t=this.normalizeRootDir(i.rootDir);await this.cleanupConflictingServices(t);const s=P(t),r=this.captureDaemonBaseline(s),e=r.status,o=v(s.stdoutLogFile),n=v(s.stderrLogFile),d=await this.createStore(t).load();if(e.running&&d&&this.isDescriptorCurrent(t,d)){if(e.state==="starting"){const h=r.lock;if(h!==null&&h.pid===e.pid&&typeof h.root_dir=="string"&&a.resolve(h.root_dir)===a.resolve(s.rootDir)&&typeof h.instance_id=="string"&&h.instance_id.length>0&&e.instance_id===h.instance_id&&F(h)){const f=await this.resolveServiceLogPaths(t);return await this.waitForDaemonStarted(s,{baseline:r,stdoutLogFile:f.stdoutPath,stderrLogFile:f.stderrPath,stdoutLogCursor:o,stderrLogCursor:n}),this.status({rootDir:t})}}if(this.isDaemonReady(s,r,!1))return this.status({rootDir:t})}const u=d?this.isDescriptorCurrent(t,d)&&e.running?d:await this.refreshDescriptor(t,d):await this.resolveActiveDescriptor(t),m=await this.resolveServiceLogPaths(t);try{e.running?await this.adapter.restart(this.toRestartParams(u)):await this.adapter.start(this.toStartParams(u))}catch(h){if(h instanceof Error&&h.message.includes("plist missing"))await this.adapter.install({...this.toAdapterPayload(u,t),stdoutPath:m.stdoutPath,stderrPath:m.stderrPath,homeDir:this.homeDir,uid:this.uid,runCommand:p}),await this.adapter.start(this.toStartParams(u));else throw h}return await this.waitForDaemonStarted(s,{baseline:r,requireNewDaemon:!0,stdoutLogFile:m.stdoutPath,stderrLogFile:m.stderrPath,stdoutLogCursor:o,stderrLogCursor:n}),this.status({rootDir:t})}async stop(i){const t=this.normalizeRootDir(i.rootDir),{descriptor:s}=await this.loadDescriptor(t),r=P(t),e=S(r.daemonStatusFile);return await this.adapter.stop(this.toStopParams(s)),e.running&&e.pid&&(await this.waitForExit(e.pid,{timeoutMs:5e3})||this.canForceTerminateDaemon(r,e.pid)&&(await this.terminateTree(e.pid,{platform:this.platform,runCommandImpl:p}),await this.waitForExit(e.pid,{timeoutMs:5e3}))),this.status({rootDir:t})}async restart(i){const t=this.normalizeRootDir(i.rootDir);await this.cleanupConflictingServices(t);const s=await this.resolveActiveDescriptor(t),r=P(t),e=this.captureDaemonBaseline(r),o=await this.resolveServiceLogPaths(t),n=v(o.stdoutPath),c=v(o.stderrPath);try{await this.adapter.restart(this.toRestartParams(s))}catch(d){if(d instanceof Error&&d.message.includes("plist missing"))await this.adapter.install({...this.toAdapterPayload(s,t),stdoutPath:o.stdoutPath,stderrPath:o.stderrPath,homeDir:this.homeDir,uid:this.uid,runCommand:p}),await this.adapter.start(this.toStartParams(s));else throw d}return await this.waitForDaemonStarted(r,{baseline:e,requireNewDaemon:!0,stdoutLogFile:o.stdoutPath,stderrLogFile:o.stderrPath,stdoutLogCursor:n,stderrLogCursor:c}),this.status({rootDir:t})}async uninstall(i){const t=this.normalizeRootDir(i.rootDir),s=this.createStore(t),r=await s.load();return r&&(await this.adapter.uninstall(this.toUninstallParams(r)),await s.clear()),this.status({rootDir:t})}async status(i){const t=this.normalizeRootDir(i.rootDir),r=await this.createStore(t).load(),e=P(t),o=S(e.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:o.state,pid:o.pid,connection_state:o.connection_state,updated_at:o.updated_at,reason:o.reason}:{installed:!1,install_state:"missing",service_kind:this.adapter.kind,root_dir:t,daemon_state:o.state,pid:o.pid,reason:o.reason}}}export{rt as ServiceManager};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{createHash as d}from"node:crypto";import a from"node:os";import
|
|
2
|
-
`:t==="r"?"\r":t==="t"?" ":t,
|
|
1
|
+
import{createHash as d}from"node:crypto";import a from"node:os";import i from"node:path";import{normalizeString as x}from"../core/util/normalize-string.js";const p="com.dhfpub.grix-connector.daemon.",m="grix-connector-daemon-",g="GrixConnectorDaemon-";function h(e){return d("sha1").update(x(e)||"default").digest("hex").slice(0,12)}function v(e,r=process.platform){const n=h(e);return r==="win32"?`${g}${n}`:r==="darwin"?`${p}${n}`:`${m}${n}`}function j(e=process.platform){return e==="win32"?g:e==="darwin"?p:m}function D(e,r=process.env,n=a.homedir()){const o=String(r.LOCALAPPDATA??"").trim(),s=o&&i.isAbsolute(o)?o:i.join(n,"AppData","Local");return i.join(s,"grix-connector","runtimes",v(i.resolve(e),"win32"))}function S(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,'"')}function E(e){const r=[...e.matchAll(/<string>([^<]+)<\/string>/g)].map(n=>S(n[1]));for(let n=0;n<r.length-1;n+=1)if(r[n]==="--config-dir")return r[n+1];return null}function L(e){const r=e.match(/^ExecStart=(.*)$/m)?.[1];if(!r)return null;const n=[];let o="",s=null,u=!1,c=!1;const l=()=>{c&&(n.push(o.replace(/\$\$/g,"$").replace(/%%/g,"%")),o="",c=!1)};for(const t of r){if(u){o+=t==="n"?`
|
|
2
|
+
`:t==="r"?"\r":t==="t"?" ":t,u=!1,c=!0;continue}if(t==="\\"){u=!0,c=!0;continue}if(s!==null){t===s?s=null:o+=t,c=!0;continue}if(t==="'"||t==='"'){s=t,c=!0;continue}if(/\s/.test(t)){l();continue}o+=t,c=!0}u&&(o+="\\"),l();const f=n.indexOf("--config-dir");return f>=0?n[f+1]??null:null}function R(e){return i.join(e,"daemon-service.json")}function C(e){return i.join(e,"service","daemon.out.log")}function b(e){return i.join(e,"service","daemon.err.log")}function w(e,r){return i.join(r??a.homedir(),"Library","LaunchAgents",`${e}.plist`)}function _(e,r){return i.join(r??a.homedir(),".config","systemd","user",`${e}.service`)}function F(e,r){return i.join(r??a.homedir(),".grix","service",`${e}.bare.json`)}export{p as SERVICE_PREFIX_DARWIN,m as SERVICE_PREFIX_LINUX,g as SERVICE_PREFIX_WIN32,v as buildServiceID,j as getServicePrefix,E as parseConfigDirFromPlistXML,L as parseConfigDirFromSystemdUnit,F as resolveBareDaemonMarkerPath,_ as resolveLinuxUserUnitPath,w as resolveMacOSLaunchAgentPath,R as resolveServiceInstallRecordPath,b as resolveServiceStderrPath,C as resolveServiceStdoutPath,D as resolveWindowsServiceRuntimeDir};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{existsSync as P,mkdirSync as y,copyFileSync as v,renameSync as E,rmSync as R,readFileSync as I,writeFileSync as M}from"node:fs";import O from"node:os";import s from"node:path";import{log as l}from"../core/log/index.js";import{readJSONFile as A,writeJSONFileAtomic as k}from"../core/util/json-file.js";import{WINDOWS_WRAPPER_TEMPLATE_MARKER as T,WINDOWS_WRAPPER_TEMPLATE_VERSION as u,buildWindowsWrapperScript as H,resolveWindowsWrapperPath as L}from"./platform-adapter.js";import{findProcessesByCommandLine as V,spawnDetached as G}from"./process-control.js";import{buildServiceID as q,resolveServiceInstallRecordPath as J}from"./service-paths.js";const b=3,X=360*60*1e3,Y={handoff_attempts:0,last_attempt_at:0,refreshed_template:0};function B(r){for(const e of r.split(/\r?\n/,8)){const t=e.indexOf(T);if(t<0)continue;const n=Number.parseInt(e.slice(t+T.length).trim(),10);if(Number.isFinite(n)&&n>0)return n}return 0}function C(r){const e=n=>({refresh:!1,handoff:!1,reason:n});if(r.platform!=="win32")return e("not windows");if(r.upgradePending)return e("upgrade transaction in flight");if(r.installedTemplate<0)return e("no installed wrapper");const t=r.installedTemplate<u;return r.supervised?{refresh:t,handoff:!1,reason:t?"refresh under supervision":"already current"}:r.wrapperProcessAlive?r.state.handoff_attempts>=b?{refresh:t,handoff:!1,reason:"handoff attempts exhausted"}:r.state.last_attempt_at>0&&r.now-r.state.last_attempt_at<X?{refresh:t,handoff:!1,reason:"handoff retry throttled"}:{refresh:t,handoff:!0,reason:"unsupervised daemon under a stale wrapper"}:{refresh:t,handoff:!1,reason:"daemon not running under a wrapper"}}function N(r){return s.join(r,"data","wrapper-migration.json")}function K(r){const e=A(N(r));return!e||typeof e!="object"?{...Y}:{handoff_attempts:Number.isFinite(e.handoff_attempts)?Number(e.handoff_attempts):0,last_attempt_at:Number.isFinite(e.last_attempt_at)?Number(e.last_attempt_at):0,refreshed_template:Number.isFinite(e.refreshed_template)?Number(e.refreshed_template):0}}async function F(r,e){await k(N(r),e)}function U(r){try{return B(I(r,"utf8"))}catch{return-1}}function z(r){const e=H({nodePath:r.nodePath,cliPath:r.cliPath,configDir:r.configDir,rootDir:r.rootDir});y(s.dirname(r.wrapperPath),{recursive:!0});const t=`${r.wrapperPath}.tmp-${process.pid}`;try{M(t,e,"utf8"),E(t,r.wrapperPath)}finally{R(t,{force:!0})}const n=s.join(r.packageDir,"scripts","upgrade-guardian.mjs");if(!P(n))return;const d=s.join(r.rootDir,"bin");y(d,{recursive:!0});const c=s.join(d,"upgrade-guardian.mjs"),o=s.join(d,"upgrade-guardian.fallback.mjs"),p=`${c}.tmp-${process.pid}`;try{v(n,p),E(p,c),v(n,o)}finally{R(p,{force:!0})}}async function or(r){const e=r.platform??process.platform,t=r.env??process.env,n=r.homeDir??O.homedir(),d=r.now??Date.now(),c=a=>({plan:{refresh:!1,handoff:!1,reason:a},refreshed:!1,handoffStarted:!1});if(e!=="win32")return c("not windows");const o=A(J(r.rootDir));if(!o?.node_path||!o.cli_path)return c("no service install record");const p=o.service_id||q(r.rootDir,"win32"),m=L(p,n),w=U(m),S=P(s.join(r.rootDir,"data","upgrade-pending.json")),D=t.GRIX_WRAPPER_SUPERVISED==="1",h=K(r.rootDir);let _=!1;if(!D&&!S&&w>=0){const a=r.findWrapperProcesses??V;try{_=(await a(`${p}-wrapper.vbs`)).filter($=>$!==process.pid).length>0}catch{_=!1}}const i=C({platform:e,supervised:D,installedTemplate:w,wrapperProcessAlive:_,upgradePending:S,state:h,now:d});let f=!1;if(i.refresh)try{z({wrapperPath:m,rootDir:r.rootDir,nodePath:o.node_path,cliPath:o.cli_path,configDir:o.config_dir||void 0,packageDir:s.dirname(s.dirname(o.cli_path))}),f=!0,l.info("wrapper-migration",`Refreshed Windows wrapper ${w} -> ${u}: ${m}`)}catch(a){return l.warn("wrapper-migration",`Failed to refresh Windows wrapper: ${a instanceof Error?a.message:a}`),{plan:i,refreshed:!1,handoffStarted:!1}}if(!i.handoff||!r.requestGracefulShutdown)return i.reason&&!i.handoff&&l.info("wrapper-migration",`No wrapper handoff: ${i.reason}`),f&&await F(r.rootDir,{...h,refreshed_template:u}).catch(()=>{}),{plan:i,refreshed:f,handoffStarted:!1};const g=s.join(r.rootDir,"bin","upgrade-guardian.mjs");if(!P(g))return l.warn("wrapper-migration",`Wrapper handoff skipped: guardian missing at ${g}`),{plan:i,refreshed:f,handoffStarted:!1};await F(r.rootDir,{handoff_attempts:h.handoff_attempts+1,last_attempt_at:d,refreshed_template:f?u:h.refreshed_template}).catch(()=>{});const j=r.spawnHelper??((a,W)=>{G(a,W)});try{j(o.node_path,[g,"adopt-wrapper","--root",r.rootDir,"--wrapper",m,"--service-id",p,"--daemon-pid",String(process.pid)])}catch(a){return l.warn("wrapper-migration",`Failed to spawn wrapper adopter: ${a instanceof Error?a.message:a}`),{plan:i,refreshed:f,handoffStarted:!1}}return l.info("wrapper-migration",`Handing off to the refreshed Windows wrapper (attempt ${h.handoff_attempts+1}/${b}); shutting down gracefully`),await r.requestGracefulShutdown(),{plan:i,refreshed:f,handoffStarted:!0}}export{b as WRAPPER_HANDOFF_MAX_ATTEMPTS,X as WRAPPER_HANDOFF_RETRY_INTERVAL_MS,or as migrateWindowsWrapper,B as parseWrapperTemplateVersion,C as planWrapperMigration,U as readInstalledWrapperTemplate,K as readWrapperMigrationState,z as refreshWrapperAssets,N as resolveWrapperMigrationStatePath};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{SessionManager as a}from"./manager.js";export{a as SessionManager};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{EventEmitter as r}from"events";import{AgentProcess as c}from"../agent/process.js";import{AcpClient as l}from"../protocol/acp-client.js";class h extends r{sessions=new Map;async create(s){const e=new c,n=await e.start(s.agent),i=new l;i.on("event",a=>{this.emit("event",a)}),await i.connect({transport:n,sessionId:s.sessionId,authMethod:s.authMethod,initialMode:s.initialMode});const t=i.sessionId,o={id:t,process:e,client:i};return this.sessions.set(t,o),n.on("close",()=>{this.sessions.delete(t),this.emit("sessionClosed",t)}),this.emit("sessionCreated",t),o}get(s){return this.sessions.get(s)}list(){return[...this.sessions.values()]}async close(s){const e=this.sessions.get(s);e&&(this.sessions.delete(s),await e.process.close(),this.emit("sessionClosed",s))}async closeAll(){const s=[...this.sessions.keys()];await Promise.all(s.map(e=>this.close(e)))}get size(){return this.sessions.size}}export{h as SessionManager};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{JsonRpcTransport as o}from"./json-rpc.js";export{o as JsonRpcTransport};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{EventEmitter as p}from"events";class w extends p{nextId=1;pending=new Map;writeLock=Promise.resolve();closed=!1;_readable;_writable;_onNotify;_onRequest;constructor(t,e,r,o){super(),this._readable=t,this._writable=e,this._onNotify=r,this._onRequest=o,this.startReadLoop()}setHandlers(t,e){t&&(this._onNotify=t),e&&(this._onRequest=e)}async call(t,e,r){if(this.closed)throw new Error("transport closed");const o=this.nextId++,s=String(o),a=await new Promise((i,d)=>{if(this.pending.set(s,{resolve:i}),r){const n=()=>{this.pending.delete(s),d(new Error(`aborted: ${r.reason??"request cancelled"}`))};if(r.aborted){n();return}r.addEventListener("abort",n,{once:!0});const c=i,h=l=>{r.removeEventListener("abort",n),c(l)};this.pending.set(s,{resolve:h})}this.write({jsonrpc:"2.0",id:o,method:t,params:e??null}).catch(n=>{this.pending.delete(s),d(n)})});if(a.error){const i=new Error(a.error.message);throw i.code=a.error.code,i}return a.result}async notify(t,e){if(this.closed)throw new Error("transport closed");await this.write({jsonrpc:"2.0",method:t,params:e??null})}async respondSuccess(t,e){await this.write({jsonrpc:"2.0",id:t,result:e})}async respondError(t,e,r){await this.write({jsonrpc:"2.0",id:t,error:{code:e,message:r}})}close(){if(!this.closed){this.closed=!0;for(const[t,{resolve:e}]of this.pending)e({error:{code:-32e3,message:"transport closed"}});this.pending.clear(),this._readable.destroy(),this.emit("close")}}startReadLoop(){let t="";this._readable.on("data",e=>{t+=e.toString();const r=t.split(`
|
|
2
|
+
`);t=r.pop()??"";for(const o of r){const s=o.trim();s.length!==0&&this.dispatch(s)}}),this._readable.on("end",()=>{t.trim()&&this.dispatch(t.trim()),this.close()}),this._readable.on("error",e=>{this.emit("error",e),this.close()})}dispatch(t){let e;try{e=JSON.parse(t)}catch{return}if(e.id!=null&&!e.method){this.completePending(e.id,e.result,e.error);return}if(e.method&&(e.id==null||e.id===null)){this._onNotify?.(e.method,e.params);return}e.method&&e.id!=null&&this._onRequest?.(e.method,e.id,e.params)}completePending(t,e,r){const o=String(t),s=this.pending.get(o);s&&(this.pending.delete(o),s.resolve({result:e,error:r}))}async write(t){const e=this.writeLock;return this.writeLock=e.then(async()=>new Promise((r,o)=>{const s=JSON.stringify(t)+`
|
|
3
|
+
`;this._writable.write(s,"utf-8")?r():(this._writable.once("drain",r),this._writable.once("error",o))})),this.writeLock}}export{w as JsonRpcTransport};
|