shennian 0.3.41 → 0.3.42
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.
|
@@ -74,6 +74,12 @@ export declare function startDaemonProcess(opts?: {
|
|
|
74
74
|
export declare function shouldReplaceRunningDaemon(status: Pick<DaemonStatus, 'pid' | 'running' | 'adopted'>, record?: {
|
|
75
75
|
version?: string;
|
|
76
76
|
} | null, currentVersion?: string): boolean;
|
|
77
|
+
export declare function isAutoStartServicePresent(platform?: Platform): boolean;
|
|
78
|
+
export declare function canReuseRunningDaemonForStart(status: Pick<DaemonStatus, 'pid' | 'running' | 'stale' | 'remoteAccessDisabled' | 'adopted'>, opts: {
|
|
79
|
+
api?: string;
|
|
80
|
+
}, servicePresent: boolean, record?: {
|
|
81
|
+
version?: string;
|
|
82
|
+
} | null, currentVersion?: string): boolean;
|
|
77
83
|
/**
|
|
78
84
|
* Install the platform-native auto-start service.
|
|
79
85
|
* Returns true if the service was immediately started (so caller can skip startDaemonProcess).
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import
|
|
2
|
-
`)}function
|
|
3
|
-
<string>${
|
|
4
|
-
`),r=[n.command,...n.args].map(
|
|
1
|
+
import c from"chalk";import i from"node:fs";import s from"node:path";import u from"node:os";import{execSync as a,spawn as de}from"node:child_process";import{randomUUID as le}from"node:crypto";import{fileURLToPath as pe}from"node:url";import{getShennianDir as me,loadConfig as j,resolveShennianPath as h,saveConfig as fe}from"../config/index.js";import{buildAugmentedPath as Se}from"../env-path.js";import{buildWindowsLauncherCommand as he,buildWindowsScheduledTaskCommands as ge,buildWindowsScheduledTaskXml as we,buildWindowsStartupVbs as ye,escapeXml as T,isWindowsCmdScript as ve,quoteCmdArg as W,quoteSystemdArg as Ee,suspendWindowsScheduledTask as Pe}from"./daemon-windows.js";import{waitForDaemonReadyStatus as L}from"./daemon-start-wait.js";import{findRunningWindowsDaemonProcessIds as Ae,isShennianRunServiceCommand as Ie}from"./daemon-process.js";import{getCurrentVersion as F}from"../upgrade/engine.js";import{buildWindowsLauncherCommand as An,buildWindowsScheduledTaskCommands as In,buildWindowsScheduledTaskSuspendCommands as kn,buildWindowsScheduledTaskXml as Dn,buildWindowsStartupVbs as Nn,suspendWindowsScheduledTask as bn}from"./daemon-windows.js";import{isShennianRunServiceCommand as Tn}from"./daemon-process.js";const ke=s.dirname(pe(import.meta.url)),S=me(),g=h("daemon.pid"),d=h("daemon.log"),x=h("remote-access.disabled"),D=h("daemon-launcher.json"),B=s.resolve(ke,"../../bin/shennian.js"),V=process.execPath,J=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","SHENNIAN_DESKTOP_SERVER_URL","SHENNIAN_WECHAT_CHANNEL_HELPER_DIR","SHENNIAN_HOME","SHENNIAN_NATIVE_FUSION_DISABLED","SHENNIAN_WECHAT_DELIVERABILITY_TRACE"]);function De(e){return J.has(e)}function l(){const e=u.platform();return e==="darwin"||e==="linux"||e==="win32"?e:"linux"}function O(e){const n=e.replace(/\\/g,"/").toLowerCase(),t=u.tmpdir().replace(/\\/g,"/").toLowerCase();return n.includes("/_npx/")||n.includes("/npm-cache/_npx/")||n.includes("/pnpm/dlx/")||n.startsWith(t.endsWith("/")?t:`${t}/`)}function Ne(e){return i.existsSync(e.scriptPath)&&!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 be(e){const n=e.trim();if(!n)return null;if(n.startsWith("{"))try{const r=JSON.parse(n),o=Number(r.pid);return!Number.isInteger(o)||o<=0?null:{pid:o,...typeof r.instanceId=="string"?{instanceId:r.instanceId}:{},...typeof r.version=="string"?{version:r.version}:{},...r.launcher==="desktop-managed"||r.launcher==="global-cli"||r.launcher==="unknown"?{launcher:r.launcher}:{},...typeof r.startedAt=="string"?{startedAt:r.startedAt}:{},...r.adopted===!0?{adopted:!0}:{}}}catch{return null}const t=parseInt(n,10);return isNaN(t)?null:{pid:t}}function P(){try{return be(i.readFileSync(g,"utf-8"))}catch{return null}}function E(e){try{return process.kill(e,0),!0}catch{return!1}}function G(e,n=3e3){const t=Date.now();for(;Date.now()-t<n;){if(!E(e))return!0;Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,100)}return!E(e)}function Re(){return i.existsSync(x)}function Te(){try{i.unlinkSync(x)}catch{}}function K(){return"global-cli"}function Le(){return`${process.pid}-${Date.now()}-${le()}`}function xe(e,n,t={}){i.mkdirSync(S,{recursive:!0}),i.writeFileSync(g,JSON.stringify({pid:e,instanceId:n,...t.version?{version:t.version}:{},launcher:t.launcher??K(),...t.adopted?{adopted:!0}:{},startedAt:new Date().toISOString()},null,2))}function yn(e,n){const t=P();if(!(t?.pid!==e||t.instanceId!==n))try{i.unlinkSync(g)}catch{}}function X(e,n=K(),t){i.mkdirSync(S,{recursive:!0}),i.writeFileSync(D,JSON.stringify({pid:e,launcher:n,...t?{instanceId:t}:{},updatedAt:new Date().toISOString()},null,2))}function Oe(e){if(e)try{if(JSON.parse(i.readFileSync(D,"utf-8")).instanceId!==e)return}catch{return}try{i.unlinkSync(D)}catch{}}function He(e){e&&X(e)}function _e(e,n){if(!e||!n)return"unknown";try{const t=JSON.parse(i.readFileSync(D,"utf-8"));if(t.pid!==e)return"unknown";if(t.launcher==="desktop-managed"||t.launcher==="global-cli")return t.launcher}catch{}return H(e)}function H(e){if(l()==="win32")return"unknown";try{const n=a(`ps -p ${e} -o command=`,{encoding:"utf-8",stdio:["ignore","pipe","ignore"],timeout:1e3,windowsHide:!0}).replace(/\\/g,"/");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(l()==="win32")return Ae(e);try{return a("ps -axo pid=,command=",{encoding:"utf-8",stdio:["ignore","pipe","ignore"],timeout:1e3,windowsHide:!0}).split(/\r?\n/).map(t=>{const r=t.trim().match(/^(\d+)\s+(.+)$/);if(!r)return null;const o=Number(r[1]),f=r[2];return!Number.isInteger(o)||o===e?null:Ie(f)?o:null}).filter(t=>typeof t=="number")}catch{return[]}}function $e(e=process.env,n=S,t=u.tmpdir(),r=s.join(u.homedir(),".shennian")){if(e.SHENNIAN_E2E_ISOLATED_DAEMON!=="1"||!e.SHENNIAN_HOME?.trim()||s.resolve(n)===s.resolve(r))return!1;const o=s.relative(s.resolve(t),s.resolve(n));return o!==""&&o!==".."&&!o.startsWith(`..${s.sep}`)&&!s.isAbsolute(o)||s.resolve(n)===s.resolve(e.SHENNIAN_HOME)}function Ce(e=process.env,n=S){return!$e(e,n)}function m(e={}){let n=P(),t=n?.pid??null,r=t!==null&&E(t),o=t!==null&&!r,f=n?.adopted===!0;const v=j();if(o&&e.cleanupStale){try{i.unlinkSync(g)}catch{}n=null,t=null,r=!1,o=!1}if(!r&&Ce()){const w=q()[0];if(w&&(t=w,r=!0,o=!1,f=!0,e.cleanupStale)){const U=Le();xe(w,U,{launcher:H(w),adopted:!0}),X(w,H(w)),n={pid:w,instanceId:U,adopted:!0}}}return{running:r,pid:t,stale:o,remoteAccessDisabled:Re(),launcher:_e(t,r),platform:l(),shennianDir:S,pidFile:g,logFile:d,...n?.instanceId?{instanceId:n.instanceId}:{},...f?{adopted:!0}:{},...v.machineId?{machineId:v.machineId}:{},paired:!!(v.machineToken&&v.machineId),...v.serverUrl?{serverUrl:v.serverUrl}:{}}}function y(e){process.stdout.write(`${JSON.stringify(e,null,2)}
|
|
2
|
+
`)}function Y(e){const n=e?.trim();if(!n)return;const t=j();t.serverUrl=n,fe(t)}function z(e){return e?.trim()||process.env.SHENNIAN_DESKTOP_SERVER_URL?.trim()||void 0}const _="com.shennian.agent",p=s.join(u.homedir(),"Library/LaunchAgents",`${_}.plist`),Me=s.join(u.homedir(),"AppData","Roaming","Microsoft","Windows","Start Menu","Programs","Startup"),N=h("autostart.cmd"),b=h("autostart.vbs"),R=h("autostart.xml"),Ue=s.join(Me,"ShennianAgent.vbs");function Q(e){const n=l()==="win32"?`where ${e}`:`command -v ${e}`;try{return a(n,{stdio:["ignore","pipe","pipe"],encoding:"utf-8",windowsHide:!0}).split(/\r?\n/).map(o=>o.trim()).find(Boolean)??null}catch{return null}}function je(){const e=l()==="win32"?"npx.cmd":"npx",n=s.join(s.dirname(V),e);return i.existsSync(n)?n:Q("npx")}function A(){return Ne({nodeExec:V,scriptPath:B,shennianCommandPath:Q("shennian"),npxPath:je()})}function Z(){try{a(`schtasks /delete /tn "${k}" /f`,{stdio:"pipe",windowsHide:!0})}catch{}}function ee(){try{i.unlinkSync(Ue)}catch{}}function We(){const e=process.env.USERDOMAIN?.trim(),n=process.env.COMPUTERNAME?.trim(),t=process.env.USERNAME?.trim()||u.userInfo().username;return e&&e.toUpperCase()!=="WORKGROUP"?`${e}\\${t}`:n?`${n}\\${t}`:t}function Fe(e){if(l()==="win32"&&ve(e.command)){const n=[e.command,...e.args].map(W).join(" ");return{command:process.env.ComSpec||"cmd.exe",args:["/d","/s","/c",`"${n}"`],windowsVerbatimArguments:!0}}return{command:e.command,args:e.args}}function Be(e,n,t=process.env){return{detached:!0,stdio:["ignore",n,n],env:t,windowsHide:!0,...e.windowsVerbatimArguments?{windowsVerbatimArguments:!0}:{}}}function Ve(){const e=A();i.writeFileSync(N,he(e,d)),i.writeFileSync(b,ye(N)),ee(),Z();const n=we({userId:We(),command:s.join(process.env.SystemRoot||"C:\\Windows","System32","wscript.exe"),arguments:[W(b)]});i.writeFileSync(R,n,"utf8");const t=ge({taskName:k,xmlPath:R});try{return a(t.create,{stdio:"pipe",windowsHide:!0}),a(t.run,{stdio:"pipe",windowsHide:!0}),!0}catch{return!1}}function Je(){Pe(k,e=>{a(e,{stdio:"pipe",windowsHide:!0})})}function ne(){const e={};for(const n of J)process.env[n]&&(e[n]=process.env[n]);if(e.HOME??=u.homedir(),e.PATH=Se({pathValue:e.PATH,env:e}),e.USER??=u.userInfo().username,l()==="win32"){const n=process.env.TEMP||process.env.TMP||u.tmpdir(),t=u.homedir();e.USERPROFILE??=t;const r=s.win32.parse(t);e.HOMEDRIVE??=r.root.replace(/[\\/]$/,"")||process.env.HOMEDRIVE||"",e.HOMEPATH??=t.slice((e.HOMEDRIVE||"").length)||process.env.HOMEPATH||"",e.USERNAME??=process.env.USERNAME||u.userInfo().username,e.COMPUTERNAME??=process.env.COMPUTERNAME||"",e.TMPDIR??=n,e.TEMP??=n,e.TMP??=n}else e.TMPDIR??="/tmp";return e}function Ge(){const e=ne(),n=A(),t=Object.entries(e).map(([o,f])=>` <key>${T(o)}</key>
|
|
3
|
+
<string>${T(f)}</string>`).join(`
|
|
4
|
+
`),r=[n.command,...n.args].map(o=>` <string>${T(o)}</string>`).join(`
|
|
5
5
|
`);return`<?xml version="1.0" encoding="UTF-8"?>
|
|
6
6
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
7
7
|
<plist version="1.0">
|
|
8
8
|
<dict>
|
|
9
9
|
<key>Label</key>
|
|
10
|
-
<string>${
|
|
10
|
+
<string>${_}</string>
|
|
11
11
|
<key>ProgramArguments</key>
|
|
12
12
|
<array>
|
|
13
13
|
${r}
|
|
@@ -27,8 +27,8 @@ ${t}
|
|
|
27
27
|
<key>StandardErrorPath</key>
|
|
28
28
|
<string>${d}</string>
|
|
29
29
|
</dict>
|
|
30
|
-
</plist>`}const
|
|
31
|
-
`),r=[n.command,...n.args].map(
|
|
30
|
+
</plist>`}const I=s.join(u.homedir(),".config/systemd/user/shennian.service");function Ke(){const e=ne(),n=A(),t=Object.entries(e).map(([o,f])=>`Environment=${o}=${f}`).join(`
|
|
31
|
+
`),r=[n.command,...n.args].map(Ee).join(" ");return`[Unit]
|
|
32
32
|
Description=Shennian Agent Daemon
|
|
33
33
|
After=network.target
|
|
34
34
|
|
|
@@ -41,6 +41,6 @@ StandardOutput=append:${d}
|
|
|
41
41
|
StandardError=append:${d}
|
|
42
42
|
|
|
43
43
|
[Install]
|
|
44
|
-
WantedBy=default.target`}const
|
|
44
|
+
WantedBy=default.target`}const k="ShennianAgent";function Xe(e){a(e,{stdio:"pipe",windowsHide:!0})}function qe(){const e=process.getuid?.();if(typeof e=="number")return e;const n=u.userInfo();return typeof n.uid=="number"?n.uid:n.username}function te(e=qe()){return`gui/${e}/${_}`}function Ye(e=Xe){try{return e(`launchctl unload "${p}" 2>/dev/null; launchctl load -w "${p}"`),e(`launchctl kickstart -k "${te()}"`),!0}catch{try{return e(`launchctl load -w "${p}"`),e(`launchctl kickstart -k "${te()}"`),!0}catch{return!1}}}function ze(){i.mkdirSync(S,{recursive:!0});const e={};for(const[n,t]of Object.entries(process.env))t!==void 0&&De(n)&&(e[n]=t);i.writeFileSync(h("env.json"),JSON.stringify(e,null,2))}function re(e={}){i.mkdirSync(S,{recursive:!0});const n=m({cleanupStale:!0});if(n.pid!==null&&n.running&&!$(n)){e.quiet||console.log(c.green(`\u2713 Background service already running (PID ${n.pid})`));return}ie(n);const t=i.openSync(d,"a"),r=Fe(A()),o=de(r.command,r.args,Be(r,t));o.unref(),i.closeSync(t),He(o.pid),e.quiet||(console.log(c.green(`\u2713 Background service started (PID ${o.pid})`)),console.log(c.gray(` Logs: ${d}`)))}function $(e,n=P(),t=F()){return e.pid===null||!e.running?!1:e.adopted===!0||n?.version!==t}function Qe(e=l()){switch(e){case"darwin":return i.existsSync(p);case"linux":return i.existsSync(I);case"win32":return i.existsSync(N)&&i.existsSync(b)&&i.existsSync(R)}}function Ze(e,n,t,r=P(),o=F()){return!n.api?.trim()&&e.pid!==null&&e.running&&!e.stale&&!e.remoteAccessDisabled&&t&&!$(e,r,o)}function ie(e=m({cleanupStale:!0})){if(!(!$(e)||e.pid===null))try{process.kill(e.pid,"SIGTERM"),G(e.pid,5e3)||(process.kill(e.pid,"SIGKILL"),G(e.pid,2e3));try{P()?.pid===e.pid&&i.unlinkSync(g)}catch{}}catch{}}function oe(){i.mkdirSync(S,{recursive:!0});const e=l();switch(A().mode==="direct"&&O(B)&&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.")),e){case"darwin":{const t=s.dirname(p);return i.mkdirSync(t,{recursive:!0}),i.writeFileSync(p,Ge()),Ye()}case"linux":{const t=s.dirname(I);i.mkdirSync(t,{recursive:!0}),i.writeFileSync(I,Ke());try{a("systemctl --user daemon-reload && systemctl --user enable shennian",{stdio:"pipe",windowsHide:!0})}catch{return!1}try{a(`loginctl enable-linger ${u.userInfo().username}`,{stdio:"pipe",windowsHide:!0})}catch{}try{return a("systemctl --user restart shennian",{stdio:"pipe",windowsHide:!0}),!0}catch{return!1}}case"win32":return Ve()}}function en(){const n=m({cleanupStale:!0}).pid;if(n===null)return{};if(!E(n)){try{i.unlinkSync(g)}catch{}return{stalePid:n}}try{return process.kill(n,"SIGTERM"),{stoppedPid:n}}catch(t){return{error:t instanceof Error?t.message:String(t)}}}async function se(e=5e3){const n=en();if(!n.stoppedPid)return n;if(!await M(n.stoppedPid,e))try{process.kill(n.stoppedPid,"SIGKILL"),await M(n.stoppedPid,2e3)}catch(r){return{...n,error:r instanceof Error?r.message:String(r)}}try{i.unlinkSync(g)}catch{}Oe();for(const r of q())if(r!==n.stoppedPid)try{process.kill(r,"SIGTERM"),await M(r,2e3)}catch{}return n}function nn(e={}){Y(z(e.api)),Te(),ie(),oe()||re({quiet:e.json}),e.json?y(L(()=>m({cleanupStale:!0}))):console.log(c.green("\u2713 Background service started"))}async function tn(e={}){switch(i.mkdirSync(S,{recursive:!0}),i.writeFileSync(x,new Date().toISOString()),l()){case"darwin":{if(i.existsSync(p))try{a(`launchctl unload -w "${p}"`,{stdio:"pipe",windowsHide:!0})}catch{}break}case"linux":{try{a("systemctl --user disable --now shennian",{stdio:"pipe",windowsHide:!0})}catch{}break}case"win32":{try{a(`schtasks /change /tn "${k}" /disable`,{stdio:"pipe",windowsHide:!0})}catch{}try{a(`schtasks /end /tn "${k}"`,{stdio:"pipe",windowsHide:!0})}catch{}break}}const t=await se(),r=m({cleanupStale:!0});if(e.json){y(t.error?{...r,error:t.error}:r);return}t.error?console.error(c.red(`\u2717 Failed to stop: ${t.error}`)):console.log(c.green("\u2713 Background service stopped"))}function ce(e){const n=m({cleanupStale:!0});if(Ze(n,e,Qe())){e.json?y(n):console.log(c.green(`\u2713 Background service already running (PID ${n.pid})`));return}ze(),nn(e)}async function C(e={}){await tn(e)}async function M(e,n=5e3){const t=Date.now();for(;Date.now()-t<n;){if(!E(e))return!0;await new Promise(r=>setTimeout(r,100))}return!E(e)}async function rn(e={}){Y(z(e.api));const n=l();n==="win32"&&Je();const t=await se();if(t.error){e.json?y({...m(),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")),(n==="linux"||n==="win32")&&oe()){e.json&&y(L(()=>m({cleanupStale:!0})));return}re({quiet:e.json}),e.json&&y(L(()=>m({cleanupStale:!0})))}function ae(e={}){const n=m({cleanupStale:!0});if(e.json){y(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: ${d}`))):console.log(c.yellow(`\u25CF Background service stopped (PID ${n.pid} is stale)`))}function ue(e){if(!i.existsSync(d)){console.log(c.gray("No logs yet"));return}try{const n=a(u.platform()==="win32"?`powershell Get-Content -Tail ${e.lines} "${d}"`:`tail -n ${e.lines} "${d}"`,{encoding:"utf-8",windowsHide:!0});process.stdout.write(n)}catch{const n=i.readFileSync(d,"utf-8").split(`
|
|
45
45
|
`).slice(-e.lines);console.log(n.join(`
|
|
46
|
-
`))}}async function
|
|
46
|
+
`))}}async function on(){switch(await C(),l()){case"darwin":{if(i.existsSync(p)){try{a(`launchctl unload -w "${p}"`,{stdio:"pipe",windowsHide:!0})}catch{}i.unlinkSync(p),console.log(c.green("\u2713 Auto-start uninstalled (launchd)"))}break}case"linux":{try{a("systemctl --user disable --now shennian",{stdio:"pipe",windowsHide:!0})}catch{}if(i.existsSync(I)){i.unlinkSync(I);try{a("systemctl --user daemon-reload",{stdio:"pipe",windowsHide:!0})}catch{}}console.log(c.green("\u2713 Auto-start uninstalled (systemd)"));break}case"win32":{Z();try{i.unlinkSync(N)}catch{}try{i.unlinkSync(b)}catch{}try{i.unlinkSync(R)}catch{}ee(),console.log(c.green("\u2713 Auto-start uninstalled (Task Scheduler)"));break}}}function vn(e){e.command("start").description("Start the background service").option("--json","Print machine-readable status JSON").option("--api <url>","Server URL override").action(r=>ce(r)),e.command("stop").description("Stop the background service").option("--json","Print machine-readable status JSON").action(r=>C(r)),e.command("status").description("Show background service status").option("--json","Print machine-readable status JSON").action(r=>ae(r)),e.command("logs").description("Show recent logs").option("-n, --lines <n>","Number of lines","50").action(r=>ue({lines:parseInt(r.lines,10)}));const n=e.command("daemon",{hidden:!0}).description("Deprecated: use top-level start/stop/status/logs"),t=(r,o)=>{o||console.error(c.yellow(`\u26A0 Deprecated command. Use \`shennian ${r}\` instead.`))};n.command("start").description("Start the background service").option("--json","Print machine-readable status JSON").option("--api <url>","Server URL override").action(r=>{t("start",r.json),ce(r)}),n.command("stop").description("Stop the background service").option("--json","Print machine-readable status JSON").action(async r=>{t("stop",r.json),await C(r)}),n.command("restart").description("Restart the background service").option("--json","Print machine-readable status JSON").option("--api <url>","Server URL override").action(r=>{t("stop && shennian start",r.json),rn(r)}),n.command("status").description("Show background service status").option("--json","Print machine-readable status JSON").action(r=>{t("status",r.json),ae(r)}),n.command("logs").description("Show recent logs").option("-n, --lines <n>","Number of lines","50").action(r=>{t("logs"),ue({lines:parseInt(r.lines,10)})}),n.command("uninstall").description("Uninstall auto-start service").action(on)}export{Be as buildDaemonSpawnOptions,An as buildWindowsLauncherCommand,In as buildWindowsScheduledTaskCommands,kn as buildWindowsScheduledTaskSuspendCommands,Dn as buildWindowsScheduledTaskXml,Nn as buildWindowsStartupVbs,Ze as canReuseRunningDaemonForStart,ne as captureEnvForService,Oe as clearDaemonLauncher,yn as clearDaemonPidIfOwner,Te as clearRemoteAccessDisabled,Le as createDaemonInstanceId,q as findRunningDaemonProcessIds,K as getCurrentProcessDaemonLauncher,m as getDaemonStatus,te as getLaunchdServiceTarget,oe as installService,Qe as isAutoStartServicePresent,O as isEphemeralCliPath,$e as isIsolatedDaemonE2eInstance,Re as isRemoteAccessDisabled,De as isSafeSnapshotEnvKey,Tn as isShennianRunServiceCommand,He as recordStartedDaemon,vn as registerDaemonCommand,Ye as reloadLaunchdAgent,Ne as resolveServiceLaunchSpec,ze as saveEnvSnapshot,Ce as shouldDiscoverGlobalDaemonProcesses,$ as shouldReplaceRunningDaemon,re as startDaemonProcess,bn as suspendWindowsScheduledTask,X as writeDaemonLauncher,xe as writeDaemonPid};
|