shennian 0.4.21 → 0.4.23

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.
@@ -306,8 +306,8 @@
306
306
  },
307
307
  {
308
308
  "file": "src/commands/daemon.js",
309
- "beforeBytes": 45184,
310
- "afterBytes": 21864
309
+ "beforeBytes": 45283,
310
+ "afterBytes": 21874
311
311
  },
312
312
  {
313
313
  "file": "src/commands/integration.js",
@@ -1,5 +1,5 @@
1
- import c from"chalk";import o from"node:fs";import a from"node:path";import d from"node:os";import{execSync as u,spawn as Se}from"node:child_process";import{randomUUID as F}from"node:crypto";import{fileURLToPath as he}from"node:url";import{getShennianDir as ge,loadConfig as B,resolveShennianPath as S,saveConfig as ye}from"../config/index.js";import{buildAugmentedPath as we}from"../env-path.js";import{buildWindowsLauncherCommand as Ee,buildWindowsScheduledTaskCommands as ve,buildWindowsScheduledTaskXml as Pe,buildWindowsStartupVbs as Ae,escapeXml as x,isWindowsCmdScript as Ne,quoteCmdArg as V,quoteSystemdArg as Ie,suspendWindowsScheduledTask as De}from"./daemon-windows.js";import{waitForDaemonReadyStatus as T}from"./daemon-start-wait.js";import{findRunningWindowsDaemonProcessIds as ke,isShennianRunServiceCommand as _e}from"./daemon-process.js";import{getCurrentVersion as G}from"../upgrade/engine.js";import{buildWindowsLauncherCommand as Rn,buildWindowsScheduledTaskCommands as xn,buildWindowsScheduledTaskSuspendCommands as Tn,buildWindowsScheduledTaskXml as Ln,buildWindowsStartupVbs as On,suspendWindowsScheduledTask as Cn}from"./daemon-windows.js";import{isShennianRunServiceCommand as $n}from"./daemon-process.js";const be=a.dirname(he(import.meta.url)),h=ge(),y=S("daemon.pid"),m=S("daemon.log"),L=S("remote-access.disabled"),k=S("daemon-launcher.json"),K=a.resolve(be,"../../bin/shennian.js"),J=process.execPath,q=new Set(["PATH","HOME","USERPROFILE","HOMEDRIVE","HOMEPATH","USERNAME","USERDOMAIN","COMPUTERNAME","USER","LOGNAME","SHELL","TMPDIR","LANG","LC_ALL","LC_CTYPE","SSH_AUTH_SOCK","XDG_CONFIG_HOME","XDG_DATA_HOME","TEMP","TMP","APPDATA","LOCALAPPDATA","ELECTRON_RUN_AS_NODE","SHENNIAN_DESKTOP_CLI_SCRIPT","SHENNIAN_DESKTOP_CLI_BRIDGE","SHENNIAN_DESKTOP_SERVER_URL","SHENNIAN_WECHAT_CHANNEL_HELPER_DIR","SHENNIAN_HOME","SHENNIAN_ACCOUNT_NAMESPACE_ID","SHENNIAN_NATIVE_FUSION_DISABLED","SHENNIAN_WECHAT_DELIVERABILITY_TRACE"]);function Re(e){return q.has(e)}function p(){const e=d.platform();return e==="darwin"||e==="linux"||e==="win32"?e:"linux"}function O(e){const n=e.replace(/\\/g,"/").toLowerCase(),r=d.tmpdir().replace(/\\/g,"/").toLowerCase();return n.includes("/_npx/")||n.includes("/npm-cache/_npx/")||n.includes("/pnpm/dlx/")||n.startsWith(r.endsWith("/")?r:`${r}/`)}function xe(e){return process.env.ELECTRON_RUN_AS_NODE==="1"&&e.desktopBridgePath&&o.existsSync(e.scriptPath)&&o.existsSync(e.desktopBridgePath)?{command:e.nodeExec,args:[e.desktopBridgePath,e.scriptPath,"run-service"],mode:"direct"}:o.existsSync(e.scriptPath)&&(process.env.SHENNIAN_E2E_ISOLATED_DAEMON==="1"||!O(e.scriptPath))?{command:e.nodeExec,args:[e.scriptPath,"run-service"],mode:"direct"}:e.shennianCommandPath&&!O(e.shennianCommandPath)?{command:e.shennianCommandPath,args:["run-service"],mode:"global-shim"}:e.npxPath?{command:e.npxPath,args:["--yes","shennian","run-service"],mode:"npx"}:{command:e.nodeExec,args:[e.scriptPath,"run-service"],mode:"direct"}}function Te(e){const n=e.trim();if(!n)return null;if(n.startsWith("{"))try{const t=JSON.parse(n),s=Number(t.pid);return!Number.isInteger(s)||s<=0?null:{pid:s,...typeof t.instanceId=="string"?{instanceId:t.instanceId}:{},...typeof t.version=="string"?{version:t.version}:{},...t.launcher==="desktop-managed"||t.launcher==="global-cli"||t.launcher==="unknown"?{launcher:t.launcher}:{},...typeof t.startedAt=="string"?{startedAt:t.startedAt}:{},...t.adopted===!0?{adopted:!0}:{}}}catch{return null}const r=parseInt(n,10);return isNaN(r)?null:{pid:r}}function A(){try{return Te(o.readFileSync(y,"utf-8"))}catch{return null}}function v(e){try{return process.kill(e,0),!0}catch{return!1}}function X(e,n=3e3){const r=Date.now();for(;Date.now()-r<n;){if(!v(e))return!0;Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,100)}return!v(e)}function Le(){return o.existsSync(L)}function Oe(){try{o.unlinkSync(L)}catch{}}function Ce(e,n){const r=a.dirname(e),t=`${e}.${process.pid}.${F()}.tmp`;o.mkdirSync(r,{recursive:!0});let s=null;try{s=o.openSync(t,"w",384),o.writeSync(s,n,void 0,"utf8"),o.fsyncSync(s),o.closeSync(s),s=null,o.renameSync(t,e);try{const i=o.openSync(r,"r");try{o.fsyncSync(i)}finally{o.closeSync(i)}}catch{}}finally{s!==null&&o.closeSync(s);try{o.unlinkSync(t)}catch{}}}function He(e={}){const n=e.disabledAt??new Date().toISOString(),r=e.markerFile??L,t=e.platform??p(),s=e.servicePresent??M(t),i=e.execCommand??(l=>{u(l,{stdio:"pipe",windowsHide:!0})});if(Ce(r,n),!s)return{disabledAt:n,autoStartDisabled:!0};try{return i(t==="darwin"?`launchctl disable "${P()}"`:t==="linux"?"systemctl --user disable shennian":`schtasks /change /tn "${D}" /disable`),{disabledAt:n,autoStartDisabled:!0}}catch(l){return{disabledAt:n,autoStartDisabled:!1,autoStartError:l instanceof Error?l.message:String(l)}}}function $e(e={}){const n=e.platform??p();if(!(e.servicePresent??M(n)))return{serviceStopped:!0};const t=e.execCommand??(s=>{u(s,{stdio:"pipe",windowsHide:!0})});try{return t(n==="darwin"?`launchctl bootout "${P()}"`:n==="linux"?"systemctl --user stop shennian":`schtasks /end /tn "${D}"`),{serviceStopped:!0}}catch(s){return{serviceStopped:!1,error:s instanceof Error?s.message:String(s)}}}function Y(){return process.env.SHENNIAN_DESKTOP_CLI_SCRIPT?"desktop-managed":"global-cli"}function Me(){return`${process.pid}-${Date.now()}-${F()}`}function Ue(e,n,r={}){o.mkdirSync(h,{recursive:!0}),o.writeFileSync(y,JSON.stringify({pid:e,instanceId:n,...r.version?{version:r.version}:{},launcher:r.launcher??Y(),...r.adopted?{adopted:!0}:{},startedAt:new Date().toISOString()},null,2))}function Dn(e,n){const r=A();if(!(r?.pid!==e||r.instanceId!==n))try{o.unlinkSync(y)}catch{}}function z(e,n=Y(),r){o.mkdirSync(h,{recursive:!0}),o.writeFileSync(k,JSON.stringify({pid:e,launcher:n,...r?{instanceId:r}:{},updatedAt:new Date().toISOString()},null,2))}function je(e){if(e)try{if(JSON.parse(o.readFileSync(k,"utf-8")).instanceId!==e)return}catch{return}try{o.unlinkSync(k)}catch{}}function We(e){e&&z(e)}function Fe(e,n){if(!e||!n)return"unknown";try{const r=JSON.parse(o.readFileSync(k,"utf-8"));if(r.pid!==e)return"unknown";if(r.launcher==="desktop-managed"||r.launcher==="global-cli")return r.launcher}catch{}return C(e)}function C(e){if(p()==="win32")return"unknown";try{const n=u(`ps -p ${e} -o command=`,{encoding:"utf-8",stdio:["ignore","pipe","ignore"],timeout:1e3,windowsHide:!0}).replace(/\\/g,"/");if(n.includes("/cli-bridge.js")||n.includes("/Resources/daemon/")||n.includes("\\resources\\daemon\\"))return"desktop-managed";if(n.includes("/node_modules/shennian/")||n.includes("/bin/shennian")||n.includes(" shennian run-service")||n.includes(" shennian.js run-service"))return"global-cli"}catch{}return"unknown"}function Q(e=process.pid){if(p()==="win32")return ke(e);try{return u("ps -axo pid=,command=",{encoding:"utf-8",stdio:["ignore","pipe","ignore"],timeout:1e3,windowsHide:!0}).split(/\r?\n/).map(r=>{const t=r.trim().match(/^(\d+)\s+(.+)$/);if(!t)return null;const s=Number(t[1]),i=t[2];return!Number.isInteger(s)||s===e?null:_e(i)?s:null}).filter(r=>typeof r=="number")}catch{return[]}}function Z(e=process.env,n=h,r=d.tmpdir(),t=a.join(d.homedir(),".shennian")){if(e.SHENNIAN_E2E_ISOLATED_DAEMON!=="1"||!e.SHENNIAN_HOME?.trim()||a.resolve(n)===a.resolve(t))return!1;const s=a.relative(a.resolve(r),a.resolve(n));return s!==""&&s!==".."&&!s.startsWith(`..${a.sep}`)&&!a.isAbsolute(s)||a.resolve(n)===a.resolve(e.SHENNIAN_HOME)}function Be(e=process.env,n=h){return!Z(e,n)}function Ve(e=process.env,n=h){return!Z(e,n)}function f(e={}){let n=A(),r=n?.pid??null,t=r!==null&&v(r),s=r!==null&&!t,i=n?.adopted===!0;const l=B();if(s&&e.cleanupStale){try{o.unlinkSync(y)}catch{}n=null,r=null,t=!1,s=!1}if(!t&&Be()){const E=Q()[0];if(E&&(r=E,t=!0,s=!1,i=!0,e.cleanupStale)){const W=Me();Ue(E,W,{launcher:C(E),adopted:!0}),z(E,C(E)),n={pid:E,instanceId:W,adopted:!0}}}return{running:t,pid:r,stale:s,remoteAccessDisabled:Le(),launcher:Fe(r,t),platform:p(),shennianDir:h,pidFile:y,logFile:m,...n?.instanceId?{instanceId:n.instanceId}:{},...i?{adopted:!0}:{},...l.machineId?{machineId:l.machineId}:{},paired:!!(l.machineToken&&l.machineId),...l.serverUrl?{serverUrl:l.serverUrl}:{}}}function w(e){process.stdout.write(`${JSON.stringify(e,null,2)}
2
- `)}function ee(e){const n=e?.trim();if(!n)return;const r=B();r.serverUrl=n,ye(r)}function ne(e){return e?.trim()||process.env.SHENNIAN_DESKTOP_SERVER_URL?.trim()||void 0}const H="com.shennian.agent",g=a.join(d.homedir(),"Library/LaunchAgents",`${H}.plist`),te=S("Shennian.app"),Ge=a.join(d.homedir(),"AppData","Roaming","Microsoft","Windows","Start Menu","Programs","Startup"),_=S("autostart.cmd"),b=S("autostart.vbs"),R=S("autostart.xml"),Ke=a.join(Ge,"ShennianAgent.vbs");function re(e){const n=p()==="win32"?`where ${e}`:`command -v ${e}`;try{return u(n,{stdio:["ignore","pipe","pipe"],encoding:"utf-8",windowsHide:!0}).split(/\r?\n/).map(s=>s.trim()).find(Boolean)??null}catch{return null}}function Je(){const e=p()==="win32"?"npx.cmd":"npx",n=a.join(a.dirname(J),e);return o.existsSync(n)?n:re("npx")}function N(){return xe({nodeExec:J,scriptPath:K,shennianCommandPath:re("shennian"),npxPath:Je(),desktopBridgePath:process.env.SHENNIAN_DESKTOP_CLI_BRIDGE})}function oe(){try{u(`schtasks /delete /tn "${D}" /f`,{stdio:"pipe",windowsHide:!0})}catch{}}function se(){try{o.unlinkSync(Ke)}catch{}}function qe(){const e=process.env.USERDOMAIN?.trim(),n=process.env.COMPUTERNAME?.trim(),r=process.env.USERNAME?.trim()||d.userInfo().username;return e&&e.toUpperCase()!=="WORKGROUP"?`${e}\\${r}`:n?`${n}\\${r}`:r}function Xe(e){if(p()==="win32"&&Ne(e.command)){const n=[e.command,...e.args].map(V).join(" ");return{command:process.env.ComSpec||"cmd.exe",args:["/d","/s","/c",`"${n}"`],windowsVerbatimArguments:!0}}return{command:e.command,args:e.args}}function Ye(e,n,r=process.env){return{detached:!0,stdio:["ignore",n,n],env:r,windowsHide:!0,...e.windowsVerbatimArguments?{windowsVerbatimArguments:!0}:{}}}function ze(){const e=N();o.writeFileSync(_,Ee(e,m)),o.writeFileSync(b,Ae(_)),se(),oe();const n=Pe({userId:qe(),command:a.join(process.env.SystemRoot||"C:\\Windows","System32","wscript.exe"),arguments:[V(b)]});o.writeFileSync(R,n,"utf8");const r=ve({taskName:D,xmlPath:R});try{return u(r.create,{stdio:"pipe",windowsHide:!0}),u(r.run,{stdio:"pipe",windowsHide:!0}),!0}catch{return!1}}function Qe(){De(D,e=>{u(e,{stdio:"pipe",windowsHide:!0})})}function ie(){const e={};for(const n of q)process.env[n]&&(e[n]=process.env[n]);if(e.HOME??=d.homedir(),e.PATH=we({pathValue:e.PATH,env:e}),e.USER??=d.userInfo().username,p()==="win32"){const n=process.env.TEMP||process.env.TMP||d.tmpdir(),r=d.homedir();e.USERPROFILE??=r;const t=a.win32.parse(r);e.HOMEDRIVE??=t.root.replace(/[\\/]$/,"")||process.env.HOMEDRIVE||"",e.HOMEPATH??=r.slice((e.HOMEDRIVE||"").length)||process.env.HOMEPATH||"",e.USERNAME??=process.env.USERNAME||d.userInfo().username,e.COMPUTERNAME??=process.env.COMPUTERNAME||"",e.TMPDIR??=n,e.TEMP??=n,e.TMP??=n}else e.TMPDIR??="/tmp";return e}function Ze(e={}){const n=ie(),r=e.launch??N(),t=Object.entries(n).map(([i,l])=>` <key>${x(i)}</key>
1
+ import c from"chalk";import o from"node:fs";import a from"node:path";import d from"node:os";import{execSync as u,spawn as he}from"node:child_process";import{randomUUID as F}from"node:crypto";import{fileURLToPath as ge}from"node:url";import{getShennianDir as ye,loadConfig as B,resolveShennianPath as S,saveConfig as we}from"../config/index.js";import{buildAugmentedPath as Ee}from"../env-path.js";import{buildWindowsLauncherCommand as ve,buildWindowsScheduledTaskCommands as Pe,buildWindowsScheduledTaskXml as Ae,buildWindowsStartupVbs as Ne,escapeXml as x,isWindowsCmdScript as Ie,quoteCmdArg as V,quoteSystemdArg as De,suspendWindowsScheduledTask as ke}from"./daemon-windows.js";import{waitForDaemonReadyStatus as T}from"./daemon-start-wait.js";import{findRunningWindowsDaemonProcessIds as _e,isShennianRunServiceCommand as be}from"./daemon-process.js";import{getCurrentVersion as G}from"../upgrade/engine.js";import{buildWindowsLauncherCommand as Rn,buildWindowsScheduledTaskCommands as xn,buildWindowsScheduledTaskSuspendCommands as Tn,buildWindowsScheduledTaskXml as Ln,buildWindowsStartupVbs as On,suspendWindowsScheduledTask as Cn}from"./daemon-windows.js";import{isShennianRunServiceCommand as $n}from"./daemon-process.js";const Re=a.dirname(ge(import.meta.url)),h=ye(),y=S("daemon.pid"),m=S("daemon.log"),L=S("remote-access.disabled"),k=S("daemon-launcher.json"),K=a.resolve(Re,"../../bin/shennian.js"),J=process.execPath,q=new Set(["PATH","HOME","USERPROFILE","HOMEDRIVE","HOMEPATH","USERNAME","USERDOMAIN","COMPUTERNAME","USER","LOGNAME","SHELL","TMPDIR","LANG","LC_ALL","LC_CTYPE","SSH_AUTH_SOCK","XDG_CONFIG_HOME","XDG_DATA_HOME","TEMP","TMP","APPDATA","LOCALAPPDATA","ELECTRON_RUN_AS_NODE","SHENNIAN_DESKTOP_CLI_SCRIPT","SHENNIAN_DESKTOP_CLI_BRIDGE","SHENNIAN_DESKTOP_SERVER_URL","SHENNIAN_WECHAT_CHANNEL_HELPER_DIR","SHENNIAN_HOME","SHENNIAN_ACCOUNT_NAMESPACE_ID","SHENNIAN_NATIVE_FUSION_DISABLED","SHENNIAN_WECHAT_DELIVERABILITY_TRACE"]);function xe(e){return q.has(e)}function p(){const e=d.platform();return e==="darwin"||e==="linux"||e==="win32"?e:"linux"}function O(e){const n=e.replace(/\\/g,"/").toLowerCase(),r=d.tmpdir().replace(/\\/g,"/").toLowerCase();return n.includes("/_npx/")||n.includes("/npm-cache/_npx/")||n.includes("/pnpm/dlx/")||n.startsWith(r.endsWith("/")?r:`${r}/`)}function Te(e){return process.env.ELECTRON_RUN_AS_NODE==="1"&&e.desktopBridgePath&&o.existsSync(e.scriptPath)&&o.existsSync(e.desktopBridgePath)?{command:e.nodeExec,args:[e.desktopBridgePath,e.scriptPath,"run-service"],mode:"direct"}:o.existsSync(e.scriptPath)&&(process.env.SHENNIAN_E2E_ISOLATED_DAEMON==="1"||!O(e.scriptPath))?{command:e.nodeExec,args:[e.scriptPath,"run-service"],mode:"direct"}:e.shennianCommandPath&&!O(e.shennianCommandPath)?{command:e.shennianCommandPath,args:["run-service"],mode:"global-shim"}:e.npxPath?{command:e.npxPath,args:["--yes","shennian","run-service"],mode:"npx"}:{command:e.nodeExec,args:[e.scriptPath,"run-service"],mode:"direct"}}function Le(e){const n=e.trim();if(!n)return null;if(n.startsWith("{"))try{const t=JSON.parse(n),s=Number(t.pid);return!Number.isInteger(s)||s<=0?null:{pid:s,...typeof t.instanceId=="string"?{instanceId:t.instanceId}:{},...typeof t.version=="string"?{version:t.version}:{},...t.launcher==="desktop-managed"||t.launcher==="global-cli"||t.launcher==="unknown"?{launcher:t.launcher}:{},...typeof t.startedAt=="string"?{startedAt:t.startedAt}:{},...t.adopted===!0?{adopted:!0}:{}}}catch{return null}const r=parseInt(n,10);return isNaN(r)?null:{pid:r}}function A(){try{return Le(o.readFileSync(y,"utf-8"))}catch{return null}}function v(e){try{return process.kill(e,0),!0}catch{return!1}}function X(e,n=3e3){const r=Date.now();for(;Date.now()-r<n;){if(!v(e))return!0;Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,100)}return!v(e)}function Oe(){return o.existsSync(L)}function Ce(){try{o.unlinkSync(L)}catch{}}function He(e,n){const r=a.dirname(e),t=`${e}.${process.pid}.${F()}.tmp`;o.mkdirSync(r,{recursive:!0});let s=null;try{s=o.openSync(t,"w",384),o.writeSync(s,n,void 0,"utf8"),o.fsyncSync(s),o.closeSync(s),s=null,o.renameSync(t,e);try{const i=o.openSync(r,"r");try{o.fsyncSync(i)}finally{o.closeSync(i)}}catch{}}finally{s!==null&&o.closeSync(s);try{o.unlinkSync(t)}catch{}}}function $e(e={}){const n=e.disabledAt??new Date().toISOString(),r=e.markerFile??L,t=e.platform??p(),s=e.servicePresent??M(t),i=e.execCommand??(l=>{u(l,{stdio:"pipe",windowsHide:!0})});if(He(r,n),!s)return{disabledAt:n,autoStartDisabled:!0};try{return i(t==="darwin"?`launchctl disable "${P()}"`:t==="linux"?"systemctl --user disable shennian":`schtasks /change /tn "${D}" /disable`),{disabledAt:n,autoStartDisabled:!0}}catch(l){return{disabledAt:n,autoStartDisabled:!1,autoStartError:l instanceof Error?l.message:String(l)}}}function Me(e={}){const n=e.platform??p();if(!(e.servicePresent??M(n)))return{serviceStopped:!0};const t=e.execCommand??(s=>{u(s,{stdio:"pipe",windowsHide:!0})});try{return t(n==="darwin"?`launchctl bootout "${P()}"`:n==="linux"?"systemctl --user stop shennian":`schtasks /end /tn "${D}"`),{serviceStopped:!0}}catch(s){return{serviceStopped:!1,error:s instanceof Error?s.message:String(s)}}}function Y(){return process.env.SHENNIAN_DESKTOP_CLI_SCRIPT?"desktop-managed":"global-cli"}function Ue(){return`${process.pid}-${Date.now()}-${F()}`}function je(e,n,r={}){o.mkdirSync(h,{recursive:!0}),o.writeFileSync(y,JSON.stringify({pid:e,instanceId:n,...r.version?{version:r.version}:{},launcher:r.launcher??Y(),...r.adopted?{adopted:!0}:{},startedAt:new Date().toISOString()},null,2))}function Dn(e,n){const r=A();if(!(r?.pid!==e||r.instanceId!==n))try{o.unlinkSync(y)}catch{}}function z(e,n=Y(),r){o.mkdirSync(h,{recursive:!0}),o.writeFileSync(k,JSON.stringify({pid:e,launcher:n,...r?{instanceId:r}:{},updatedAt:new Date().toISOString()},null,2))}function We(e){if(e)try{if(JSON.parse(o.readFileSync(k,"utf-8")).instanceId!==e)return}catch{return}try{o.unlinkSync(k)}catch{}}function Fe(e){e&&z(e)}function Be(e,n){if(!e||!n)return"unknown";try{const r=JSON.parse(o.readFileSync(k,"utf-8"));if(r.pid!==e)return"unknown";if(r.launcher==="desktop-managed"||r.launcher==="global-cli")return r.launcher}catch{}return C(e)}function C(e){if(p()==="win32")return"unknown";try{const n=u(`ps -p ${e} -o command=`,{encoding:"utf-8",stdio:["ignore","pipe","ignore"],timeout:1e3,windowsHide:!0}).replace(/\\/g,"/");if(n.includes("/cli-bridge.js")||n.includes("/Resources/daemon/")||n.includes("\\resources\\daemon\\"))return"desktop-managed";if(n.includes("/node_modules/shennian/")||n.includes("/bin/shennian")||n.includes(" shennian run-service")||n.includes(" shennian.js run-service"))return"global-cli"}catch{}return"unknown"}function Q(e=process.pid){if(p()==="win32")return _e(e);try{return u("ps -axo pid=,command=",{encoding:"utf-8",stdio:["ignore","pipe","ignore"],timeout:1e3,windowsHide:!0}).split(/\r?\n/).map(r=>{const t=r.trim().match(/^(\d+)\s+(.+)$/);if(!t)return null;const s=Number(t[1]),i=t[2];return!Number.isInteger(s)||s===e?null:be(i)?s:null}).filter(r=>typeof r=="number")}catch{return[]}}function Z(e=process.env,n=h,r=d.tmpdir(),t=a.join(d.homedir(),".shennian")){if(e.SHENNIAN_E2E_ISOLATED_DAEMON!=="1"||!e.SHENNIAN_HOME?.trim()||a.resolve(n)===a.resolve(t))return!1;const s=a.relative(a.resolve(r),a.resolve(n));return s!==""&&s!==".."&&!s.startsWith(`..${a.sep}`)&&!a.isAbsolute(s)||a.resolve(n)===a.resolve(e.SHENNIAN_HOME)}function ee(e=process.env,n=h){return!Z(e,n)}function Ve(e=process.env,n=h){return!Z(e,n)}function f(e={}){let n=A(),r=n?.pid??null,t=r!==null&&v(r),s=r!==null&&!t,i=n?.adopted===!0;const l=B();if(s&&e.cleanupStale){try{o.unlinkSync(y)}catch{}n=null,r=null,t=!1,s=!1}if(!t&&ee()){const E=Q()[0];if(E&&(r=E,t=!0,s=!1,i=!0,e.cleanupStale)){const W=Ue();je(E,W,{launcher:C(E),adopted:!0}),z(E,C(E)),n={pid:E,instanceId:W,adopted:!0}}}return{running:t,pid:r,stale:s,remoteAccessDisabled:Oe(),launcher:Be(r,t),platform:p(),shennianDir:h,pidFile:y,logFile:m,...n?.instanceId?{instanceId:n.instanceId}:{},...i?{adopted:!0}:{},...l.machineId?{machineId:l.machineId}:{},paired:!!(l.machineToken&&l.machineId),...l.serverUrl?{serverUrl:l.serverUrl}:{}}}function w(e){process.stdout.write(`${JSON.stringify(e,null,2)}
2
+ `)}function ne(e){const n=e?.trim();if(!n)return;const r=B();r.serverUrl=n,we(r)}function te(e){return e?.trim()||process.env.SHENNIAN_DESKTOP_SERVER_URL?.trim()||void 0}const H="com.shennian.agent",g=a.join(d.homedir(),"Library/LaunchAgents",`${H}.plist`),re=S("Shennian.app"),Ge=a.join(d.homedir(),"AppData","Roaming","Microsoft","Windows","Start Menu","Programs","Startup"),_=S("autostart.cmd"),b=S("autostart.vbs"),R=S("autostart.xml"),Ke=a.join(Ge,"ShennianAgent.vbs");function oe(e){const n=p()==="win32"?`where ${e}`:`command -v ${e}`;try{return u(n,{stdio:["ignore","pipe","pipe"],encoding:"utf-8",windowsHide:!0}).split(/\r?\n/).map(s=>s.trim()).find(Boolean)??null}catch{return null}}function Je(){const e=p()==="win32"?"npx.cmd":"npx",n=a.join(a.dirname(J),e);return o.existsSync(n)?n:oe("npx")}function N(){return Te({nodeExec:J,scriptPath:K,shennianCommandPath:oe("shennian"),npxPath:Je(),desktopBridgePath:process.env.SHENNIAN_DESKTOP_CLI_BRIDGE})}function se(){try{u(`schtasks /delete /tn "${D}" /f`,{stdio:"pipe",windowsHide:!0})}catch{}}function ie(){try{o.unlinkSync(Ke)}catch{}}function qe(){const e=process.env.USERDOMAIN?.trim(),n=process.env.COMPUTERNAME?.trim(),r=process.env.USERNAME?.trim()||d.userInfo().username;return e&&e.toUpperCase()!=="WORKGROUP"?`${e}\\${r}`:n?`${n}\\${r}`:r}function Xe(e){if(p()==="win32"&&Ie(e.command)){const n=[e.command,...e.args].map(V).join(" ");return{command:process.env.ComSpec||"cmd.exe",args:["/d","/s","/c",`"${n}"`],windowsVerbatimArguments:!0}}return{command:e.command,args:e.args}}function Ye(e,n,r=process.env){return{detached:!0,stdio:["ignore",n,n],env:r,windowsHide:!0,...e.windowsVerbatimArguments?{windowsVerbatimArguments:!0}:{}}}function ze(){const e=N();o.writeFileSync(_,ve(e,m)),o.writeFileSync(b,Ne(_)),ie(),se();const n=Ae({userId:qe(),command:a.join(process.env.SystemRoot||"C:\\Windows","System32","wscript.exe"),arguments:[V(b)]});o.writeFileSync(R,n,"utf8");const r=Pe({taskName:D,xmlPath:R});try{return u(r.create,{stdio:"pipe",windowsHide:!0}),u(r.run,{stdio:"pipe",windowsHide:!0}),!0}catch{return!1}}function Qe(){ke(D,e=>{u(e,{stdio:"pipe",windowsHide:!0})})}function ce(){const e={};for(const n of q)process.env[n]&&(e[n]=process.env[n]);if(e.HOME??=d.homedir(),e.PATH=Ee({pathValue:e.PATH,env:e}),e.USER??=d.userInfo().username,p()==="win32"){const n=process.env.TEMP||process.env.TMP||d.tmpdir(),r=d.homedir();e.USERPROFILE??=r;const t=a.win32.parse(r);e.HOMEDRIVE??=t.root.replace(/[\\/]$/,"")||process.env.HOMEDRIVE||"",e.HOMEPATH??=r.slice((e.HOMEDRIVE||"").length)||process.env.HOMEPATH||"",e.USERNAME??=process.env.USERNAME||d.userInfo().username,e.COMPUTERNAME??=process.env.COMPUTERNAME||"",e.TMPDIR??=n,e.TEMP??=n,e.TMP??=n}else e.TMPDIR??="/tmp";return e}function Ze(e={}){const n=ce(),r=e.launch??N(),t=Object.entries(n).map(([i,l])=>` <key>${x(i)}</key>
3
3
  <string>${x(l)}</string>`).join(`
4
4
  `),s=[r.command,...r.args].map(i=>` <string>${x(i)}</string>`).join(`
5
5
  `);return`<?xml version="1.0" encoding="UTF-8"?>
@@ -27,8 +27,8 @@ ${t}
27
27
  <key>StandardErrorPath</key>
28
28
  <string>${m}</string>
29
29
  </dict>
30
- </plist>`}function ce(e=te){o.rmSync(e,{recursive:!0,force:!0})}function en(e=p()){return e!=="darwin"?null:"macOS may show \u201CNode.js Foundation\u201D under Allow in the Background. This is the Node.js runtime used by Shennian Client."}const I=a.join(d.homedir(),".config/systemd/user/shennian.service");function nn(){const e=ie(),n=N(),r=Object.entries(e).map(([s,i])=>`Environment=${s}=${i}`).join(`
31
- `),t=[n.command,...n.args].map(Ie).join(" ");return`[Unit]
30
+ </plist>`}function ae(e=re){o.rmSync(e,{recursive:!0,force:!0})}function en(e=p()){return e!=="darwin"?null:"macOS may show \u201CNode.js Foundation\u201D under Allow in the Background. This is the Node.js runtime used by Shennian Client."}const I=a.join(d.homedir(),".config/systemd/user/shennian.service");function nn(){const e=ce(),n=N(),r=Object.entries(e).map(([s,i])=>`Environment=${s}=${i}`).join(`
31
+ `),t=[n.command,...n.args].map(De).join(" ");return`[Unit]
32
32
  Description=Shennian Agent Daemon
33
33
  After=network.target
34
34
 
@@ -41,6 +41,6 @@ StandardOutput=append:${m}
41
41
  StandardError=append:${m}
42
42
 
43
43
  [Install]
44
- WantedBy=default.target`}const D="ShennianAgent";function tn(e){u(e,{stdio:"pipe",windowsHide:!0})}function rn(){const e=process.getuid?.();if(typeof e=="number")return e;const n=d.userInfo();return typeof n.uid=="number"?n.uid:n.username}function P(e=rn()){return`gui/${e}/${H}`}function on(e=tn){try{return e(`launchctl enable "${P()}"; launchctl unload "${g}" 2>/dev/null; launchctl load -w "${g}"`),e(`launchctl kickstart -k "${P()}"`),!0}catch{try{return e(`launchctl enable "${P()}"`),e(`launchctl load -w "${g}"`),e(`launchctl kickstart -k "${P()}"`),!0}catch{return!1}}}function sn(){o.mkdirSync(h,{recursive:!0});const e={};for(const[n,r]of Object.entries(process.env))r!==void 0&&Re(n)&&(e[n]=r);o.writeFileSync(S("env.json"),JSON.stringify(e,null,2))}function ae(e={}){o.mkdirSync(h,{recursive:!0});const n=f({cleanupStale:!0});if(n.pid!==null&&n.running&&!$(n)){e.quiet||console.log(c.green(`\u2713 Background service already running (PID ${n.pid})`));return}ue(n);const r=o.openSync(m,"a"),t=Xe(N()),s=Se(t.command,t.args,Ye(t,r));s.unref(),o.closeSync(r),We(s.pid),e.quiet||(console.log(c.green(`\u2713 Background service started (PID ${s.pid})`)),console.log(c.gray(` Logs: ${m}`)))}function $(e,n=A(),r=G()){return e.pid===null||!e.running?!1:e.adopted===!0||n?.version!==r}function M(e=p()){switch(e){case"darwin":return o.existsSync(g)&&!o.existsSync(te);case"linux":return o.existsSync(I);case"win32":return o.existsSync(_)&&o.existsSync(b)&&o.existsSync(R)}}function cn(e,n,r,t=A(),s=G()){return!n.api?.trim()&&e.pid!==null&&e.running&&!e.stale&&!e.remoteAccessDisabled&&r&&!$(e,t,s)}function ue(e=f({cleanupStale:!0})){if(!(!$(e)||e.pid===null))try{process.kill(e.pid,"SIGTERM"),X(e.pid,5e3)||(process.kill(e.pid,"SIGKILL"),X(e.pid,2e3));try{A()?.pid===e.pid&&o.unlinkSync(y)}catch{}}catch{}}function de(e={}){if(o.mkdirSync(h,{recursive:!0}),!Ve())return!1;const n=p();switch(N().mode==="direct"&&O(K)&&console.warn(c.yellow("\u26A0 Warning: Current CLI path is temporary (npx). Auto-start may not work after reboot.\n Run `npm install -g shennian@latest` for reliable auto-start.")),n){case"darwin":{const t=a.dirname(g);o.mkdirSync(t,{recursive:!0}),ce(),o.writeFileSync(g,Ze());const s=on(),i=en(n);return!e.quiet&&i&&console.log(c.gray(`\u2139 ${i}`)),s}case"linux":{const t=a.dirname(I);o.mkdirSync(t,{recursive:!0}),o.writeFileSync(I,nn());try{u("systemctl --user daemon-reload && systemctl --user enable shennian",{stdio:"pipe",windowsHide:!0})}catch{return!1}try{u(`loginctl enable-linger ${d.userInfo().username}`,{stdio:"pipe",windowsHide:!0})}catch{}try{return u("systemctl --user restart shennian",{stdio:"pipe",windowsHide:!0}),!0}catch{return!1}}case"win32":return ze()}}function an(){const n=f({cleanupStale:!0}).pid;if(n===null)return{};if(!v(n)){try{o.unlinkSync(y)}catch{}return{stalePid:n}}try{return process.kill(n,"SIGTERM"),{stoppedPid:n}}catch(r){return{error:r instanceof Error?r.message:String(r)}}}async function le(e=5e3){const n=an();if(!n.stoppedPid)return n;if(!await j(n.stoppedPid,e))try{process.kill(n.stoppedPid,"SIGKILL"),await j(n.stoppedPid,2e3)}catch(t){return{...n,error:t instanceof Error?t.message:String(t)}}try{o.unlinkSync(y)}catch{}je();for(const t of Q())if(t!==n.stoppedPid)try{process.kill(t,"SIGTERM"),await j(t,2e3)}catch{}return n}function un(e={}){ee(ne(e.api)),Oe(),ue(),de({quiet:e.json})||ae({quiet:e.json}),e.json?w(T(()=>f({cleanupStale:!0}))):console.log(c.green("\u2713 Background service started"))}async function dn(e={}){const n=He(),r=$e(),t=await le(),s=f({cleanupStale:!0}),i=t.error??n.autoStartError??r.error;if(e.json){w(i?{...s,error:i}:s);return}i?console.error(c.red(`\u2717 Failed to stop completely: ${i}`)):console.log(c.green("\u2713 Background service stopped"))}function pe(e){const n=f({cleanupStale:!0});if(cn(n,e,M())){e.json?w(n):console.log(c.green(`\u2713 Background service already running (PID ${n.pid})`));return}sn(),un(e)}async function U(e={}){await dn(e)}async function j(e,n=5e3){const r=Date.now();for(;Date.now()-r<n;){if(!v(e))return!0;await new Promise(t=>setTimeout(t,100))}return!v(e)}async function ln(e={}){const n=f({cleanupStale:!0});if(n.remoteAccessDisabled){e.json?w({...n,error:"remote_access_disabled_use_shennian_start"}):console.error(c.yellow("Remote access is paused. Run `shennian start` on this computer to resume."));return}ee(ne(e.api));const r=p();r==="win32"&&Qe();const t=await le();if(t.error){e.json?w({...f(),error:t.error}):console.error(c.red(`\u2717 Failed to stop: ${t.error}`));return}if(t.stoppedPid!==void 0?e.json||console.log(c.green(`\u2713 Background service stopped (PID ${t.stoppedPid})`)):t.stalePid!==void 0?e.json||console.log(c.yellow(`\u26A0 Service process no longer exists, cleaned up stale PID ${t.stalePid}`)):e.json||console.log(c.gray("\u25CF Background service not running, starting it now")),(r==="linux"||r==="win32")&&de()){e.json&&w(T(()=>f({cleanupStale:!0})));return}ae({quiet:e.json}),e.json&&w(T(()=>f({cleanupStale:!0})))}function me(e={}){const n=f({cleanupStale:!0});if(e.json){w(n);return}if(n.pid===null){console.log(c.gray("\u25CF Background service not running"));return}n.running?(console.log(c.green(`\u25CF Background service running (PID ${n.pid})`)),console.log(c.gray(` Logs: ${m}`))):console.log(c.yellow(`\u25CF Background service stopped (PID ${n.pid} is stale)`))}function fe(e){if(!o.existsSync(m)){console.log(c.gray("No logs yet"));return}try{const n=u(d.platform()==="win32"?`powershell Get-Content -Tail ${e.lines} "${m}"`:`tail -n ${e.lines} "${m}"`,{encoding:"utf-8",windowsHide:!0});process.stdout.write(n)}catch{const n=o.readFileSync(m,"utf-8").split(`
44
+ WantedBy=default.target`}const D="ShennianAgent";function tn(e){u(e,{stdio:"pipe",windowsHide:!0})}function rn(){const e=process.getuid?.();if(typeof e=="number")return e;const n=d.userInfo();return typeof n.uid=="number"?n.uid:n.username}function P(e=rn()){return`gui/${e}/${H}`}function on(e=tn){try{return e(`launchctl enable "${P()}"; launchctl unload "${g}" 2>/dev/null; launchctl load -w "${g}"`),e(`launchctl kickstart -k "${P()}"`),!0}catch{try{return e(`launchctl enable "${P()}"`),e(`launchctl load -w "${g}"`),e(`launchctl kickstart -k "${P()}"`),!0}catch{return!1}}}function sn(){o.mkdirSync(h,{recursive:!0});const e={};for(const[n,r]of Object.entries(process.env))r!==void 0&&xe(n)&&(e[n]=r);o.writeFileSync(S("env.json"),JSON.stringify(e,null,2))}function ue(e={}){o.mkdirSync(h,{recursive:!0});const n=f({cleanupStale:!0});if(n.pid!==null&&n.running&&!$(n)){e.quiet||console.log(c.green(`\u2713 Background service already running (PID ${n.pid})`));return}de(n);const r=o.openSync(m,"a"),t=Xe(N()),s=he(t.command,t.args,Ye(t,r));s.unref(),o.closeSync(r),Fe(s.pid),e.quiet||(console.log(c.green(`\u2713 Background service started (PID ${s.pid})`)),console.log(c.gray(` Logs: ${m}`)))}function $(e,n=A(),r=G()){return e.pid===null||!e.running?!1:e.adopted===!0||n?.version!==r}function M(e=p()){switch(e){case"darwin":return o.existsSync(g)&&!o.existsSync(re);case"linux":return o.existsSync(I);case"win32":return o.existsSync(_)&&o.existsSync(b)&&o.existsSync(R)}}function cn(e,n,r,t=A(),s=G()){return!n.api?.trim()&&e.pid!==null&&e.running&&!e.stale&&!e.remoteAccessDisabled&&r&&!$(e,t,s)}function de(e=f({cleanupStale:!0})){if(!(!$(e)||e.pid===null))try{process.kill(e.pid,"SIGTERM"),X(e.pid,5e3)||(process.kill(e.pid,"SIGKILL"),X(e.pid,2e3));try{A()?.pid===e.pid&&o.unlinkSync(y)}catch{}}catch{}}function le(e={}){if(o.mkdirSync(h,{recursive:!0}),!Ve())return!1;const n=p();switch(N().mode==="direct"&&O(K)&&console.warn(c.yellow("\u26A0 Warning: Current CLI path is temporary (npx). Auto-start may not work after reboot.\n Run `npm install -g shennian@latest` for reliable auto-start.")),n){case"darwin":{const t=a.dirname(g);o.mkdirSync(t,{recursive:!0}),ae(),o.writeFileSync(g,Ze());const s=on(),i=en(n);return!e.quiet&&i&&console.log(c.gray(`\u2139 ${i}`)),s}case"linux":{const t=a.dirname(I);o.mkdirSync(t,{recursive:!0}),o.writeFileSync(I,nn());try{u("systemctl --user daemon-reload && systemctl --user enable shennian",{stdio:"pipe",windowsHide:!0})}catch{return!1}try{u(`loginctl enable-linger ${d.userInfo().username}`,{stdio:"pipe",windowsHide:!0})}catch{}try{return u("systemctl --user restart shennian",{stdio:"pipe",windowsHide:!0}),!0}catch{return!1}}case"win32":return ze()}}function an(){const n=f({cleanupStale:!0}).pid;if(n===null)return{};if(!v(n)){try{o.unlinkSync(y)}catch{}return{stalePid:n}}try{return process.kill(n,"SIGTERM"),{stoppedPid:n}}catch(r){return{error:r instanceof Error?r.message:String(r)}}}async function pe(e=5e3){const n=an();if(!n.stoppedPid)return n;if(!await j(n.stoppedPid,e))try{process.kill(n.stoppedPid,"SIGKILL"),await j(n.stoppedPid,2e3)}catch(t){return{...n,error:t instanceof Error?t.message:String(t)}}try{o.unlinkSync(y)}catch{}if(We(),ee()){for(const t of Q())if(t!==n.stoppedPid)try{process.kill(t,"SIGTERM"),await j(t,2e3)}catch{}}return n}function un(e={}){ne(te(e.api)),Ce(),de(),le({quiet:e.json})||ue({quiet:e.json}),e.json?w(T(()=>f({cleanupStale:!0}))):console.log(c.green("\u2713 Background service started"))}async function dn(e={}){const n=$e(),r=Me(),t=await pe(),s=f({cleanupStale:!0}),i=t.error??n.autoStartError??r.error;if(e.json){w(i?{...s,error:i}:s);return}i?console.error(c.red(`\u2717 Failed to stop completely: ${i}`)):console.log(c.green("\u2713 Background service stopped"))}function me(e){const n=f({cleanupStale:!0});if(cn(n,e,M())){e.json?w(n):console.log(c.green(`\u2713 Background service already running (PID ${n.pid})`));return}sn(),un(e)}async function U(e={}){await dn(e)}async function j(e,n=5e3){const r=Date.now();for(;Date.now()-r<n;){if(!v(e))return!0;await new Promise(t=>setTimeout(t,100))}return!v(e)}async function ln(e={}){const n=f({cleanupStale:!0});if(n.remoteAccessDisabled){e.json?w({...n,error:"remote_access_disabled_use_shennian_start"}):console.error(c.yellow("Remote access is paused. Run `shennian start` on this computer to resume."));return}ne(te(e.api));const r=p();r==="win32"&&Qe();const t=await pe();if(t.error){e.json?w({...f(),error:t.error}):console.error(c.red(`\u2717 Failed to stop: ${t.error}`));return}if(t.stoppedPid!==void 0?e.json||console.log(c.green(`\u2713 Background service stopped (PID ${t.stoppedPid})`)):t.stalePid!==void 0?e.json||console.log(c.yellow(`\u26A0 Service process no longer exists, cleaned up stale PID ${t.stalePid}`)):e.json||console.log(c.gray("\u25CF Background service not running, starting it now")),(r==="linux"||r==="win32")&&le()){e.json&&w(T(()=>f({cleanupStale:!0})));return}ue({quiet:e.json}),e.json&&w(T(()=>f({cleanupStale:!0})))}function fe(e={}){const n=f({cleanupStale:!0});if(e.json){w(n);return}if(n.pid===null){console.log(c.gray("\u25CF Background service not running"));return}n.running?(console.log(c.green(`\u25CF Background service running (PID ${n.pid})`)),console.log(c.gray(` Logs: ${m}`))):console.log(c.yellow(`\u25CF Background service stopped (PID ${n.pid} is stale)`))}function Se(e){if(!o.existsSync(m)){console.log(c.gray("No logs yet"));return}try{const n=u(d.platform()==="win32"?`powershell Get-Content -Tail ${e.lines} "${m}"`:`tail -n ${e.lines} "${m}"`,{encoding:"utf-8",windowsHide:!0});process.stdout.write(n)}catch{const n=o.readFileSync(m,"utf-8").split(`
45
45
  `).slice(-e.lines);console.log(n.join(`
46
- `))}}async function pn(){switch(await U(),p()){case"darwin":{if(o.existsSync(g)){try{u(`launchctl unload -w "${g}"`,{stdio:"pipe",windowsHide:!0})}catch{}o.unlinkSync(g)}ce(),console.log(c.green("\u2713 Auto-start uninstalled (launchd)"));break}case"linux":{try{u("systemctl --user disable --now shennian",{stdio:"pipe",windowsHide:!0})}catch{}if(o.existsSync(I)){o.unlinkSync(I);try{u("systemctl --user daemon-reload",{stdio:"pipe",windowsHide:!0})}catch{}}console.log(c.green("\u2713 Auto-start uninstalled (systemd)"));break}case"win32":{oe();try{o.unlinkSync(_)}catch{}try{o.unlinkSync(b)}catch{}try{o.unlinkSync(R)}catch{}se(),console.log(c.green("\u2713 Auto-start uninstalled (Task Scheduler)"));break}}}function kn(e){e.command("start").description("Start the background service").option("--json","Print machine-readable status JSON").option("--api <url>","Server URL override").action(t=>pe(t)),e.command("stop").description("Stop the background service").option("--json","Print machine-readable status JSON").action(t=>U(t)),e.command("status").description("Show background service status").option("--json","Print machine-readable status JSON").action(t=>me(t)),e.command("logs").description("Show recent logs").option("-n, --lines <n>","Number of lines","50").action(t=>fe({lines:parseInt(t.lines,10)}));const n=e.command("daemon",{hidden:!0}).description("Deprecated: use top-level start/stop/status/logs"),r=(t,s)=>{s||console.error(c.yellow(`\u26A0 Deprecated command. Use \`shennian ${t}\` instead.`))};n.command("start").description("Start the background service").option("--json","Print machine-readable status JSON").option("--api <url>","Server URL override").action(t=>{r("start",t.json),pe(t)}),n.command("stop").description("Stop the background service").option("--json","Print machine-readable status JSON").action(async t=>{r("stop",t.json),await U(t)}),n.command("restart").description("Restart the background service").option("--json","Print machine-readable status JSON").option("--api <url>","Server URL override").action(t=>{r("stop && shennian start",t.json),ln(t)}),n.command("status").description("Show background service status").option("--json","Print machine-readable status JSON").action(t=>{r("status",t.json),me(t)}),n.command("logs").description("Show recent logs").option("-n, --lines <n>","Number of lines","50").action(t=>{r("logs"),fe({lines:parseInt(t.lines,10)})}),n.command("uninstall").description("Uninstall auto-start service").action(pn)}export{Ye as buildDaemonSpawnOptions,Ze as buildMacLaunchdPlist,nn as buildSystemdUnit,Rn as buildWindowsLauncherCommand,xn as buildWindowsScheduledTaskCommands,Tn as buildWindowsScheduledTaskSuspendCommands,Ln as buildWindowsScheduledTaskXml,On as buildWindowsStartupVbs,cn as canReuseRunningDaemonForStart,ie as captureEnvForService,je as clearDaemonLauncher,Dn as clearDaemonPidIfOwner,Oe as clearRemoteAccessDisabled,Me as createDaemonInstanceId,Q as findRunningDaemonProcessIds,Y as getCurrentProcessDaemonLauncher,f as getDaemonStatus,P as getLaunchdServiceTarget,en as getMacBackgroundItemNotice,de as installService,M as isAutoStartServicePresent,O as isEphemeralCliPath,Z as isIsolatedDaemonE2eInstance,Le as isRemoteAccessDisabled,Re as isSafeSnapshotEnvKey,$n as isShennianRunServiceCommand,He as prepareRemoteAccessPause,We as recordStartedDaemon,kn as registerDaemonCommand,on as reloadLaunchdAgent,ce as removeLegacyMacBackgroundApp,xe as resolveServiceLaunchSpec,sn as saveEnvSnapshot,Be as shouldDiscoverGlobalDaemonProcesses,Ve as shouldInstallPlatformService,$ as shouldReplaceRunningDaemon,ae as startDaemonProcess,$e as stopPreparedRemoteAccessService,Cn as suspendWindowsScheduledTask,z as writeDaemonLauncher,Ue as writeDaemonPid};
46
+ `))}}async function pn(){switch(await U(),p()){case"darwin":{if(o.existsSync(g)){try{u(`launchctl unload -w "${g}"`,{stdio:"pipe",windowsHide:!0})}catch{}o.unlinkSync(g)}ae(),console.log(c.green("\u2713 Auto-start uninstalled (launchd)"));break}case"linux":{try{u("systemctl --user disable --now shennian",{stdio:"pipe",windowsHide:!0})}catch{}if(o.existsSync(I)){o.unlinkSync(I);try{u("systemctl --user daemon-reload",{stdio:"pipe",windowsHide:!0})}catch{}}console.log(c.green("\u2713 Auto-start uninstalled (systemd)"));break}case"win32":{se();try{o.unlinkSync(_)}catch{}try{o.unlinkSync(b)}catch{}try{o.unlinkSync(R)}catch{}ie(),console.log(c.green("\u2713 Auto-start uninstalled (Task Scheduler)"));break}}}function kn(e){e.command("start").description("Start the background service").option("--json","Print machine-readable status JSON").option("--api <url>","Server URL override").action(t=>me(t)),e.command("stop").description("Stop the background service").option("--json","Print machine-readable status JSON").action(t=>U(t)),e.command("status").description("Show background service status").option("--json","Print machine-readable status JSON").action(t=>fe(t)),e.command("logs").description("Show recent logs").option("-n, --lines <n>","Number of lines","50").action(t=>Se({lines:parseInt(t.lines,10)}));const n=e.command("daemon",{hidden:!0}).description("Deprecated: use top-level start/stop/status/logs"),r=(t,s)=>{s||console.error(c.yellow(`\u26A0 Deprecated command. Use \`shennian ${t}\` instead.`))};n.command("start").description("Start the background service").option("--json","Print machine-readable status JSON").option("--api <url>","Server URL override").action(t=>{r("start",t.json),me(t)}),n.command("stop").description("Stop the background service").option("--json","Print machine-readable status JSON").action(async t=>{r("stop",t.json),await U(t)}),n.command("restart").description("Restart the background service").option("--json","Print machine-readable status JSON").option("--api <url>","Server URL override").action(t=>{r("stop && shennian start",t.json),ln(t)}),n.command("status").description("Show background service status").option("--json","Print machine-readable status JSON").action(t=>{r("status",t.json),fe(t)}),n.command("logs").description("Show recent logs").option("-n, --lines <n>","Number of lines","50").action(t=>{r("logs"),Se({lines:parseInt(t.lines,10)})}),n.command("uninstall").description("Uninstall auto-start service").action(pn)}export{Ye as buildDaemonSpawnOptions,Ze as buildMacLaunchdPlist,nn as buildSystemdUnit,Rn as buildWindowsLauncherCommand,xn as buildWindowsScheduledTaskCommands,Tn as buildWindowsScheduledTaskSuspendCommands,Ln as buildWindowsScheduledTaskXml,On as buildWindowsStartupVbs,cn as canReuseRunningDaemonForStart,ce as captureEnvForService,We as clearDaemonLauncher,Dn as clearDaemonPidIfOwner,Ce as clearRemoteAccessDisabled,Ue as createDaemonInstanceId,Q as findRunningDaemonProcessIds,Y as getCurrentProcessDaemonLauncher,f as getDaemonStatus,P as getLaunchdServiceTarget,en as getMacBackgroundItemNotice,le as installService,M as isAutoStartServicePresent,O as isEphemeralCliPath,Z as isIsolatedDaemonE2eInstance,Oe as isRemoteAccessDisabled,xe as isSafeSnapshotEnvKey,$n as isShennianRunServiceCommand,$e as prepareRemoteAccessPause,Fe as recordStartedDaemon,kn as registerDaemonCommand,on as reloadLaunchdAgent,ae as removeLegacyMacBackgroundApp,Te as resolveServiceLaunchSpec,sn as saveEnvSnapshot,ee as shouldDiscoverGlobalDaemonProcesses,Ve as shouldInstallPlatformService,$ as shouldReplaceRunningDaemon,ue as startDaemonProcess,Me as stopPreparedRemoteAccessService,Cn as suspendWindowsScheduledTask,z as writeDaemonLauncher,je as writeDaemonPid};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shennian",
3
- "version": "0.4.21",
3
+ "version": "0.4.23",
4
4
  "description": "Shennian — AI Agent Control Plane CLI",
5
5
  "type": "module",
6
6
  "bin": {