shennian 0.5.52 → 0.5.53

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.
@@ -496,8 +496,8 @@
496
496
  },
497
497
  {
498
498
  "file": "src/commands/daemon-process.js",
499
- "beforeBytes": 7019,
500
- "afterBytes": 3895
499
+ "beforeBytes": 7623,
500
+ "afterBytes": 4114
501
501
  },
502
502
  {
503
503
  "file": "src/commands/daemon-service-spec.js",
@@ -511,8 +511,8 @@
511
511
  },
512
512
  {
513
513
  "file": "src/commands/daemon-state.js",
514
- "beforeBytes": 10460,
515
- "afterBytes": 5023
514
+ "beforeBytes": 10537,
515
+ "afterBytes": 5070
516
516
  },
517
517
  {
518
518
  "file": "src/commands/daemon-stop-ipc.js",
@@ -761,8 +761,8 @@
761
761
  },
762
762
  {
763
763
  "file": "src/guides/personal.js",
764
- "beforeBytes": 12413,
765
- "afterBytes": 21939
764
+ "beforeBytes": 12584,
765
+ "afterBytes": 22248
766
766
  },
767
767
  {
768
768
  "file": "src/guides/types.js",
@@ -771,8 +771,8 @@
771
771
  },
772
772
  {
773
773
  "file": "src/index.js",
774
- "beforeBytes": 46204,
775
- "afterBytes": 22618
774
+ "beforeBytes": 46161,
775
+ "afterBytes": 22666
776
776
  },
777
777
  {
778
778
  "file": "src/local-apps/service.js",
@@ -1 +1 @@
1
- import{execFileSync as u}from"node:child_process";import l from"node:os";const d=5e3;function m(e){try{const n=["$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue'",`try { $rows = @(Get-CimInstance Win32_Process -Filter 'ProcessId = ${e}' -ErrorAction Stop)`,`[ordered]@{ pid = ${e}; queryCompleted = $true; running = ($rows.Count -gt 0) } | ConvertTo-Json -Compress`,"} catch { exit 1 }"].join("; "),r=u("powershell.exe",["-NoProfile","-NonInteractive","-Command",n],{encoding:"utf8",stdio:["ignore","pipe","ignore"],timeout:d,windowsHide:!0}),t=JSON.parse(r.trim());return t?.pid===e&&t.queryCompleted===!0&&typeof t.running=="boolean"?t.running:null}catch{return null}}function $(e){if(!Number.isSafeInteger(e)||e<=0)return!1;try{return process.kill(e,0),!0}catch(n){const r=n&&typeof n=="object"&&"code"in n?n.code:null;return r==="ESRCH"?!1:(r==="EPERM"||r==="EACCES")&&l.platform()==="win32"?m(e)??!0:!0}}function p(e){const n=e.replace(/\\/g,"/").trim();return g(n)||h(n)||S(n)||a(n,"shennian")||a(n,"npx")}function y(e){const n=e.replace(/\\/g,"/").toLowerCase();return n.includes("/cli-bridge.js")||n.includes("/resources/daemon/")?"desktop-managed":n.includes("/node_modules/shennian/")||n.includes("/bin/shennian")||n.includes(" shennian run-service")||n.includes(" shennian.js run-service")?"global-cli":"unknown"}function f(e,n=process.pid){let r;try{r=JSON.parse(C(e))}catch{return[]}return(Array.isArray(r)?r:r?[r]:[]).map(i=>{if(!i||typeof i!="object")return null;const o=i,s=Number(o.ProcessId),c=typeof o.CommandLine=="string"?o.CommandLine:"";return!Number.isInteger(s)||s<=0||s===n?null:p(c)?s:null}).filter(i=>typeof i=="number")}function C(e){const n=e.trim(),r=[...n].map((s,c)=>s==="["||s==="{"?c:-1).find(s=>s>=0)??-1;if(r<0)return n;const i=n[r]==="["?"]":"}",o=n.lastIndexOf(i);return o>=r?n.slice(r,o+1):n.slice(r)}function w(e=process.pid){try{const n=["$ProgressPreference = 'SilentlyContinue'","Get-CimInstance Win32_Process | Where-Object { $_.CommandLine -match 'run-service' } | Select-Object ProcessId,CommandLine | ConvertTo-Json -Compress"].join("; "),r=u("powershell.exe",["-NoProfile","-NonInteractive","-Command",n],{encoding:"utf8",stdio:["ignore","pipe","ignore"],timeout:d,windowsHide:!0});return f(r,e)}catch{return[]}}function v(e){if(!Number.isSafeInteger(e)||e<=0)return null;try{const n=["$ProgressPreference = 'SilentlyContinue'",`Get-CimInstance Win32_Process -Filter "ProcessId = ${e}" | Select-Object -ExpandProperty CommandLine`].join("; ");return u("powershell.exe",["-NoProfile","-NonInteractive","-Command",n],{encoding:"utf8",stdio:["ignore","pipe","ignore"],timeout:d,windowsHide:!0}).trim()||null}catch{return null}}function g(e){return/(?:^|["\s])[^"\s]*updater-worker\.js["\s]/i.test(e)&&/(?:^|["\s])--service(?:["\s]|$)/i.test(e)&&/(?:^|["\s])run-service(?:["\s]|$)/i.test(e)}function h(e){return/(?:^|["\s])[^"\s]*shennianclient\.exe["\s]/i.test(e)&&/(?:^|["\s])[^"\s]*cli-bridge\.js["\s]/i.test(e)&&/(?:^|["\s])[^"\s]*\/daemon\/dist\/bin\/shennian\.js["\s]/i.test(e)&&/(?:^|["\s])run-service(?:["\s]|$)/i.test(e)}function S(e){return/^"[^"]*\/node(?:\.exe)?"\s+"?[^"]*(?:\/node_modules\/shennian\/|\/dist\/bin\/shennian\.js|\/bin\/shennian)"?\s+run-service(?:\s|$)/i.test(e)||/^(?:\S*\/)?node(?:\.exe)?\s+\S*(?:\/node_modules\/shennian\/|\/dist\/bin\/shennian\.js|\/bin\/shennian)\s+run-service(?:\s|$)/i.test(e)}function a(e,n){const r=n==="shennian"?`${n}(?:\\.cmd|\\.exe)?`:`${n}(?:\\.cmd|\\.exe)?`,t=n==="npx"?"\\s+(?:--yes\\s+)?shennian\\s+run-service(?:\\s|$)":"\\s+run-service(?:\\s|$)";return new RegExp(`^"[^"]*\\/${r}"${t}`,"i").test(e)||new RegExp(`^(?:\\S*\\/)?${r}${t}`,"i").test(e)}export{w as findRunningWindowsDaemonProcessIds,y as inferDaemonLauncherFromCommand,$ as isDaemonProcessRunning,p as isShennianRunServiceCommand,f as parseWindowsDaemonProcessJson,v as readWindowsProcessCommand};
1
+ import{execFileSync as u}from"node:child_process";import d from"node:os";import l from"node:fs";const a=5e3;function p(e){if(d.platform()!=="linux")return!0;try{return l.readlinkSync(`/proc/${e}/ns/pid`)===l.readlinkSync("/proc/self/ns/pid")}catch{return!0}}function f(e){try{const n=["$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue'",`try { $rows = @(Get-CimInstance Win32_Process -Filter 'ProcessId = ${e}' -ErrorAction Stop)`,`[ordered]@{ pid = ${e}; queryCompleted = $true; running = ($rows.Count -gt 0) } | ConvertTo-Json -Compress`,"} catch { exit 1 }"].join("; "),r=u("powershell.exe",["-NoProfile","-NonInteractive","-Command",n],{encoding:"utf8",stdio:["ignore","pipe","ignore"],timeout:a,windowsHide:!0}),t=JSON.parse(r.trim());return t?.pid===e&&t.queryCompleted===!0&&typeof t.running=="boolean"?t.running:null}catch{return null}}function v(e){if(!Number.isSafeInteger(e)||e<=0||!p(e))return!1;try{return process.kill(e,0),!0}catch(n){const r=n&&typeof n=="object"&&"code"in n?n.code:null;return r==="ESRCH"?!1:(r==="EPERM"||r==="EACCES")&&d.platform()==="win32"?f(e)??!0:!0}}function C(e){const n=e.replace(/\\/g,"/").trim();return h(n)||x(n)||P(n)||m(n,"shennian")||m(n,"npx")}function b(e){const n=e.replace(/\\/g,"/").toLowerCase();return n.includes("/cli-bridge.js")||n.includes("/resources/daemon/")?"desktop-managed":n.includes("/node_modules/shennian/")||n.includes("/bin/shennian")||n.includes(" shennian run-service")||n.includes(" shennian.js run-service")?"global-cli":"unknown"}function g(e,n=process.pid){let r;try{r=JSON.parse(S(e))}catch{return[]}return(Array.isArray(r)?r:r?[r]:[]).map(i=>{if(!i||typeof i!="object")return null;const o=i,s=Number(o.ProcessId),c=typeof o.CommandLine=="string"?o.CommandLine:"";return!Number.isInteger(s)||s<=0||s===n?null:C(c)?s:null}).filter(i=>typeof i=="number")}function S(e){const n=e.trim(),r=[...n].map((s,c)=>s==="["||s==="{"?c:-1).find(s=>s>=0)??-1;if(r<0)return n;const i=n[r]==="["?"]":"}",o=n.lastIndexOf(i);return o>=r?n.slice(r,o+1):n.slice(r)}function I(e=process.pid){try{const n=["$ProgressPreference = 'SilentlyContinue'","Get-CimInstance Win32_Process | Where-Object { $_.CommandLine -match 'run-service' } | Select-Object ProcessId,CommandLine | ConvertTo-Json -Compress"].join("; "),r=u("powershell.exe",["-NoProfile","-NonInteractive","-Command",n],{encoding:"utf8",stdio:["ignore","pipe","ignore"],timeout:a,windowsHide:!0});return g(r,e)}catch{return[]}}function j(e){if(!Number.isSafeInteger(e)||e<=0)return null;try{const n=["$ProgressPreference = 'SilentlyContinue'",`Get-CimInstance Win32_Process -Filter "ProcessId = ${e}" | Select-Object -ExpandProperty CommandLine`].join("; ");return u("powershell.exe",["-NoProfile","-NonInteractive","-Command",n],{encoding:"utf8",stdio:["ignore","pipe","ignore"],timeout:a,windowsHide:!0}).trim()||null}catch{return null}}function h(e){return/(?:^|["\s])[^"\s]*updater-worker\.js["\s]/i.test(e)&&/(?:^|["\s])--service(?:["\s]|$)/i.test(e)&&/(?:^|["\s])run-service(?:["\s]|$)/i.test(e)}function x(e){return/(?:^|["\s])[^"\s]*shennianclient\.exe["\s]/i.test(e)&&/(?:^|["\s])[^"\s]*cli-bridge\.js["\s]/i.test(e)&&/(?:^|["\s])[^"\s]*\/daemon\/dist\/bin\/shennian\.js["\s]/i.test(e)&&/(?:^|["\s])run-service(?:["\s]|$)/i.test(e)}function P(e){return/^"[^"]*\/node(?:\.exe)?"\s+"?[^"]*(?:\/node_modules\/shennian\/|\/dist\/bin\/shennian\.js|\/bin\/shennian)"?\s+run-service(?:\s|$)/i.test(e)||/^(?:\S*\/)?node(?:\.exe)?\s+\S*(?:\/node_modules\/shennian\/|\/dist\/bin\/shennian\.js|\/bin\/shennian)\s+run-service(?:\s|$)/i.test(e)}function m(e,n){const r=n==="shennian"?`${n}(?:\\.cmd|\\.exe)?`:`${n}(?:\\.cmd|\\.exe)?`,t=n==="npx"?"\\s+(?:--yes\\s+)?shennian\\s+run-service(?:\\s|$)":"\\s+run-service(?:\\s|$)";return new RegExp(`^"[^"]*\\/${r}"${t}`,"i").test(e)||new RegExp(`^(?:\\S*\\/)?${r}${t}`,"i").test(e)}export{I as findRunningWindowsDaemonProcessIds,b as inferDaemonLauncherFromCommand,p as isDaemonProcessInCurrentNamespace,v as isDaemonProcessRunning,C as isShennianRunServiceCommand,g as parseWindowsDaemonProcessJson,j as readWindowsProcessCommand};
@@ -1 +1 @@
1
- import i from"node:fs";import c from"node:path";import f from"node:os";import{execSync as g}from"node:child_process";import{randomUUID as A}from"node:crypto";import{getShennianDir as O,loadConfig as b,resolveShennianPath as p}from"../config/index.js";import{findRunningWindowsDaemonProcessIds as P,inferDaemonLauncherFromCommand as w,isDaemonProcessRunning as k,isShennianRunServiceCommand as F,readWindowsProcessCommand as L}from"./daemon-process.js";const u=O(),l=p("daemon.pid"),R=p("daemon.log"),D=p("remote-access.disabled"),m=p("daemon-launcher.json");function h(){const e=f.platform();return e==="darwin"||e==="linux"||e==="win32"?e:"linux"}function _(e){const n=e.trim();if(!n)return null;if(n.startsWith("{"))try{const t=JSON.parse(n),o=Number(t.pid);return!Number.isInteger(o)||o<=0?null:{pid:o,...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 N(){try{return _(i.readFileSync(l,"utf-8"))}catch{return null}}function S(e){return k(e)}function z(e,n=3e3){const r=Date.now();for(;Date.now()-r<n;){if(!S(e))return!0;Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,100)}return!S(e)}function H(){try{return i.lstatSync(D),!0}catch(e){return!(e&&typeof e=="object"&&"code"in e&&e.code==="ENOENT")}}function K(){try{i.unlinkSync(D)}catch(e){if(e&&typeof e=="object"&&"code"in e&&e.code==="ENOENT")return;throw e}}function E(){return"global-cli"}function C(){return`${process.pid}-${Date.now()}-${A()}`}function T(e,n,r={}){i.mkdirSync(u,{recursive:!0}),i.writeFileSync(l,JSON.stringify({pid:e,instanceId:n,...r.version?{version:r.version}:{},launcher:r.launcher??E(),...r.adopted?{adopted:!0}:{},startedAt:new Date().toISOString()},null,2))}function Q(e,n){const r=N();if(!(r?.pid!==e||r.instanceId!==n))try{i.unlinkSync(l)}catch{}}function x(e,n=E(),r){i.mkdirSync(u,{recursive:!0}),i.writeFileSync(m,JSON.stringify({pid:e,launcher:n,...r?{instanceId:r}:{},updatedAt:new Date().toISOString()},null,2))}function X(e){if(e)try{if(JSON.parse(i.readFileSync(m,"utf-8")).instanceId!==e)return}catch{return}try{i.unlinkSync(m)}catch{}}function Y(e){e&&x(e)}function U(e,n){if(!e||!n)return"unknown";try{const r=JSON.parse(i.readFileSync(m,"utf-8"));if(r.pid!==e)return"unknown";if(r.launcher==="desktop-managed"||r.launcher==="global-cli")return r.launcher}catch{}return I(e)}function I(e){if(h()==="win32"){const n=L(e);return n?w(n):"unknown"}try{const n=g(`ps -p ${e} -o command=`,{encoding:"utf-8",stdio:["ignore","pipe","ignore"],timeout:1e3,windowsHide:!0}).replace(/\\/g,"/");return w(n)}catch{}return"unknown"}function $(e=process.pid){if(h()==="win32")return P(e);try{return g("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 o=Number(t[1]),d=t[2];return!Number.isInteger(o)||o===e?null:F(d)?o:null}).filter(r=>typeof r=="number")}catch{return[]}}function v(e=process.env,n=u,r=f.tmpdir(),t=c.join(f.homedir(),".shennian")){if(e.SHENNIAN_E2E_ISOLATED_DAEMON!=="1"||!e.SHENNIAN_HOME?.trim()||c.resolve(n)===c.resolve(t))return!1;const o=c.relative(c.resolve(r),c.resolve(n));return o!==""&&o!==".."&&!o.startsWith(`..${c.sep}`)&&!c.isAbsolute(o)||c.resolve(n)===c.resolve(e.SHENNIAN_HOME)}function J(e=process.env,n=u){return!v(e,n)}function Z(e=process.env,n=u){return e.SHENNIAN_DAEMON_SUPERVISOR!=="docker"&&!v(e,n)}function ee(e={}){let n=N(),r=n?.pid??null,t=r!==null&&S(r),o=r!==null&&!t,d=n?.adopted===!0;const s=b();if(o&&e.cleanupStale){try{i.unlinkSync(l)}catch{}n=null,r=null,t=!1,o=!1}if(!t&&J()){const a=$()[0];if(a&&(r=a,t=!0,o=!1,d=!0,e.cleanupStale)){const y=C();T(a,y,{launcher:I(a),adopted:!0}),x(a,I(a)),n={pid:a,instanceId:y,adopted:!0}}}return{running:t,pid:r,stale:o,remoteAccessDisabled:H(),launcher:U(r,t),...t&&n?.pid===r&&n.version?{daemonVersion:n.version}:{},platform:h(),shennianDir:u,pidFile:l,logFile:R,...n?.instanceId?{instanceId:n.instanceId}:{},...d?{adopted:!0}:{},...s.machineId?{machineId:s.machineId}:{},paired:!!(s.machineToken&&s.machineId),...s.serverUrl?{serverUrl:s.serverUrl}:{}}}export{m as LAUNCHER_FILE,R as LOG_FILE,l as PID_FILE,D as REMOTE_ACCESS_DISABLED_FILE,u as SHENNIAN_DIR,X as clearDaemonLauncher,Q as clearDaemonPidIfOwner,K as clearRemoteAccessDisabled,C as createDaemonInstanceId,$ as findRunningDaemonProcessIds,E as getCurrentProcessDaemonLauncher,ee as getDaemonStatus,h as getPlatform,v as isIsolatedDaemonE2eInstance,H as isRemoteAccessDisabled,S as isRunning,N as readPidRecord,Y as recordStartedDaemon,J as shouldDiscoverGlobalDaemonProcesses,Z as shouldInstallPlatformService,z as waitForPidExitSync,x as writeDaemonLauncher,T as writeDaemonPid};
1
+ import i from"node:fs";import c from"node:path";import f from"node:os";import{execSync as g}from"node:child_process";import{randomUUID as A}from"node:crypto";import{getShennianDir as O,loadConfig as P,resolveShennianPath as p}from"../config/index.js";import{findRunningWindowsDaemonProcessIds as b,inferDaemonLauncherFromCommand as w,isDaemonProcessInCurrentNamespace as k,isDaemonProcessRunning as F,isShennianRunServiceCommand as L,readWindowsProcessCommand as R}from"./daemon-process.js";const u=O(),l=p("daemon.pid"),_=p("daemon.log"),D=p("remote-access.disabled"),m=p("daemon-launcher.json");function h(){const e=f.platform();return e==="darwin"||e==="linux"||e==="win32"?e:"linux"}function H(e){const n=e.trim();if(!n)return null;if(n.startsWith("{"))try{const t=JSON.parse(n),o=Number(t.pid);return!Number.isInteger(o)||o<=0?null:{pid:o,...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 N(){try{return H(i.readFileSync(l,"utf-8"))}catch{return null}}function S(e){return F(e)}function K(e,n=3e3){const r=Date.now();for(;Date.now()-r<n;){if(!S(e))return!0;Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,100)}return!S(e)}function C(){try{return i.lstatSync(D),!0}catch(e){return!(e&&typeof e=="object"&&"code"in e&&e.code==="ENOENT")}}function Q(){try{i.unlinkSync(D)}catch(e){if(e&&typeof e=="object"&&"code"in e&&e.code==="ENOENT")return;throw e}}function E(){return"global-cli"}function T(){return`${process.pid}-${Date.now()}-${A()}`}function U(e,n,r={}){i.mkdirSync(u,{recursive:!0}),i.writeFileSync(l,JSON.stringify({pid:e,instanceId:n,...r.version?{version:r.version}:{},launcher:r.launcher??E(),...r.adopted?{adopted:!0}:{},startedAt:new Date().toISOString()},null,2))}function X(e,n){const r=N();if(!(r?.pid!==e||r.instanceId!==n))try{i.unlinkSync(l)}catch{}}function x(e,n=E(),r){i.mkdirSync(u,{recursive:!0}),i.writeFileSync(m,JSON.stringify({pid:e,launcher:n,...r?{instanceId:r}:{},updatedAt:new Date().toISOString()},null,2))}function Y(e){if(e)try{if(JSON.parse(i.readFileSync(m,"utf-8")).instanceId!==e)return}catch{return}try{i.unlinkSync(m)}catch{}}function Z(e){e&&x(e)}function $(e,n){if(!e||!n)return"unknown";try{const r=JSON.parse(i.readFileSync(m,"utf-8"));if(r.pid!==e)return"unknown";if(r.launcher==="desktop-managed"||r.launcher==="global-cli")return r.launcher}catch{}return I(e)}function I(e){if(h()==="win32"){const n=R(e);return n?w(n):"unknown"}try{const n=g(`ps -p ${e} -o command=`,{encoding:"utf-8",stdio:["ignore","pipe","ignore"],timeout:1e3,windowsHide:!0}).replace(/\\/g,"/");return w(n)}catch{}return"unknown"}function J(e=process.pid){if(h()==="win32")return b(e);try{return g("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 o=Number(t[1]),d=t[2];return!Number.isInteger(o)||o===e?null:L(d)&&k(o)?o:null}).filter(r=>typeof r=="number")}catch{return[]}}function v(e=process.env,n=u,r=f.tmpdir(),t=c.join(f.homedir(),".shennian")){if(e.SHENNIAN_E2E_ISOLATED_DAEMON!=="1"||!e.SHENNIAN_HOME?.trim()||c.resolve(n)===c.resolve(t))return!1;const o=c.relative(c.resolve(r),c.resolve(n));return o!==""&&o!==".."&&!o.startsWith(`..${c.sep}`)&&!c.isAbsolute(o)||c.resolve(n)===c.resolve(e.SHENNIAN_HOME)}function M(e=process.env,n=u){return!v(e,n)}function ee(e=process.env,n=u){return e.SHENNIAN_DAEMON_SUPERVISOR!=="docker"&&!v(e,n)}function ne(e={}){let n=N(),r=n?.pid??null,t=r!==null&&S(r),o=r!==null&&!t,d=n?.adopted===!0;const s=P();if(o&&e.cleanupStale){try{i.unlinkSync(l)}catch{}n=null,r=null,t=!1,o=!1}if(!t&&M()){const a=J()[0];if(a&&(r=a,t=!0,o=!1,d=!0,e.cleanupStale)){const y=T();U(a,y,{launcher:I(a),adopted:!0}),x(a,I(a)),n={pid:a,instanceId:y,adopted:!0}}}return{running:t,pid:r,stale:o,remoteAccessDisabled:C(),launcher:$(r,t),...t&&n?.pid===r&&n.version?{daemonVersion:n.version}:{},platform:h(),shennianDir:u,pidFile:l,logFile:_,...n?.instanceId?{instanceId:n.instanceId}:{},...d?{adopted:!0}:{},...s.machineId?{machineId:s.machineId}:{},paired:!!(s.machineToken&&s.machineId),...s.serverUrl?{serverUrl:s.serverUrl}:{}}}export{m as LAUNCHER_FILE,_ as LOG_FILE,l as PID_FILE,D as REMOTE_ACCESS_DISABLED_FILE,u as SHENNIAN_DIR,Y as clearDaemonLauncher,X as clearDaemonPidIfOwner,Q as clearRemoteAccessDisabled,T as createDaemonInstanceId,J as findRunningDaemonProcessIds,E as getCurrentProcessDaemonLauncher,ne as getDaemonStatus,h as getPlatform,v as isIsolatedDaemonE2eInstance,C as isRemoteAccessDisabled,S as isRunning,N as readPidRecord,Z as recordStartedDaemon,M as shouldDiscoverGlobalDaemonProcesses,ee as shouldInstallPlatformService,K as waitForPidExitSync,x as writeDaemonLauncher,U as writeDaemonPid};
@@ -13,7 +13,7 @@ const e=[{id:"computers",title:"\u8FDE\u63A5\u7535\u8111\u3001\u4E3B\u7535\u8111
13
13
  \u7FA4\u91CC\u9700\u8981\u67D0\u4E2A\u53D7\u7BA1\u667A\u80FD\u4F53\u5DE5\u4F5C\u65F6\uFF0C\u786E\u8BA4\u672C\u4EBA\u62E5\u6709\u7684\u667A\u80FD\u4F53\u548C\u7CBE\u786E\u7FA4\u804A\uFF0C\u5728\u8BE5\u7FA4\u63D0\u53CA\u76EE\u6807\u5B89\u6392\uFF0C\u7531\u5BF9\u5E94\u53D7\u7BA1\u4E0A\u4E0B\u6587\u64CD\u4F5C\u3002\u4E0D\u8981\u628A\u7BA1\u5BB6\u8BA1\u5212\u5F53\u6210\u7FA4\u8BA1\u5212\uFF0C\u4E0D\u7ED5\u8FC7\u6240\u6709\u6743\u3002
14
14
  \u79BB\u7EBF\u5230\u70B9\u8DF3\u8FC7\u3001\u4E0D\u7B49\u5F85\u4E0A\u7EBF\u548C\u8865\u8DD1\uFF1B\u6682\u505C/\u5220\u9664\u505C\u6B62\u672A\u6765\u89E6\u53D1\uFF0C\u4E0D\u64A4\u56DE\u5DF2\u5165\u961F\u6216\u5DF2\u5F00\u59CB\u5DE5\u4F5C\uFF1B\u6062\u590D\u4ECE\u672A\u6765\u65F6\u70B9\u7EE7\u7EED\u3002\u53EA\u6709\u771F\u5B9E\u4FDD\u5B58\u6210\u529F\u624D\u80FD\u8BF4\u5DF2\u5B89\u6392\uFF0C\u6295\u9012\u6210\u529F\u4E0D\u7B49\u4E8E\u5DE5\u4F5C\u5B8C\u6210\u3002\u65E0\u6CD5\u521B\u5EFA\u5C31\u660E\u786E\u8BF4\u660E\u5E76\u5F15\u5BFC\u6B63\u786E\u5165\u53E3\uFF0C\u4E0D\u53E3\u5934\u627F\u8BFA\u3002`},{id:"reminders",title:"\u624B\u673A\u65E5\u7A0B\u4E0E\u901A\u77E5\u63D0\u9192",summary:"\u786E\u8BA4\u65F6\u95F4\u548C\u91CD\u590D\u89C4\u5219\uFF0C\u5728\u65E5\u7A0B\u521B\u5EFA\u5E76\u68C0\u67E5\u901A\u77E5\u6743\u9650\u3002",keywords:["\u65E5\u7A0B","\u901A\u77E5","\u63D0\u9192","\u63A8\u9001","\u91CD\u590D\u63D0\u9192","reminder"],execution:"phone-guided",body:`# \u65E5\u7A0B\u4E0E\u901A\u77E5
15
15
  \u5148\u95EE\u63D0\u9192\u4EC0\u4E48\u3001\u4F55\u65F6\u3001\u65F6\u533A\u3001\u662F\u5426\u91CD\u590D\u53CA\u7ED3\u675F\u6761\u4EF6\uFF1B\u6A21\u7CCA\u65F6\u95F4\u5148\u786E\u8BA4\u3002\u624B\u673A \u529F\u80FD \u2192 \u65E5\u7A0B\uFF08\u6216\u65E5\u7A0B\u5E95\u90E8\u5165\u53E3\uFF09\u9ED8\u8BA4\u9010\u884C\u5F85\u529E\uFF0C\u53F3\u4E0A\u89D2\u8BBE\u7F6E\u53EF\u5207\u6362\u65E5\u5386/\u5F53\u5929/\u591A\u5929\u3002\u5E95\u90E8\u795E\u5FF5\u8F93\u5165\u680F\u6216\u53F3\u4E0A\u89D2\uFF0B\u7528\u6587\u5B57/\u8BED\u97F3\u5411\u4E3B Agent \u63D0\u51FA\u6DFB\u52A0\u8BF7\u6C42\uFF1B\u70B9\u884C\u4FEE\u6539\u6587\u5B57\u540E\u81EA\u52A8\u89E3\u6790\u4FDD\u5B58\u3002
16
- \u8BED\u97F3\u8F6C\u5199\u8BC6\u522B\u51FA\u7684\u65E5\u7A0B\u53EA\u662F\u5019\u9009\uFF0C\u5FC5\u987B\u8BA9\u7528\u6237\u786E\u8BA4\u540E\u624D\u521B\u5EFA\u3002\u63D0\u9192\u4E0E AI \u5DE5\u4F5C\u8C03\u5EA6\u662F\u4E0D\u540C\u6A21\u578B\uFF1B\u4E0D\u8981\u7528 AI \u5B9A\u65F6\u4EFB\u52A1\u5047\u88C5\u5DF2\u7ECF\u8BBE\u7F6E\u624B\u673A\u901A\u77E5\u3002\u795E\u5FF5\u4E3B Agent \u53EF\u7528 shennian reminder --operation list/preview/create/update/complete/restore/delete\uFF1B\u5148 help reminder \u6838\u5BF9\u5F53\u524D Client \u652F\u6301\u3002\u521B\u5EFA\u4F7F\u7528\u7A33\u5B9A --id\u3001--content\u3001--when\u3001--timezone\uFF0C\u4FEE\u6539\u5E26\u5217\u8868\u4E2D\u7684 --revision\uFF0C\u6A21\u7CCA\u65F6\u95F4\u5148\u8BE2\u95EE\uFF1B\u53EA\u5728\u771F\u5B9E\u4FDD\u5B58\u6210\u529F\u540E\u786E\u8BA4\u3002\u4E0D\u8BFB\u53D6\u624B\u673A Token\u3001\u4E0D\u76F4\u63A5\u6539\u4E1A\u52A1\u5E93\uFF1B\u65E7 Client \u4E0D\u652F\u6301\u65F6\u660E\u786E\u8BF4\u660E\u9700\u66F4\u65B0\u3002
16
+ \u8BED\u97F3\u8F6C\u5199\u8BC6\u522B\u51FA\u7684\u65E5\u7A0B\u53EA\u662F\u5019\u9009\uFF0C\u5FC5\u987B\u8BA9\u7528\u6237\u786E\u8BA4\u540E\u624D\u521B\u5EFA\u3002\u63D0\u9192\u4E0E AI \u5DE5\u4F5C\u8C03\u5EA6\u662F\u4E0D\u540C\u6A21\u578B\uFF1B\u4E0D\u8981\u7528 AI \u5B9A\u65F6\u4EFB\u52A1\u5047\u88C5\u5DF2\u7ECF\u8BBE\u7F6E\u624B\u673A\u901A\u77E5\u3002\u795E\u5FF5\u4E3B Agent \u53EF\u7528 shennian reminder --operation list/preview/create/update/complete/restore/delete\uFF1B\u5148 help reminder \u6838\u5BF9\u5F53\u524D Client \u652F\u6301\u3002\u521B\u5EFA\u4F7F\u7528\u7A33\u5B9A --id\u3001--content\u3001--when\u3001--timezone\uFF1B\u540C\u4E00\u4E8B\u9879\u6BCF\u5929\u591A\u6B21\u63D0\u9192\u5408\u4E3A\u4E00\u6761\uFF0C\u652F\u6301\u7684 Server \u4E0A\u53EF\u7528 --when "\u6BCF\u592909:00\u300112:30\u300118:30"\uFF0C\u52FF\u62C6\u6210\u4E09\u4E2A\u4E8B\u9879\uFF1B\u65E7\u670D\u52A1\u4E0D\u652F\u6301\u65F6\u660E\u786E\u8BF4\u660E\uFF0C\u4FEE\u6539\u5E26\u5217\u8868\u4E2D\u7684 --revision\uFF0C\u6A21\u7CCA\u65F6\u95F4\u5148\u8BE2\u95EE\uFF1B\u53EA\u5728\u771F\u5B9E\u4FDD\u5B58\u6210\u529F\u540E\u786E\u8BA4\u3002\u4E0D\u8BFB\u53D6\u624B\u673A Token\u3001\u4E0D\u76F4\u63A5\u6539\u4E1A\u52A1\u5E93\uFF1B\u65E7 Client \u4E0D\u652F\u6301\u65F6\u660E\u786E\u8BF4\u660E\u9700\u66F4\u65B0\u3002
17
17
  \u68C0\u67E5\u624B\u673A\u901A\u77E5\u6743\u9650\uFF1B\u672C\u5730\u201C\u4FDD\u5B58\u6210\u529F\u201D\u3001\u670D\u52A1\u7AEF\u6295\u9012\u3001\u624B\u673A\u6536\u5230\u548C\u7528\u6237\u5DF2\u8BFB\u662F\u4E0D\u540C\u72B6\u6001\u3002\u670D\u52A1\u4E0D\u652F\u6301\u3001\u79BB\u7EBF\u6216\u6743\u9650\u5173\u95ED\u65F6\u76F4\u8BF4\uFF0C\u4E0D\u80FD\u4FDD\u8BC1\u4EFB\u610F\u9501\u5C4F\u573A\u666F\u9001\u8FBE\u6216\u64AD\u62A5\u3002\u5F00\u53D1\u5019\u9009\u8BF4\u660E\u4E0D\u4EE3\u8868\u65E7\u6B63\u5F0F\u7248\u5DF2\u5177\u5907\u80FD\u529B\u3002
18
18
  \u53D6\u6D88/\u5220\u9664\u5148\u786E\u8BA4\u7CBE\u786E\u9879\uFF0C\u91CD\u590D\u63D0\u9192\u5148\u533A\u5206\u4E00\u6B21\u8FD8\u662F\u6574\u4E2A\u89C4\u5219\u3002\u4E0D\u8981\u628A\u7528\u6237\u8BF4\u201C\u5E2E\u6211\u8BB0\u4E0B\u201D\u9ED8\u8BA4\u53D8\u6210\u65E0\u9650\u91CD\u590D\u901A\u77E5\uFF0C\u4E5F\u4E0D\u8981\u66FF\u4ED6\u8BA2\u9605\u5176\u4ED6\u6E20\u9053\u3002`},{id:"recording",title:"\u5168\u5929\u5019\u5F55\u97F3\u3001\u8BED\u97F3\u8F93\u5165\u4E0E\u6574\u7406",summary:"\u7528\u6237\u4E3B\u52A8\u5F00\u5F55\uFF0C\u7406\u89E3\u8F6C\u5199\u3001\u539F\u97F3\u3001\u4E3B\u7535\u8111\u540C\u6B65\u548C\u9690\u79C1\u9650\u5236\u3002",keywords:["\u5F55\u97F3","\u8F6C\u5199","\u4F1A\u8BAE\u7EAA\u8981","\u5168\u5929\u5019","\u8BED\u97F3\u8F93\u5165","\u539F\u97F3","ASR"],execution:"mixed",body:`# \u5F55\u97F3\u4E0E\u8BED\u97F3
19
19
  \u624B\u673A \u795E\u5FF5 \u2192 \uFF0B \u2192 \u5168\u5929\u5019\u5F55\u97F3 \u6216 \u529F\u80FD \u2192 \u5168\u5929\u5019\u5F55\u97F3\uFF0C\u9700\u7528\u6237\u786E\u8BA4\u7528\u9014\u3001\u9EA6\u514B\u98CE\u6743\u9650\u548C\u76EE\u6807\u4E3B\u7535\u8111\u540E\u624B\u52A8\u5F00\u59CB\uFF1B\u754C\u9762\u53EF\u67E5\u770B\u8F6C\u5199\u3001\u72B6\u6001\u4E0E\u505C\u6B62\u3002\u8FDB\u7A0B\u91CD\u542F\u4E0D\u81EA\u52A8\u5F00\u9EA6\uFF0C\u4E0D\u58F0\u79F0\u5168\u5929\u540E\u53F0\u6C38\u4E0D\u95F4\u65AD\u3002\u795E\u5FF5\u8F93\u5165\u533A\u70B9\u6309\u7F16\u8F91\u3001\u957F\u6309\u8BF4\u8BDD\u3001\u677E\u5F00\u53D1\u9001\u8BC6\u522B\u6587\u5B57\uFF0C\u53D6\u6D88\u4E0D\u53D1\u9001\uFF1B\u4E0E\u5168\u5929\u5019\u5F55\u97F3\u5E76\u7528\u7684\u80FD\u529B\u4EE5\u5B9E\u9645\u7248\u672C\u4E3A\u51C6\u3002
package/dist/src/index.js CHANGED
@@ -1,3 +1,3 @@
1
- import{registerEnglishCommand as we}from"./commands/english.js";import{registerConfigCommand as Ce}from"./commands/config.js";import{registerLocalAppsCommand as Re}from"./commands/local-apps.js";import{registerReminderCommand as ke}from"./commands/reminder.js";import{personalScheduleHandlers as be}from"./schedules/personal-handlers.js";import{registerScheduleCommand as Ae}from"./commands/schedule.js";import{executeServerSchedule as Ee,deliverServerSchedule as Pe}from"./schedules/server-client.js";import{Command as Te}from"commander";import De from"chalk";import Me from"node:os";import{randomUUID as Ue}from"node:crypto";import z from"node:fs";import{loadConfig as p,getShennianDir as _e,resolveShennianPath as J,normalizeAutoUpgradePolicy as Ne}from"./config/index.js";import{CliRelayClient as Oe}from"./relay/client.js";import{collectKnownLogSecrets as xe,installCliLogRedaction as $e}from"./log-redaction.js";import{registerPairCommand as Le,runSmartStart as Ve}from"./commands/pair.js";import{registerLogoutCommand as je}from"./commands/logout.js";import{clearDaemonPidIfOwner as re,createDaemonInstanceId as He,clearDaemonLauncher as ae,findRunningDaemonProcessIds as Fe,isRemoteAccessDisabled as ie,prepareRemoteAccessPause as Be,stopPreparedRemoteAccessService as We,isIsolatedDaemonE2eInstance as Ge,getDaemonStatus as se,registerDaemonCommand as qe,writeDaemonPid as ce,writeDaemonLauncher as de}from"./commands/daemon.js";import{registerRuntimeCommand as Ke}from"./commands/runtime.js";import{registerAdapterCommand as ze}from"./commands/adapter.js";import{registerAgentCommand as Je}from"./commands/agent.js";import{registerManagerCommand as Qe}from"./commands/manager.js";import{registerWorkerCommand as Ye}from"./commands/worker.js";import{registerProjectCommand as Ze}from"./commands/project.js";import{createProjectCoordinationIpcHandlers as Xe}from"./project-coordination/ipc.js";import{registerStewardCommand as eo}from"./commands/steward.js";import{registerRecordingCommand as oo}from"./commands/recordings.js";import{handleUpgradeStart as to,registerUpgradeCommand as no}from"./commands/upgrade.js";import{registerToolsCommand as ro}from"./commands/tools.js";import{registerQueueCommand as ao}from"./commands/queue.js";import{registerSkillCommand as io}from"./commands/skill.js";import{refreshExistingSkillForHosts as so}from"./skill/hosts.js";import{registerSetupCommand as co}from"./commands/setup.js";import{getUnavailableAcpAgents as mo}from"./agents/acp/discovery.js";import{registerCommandReference as lo}from"./commands/command-reference.js";import{registerIntegrationCommand as po}from"./commands/integration.js";import{registerRoomCommand as go}from"./commands/room.js";import{registerContactCommand as uo}from"./commands/contact.js";import{registerSupportCommand as fo}from"./commands/support.js";import{SessionManager as ho}from"./session/manager.js";import{createTrustedProjectFsRequestResolver as vo}from"./session/handlers/project-fs.js";import{SERVERS as Io}from"./region.js";import{clearUpgradeAttempt as So,getCurrentVersion as me,handleStartupCrashCheck as yo,readUpgradeAttempt as wo}from"./upgrade/engine.js";import{AutoUpgradeScheduler as Co}from"./upgrade/scheduler.js";import{ensureUpdaterInstalled as Ro}from"./upgrade/updater-bootstrap.js";import{launchUpdater as ko,markUpdaterHealthy as bo}from"./upgrade/updater-launcher.js";import{detectAgents as le}from"./agents/detect.js";import{PublicAgentDeliveryWorker as Ao}from"./agents/public-delivery-worker.js";import{augmentProcessPath as pe}from"./env-path.js";import{acquireDaemonInstanceLock as Eo}from"./commands/daemon-instance-lock.js";pe();const T=me();import{getCachedAgentInfos as L,resolveAgentInfos as Po}from"./agents/model-registry.js";import{initCliLogReporter as To,reportLog as D,reportUpgradeAggregateMetric as Do}from"./log-reporter.js";import{isNativeFusionEnabled as Mo}from"./native-fusion/config.js";import{NativeSessionFusionService as Uo}from"./native-fusion/service.js";import{startDaemonLogRetention as _o}from"./daemon-log.js";import{startDaemonIpcServer as ge}from"./daemon-ipc/server.js";import{resolveDaemonIpcPaths as No,resolveManagedRoomIpcPaths as Oo}from"./daemon-ipc/paths.js";import{createDaemonControlHandlers as xo}from"./daemon-ipc/control.js";import{createAgentReadinessHandlers as $o}from"./daemon-ipc/agent-readiness.js";import{scanMachineAgents as ue}from"./session/handlers/agents.js";import{validateAgentWorkspaceConfiguration as Lo}from"./session/handlers/agent-workspace-validation.js";import{DAEMON_IPC_VERSION as Vo}from"./daemon-ipc/protocol.js";import{RoomSessionRegistry as jo}from"./room/session-registry.js";import{HttpRoomBindingClient as Ho}from"./room/room-binding-client.js";import{TrustedManagedRoomBinder as Fo}from"./room/managed-room-binding.js";import{RoomHostSessionObservationStore as Bo}from"./room/host-session-observations.js";import{RoomMirrorSyncService as Wo}from"./room/mirror-sync-service.js";import{handleLiveRoomDelivery as Go}from"./room/live-delivery.js";import{NativeSourceDeletionStore as qo}from"./native-fusion/native-source-deletions.js";import{matchesRoomOwner as Ko,isCurrentRegistration as zo}from"./room/registration-authority.js";import{RoomActivationService as Jo,resolveManagedAgentPolicy as Qo}from"./room/activation-service.js";import{prepareStandaloneAgentTurn as Yo}from"./room/standalone-agent-turn.js";import{RoomActivationAudit as Zo}from"./room/activation-audit.js";import{RoomAttachmentCache as Xo}from"./room/attachment-cache.js";import{RoomAttachmentUploader as et}from"./room/attachment-upload.js";import{ManagedRoomContextAuthority as ot}from"./room/managed-context.js";import{createManagedRoomExecutor as tt}from"./room/managed-room-ipc.js";import{SESSION_SYNC_PROTOCOL_VERSION as fe,SESSION_SYNC_ADVERTISED_CAPABILITIES as he}from"@shennian/wire";import{getDaemonInstallationId as nt}from"./session/store.js";import{OWNER_DIRECT_TURN_OPTIONS as rt}from"./session/queue-helpers.js";import{synchronizeMachinePersonalAuthority as at}from"./personal-sync/machine-authority.js";import{CLI_SESSION_SYNC_DATA_EPOCH as ve,ensurePersonalDataEpoch as it}from"./personal-sync/epoch.js";import{DeletionSyncRetryWaitError as st,DeletionSyncTerminalError as ct}from"./session/deletion-sync-state.js";const Ie=_e(),dt=J("daemon.pid"),mt=J("daemon.instance.lock");function lt(){try{const i=z.readFileSync(dt,"utf-8").trim();if(i.startsWith("{")){const f=JSON.parse(i),m=Number(f.pid);return Number.isInteger(m)&&m>0?m:null}const l=parseInt(i,10);return Number.isInteger(l)&&l>0?l:null}catch{return null}}function pt(i){return i.replace(/^https:\/\//,"wss://").replace(/^http:\/\//,"ws://")}function Q(){process.stdout.write(`${JSON.stringify({ok:!1,error:"integration_command_retired",message:"Room MCP and Hooks were retired. Use the Shennian Skill and CLI.",nextAction:{type:"open_install_guide",url:"https://shennian.net/install.md"}})}
2
- `),process.exitCode=1}function gt(i){const l=[`trigger=${i.trigger??"unknown"}`,`phase=${i.phase}`,`code=${i.code??"unknown"}`,`attempt=${i.reconnectAttempt}`];return i.reason&&l.push(`reason=${i.reason}`),i.error&&l.push(`error=${i.error}`),l.join(" ")}import{assertSingleServerBinding as V}from"./config/server-binding.js";const a=new Te;a.name("shennian").description("Shennian \u2014 AI Agent Control Plane").version(T),a.enablePositionalOptions(),a.hook("preAction",(i,l)=>{const f=l.optsWithGlobals(),m=p();for(const I of[f.api,f.server,process.env.SHENNIAN_DESKTOP_SERVER_URL])V(I,m)}),po(a),go(a),uo(a),fo(a),Ae(a),ke(a),a.option("--api <url>","Server URL override").option("--name <name>","Machine name",Me.hostname()).action(async i=>{const l=p(),f=V(i.api??process.env.SHENNIAN_DESKTOP_SERVER_URL??l.serverUrl??void 0,l);await Ve(f,i.name)}),a.command("run-service",{hidden:!0}).description("(internal) Connect to relay server, called by the background service").option("--api <url>","Server URL override").action(async i=>{const l=J("env.json");try{const e=JSON.parse(z.readFileSync(l,"utf-8"));for(const[t,o]of Object.entries(e))process.env[t]||(process.env[t]=o);pe()}catch{}$e(xe(process.env,p()));const f=_o();ie()&&(console.log(`[${new Date().toISOString()}] remote access disabled, service start skipped`),clearInterval(f),process.exit(0));const m=He(),I=Eo({lockPath:mt,instanceId:m});I.acquired||(console.log(`[${new Date().toISOString()}] daemon already running`+(I.ownerPid?` (PID ${I.ownerPid})`:"")+", skipping duplicate start"),clearInterval(f),process.exit(0));try{const e=lt();if(e&&e!==process.pid)try{process.kill(e,0),console.log(`[${new Date().toISOString()}] daemon already running (PID ${e}), skipping duplicate start`),I.release(),process.exit(0)}catch{}}catch{}const Y=Ge(process.env,Ie)?[]:Fe(process.pid);Y.length>0&&(console.log(`[${new Date().toISOString()}] daemon already running (PID ${Y[0]}), skipping duplicate start`),I.release(),process.exit(0)),ce(process.pid,m,{version:T}),de(process.pid,void 0,m),process.on("exit",()=>{re(process.pid,m),ae(m)}),process.on("exit",I.release);let j=null;try{j=Ro()}catch(e){console.error(`[upgrade] updater bootstrap unavailable: ${e instanceof Error?e.message:String(e)}`)}const M=await yo();if(M){j||(console.error("[upgrade] Crash-loop rollback blocked: updater bootstrap unavailable"),process.exit(1));try{ko({fromVersion:T,targetVersion:M.from,oldDaemonPid:process.pid,operation:"rollback",rollbackJobId:M.jobId},{readiness:j}),console.error(`[upgrade] New version crashed ${M.attemptCount} times; external rollback scheduled.`),process.stdin.resume();return}catch(e){console.error(`[upgrade] Crash-loop rollback could not start: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}}try{it()}catch(e){console.error(`[personal-sync] data epoch initialization failed: ${e instanceof Error?e.message:String(e)}`),process.exitCode=1;return}const s=p(),g=V(i.api??process.env.SHENNIAN_DESKTOP_SERVER_URL??s.serverUrl??Io.cn.url,s),h=me(),d=await le({serverUrl:g,authToken:s.machineToken??s.accessToken}),y=d.map(e=>e.type);let H=L(d);const v=new jo,U=new Bo,k=new ot(v);V(g,s);const w=new Ho(g),Se=new Xo({actionClient:w}),ye=new et({actionClient:w});let C=null,r;const Z=tt({authority:k,actionClient:w,attachmentCache:Se,attachmentUploader:ye,observations:U,getMachineCredentials:()=>({machineToken:p().machineToken}),managerExecutor:e=>r.executeManagedManagerAction(e),onSendOutcome:e=>r.noteManagedRoomSendOutcome(e),getActiveRunId:(e,t)=>r.getManagedRoomActiveRunId(e,t),scheduleExecutor:(e,t,o)=>Ee({serverUrl:g,machineToken:p().machineToken,sessionId:e,action:t,args:o}),onPaused:({registryKey:e,sessionId:t})=>{const n=v.getByRegistryKey(e)?.binding;n&&v.setBinding({registryKey:e,bindingId:n.bindingId,roomId:n.roomId,agentIdentityId:n.agentIdentityId,agentMembershipId:n.agentMembershipId,status:"paused",activationMode:"paused"}),k.revokeSession(e),r?.discardPendingManagedRoomMessages(t)}});let F=null,B=null,W=null,G=null,X=!1;const b=await ge({paths:No(),handlers:{...Xe(()=>r),...xo({daemonVersion:h,protocolVersion:Vo,getStatus:()=>se(),getAgents:()=>d,requestShutdown:()=>{G?G():X=!0},completeAgentAuthentication:e=>r.resumePendingAcpAuthentication(e),bindManagedRoom:e=>r.bindManagedRoomFromLocal(e),stewardSay:e=>r.stewardSayFromLocal(e),startUpgrade:async e=>{if(!F)throw new Error("upgrade_unavailable");return F(e)},prepareExternalUpgrade:e=>{if(!B)throw new Error("external_upgrade_unavailable");return B(e)},cancelExternalUpgrade:()=>{if(!W)throw new Error("external_upgrade_unavailable");return W()}}),...$o({getStatus:()=>se(),getSnapshot:()=>L(d).map(e=>{const t=d.find(o=>o.type===e.type);return{...e,runtimePlatform:t?.runtimePlatform,runtimeIsWsl:t?.runtimeIsWsl}}),getUnavailable:mo,discover:async e=>{if(!r)throw new Error("daemon_starting");const t=await ue(!0,e);if(e){const n=d.filter(u=>u.type!==e);d.splice(0,d.length,...n,...t.detectedAgents)}else d.splice(0,d.length,...t.detectedAgents);const o=L(d);return c.sendEvent({type:"event",event:"machine.agents",payload:{agentList:d.map(n=>n.type),agents:o}}),t.agents.map(n=>{const u=t.detectedAgents.find(K=>K.type===n.type);return{...n,runtimePlatform:u?.runtimePlatform,runtimeIsWsl:u?.runtimeIsWsl}})},validate:async e=>{if(!r)throw new Error("daemon_starting");return Lo(e,{ignoreNativeSession:(t,o)=>E?.ignoreNativeSource(t,o)})}})}});let A;try{A=await ge({paths:Oo(),handlers:{"managed-room.execute":e=>Z(e),...be(g,v)}})}catch(e){throw await b.close(),e}let ee=!1;const _=()=>{ee||(ee=!0,Promise.allSettled([b.close(),A.close()]).finally(()=>process.exit(0)))};if(process.once("SIGINT",_),process.once("SIGTERM",_),!s.machineToken){console.error('Shennian CLI is not paired. Run "shennian pair --browser" or "shennian pair --token" first.'),await Promise.allSettled([b.close(),A.close()]),process.exitCode=1;return}process.removeListener("SIGINT",_),process.removeListener("SIGTERM",_);const oe=`${pt(g)}/relay/machine`,N=s.machineToken;if(!N)return;try{await at({serverUrl:g,machineToken:N,machineId:s.machineId})}catch(e){console.error(`[personal-sync] machine authority verification failed: ${e instanceof Error?e.message:String(e)}`),await Promise.allSettled([b.close(),A.close()]),process.exit(1)}s.machineId&&To(g,s.machineId),console.log(`[${new Date().toISOString()}] Connecting to ${oe}... (v${h}) agents: ${y.join(",")}`),D({level:"info",wsEvent:"daemon.start",metadata:{version:h,agents:y}});let E=null,P=null,R=0,q=!1,S=wo();const te=Ne(s.autoUpgrade),O=s.machineId?new Ao({serverUrl:g,machineId:s.machineId,getMachineToken:()=>p().machineToken,getDetectedAgents:()=>le({serverUrl:g,authToken:p().machineToken}),onRuntimeChanged:async()=>{const e=R,t=await ue(!0);if(d.splice(0,d.length,...t.detectedAgents),y.splice(0,y.length,...t.agentList),H=t.agents,!(await c.sendReq({type:"req",id:Ue(),method:"machine.agents.report",params:{agents:t.agents}},2e4)).ok)throw new Error("machine_capability_report_rejected");e===R&&c.getState()==="connected"&&O?.start()},onError:()=>console.warn("[public-agent] delivery attempt failed")}):null,c=new Oe({serverUrl:oe,machineToken:N,cliVersion:h,agentList:y,autoUpgradePolicy:te,sessionSyncProtocolVersion:fe,sessionSyncCapabilities:he,daemonInstallationId:nt(),dataEpoch:ve,updaterProtocolVersion:1,onConnected:()=>{console.log(`[${new Date().toISOString()}] \u2713 Connected`),D({level:"info",wsEvent:"daemon.connected"}),c.sendEvent({type:"event",event:"machine.agents",payload:{agentList:y,agents:H}}),Po(d,{serverUrl:s.serverUrl??g,authToken:s.machineToken??s.accessToken}).then(o=>{JSON.stringify(o)!==JSON.stringify(H)&&c.sendEvent({type:"event",event:"machine.agents",payload:{agentList:y,agents:o}})}).catch(()=>{}),S&&c.sendEvent({type:"event",event:"upgrade",payload:{state:"recovering",machineId:"self",from:S.from,to:S.to,...S.jobId?{jobId:S.jobId}:{},activeRunCount:r.getPendingRecoveryCount()}}),x.start(),P?.start();const e=++R,t=async()=>{try{if(await r.synchronizeSessionDeletions(),await r.recoverInterruptedRuns(),S){const o=S;S=null,o.jobId&&bo(o.jobId,o.to),So(),console.log(`[${new Date().toISOString()}] [upgrade] ${o.operation==="rollback"?"Rolled back":"Healthy"}: ${o.from} \u2192 ${o.to}`),Do({kind:"upgrade",result:o.operation==="rollback"?"rolled_back":"healthy",stage:"terminal"}),c.sendEvent({type:"event",event:"upgrade",payload:{state:o.operation==="rollback"?"rolled_back":"healthy",machineId:"self",from:o.from,to:o.to,...o.jobId?{jobId:o.jobId}:{}}}),o.operation!=="rollback"&&c.sendEvent({type:"event",event:"upgrade",payload:{state:"success",machineId:"self",from:o.from,to:o.to}})}q||(q=!0,so({clientVersion:h}).then(o=>{const n=o.filter(u=>!u.ok||!["current","registered","updated"].includes(u.result.status));n.length>0&&console.warn(`[skill] ${n.length} installed Skill copies need attention; run shennian setup for details`)}).catch(()=>console.warn("[skill] Official Skill refresh failed; Client remains available")).finally(()=>{q=!1})),e===R&&c.getState()==="connected"&&(E?.handleConnected(),O?.start())}catch(o){if(console.error("[session.deletions] startup catch-up failed",o),e===R&&c.getState()==="connected"){if(o instanceof ct)return;const n=o instanceof st?Math.max(1e3,o.retryAfterMs):5e3;setTimeout(()=>{t()},n).unref?.()}}};t()},onDisconnected:e=>{R+=1,r?.revokeProjectFsHandles(),O?.stop(),P?.stop(),console.log(`[${new Date().toISOString()}] \u26A0 Disconnected, reconnecting... ${gt(e)}`),D({level:"warn",wsEvent:"daemon.disconnected",metadata:{code:e.code,reason:e.reason,error:e.error,phase:e.phase,trigger:e.trigger,reconnectAttempt:e.reconnectAttempt}})},onProjectFsCapabilityChanged:e=>{e||r?.revokeProjectFsHandles()},onReq:e=>{if(console.log(`[${new Date().toISOString()}] [req] ${e.method}`),D({level:"info",type:"ws",wsEvent:e.method,wsDirection:"in",traceId:e.traceId}),e.method==="room.message.deliver"){Go(c,P,e);return}r.handleReq(e)}});E=Mo()?new Uo(c):null,P=new Wo({registry:v,observations:U,actionClient:w,getMachineCredentials:()=>({machineToken:p().machineToken}),isSessionDeleted:e=>new qo().hasSession(e),onMessages:async(e,t,o,n)=>{await C?.processMessages(e,t,o,n)},onBindingPaused:e=>{e.lifecycleState==="closed"?(k.revokeSession(e.registryKey),r?.retireManagedRoomSession(e.nianSessionId).catch(()=>{console.warn("[room.sync] retired session cleanup failed")})):r?.discardPendingManagedRoomMessages(e.nianSessionId)}});const x=new Co({currentVersion:h,machineId:s.machineId??"unknown-machine",serverUrl:s.serverUrl??g,getIdleState:()=>r.getUpgradeIdleState(),sessionSyncProtocolVersion:fe,dataEpoch:ve,advertisedCapabilities:he,updaterProtocolVersion:1,startUpgrade:async(e,t)=>{const{handleUpgradeStart:o}=await import("./commands/upgrade.js");await o(c,"auto-upgrade",e,{currentVersion:h,prepareForUpgrade:n=>r.prepareForUpgrade(n),cancelUpgradePreparation:()=>r.cancelUpgradePreparation(),shutdownAfterHandoff:()=>{setTimeout(()=>process.kill(process.pid,"SIGTERM"),100).unref?.()},suppressResponse:!0,waitForCompletion:!0,canHandoff:t?void 0:()=>r.getUpgradeIdleState().idle})}});x.setPolicy(te),r=new ho(c,E,h,x,new Fo({registry:v,observations:U,bindingClient:w,getMachineCredentials:()=>{const e=p();return{machineId:e.machineId,machineToken:e.machineToken}},hostProcessIdentity:()=>`daemon:${m}`}),{prepare:()=>Be(),isDisabled:()=>ie(),shutdownAfterResponse:()=>{setTimeout(()=>{We(),process.kill(process.pid,"SIGTERM")},100).unref?.()}},e=>k.revokeToken(e),Z,null,vo(N),()=>L(d)),F=async e=>{const t=e&&typeof e=="object"&&!Array.isArray(e)?e:{},o=typeof t.targetVersion=="string"?t.targetVersion:void 0,n=t.confirmedMajor===!0;return await to(c,`local-upgrade-${Date.now()}`,o,{currentVersion:h,confirmedMajor:n,prepareForUpgrade:K=>r.prepareForUpgrade(K),cancelUpgradePreparation:()=>r.cancelUpgradePreparation(),shutdownAfterHandoff:()=>{setTimeout(()=>process.kill(process.pid,"SIGTERM"),100).unref?.()},suppressResponse:!0})},B=e=>{const t=e&&typeof e=="object"&&!Array.isArray(e)?e:{},n=`desktop-${(typeof t.targetVersion=="string"?t.targetVersion:"unknown").replace(/[^A-Za-z0-9._-]/g,"_")}-${Date.now()}`;return{jobId:n,...r.prepareForUpgrade(n)}},W=()=>(r.cancelUpgradePreparation(),{cancelled:!0}),C=new Jo({registry:v,observations:U,enqueueConversationBatch:e=>r.enqueueManagedRoomBatch(e),loadContext:async e=>{const t=p().machineToken?.trim(),o=e.binding;if(!t||!o)throw new Error("managed_room_context_unavailable");const n=await w.status({machineToken:t,roomId:o.roomId,bindingId:o.bindingId});if(!zo(v,e)||!Ko(e,n))throw new Error("managed_room_binding_unavailable");return{roomName:n.room.name,memberCount:n.room.memberCount,members:n.room.members,agentsByIdentityId:n.agent?{[n.agentIdentityId]:n.agent}:{},effectiveModelsBySessionId:n.effectiveModelId!==void 0?{[e.nianSessionId]:n.effectiveModelId}:void 0,agentSystemPromptsByIdentityId:n.agent?{[n.agentIdentityId]:n.agent.systemPrompt??""}:{}}},issueManagedRoomContext:(e,t,o,n)=>{const u=p().machineToken;if(!u)throw new Error("machine_not_authorized");return k.issue({registryKey:e,machineCredential:u,activationCauseMessageId:t,allowedActions:o,propagateWorkerRoomOrigin:n})},audit:new Zo,prepareUnboundDirectTurn:Yo,resolveManagedAgentPolicy:e=>Qo({...e,runtime:d.find(t=>t.type===e.registration.runtimeAdapter)})}),r.scheduleHandler=e=>Pe({serverUrl:g,machineToken:p().machineToken,req:e,client:c,queue:r.getScheduleQueue(),registry:v}),r.getScheduleQueue().validateScheduledTarget=async e=>{if(!e.bindingId||!e.roomId)return"ready";if(v.getByNianSessionId(e.sessionId)?.binding?.bindingId!==e.bindingId)return"ended";const o=await w.status({machineToken:p().machineToken,roomId:e.roomId,bindingId:e.bindingId});return o.status==="active"&&o.room.status==="active"?"ready":"ended"},r.setManagedRoomTurnPreparer(e=>C.prepareConversationTurn(e)),r.setManagedAgentDirectTurnPreparer((e,t)=>C.prepareDirectConversationTurn(e,t)),r.setManagedRecoveryPreparer(async e=>e.source==="managed_direct"?C.prepareDirectConversationTurn(e.sessionId,rt):e.source==="manager_event"?C.prepareDirectConversationTurn(e.sessionId,{allowedRoomActions:[],managerEvent:!0}):e.source!=="managed_room"||!e.roomContextRegistryKey||!e.activationCauseMessageId||!e.rootCauseMessageId||!e.activationSequence||e.activationHopCount===null?null:C.prepareConversationTurn([{registryKey:e.roomContextRegistryKey,causeMessageId:e.activationCauseMessageId,rootCauseMessageId:e.rootCauseMessageId,sequence:e.activationSequence,hopCount:e.activationHopCount}])),z.mkdirSync(Ie,{recursive:!0}),ce(process.pid,m,{version:h}),de(process.pid,void 0,m),c.connect(),process.stdin.resume();let ne=!1;const $=async()=>{if(!ne){ne=!0,console.log(De.gray(`
1
+ import{registerEnglishCommand as we}from"./commands/english.js";import{registerConfigCommand as Ce}from"./commands/config.js";import{registerLocalAppsCommand as Re}from"./commands/local-apps.js";import{registerReminderCommand as ke}from"./commands/reminder.js";import{personalScheduleHandlers as be}from"./schedules/personal-handlers.js";import{registerScheduleCommand as Ae}from"./commands/schedule.js";import{executeServerSchedule as Ee,deliverServerSchedule as Pe}from"./schedules/server-client.js";import{Command as Te}from"commander";import De from"chalk";import Me from"node:os";import{randomUUID as Ue}from"node:crypto";import z from"node:fs";import{loadConfig as p,getShennianDir as _e,resolveShennianPath as J,normalizeAutoUpgradePolicy as Ne}from"./config/index.js";import{CliRelayClient as Oe}from"./relay/client.js";import{collectKnownLogSecrets as xe,installCliLogRedaction as $e}from"./log-redaction.js";import{registerPairCommand as Le,runSmartStart as Ve}from"./commands/pair.js";import{registerLogoutCommand as je}from"./commands/logout.js";import{clearDaemonPidIfOwner as re,createDaemonInstanceId as He,clearDaemonLauncher as ae,findRunningDaemonProcessIds as Fe,isRemoteAccessDisabled as ie,prepareRemoteAccessPause as Be,stopPreparedRemoteAccessService as We,isIsolatedDaemonE2eInstance as Ge,getDaemonStatus as se,registerDaemonCommand as qe,writeDaemonPid as ce,writeDaemonLauncher as de}from"./commands/daemon.js";import{registerRuntimeCommand as Ke}from"./commands/runtime.js";import{registerAdapterCommand as ze}from"./commands/adapter.js";import{registerAgentCommand as Je}from"./commands/agent.js";import{registerManagerCommand as Qe}from"./commands/manager.js";import{registerWorkerCommand as Ye}from"./commands/worker.js";import{registerProjectCommand as Ze}from"./commands/project.js";import{createProjectCoordinationIpcHandlers as Xe}from"./project-coordination/ipc.js";import{registerStewardCommand as eo}from"./commands/steward.js";import{registerRecordingCommand as oo}from"./commands/recordings.js";import{handleUpgradeStart as to,registerUpgradeCommand as no}from"./commands/upgrade.js";import{registerToolsCommand as ro}from"./commands/tools.js";import{registerQueueCommand as ao}from"./commands/queue.js";import{registerSkillCommand as io}from"./commands/skill.js";import{refreshExistingSkillForHosts as so}from"./skill/hosts.js";import{registerSetupCommand as co}from"./commands/setup.js";import{getUnavailableAcpAgents as mo}from"./agents/acp/discovery.js";import{registerCommandReference as lo}from"./commands/command-reference.js";import{registerIntegrationCommand as po}from"./commands/integration.js";import{registerRoomCommand as go}from"./commands/room.js";import{registerContactCommand as uo}from"./commands/contact.js";import{registerSupportCommand as fo}from"./commands/support.js";import{SessionManager as ho}from"./session/manager.js";import{createTrustedProjectFsRequestResolver as vo}from"./session/handlers/project-fs.js";import{SERVERS as Io}from"./region.js";import{clearUpgradeAttempt as So,getCurrentVersion as me,handleStartupCrashCheck as yo,readUpgradeAttempt as wo}from"./upgrade/engine.js";import{AutoUpgradeScheduler as Co}from"./upgrade/scheduler.js";import{ensureUpdaterInstalled as Ro}from"./upgrade/updater-bootstrap.js";import{launchUpdater as ko,markUpdaterHealthy as bo}from"./upgrade/updater-launcher.js";import{detectAgents as le}from"./agents/detect.js";import{PublicAgentDeliveryWorker as Ao}from"./agents/public-delivery-worker.js";import{augmentProcessPath as pe}from"./env-path.js";import{acquireDaemonInstanceLock as Eo}from"./commands/daemon-instance-lock.js";import{isDaemonProcessRunning as Po}from"./commands/daemon-process.js";pe();const T=me();import{getCachedAgentInfos as L,resolveAgentInfos as To}from"./agents/model-registry.js";import{initCliLogReporter as Do,reportLog as D,reportUpgradeAggregateMetric as Mo}from"./log-reporter.js";import{isNativeFusionEnabled as Uo}from"./native-fusion/config.js";import{NativeSessionFusionService as _o}from"./native-fusion/service.js";import{startDaemonLogRetention as No}from"./daemon-log.js";import{startDaemonIpcServer as ge}from"./daemon-ipc/server.js";import{resolveDaemonIpcPaths as Oo,resolveManagedRoomIpcPaths as xo}from"./daemon-ipc/paths.js";import{createDaemonControlHandlers as $o}from"./daemon-ipc/control.js";import{createAgentReadinessHandlers as Lo}from"./daemon-ipc/agent-readiness.js";import{scanMachineAgents as ue}from"./session/handlers/agents.js";import{validateAgentWorkspaceConfiguration as Vo}from"./session/handlers/agent-workspace-validation.js";import{DAEMON_IPC_VERSION as jo}from"./daemon-ipc/protocol.js";import{RoomSessionRegistry as Ho}from"./room/session-registry.js";import{HttpRoomBindingClient as Fo}from"./room/room-binding-client.js";import{TrustedManagedRoomBinder as Bo}from"./room/managed-room-binding.js";import{RoomHostSessionObservationStore as Wo}from"./room/host-session-observations.js";import{RoomMirrorSyncService as Go}from"./room/mirror-sync-service.js";import{handleLiveRoomDelivery as qo}from"./room/live-delivery.js";import{NativeSourceDeletionStore as Ko}from"./native-fusion/native-source-deletions.js";import{matchesRoomOwner as zo,isCurrentRegistration as Jo}from"./room/registration-authority.js";import{RoomActivationService as Qo,resolveManagedAgentPolicy as Yo}from"./room/activation-service.js";import{prepareStandaloneAgentTurn as Zo}from"./room/standalone-agent-turn.js";import{RoomActivationAudit as Xo}from"./room/activation-audit.js";import{RoomAttachmentCache as et}from"./room/attachment-cache.js";import{RoomAttachmentUploader as ot}from"./room/attachment-upload.js";import{ManagedRoomContextAuthority as tt}from"./room/managed-context.js";import{createManagedRoomExecutor as nt}from"./room/managed-room-ipc.js";import{SESSION_SYNC_PROTOCOL_VERSION as fe,SESSION_SYNC_ADVERTISED_CAPABILITIES as he}from"@shennian/wire";import{getDaemonInstallationId as rt}from"./session/store.js";import{OWNER_DIRECT_TURN_OPTIONS as at}from"./session/queue-helpers.js";import{synchronizeMachinePersonalAuthority as it}from"./personal-sync/machine-authority.js";import{CLI_SESSION_SYNC_DATA_EPOCH as ve,ensurePersonalDataEpoch as st}from"./personal-sync/epoch.js";import{DeletionSyncRetryWaitError as ct,DeletionSyncTerminalError as dt}from"./session/deletion-sync-state.js";const Ie=_e(),mt=J("daemon.pid"),lt=J("daemon.instance.lock");function pt(){try{const i=z.readFileSync(mt,"utf-8").trim();if(i.startsWith("{")){const f=JSON.parse(i),m=Number(f.pid);return Number.isInteger(m)&&m>0?m:null}const l=parseInt(i,10);return Number.isInteger(l)&&l>0?l:null}catch{return null}}function gt(i){return i.replace(/^https:\/\//,"wss://").replace(/^http:\/\//,"ws://")}function Q(){process.stdout.write(`${JSON.stringify({ok:!1,error:"integration_command_retired",message:"Room MCP and Hooks were retired. Use the Shennian Skill and CLI.",nextAction:{type:"open_install_guide",url:"https://shennian.net/install.md"}})}
2
+ `),process.exitCode=1}function ut(i){const l=[`trigger=${i.trigger??"unknown"}`,`phase=${i.phase}`,`code=${i.code??"unknown"}`,`attempt=${i.reconnectAttempt}`];return i.reason&&l.push(`reason=${i.reason}`),i.error&&l.push(`error=${i.error}`),l.join(" ")}import{assertSingleServerBinding as V}from"./config/server-binding.js";const a=new Te;a.name("shennian").description("Shennian \u2014 AI Agent Control Plane").version(T),a.enablePositionalOptions(),a.hook("preAction",(i,l)=>{const f=l.optsWithGlobals(),m=p();for(const I of[f.api,f.server,process.env.SHENNIAN_DESKTOP_SERVER_URL])V(I,m)}),po(a),go(a),uo(a),fo(a),Ae(a),ke(a),a.option("--api <url>","Server URL override").option("--name <name>","Machine name",Me.hostname()).action(async i=>{const l=p(),f=V(i.api??process.env.SHENNIAN_DESKTOP_SERVER_URL??l.serverUrl??void 0,l);await Ve(f,i.name)}),a.command("run-service",{hidden:!0}).description("(internal) Connect to relay server, called by the background service").option("--api <url>","Server URL override").action(async i=>{const l=J("env.json");try{const e=JSON.parse(z.readFileSync(l,"utf-8"));for(const[t,o]of Object.entries(e))process.env[t]||(process.env[t]=o);pe()}catch{}$e(xe(process.env,p()));const f=No();ie()&&(console.log(`[${new Date().toISOString()}] remote access disabled, service start skipped`),clearInterval(f),process.exit(0));const m=He(),I=Eo({lockPath:lt,instanceId:m});I.acquired||(console.log(`[${new Date().toISOString()}] daemon already running`+(I.ownerPid?` (PID ${I.ownerPid})`:"")+", skipping duplicate start"),clearInterval(f),process.exit(0));try{const e=pt();e&&e!==process.pid&&Po(e)&&(console.log(`[${new Date().toISOString()}] daemon already running (PID ${e}), skipping duplicate start`),I.release(),process.exit(0))}catch{}const Y=Ge(process.env,Ie)?[]:Fe(process.pid);Y.length>0&&(console.log(`[${new Date().toISOString()}] daemon already running (PID ${Y[0]}), skipping duplicate start`),I.release(),process.exit(0)),ce(process.pid,m,{version:T}),de(process.pid,void 0,m),process.on("exit",()=>{re(process.pid,m),ae(m)}),process.on("exit",I.release);let j=null;try{j=Ro()}catch(e){console.error(`[upgrade] updater bootstrap unavailable: ${e instanceof Error?e.message:String(e)}`)}const M=await yo();if(M){j||(console.error("[upgrade] Crash-loop rollback blocked: updater bootstrap unavailable"),process.exit(1));try{ko({fromVersion:T,targetVersion:M.from,oldDaemonPid:process.pid,operation:"rollback",rollbackJobId:M.jobId},{readiness:j}),console.error(`[upgrade] New version crashed ${M.attemptCount} times; external rollback scheduled.`),process.stdin.resume();return}catch(e){console.error(`[upgrade] Crash-loop rollback could not start: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}}try{st()}catch(e){console.error(`[personal-sync] data epoch initialization failed: ${e instanceof Error?e.message:String(e)}`),process.exitCode=1;return}const s=p(),g=V(i.api??process.env.SHENNIAN_DESKTOP_SERVER_URL??s.serverUrl??Io.cn.url,s),h=me(),d=await le({serverUrl:g,authToken:s.machineToken??s.accessToken}),y=d.map(e=>e.type);let H=L(d);const v=new Ho,U=new Wo,k=new tt(v);V(g,s);const w=new Fo(g),Se=new et({actionClient:w}),ye=new ot({actionClient:w});let C=null,r;const Z=nt({authority:k,actionClient:w,attachmentCache:Se,attachmentUploader:ye,observations:U,getMachineCredentials:()=>({machineToken:p().machineToken}),managerExecutor:e=>r.executeManagedManagerAction(e),onSendOutcome:e=>r.noteManagedRoomSendOutcome(e),getActiveRunId:(e,t)=>r.getManagedRoomActiveRunId(e,t),scheduleExecutor:(e,t,o)=>Ee({serverUrl:g,machineToken:p().machineToken,sessionId:e,action:t,args:o}),onPaused:({registryKey:e,sessionId:t})=>{const n=v.getByRegistryKey(e)?.binding;n&&v.setBinding({registryKey:e,bindingId:n.bindingId,roomId:n.roomId,agentIdentityId:n.agentIdentityId,agentMembershipId:n.agentMembershipId,status:"paused",activationMode:"paused"}),k.revokeSession(e),r?.discardPendingManagedRoomMessages(t)}});let F=null,B=null,W=null,G=null,X=!1;const b=await ge({paths:Oo(),handlers:{...Xe(()=>r),...$o({daemonVersion:h,protocolVersion:jo,getStatus:()=>se(),getAgents:()=>d,requestShutdown:()=>{G?G():X=!0},completeAgentAuthentication:e=>r.resumePendingAcpAuthentication(e),bindManagedRoom:e=>r.bindManagedRoomFromLocal(e),stewardSay:e=>r.stewardSayFromLocal(e),startUpgrade:async e=>{if(!F)throw new Error("upgrade_unavailable");return F(e)},prepareExternalUpgrade:e=>{if(!B)throw new Error("external_upgrade_unavailable");return B(e)},cancelExternalUpgrade:()=>{if(!W)throw new Error("external_upgrade_unavailable");return W()}}),...Lo({getStatus:()=>se(),getSnapshot:()=>L(d).map(e=>{const t=d.find(o=>o.type===e.type);return{...e,runtimePlatform:t?.runtimePlatform,runtimeIsWsl:t?.runtimeIsWsl}}),getUnavailable:mo,discover:async e=>{if(!r)throw new Error("daemon_starting");const t=await ue(!0,e);if(e){const n=d.filter(u=>u.type!==e);d.splice(0,d.length,...n,...t.detectedAgents)}else d.splice(0,d.length,...t.detectedAgents);const o=L(d);return c.sendEvent({type:"event",event:"machine.agents",payload:{agentList:d.map(n=>n.type),agents:o}}),t.agents.map(n=>{const u=t.detectedAgents.find(K=>K.type===n.type);return{...n,runtimePlatform:u?.runtimePlatform,runtimeIsWsl:u?.runtimeIsWsl}})},validate:async e=>{if(!r)throw new Error("daemon_starting");return Vo(e,{ignoreNativeSession:(t,o)=>E?.ignoreNativeSource(t,o)})}})}});let A;try{A=await ge({paths:xo(),handlers:{"managed-room.execute":e=>Z(e),...be(g,v)}})}catch(e){throw await b.close(),e}let ee=!1;const _=()=>{ee||(ee=!0,Promise.allSettled([b.close(),A.close()]).finally(()=>process.exit(0)))};if(process.once("SIGINT",_),process.once("SIGTERM",_),!s.machineToken){console.error('Shennian CLI is not paired. Run "shennian pair --browser" or "shennian pair --token" first.'),await Promise.allSettled([b.close(),A.close()]),process.exitCode=1;return}process.removeListener("SIGINT",_),process.removeListener("SIGTERM",_);const oe=`${gt(g)}/relay/machine`,N=s.machineToken;if(!N)return;try{await it({serverUrl:g,machineToken:N,machineId:s.machineId})}catch(e){console.error(`[personal-sync] machine authority verification failed: ${e instanceof Error?e.message:String(e)}`),await Promise.allSettled([b.close(),A.close()]),process.exit(1)}s.machineId&&Do(g,s.machineId),console.log(`[${new Date().toISOString()}] Connecting to ${oe}... (v${h}) agents: ${y.join(",")}`),D({level:"info",wsEvent:"daemon.start",metadata:{version:h,agents:y}});let E=null,P=null,R=0,q=!1,S=wo();const te=Ne(s.autoUpgrade),O=s.machineId?new Ao({serverUrl:g,machineId:s.machineId,getMachineToken:()=>p().machineToken,getDetectedAgents:()=>le({serverUrl:g,authToken:p().machineToken}),onRuntimeChanged:async()=>{const e=R,t=await ue(!0);if(d.splice(0,d.length,...t.detectedAgents),y.splice(0,y.length,...t.agentList),H=t.agents,!(await c.sendReq({type:"req",id:Ue(),method:"machine.agents.report",params:{agents:t.agents}},2e4)).ok)throw new Error("machine_capability_report_rejected");e===R&&c.getState()==="connected"&&O?.start()},onError:()=>console.warn("[public-agent] delivery attempt failed")}):null,c=new Oe({serverUrl:oe,machineToken:N,cliVersion:h,agentList:y,autoUpgradePolicy:te,sessionSyncProtocolVersion:fe,sessionSyncCapabilities:he,daemonInstallationId:rt(),dataEpoch:ve,updaterProtocolVersion:1,onConnected:()=>{console.log(`[${new Date().toISOString()}] \u2713 Connected`),D({level:"info",wsEvent:"daemon.connected"}),c.sendEvent({type:"event",event:"machine.agents",payload:{agentList:y,agents:H}}),To(d,{serverUrl:s.serverUrl??g,authToken:s.machineToken??s.accessToken}).then(o=>{JSON.stringify(o)!==JSON.stringify(H)&&c.sendEvent({type:"event",event:"machine.agents",payload:{agentList:y,agents:o}})}).catch(()=>{}),S&&c.sendEvent({type:"event",event:"upgrade",payload:{state:"recovering",machineId:"self",from:S.from,to:S.to,...S.jobId?{jobId:S.jobId}:{},activeRunCount:r.getPendingRecoveryCount()}}),x.start(),P?.start();const e=++R,t=async()=>{try{if(await r.synchronizeSessionDeletions(),await r.recoverInterruptedRuns(),S){const o=S;S=null,o.jobId&&bo(o.jobId,o.to),So(),console.log(`[${new Date().toISOString()}] [upgrade] ${o.operation==="rollback"?"Rolled back":"Healthy"}: ${o.from} \u2192 ${o.to}`),Mo({kind:"upgrade",result:o.operation==="rollback"?"rolled_back":"healthy",stage:"terminal"}),c.sendEvent({type:"event",event:"upgrade",payload:{state:o.operation==="rollback"?"rolled_back":"healthy",machineId:"self",from:o.from,to:o.to,...o.jobId?{jobId:o.jobId}:{}}}),o.operation!=="rollback"&&c.sendEvent({type:"event",event:"upgrade",payload:{state:"success",machineId:"self",from:o.from,to:o.to}})}q||(q=!0,so({clientVersion:h}).then(o=>{const n=o.filter(u=>!u.ok||!["current","registered","updated"].includes(u.result.status));n.length>0&&console.warn(`[skill] ${n.length} installed Skill copies need attention; run shennian setup for details`)}).catch(()=>console.warn("[skill] Official Skill refresh failed; Client remains available")).finally(()=>{q=!1})),e===R&&c.getState()==="connected"&&(E?.handleConnected(),O?.start())}catch(o){if(console.error("[session.deletions] startup catch-up failed",o),e===R&&c.getState()==="connected"){if(o instanceof dt)return;const n=o instanceof ct?Math.max(1e3,o.retryAfterMs):5e3;setTimeout(()=>{t()},n).unref?.()}}};t()},onDisconnected:e=>{R+=1,r?.revokeProjectFsHandles(),O?.stop(),P?.stop(),console.log(`[${new Date().toISOString()}] \u26A0 Disconnected, reconnecting... ${ut(e)}`),D({level:"warn",wsEvent:"daemon.disconnected",metadata:{code:e.code,reason:e.reason,error:e.error,phase:e.phase,trigger:e.trigger,reconnectAttempt:e.reconnectAttempt}})},onProjectFsCapabilityChanged:e=>{e||r?.revokeProjectFsHandles()},onReq:e=>{if(console.log(`[${new Date().toISOString()}] [req] ${e.method}`),D({level:"info",type:"ws",wsEvent:e.method,wsDirection:"in",traceId:e.traceId}),e.method==="room.message.deliver"){qo(c,P,e);return}r.handleReq(e)}});E=Uo()?new _o(c):null,P=new Go({registry:v,observations:U,actionClient:w,getMachineCredentials:()=>({machineToken:p().machineToken}),isSessionDeleted:e=>new Ko().hasSession(e),onMessages:async(e,t,o,n)=>{await C?.processMessages(e,t,o,n)},onBindingPaused:e=>{e.lifecycleState==="closed"?(k.revokeSession(e.registryKey),r?.retireManagedRoomSession(e.nianSessionId).catch(()=>{console.warn("[room.sync] retired session cleanup failed")})):r?.discardPendingManagedRoomMessages(e.nianSessionId)}});const x=new Co({currentVersion:h,machineId:s.machineId??"unknown-machine",serverUrl:s.serverUrl??g,getIdleState:()=>r.getUpgradeIdleState(),sessionSyncProtocolVersion:fe,dataEpoch:ve,advertisedCapabilities:he,updaterProtocolVersion:1,startUpgrade:async(e,t)=>{const{handleUpgradeStart:o}=await import("./commands/upgrade.js");await o(c,"auto-upgrade",e,{currentVersion:h,prepareForUpgrade:n=>r.prepareForUpgrade(n),cancelUpgradePreparation:()=>r.cancelUpgradePreparation(),shutdownAfterHandoff:()=>{setTimeout(()=>process.kill(process.pid,"SIGTERM"),100).unref?.()},suppressResponse:!0,waitForCompletion:!0,canHandoff:t?void 0:()=>r.getUpgradeIdleState().idle})}});x.setPolicy(te),r=new ho(c,E,h,x,new Bo({registry:v,observations:U,bindingClient:w,getMachineCredentials:()=>{const e=p();return{machineId:e.machineId,machineToken:e.machineToken}},hostProcessIdentity:()=>`daemon:${m}`}),{prepare:()=>Be(),isDisabled:()=>ie(),shutdownAfterResponse:()=>{setTimeout(()=>{We(),process.kill(process.pid,"SIGTERM")},100).unref?.()}},e=>k.revokeToken(e),Z,null,vo(N),()=>L(d)),F=async e=>{const t=e&&typeof e=="object"&&!Array.isArray(e)?e:{},o=typeof t.targetVersion=="string"?t.targetVersion:void 0,n=t.confirmedMajor===!0;return await to(c,`local-upgrade-${Date.now()}`,o,{currentVersion:h,confirmedMajor:n,prepareForUpgrade:K=>r.prepareForUpgrade(K),cancelUpgradePreparation:()=>r.cancelUpgradePreparation(),shutdownAfterHandoff:()=>{setTimeout(()=>process.kill(process.pid,"SIGTERM"),100).unref?.()},suppressResponse:!0})},B=e=>{const t=e&&typeof e=="object"&&!Array.isArray(e)?e:{},n=`desktop-${(typeof t.targetVersion=="string"?t.targetVersion:"unknown").replace(/[^A-Za-z0-9._-]/g,"_")}-${Date.now()}`;return{jobId:n,...r.prepareForUpgrade(n)}},W=()=>(r.cancelUpgradePreparation(),{cancelled:!0}),C=new Qo({registry:v,observations:U,enqueueConversationBatch:e=>r.enqueueManagedRoomBatch(e),loadContext:async e=>{const t=p().machineToken?.trim(),o=e.binding;if(!t||!o)throw new Error("managed_room_context_unavailable");const n=await w.status({machineToken:t,roomId:o.roomId,bindingId:o.bindingId});if(!Jo(v,e)||!zo(e,n))throw new Error("managed_room_binding_unavailable");return{roomName:n.room.name,memberCount:n.room.memberCount,members:n.room.members,agentsByIdentityId:n.agent?{[n.agentIdentityId]:n.agent}:{},effectiveModelsBySessionId:n.effectiveModelId!==void 0?{[e.nianSessionId]:n.effectiveModelId}:void 0,agentSystemPromptsByIdentityId:n.agent?{[n.agentIdentityId]:n.agent.systemPrompt??""}:{}}},issueManagedRoomContext:(e,t,o,n)=>{const u=p().machineToken;if(!u)throw new Error("machine_not_authorized");return k.issue({registryKey:e,machineCredential:u,activationCauseMessageId:t,allowedActions:o,propagateWorkerRoomOrigin:n})},audit:new Xo,prepareUnboundDirectTurn:Zo,resolveManagedAgentPolicy:e=>Yo({...e,runtime:d.find(t=>t.type===e.registration.runtimeAdapter)})}),r.scheduleHandler=e=>Pe({serverUrl:g,machineToken:p().machineToken,req:e,client:c,queue:r.getScheduleQueue(),registry:v}),r.getScheduleQueue().validateScheduledTarget=async e=>{if(!e.bindingId||!e.roomId)return"ready";if(v.getByNianSessionId(e.sessionId)?.binding?.bindingId!==e.bindingId)return"ended";const o=await w.status({machineToken:p().machineToken,roomId:e.roomId,bindingId:e.bindingId});return o.status==="active"&&o.room.status==="active"?"ready":"ended"},r.setManagedRoomTurnPreparer(e=>C.prepareConversationTurn(e)),r.setManagedAgentDirectTurnPreparer((e,t)=>C.prepareDirectConversationTurn(e,t)),r.setManagedRecoveryPreparer(async e=>e.source==="managed_direct"?C.prepareDirectConversationTurn(e.sessionId,at):e.source==="manager_event"?C.prepareDirectConversationTurn(e.sessionId,{allowedRoomActions:[],managerEvent:!0}):e.source!=="managed_room"||!e.roomContextRegistryKey||!e.activationCauseMessageId||!e.rootCauseMessageId||!e.activationSequence||e.activationHopCount===null?null:C.prepareConversationTurn([{registryKey:e.roomContextRegistryKey,causeMessageId:e.activationCauseMessageId,rootCauseMessageId:e.rootCauseMessageId,sequence:e.activationSequence,hopCount:e.activationHopCount}])),z.mkdirSync(Ie,{recursive:!0}),ce(process.pid,m,{version:h}),de(process.pid,void 0,m),c.connect(),process.stdin.resume();let ne=!1;const $=async()=>{if(!ne){ne=!0,console.log(De.gray(`
3
3
  Disconnecting...`)),D({level:"info",wsEvent:"daemon.stop"}),clearInterval(f),O?.stop();try{await r.cleanup(),x.stop(),E?.stop(),P?.stop(),c.disconnect(),await Promise.allSettled([b.close(),A.close()]),re(process.pid,m),ae(m)}finally{process.exit(0)}}};G=$,X&&$(),process.on("SIGINT",()=>{$()}),process.on("SIGTERM",()=>{$()})}),a.command("workbuddy-session-hook",{hidden:!0}).description("(retired) WorkBuddy Room Hook").allowUnknownOption(!0).action(()=>Q()),a.command("room-session-hook",{hidden:!0}).description("(internal) Authorize the official Room tool for one trusted Agent Session").argument("<runtime>","Trusted runtime adapter").allowUnknownOption(!0).action(()=>Q()),a.command("room-tool-server",{hidden:!0}).description("(internal) Run the official Shennian Room MCP tool").allowUnknownOption(!0).action(()=>Q()),Ce(a),co(a),Le(a),je(a),qe(a),Re(a),Ke(a),ze(a,{clientVersion:T}),Je(a),Qe(a),Ye(a),Ze(a),eo(a),oo(a),we(a),no(a),ro(a),ao(a),io(a),lo(a,T),a.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shennian",
3
- "version": "0.5.52",
3
+ "version": "0.5.53",
4
4
  "description": "Shennian — AI Agent Control Plane CLI",
5
5
  "type": "module",
6
6
  "bin": {