shennian 0.2.121 → 0.2.123

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.
@@ -221,8 +221,8 @@
221
221
  },
222
222
  {
223
223
  "file": "src/channels/wechat-channel/helper-client.js",
224
- "beforeBytes": 40106,
225
- "afterBytes": 18151
224
+ "beforeBytes": 41881,
225
+ "afterBytes": 18901
226
226
  },
227
227
  {
228
228
  "file": "src/channels/wechat-channel/helper-protocol.js",
@@ -391,8 +391,8 @@
391
391
  },
392
392
  {
393
393
  "file": "src/commands/runtime.js",
394
- "beforeBytes": 39493,
395
- "afterBytes": 21665
394
+ "beforeBytes": 39879,
395
+ "afterBytes": 21821
396
396
  },
397
397
  {
398
398
  "file": "src/commands/tools.js",
@@ -441,8 +441,8 @@
441
441
  },
442
442
  {
443
443
  "file": "src/commands/wechat/utils.js",
444
- "beforeBytes": 3672,
445
- "afterBytes": 2472
444
+ "beforeBytes": 3661,
445
+ "afterBytes": 2494
446
446
  },
447
447
  {
448
448
  "file": "src/commands/wechat.js",
@@ -1,4 +1,4 @@
1
- export declare const WECHAT_CHANNEL_HELPER_VERSION = "0.1.11";
1
+ export declare const WECHAT_CHANNEL_HELPER_VERSION = "0.1.12";
2
2
  export declare const WECHAT_CHANNEL_HELPER_DIR_ENV = "SHENNIAN_WECHAT_CHANNEL_HELPER_DIR";
3
3
  export declare const SHENNIAN_HELPER_RUNTIME_DIR_ENV = "SHENNIAN_HELPER_RUNTIME_DIR";
4
4
  export declare const WECHAT_CHANNEL_HELPER_RUNTIME_REQUIRED_REASON = "helper_runtime_required";
@@ -1 +1 @@
1
- import c from"node:fs";import s from"node:path";import E from"node:crypto";const V="0.1.11",S="SHENNIAN_WECHAT_CHANNEL_HELPER_DIR",g="SHENNIAN_HELPER_RUNTIME_DIR",C="helper_runtime_required",u=["en","v"].join("");function $(n={}){const r=n.platform??process.platform;if(r!=="darwin"&&r!=="win32")return{ok:!1,reasonCode:"unsupported_platform",message:"WeChat channel helper is only available on macOS and Windows"};const e=n.baseDir?[s.resolve(n.baseDir)]:A({platform:r,env:n[u]??R(),homedir:n.homedir,includeInstalledDesktop:n.includeInstalledDesktop});let a=null;for(const t of e){const i=_({platform:r,baseDir:t,verifyIntegrity:n.verifyIntegrity});if(i.ok||(n.baseDir||c.existsSync(t))&&(a??=i,n.baseDir))return i}return a??{ok:!1,reasonCode:C,message:x(r,e)}}function _(n){const{platform:r,baseDir:e}=n,a=s.join(e,"manifest.json"),t=F(a);if(!t)return{ok:!1,reasonCode:"manifest_missing",message:`WeChat channel helper manifest is missing: ${a}`};const i=t.platforms[r],o=i?s.join(e,i.executable):"";if(!i||!o||!c.existsSync(o))return{ok:!1,reasonCode:"helper_missing",message:`WeChat channel helper executable is missing: ${o||e}`};if(N({platform:r,baseDir:e,verifyIntegrity:n.verifyIntegrity})&&i.sha256&&E.createHash("sha256").update(c.readFileSync(o)).digest("hex")!==i.sha256)return{ok:!1,reasonCode:"integrity_mismatch",message:`WeChat channel helper integrity mismatch: ${o}`};const f=H(r,o);return f.ok?{ok:!0,helperPath:o,helperDir:e,version:t.helperVersion,manifest:t,warning:i.signed&&i.notarized?void 0:"helper_not_signed_or_notarized"}:{ok:!1,reasonCode:"helper_not_executable",message:f.message}}function H(n,r){if(n!=="darwin")return{ok:!0};try{const e=c.statSync(r);return(e.mode&73)!==0?{ok:!0}:(c.chmodSync(r,e.mode|73),{ok:!0})}catch(e){return{ok:!1,message:`WeChat channel helper is not executable and could not be repaired: ${r}: ${e instanceof Error?e.message:String(e)}`}}}function A(n){const{platform:r,env:e}=n,a=r==="win32"?"windows":"macos",t=[],i=l=>{if(!l)return;const p=s.resolve(l);t.includes(p)||t.push(p)},o=e[S]?.trim();o&&i(j(o,a));const f=e[g]?.trim();if(f)for(const l of P(f,a))i(l);if(b({platform:r,platformDir:a,env:e,homedir:n.homedir,push:i}),n.includeInstalledDesktop===!1)return t;if(r==="darwin"){const l=n.homedir||e.HOME;l&&i(s.join(l,"Applications","Shennian.app","Contents","Resources","wechat-channel",a)),i(s.join("/Applications","Shennian.app","Contents","Resources","wechat-channel",a))}else if(r==="win32"){const l=n.homedir||e.USERPROFILE,p=e.LOCALAPPDATA||(l?s.join(l,"AppData","Local"):""),m=e.ProgramFiles||e.PROGRAMFILES,h=e["ProgramFiles(x86)"]||e["PROGRAMFILES(X86)"];for(const d of[p?s.join(p,"Programs","Shennian"):"",p?s.join(p,"Programs","shennian"):"",m?s.join(m,"Shennian"):"",h?s.join(h,"Shennian"):""])d&&i(s.join(d,"resources","wechat-channel",a))}return t}function b(n){const{platform:r,platformDir:e,env:a,push:t}=n;if(r==="darwin"){const i=n.homedir||a.HOME,o=k({platform:r,env:a,homedir:n.homedir});o&&(t(s.join(o,"Shennian Helper.app","Contents","Resources","wechat-channel",e)),t(s.join(o,"wechat-channel",e))),i&&t(s.join(i,"Applications","Shennian Helper.app","Contents","Resources","wechat-channel",e)),t(s.join("/Applications","Shennian Helper.app","Contents","Resources","wechat-channel",e)),t(s.join("/Library","Application Support","Shennian","Helper","wechat-channel",e))}else if(r==="win32"){const i=n.homedir||a.USERPROFILE,o=a.LOCALAPPDATA||(i?s.join(i,"AppData","Local"):""),f=a.ProgramFiles||a.PROGRAMFILES,l=a["ProgramFiles(x86)"]||a["PROGRAMFILES(X86)"];o&&(t(s.join(o,"Programs","Shennian Helper","resources","wechat-channel",e)),t(s.join(o,"Shennian","Helper","wechat-channel",e))),f&&t(s.join(f,"Shennian Helper","resources","wechat-channel",e)),l&&t(s.join(l,"Shennian Helper","resources","wechat-channel",e))}}function j(n,r){return c.existsSync(s.join(n,"manifest.json"))?n:s.join(n,r)}function P(n,r){if(c.existsSync(s.join(n,"manifest.json")))return[n];const e=s.join(n,"Shennian Helper.app","Contents","Resources","wechat-channel",r),a=s.join(n,"wechat-channel",r),t=s.join(n,r);return[e,a,t]}function k(n){const r=n[u],e=r[g]?.trim();if(e)return s.resolve(e);const a=n.homedir||(n.platform==="win32"?r.USERPROFILE:r.HOME);if(n.platform==="darwin")return a?s.join(a,"Library","Application Support","Shennian","Helper"):null;if(n.platform==="win32"){const t=r.LOCALAPPDATA||(a?s.join(a,"AppData","Local"):"");return t?s.join(t,"Shennian","Helper"):null}return null}function q(n={}){return k({platform:n.platform??process.platform,env:n.env??R(),homedir:n.homedir})}function D(n){const r=s.resolve(n);return O([s.join(r,"helper-runtime-package.json"),s.join(s.dirname(r),"..","helper-runtime-package.json")])}function U(n){const r=n.platform??process.platform;if(r!=="darwin"&&r!=="win32")return{ok:!1,reasonCode:"unsupported_platform",message:"WeChat channel helper runtime package is only available on macOS and Windows"};const e=n.manifestPath?[s.resolve(n.manifestPath)]:n.helperDir?D(n.helperDir):[],a=e.find(t=>c.existsSync(t));if(!a)return{ok:!1,reasonCode:"helper_runtime_package_manifest_missing",message:`Helper runtime package manifest is missing. Checked: ${e.join(", ")||"(none)"}`,manifestPath:e[0]};try{const t=JSON.parse(w(a)),i=I(t,r);return i.ok?{ok:!0,manifestPath:a,manifest:t}:{ok:!1,reasonCode:"helper_runtime_package_manifest_invalid",message:`${i.message}: ${a}`,manifestPath:a}}catch(t){return{ok:!1,reasonCode:"helper_runtime_package_manifest_invalid",message:`Helper runtime package manifest is invalid JSON: ${t instanceof Error?t.message:String(t)}`,manifestPath:a}}}function I(n,r){if(!n||typeof n!="object"||Array.isArray(n))return{ok:!1,message:"manifest must be an object"};const e=n;return e.schemaVersion!==1?{ok:!1,message:"schemaVersion must be 1"}:e.packageKind!=="shennian-helper-runtime"?{ok:!1,message:"packageKind must be shennian-helper-runtime"}:e.platform!==r?{ok:!1,message:`platform must be ${r}`}:e.helperVersion?!Number.isInteger(e.protocolVersion)||Number(e.protocolVersion)<=0?{ok:!1,message:"protocolVersion must be a positive integer"}:L(e.minCliVersion)?!e.sha256||typeof e.sha256.runtimeManifest!="string"?{ok:!1,message:"sha256.runtimeManifest is required"}:y(e.sha256.runtimeManifest)?e.sha256.entrypoint!==null&&typeof e.sha256.entrypoint!="string"?{ok:!1,message:"sha256.entrypoint must be a string or null"}:typeof e.sha256.entrypoint=="string"&&!y(e.sha256.entrypoint)?{ok:!1,message:"sha256.entrypoint must be a sha256 digest or null"}:!e.installTarget?.kind||!e.installTarget.defaultPath?{ok:!1,message:"installTarget.kind and installTarget.defaultPath are required"}:!e.payload?.kind||!e.payload.runtimeManifest||!e.payload.entrypoint?{ok:!1,message:"payload.kind, payload.runtimeManifest, and payload.entrypoint are required"}:r==="darwin"&&e.installTarget.kind!=="app-bundle"?{ok:!1,message:"darwin installTarget.kind must be app-bundle"}:r==="darwin"&&e.payload.kind!=="macos-helper-app"?{ok:!1,message:"darwin payload.kind must be macos-helper-app"}:r==="win32"&&e.installTarget.kind!=="directory"?{ok:!1,message:"win32 installTarget.kind must be directory"}:r==="win32"&&e.payload.kind!=="windows-helper-runtime"?{ok:!1,message:"win32 payload.kind must be windows-helper-runtime"}:!e.signature||typeof e.signature.requiredForRelease!="boolean"||typeof e.signature.signed!="boolean"||typeof e.signature.notarized!="boolean"?{ok:!1,message:"signature.requiredForRelease, signature.signed, and signature.notarized are required"}:{ok:!0}:{ok:!1,message:"sha256.runtimeManifest must be a sha256 digest"}:{ok:!1,message:"minCliVersion must be a semver string"}:{ok:!1,message:"helperVersion is required"}}function L(n){return typeof n=="string"&&/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/.test(n)}function y(n){return/^[a-f0-9]{64}$/i.test(n)}function N(n){return n.verifyIntegrity===!0?!0:n.verifyIntegrity===!1?!1:!v(n.platform,n.baseDir)}function v(n,r){const e=r.replace(/[\\/]+/g,"/");return n==="darwin"?/\/Shennian\.app\/Contents\/Resources\/wechat-channel\/macos$/i.test(e):n==="win32"?/\/resources\/wechat-channel\/windows$/i.test(e):!1}function x(n,r){const e=n==="win32"?"Windows":"macOS",a=r.length>0?` Checked helper directories: ${r.join(", ")}`:"";return`WeChat RPA requires Shennian Helper runtime on ${e}; open Shennian Desktop or use the \u4F7F\u7528\u5FAE\u4FE1 page to install Helper, then retry.${a}`}function R(){return globalThis.process?.[u]??{}}function F(n){try{const r=JSON.parse(w(n));return r.schemaVersion!==1||typeof r.helperVersion!="string"||!r.platforms?null:r}catch{return null}}function w(n){return c.readFileSync(n,"utf8").replace(/^\uFEFF/,"")}function O(n){const r=new Set,e=[];for(const a of n){const t=s.resolve(a);r.has(t)||(r.add(t),e.push(t))}return e}export{g as SHENNIAN_HELPER_RUNTIME_DIR_ENV,S as WECHAT_CHANNEL_HELPER_DIR_ENV,C as WECHAT_CHANNEL_HELPER_RUNTIME_REQUIRED_REASON,V as WECHAT_CHANNEL_HELPER_VERSION,q as getDefaultWeChatHelperRuntimeRoot,D as helperRuntimePackageManifestCandidates,U as readWeChatChannelHelperRuntimePackageManifest,$ as resolveWeChatChannelHelperAsset,I as validateWeChatChannelHelperRuntimePackageManifest};
1
+ import c from"node:fs";import s from"node:path";import E from"node:crypto";const V="0.1.12",S="SHENNIAN_WECHAT_CHANNEL_HELPER_DIR",g="SHENNIAN_HELPER_RUNTIME_DIR",C="helper_runtime_required",u=["en","v"].join("");function $(n={}){const r=n.platform??process.platform;if(r!=="darwin"&&r!=="win32")return{ok:!1,reasonCode:"unsupported_platform",message:"WeChat channel helper is only available on macOS and Windows"};const e=n.baseDir?[s.resolve(n.baseDir)]:A({platform:r,env:n[u]??R(),homedir:n.homedir,includeInstalledDesktop:n.includeInstalledDesktop});let a=null;for(const t of e){const i=_({platform:r,baseDir:t,verifyIntegrity:n.verifyIntegrity});if(i.ok||(n.baseDir||c.existsSync(t))&&(a??=i,n.baseDir))return i}return a??{ok:!1,reasonCode:C,message:x(r,e)}}function _(n){const{platform:r,baseDir:e}=n,a=s.join(e,"manifest.json"),t=F(a);if(!t)return{ok:!1,reasonCode:"manifest_missing",message:`WeChat channel helper manifest is missing: ${a}`};const i=t.platforms[r],o=i?s.join(e,i.executable):"";if(!i||!o||!c.existsSync(o))return{ok:!1,reasonCode:"helper_missing",message:`WeChat channel helper executable is missing: ${o||e}`};if(N({platform:r,baseDir:e,verifyIntegrity:n.verifyIntegrity})&&i.sha256&&E.createHash("sha256").update(c.readFileSync(o)).digest("hex")!==i.sha256)return{ok:!1,reasonCode:"integrity_mismatch",message:`WeChat channel helper integrity mismatch: ${o}`};const f=H(r,o);return f.ok?{ok:!0,helperPath:o,helperDir:e,version:t.helperVersion,manifest:t,warning:i.signed&&i.notarized?void 0:"helper_not_signed_or_notarized"}:{ok:!1,reasonCode:"helper_not_executable",message:f.message}}function H(n,r){if(n!=="darwin")return{ok:!0};try{const e=c.statSync(r);return(e.mode&73)!==0?{ok:!0}:(c.chmodSync(r,e.mode|73),{ok:!0})}catch(e){return{ok:!1,message:`WeChat channel helper is not executable and could not be repaired: ${r}: ${e instanceof Error?e.message:String(e)}`}}}function A(n){const{platform:r,env:e}=n,a=r==="win32"?"windows":"macos",t=[],i=l=>{if(!l)return;const p=s.resolve(l);t.includes(p)||t.push(p)},o=e[S]?.trim();o&&i(j(o,a));const f=e[g]?.trim();if(f)for(const l of P(f,a))i(l);if(b({platform:r,platformDir:a,env:e,homedir:n.homedir,push:i}),n.includeInstalledDesktop===!1)return t;if(r==="darwin"){const l=n.homedir||e.HOME;l&&i(s.join(l,"Applications","Shennian.app","Contents","Resources","wechat-channel",a)),i(s.join("/Applications","Shennian.app","Contents","Resources","wechat-channel",a))}else if(r==="win32"){const l=n.homedir||e.USERPROFILE,p=e.LOCALAPPDATA||(l?s.join(l,"AppData","Local"):""),m=e.ProgramFiles||e.PROGRAMFILES,h=e["ProgramFiles(x86)"]||e["PROGRAMFILES(X86)"];for(const d of[p?s.join(p,"Programs","Shennian"):"",p?s.join(p,"Programs","shennian"):"",m?s.join(m,"Shennian"):"",h?s.join(h,"Shennian"):""])d&&i(s.join(d,"resources","wechat-channel",a))}return t}function b(n){const{platform:r,platformDir:e,env:a,push:t}=n;if(r==="darwin"){const i=n.homedir||a.HOME,o=k({platform:r,env:a,homedir:n.homedir});o&&(t(s.join(o,"Shennian Helper.app","Contents","Resources","wechat-channel",e)),t(s.join(o,"wechat-channel",e))),i&&t(s.join(i,"Applications","Shennian Helper.app","Contents","Resources","wechat-channel",e)),t(s.join("/Applications","Shennian Helper.app","Contents","Resources","wechat-channel",e)),t(s.join("/Library","Application Support","Shennian","Helper","wechat-channel",e))}else if(r==="win32"){const i=n.homedir||a.USERPROFILE,o=a.LOCALAPPDATA||(i?s.join(i,"AppData","Local"):""),f=a.ProgramFiles||a.PROGRAMFILES,l=a["ProgramFiles(x86)"]||a["PROGRAMFILES(X86)"];o&&(t(s.join(o,"Programs","Shennian Helper","resources","wechat-channel",e)),t(s.join(o,"Shennian","Helper","wechat-channel",e))),f&&t(s.join(f,"Shennian Helper","resources","wechat-channel",e)),l&&t(s.join(l,"Shennian Helper","resources","wechat-channel",e))}}function j(n,r){return c.existsSync(s.join(n,"manifest.json"))?n:s.join(n,r)}function P(n,r){if(c.existsSync(s.join(n,"manifest.json")))return[n];const e=s.join(n,"Shennian Helper.app","Contents","Resources","wechat-channel",r),a=s.join(n,"wechat-channel",r),t=s.join(n,r);return[e,a,t]}function k(n){const r=n[u],e=r[g]?.trim();if(e)return s.resolve(e);const a=n.homedir||(n.platform==="win32"?r.USERPROFILE:r.HOME);if(n.platform==="darwin")return a?s.join(a,"Library","Application Support","Shennian","Helper"):null;if(n.platform==="win32"){const t=r.LOCALAPPDATA||(a?s.join(a,"AppData","Local"):"");return t?s.join(t,"Shennian","Helper"):null}return null}function q(n={}){return k({platform:n.platform??process.platform,env:n.env??R(),homedir:n.homedir})}function D(n){const r=s.resolve(n);return O([s.join(r,"helper-runtime-package.json"),s.join(s.dirname(r),"..","helper-runtime-package.json")])}function U(n){const r=n.platform??process.platform;if(r!=="darwin"&&r!=="win32")return{ok:!1,reasonCode:"unsupported_platform",message:"WeChat channel helper runtime package is only available on macOS and Windows"};const e=n.manifestPath?[s.resolve(n.manifestPath)]:n.helperDir?D(n.helperDir):[],a=e.find(t=>c.existsSync(t));if(!a)return{ok:!1,reasonCode:"helper_runtime_package_manifest_missing",message:`Helper runtime package manifest is missing. Checked: ${e.join(", ")||"(none)"}`,manifestPath:e[0]};try{const t=JSON.parse(w(a)),i=I(t,r);return i.ok?{ok:!0,manifestPath:a,manifest:t}:{ok:!1,reasonCode:"helper_runtime_package_manifest_invalid",message:`${i.message}: ${a}`,manifestPath:a}}catch(t){return{ok:!1,reasonCode:"helper_runtime_package_manifest_invalid",message:`Helper runtime package manifest is invalid JSON: ${t instanceof Error?t.message:String(t)}`,manifestPath:a}}}function I(n,r){if(!n||typeof n!="object"||Array.isArray(n))return{ok:!1,message:"manifest must be an object"};const e=n;return e.schemaVersion!==1?{ok:!1,message:"schemaVersion must be 1"}:e.packageKind!=="shennian-helper-runtime"?{ok:!1,message:"packageKind must be shennian-helper-runtime"}:e.platform!==r?{ok:!1,message:`platform must be ${r}`}:e.helperVersion?!Number.isInteger(e.protocolVersion)||Number(e.protocolVersion)<=0?{ok:!1,message:"protocolVersion must be a positive integer"}:L(e.minCliVersion)?!e.sha256||typeof e.sha256.runtimeManifest!="string"?{ok:!1,message:"sha256.runtimeManifest is required"}:y(e.sha256.runtimeManifest)?e.sha256.entrypoint!==null&&typeof e.sha256.entrypoint!="string"?{ok:!1,message:"sha256.entrypoint must be a string or null"}:typeof e.sha256.entrypoint=="string"&&!y(e.sha256.entrypoint)?{ok:!1,message:"sha256.entrypoint must be a sha256 digest or null"}:!e.installTarget?.kind||!e.installTarget.defaultPath?{ok:!1,message:"installTarget.kind and installTarget.defaultPath are required"}:!e.payload?.kind||!e.payload.runtimeManifest||!e.payload.entrypoint?{ok:!1,message:"payload.kind, payload.runtimeManifest, and payload.entrypoint are required"}:r==="darwin"&&e.installTarget.kind!=="app-bundle"?{ok:!1,message:"darwin installTarget.kind must be app-bundle"}:r==="darwin"&&e.payload.kind!=="macos-helper-app"?{ok:!1,message:"darwin payload.kind must be macos-helper-app"}:r==="win32"&&e.installTarget.kind!=="directory"?{ok:!1,message:"win32 installTarget.kind must be directory"}:r==="win32"&&e.payload.kind!=="windows-helper-runtime"?{ok:!1,message:"win32 payload.kind must be windows-helper-runtime"}:!e.signature||typeof e.signature.requiredForRelease!="boolean"||typeof e.signature.signed!="boolean"||typeof e.signature.notarized!="boolean"?{ok:!1,message:"signature.requiredForRelease, signature.signed, and signature.notarized are required"}:{ok:!0}:{ok:!1,message:"sha256.runtimeManifest must be a sha256 digest"}:{ok:!1,message:"minCliVersion must be a semver string"}:{ok:!1,message:"helperVersion is required"}}function L(n){return typeof n=="string"&&/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/.test(n)}function y(n){return/^[a-f0-9]{64}$/i.test(n)}function N(n){return n.verifyIntegrity===!0?!0:n.verifyIntegrity===!1?!1:!v(n.platform,n.baseDir)}function v(n,r){const e=r.replace(/[\\/]+/g,"/");return n==="darwin"?/\/Shennian\.app\/Contents\/Resources\/wechat-channel\/macos$/i.test(e):n==="win32"?/\/resources\/wechat-channel\/windows$/i.test(e):!1}function x(n,r){const e=n==="win32"?"Windows":"macOS",a=r.length>0?` Checked helper directories: ${r.join(", ")}`:"";return`WeChat RPA requires Shennian Helper runtime on ${e}; open Shennian Desktop or use the \u4F7F\u7528\u5FAE\u4FE1 page to install Helper, then retry.${a}`}function R(){return globalThis.process?.[u]??{}}function F(n){try{const r=JSON.parse(w(n));return r.schemaVersion!==1||typeof r.helperVersion!="string"||!r.platforms?null:r}catch{return null}}function w(n){return c.readFileSync(n,"utf8").replace(/^\uFEFF/,"")}function O(n){const r=new Set,e=[];for(const a of n){const t=s.resolve(a);r.has(t)||(r.add(t),e.push(t))}return e}export{g as SHENNIAN_HELPER_RUNTIME_DIR_ENV,S as WECHAT_CHANNEL_HELPER_DIR_ENV,C as WECHAT_CHANNEL_HELPER_RUNTIME_REQUIRED_REASON,V as WECHAT_CHANNEL_HELPER_VERSION,q as getDefaultWeChatHelperRuntimeRoot,D as helperRuntimePackageManifestCandidates,U as readWeChatChannelHelperRuntimePackageManifest,$ as resolveWeChatChannelHelperAsset,I as validateWeChatChannelHelperRuntimePackageManifest};
@@ -1,3 +1,3 @@
1
- import{spawn as w}from"node:child_process";import{randomUUID as x}from"node:crypto";import f from"node:fs";import D from"node:net";import H from"node:os";import d from"node:path";import{createInterface as g}from"node:readline";import{decideWeChatChannelActivityGate as S,normalizeWeChatChannelActivitySnapshot as k}from"./human-coordination.js";import{createWeChatChannelHelperHello as E,extractWeChatChannelHelperWarmupSnapshot as q,timeoutForWeChatChannelHelperCommand as O,validateWeChatChannelHelperReady as C}from"./helper-protocol.js";const F=["en","v"].join(""),m=1500,N=1500,_=8e3,G="SHENNIAN_WECHAT_DANGEROUS_GUARD_THROTTLE_MS";function L(){const t=process.env[G];if(t===void 0||t==="")return _;const e=Number.parseInt(t,10);return!Number.isFinite(e)||e<0?_:e}class me{options;child=null;socket=null;lines=null;readyState=null;warmupState=null;stderrTail="";startPromise=null;requestQueueTail=Promise.resolve();lastGuardPassAtMs=0;pending=new Map;constructor(e){this.options=e}async start(){return this.hasTransport()&&this.readyState?this.readyState:this.startPromise?this.startPromise:(this.hasTransport()&&await this.stop(),this.startPromise=this.startFresh().catch(async e=>{throw await this.stop().catch(()=>{}),e}).finally(()=>{this.startPromise=null}),this.startPromise)}async startFresh(){const e=B(this.options.helperPath,this.options.args??[]);return e.transport==="macos-socket"?this.startDarwinAppSocketFresh(e):this.startStdioFresh(e)}async startStdioFresh(e){const r=w(e.command,e.args,{cwd:this.options.cwd,stdio:["pipe","pipe","pipe"],windowsHide:!0});this.child=r,this.stderrTail="",this.lines=g({input:r.stdout}),this.lines.on("line",i=>this.handleLine(i)),r.stderr.on("data",i=>{this.captureStderr(i)}),r.stdin.on("error",i=>{this.rejectAllPending(i instanceof Error?i:new Error(String(i)))}),r.once("error",i=>{this.child===r&&(this.child=null,this.readyState=null,this.lines?.close(),this.lines=null),this.rejectAllPending(i instanceof Error?i:new Error(String(i)))}),r.once("exit",(i,n)=>{this.child===r&&(this.child=null,this.readyState=null,this.lines?.close(),this.lines=null),this.rejectAllPending(new Error(this.formatHelperExitMessage(i,n)))});const s=new Promise((i,n)=>{const a=setTimeout(()=>n(new Error("WeChat channel helper handshake timed out")),1e4),l=h=>{clearTimeout(a),this.lines?.off("line",c),r.off("exit",o),n(new Error(`WeChat channel helper failed to start: ${h.message}`))},o=(h,u)=>{clearTimeout(a),r.off("error",l),this.lines?.off("line",c),n(new Error(this.formatHelperExitMessage(h,u)))},c=h=>{let u;try{u=JSON.parse(h)}catch{clearTimeout(a),r.off("error",l),this.lines?.off("line",c),n(new Error("WeChat channel helper sent invalid handshake JSON"));return}if(!A(u))return;clearTimeout(a),r.off("error",l),r.off("exit",o),this.lines?.off("line",c);const p=C(u,this.options.expectedHelperVersion,this.options.requiredCapabilities);p.ok?(this.readyState=u,this.captureWarmupSnapshot(u),i(u)):n(new Error(`${p.errorCode}: ${p.errorSummary}`))};r.once("error",l),r.once("exit",o),this.lines?.on("line",c)});try{r.stdin.write(`${JSON.stringify(E(this.options.expectedHelperVersion,this.options.requiredCapabilities))}
2
- `)}catch(i){throw await this.stop().catch(()=>{}),i}return s}async startDarwinAppSocketFresh(e){const r=await this.connectDarwinHelperSocket(e);this.socket=r,this.stderrTail="",this.lines=g({input:r}),this.lines.on("line",i=>this.handleLine(i)),r.on("error",i=>{this.socket===r&&(this.socket=null,this.readyState=null,this.lines?.close(),this.lines=null),this.rejectAllPending(i instanceof Error?i:new Error(String(i)))}),r.once("close",()=>{this.socket===r&&(this.socket=null,this.readyState=null,this.lines?.close(),this.lines=null),this.rejectAllPending(new Error("WeChat channel helper socket closed"))});const s=new Promise((i,n)=>{const a=setTimeout(()=>n(new Error("WeChat channel helper socket handshake timed out")),1e4),l=h=>{clearTimeout(a),this.lines?.off("line",c),r.off("close",o),n(new Error(`WeChat channel helper socket failed: ${h.message}`))},o=()=>{clearTimeout(a),r.off("error",l),this.lines?.off("line",c),n(new Error("WeChat channel helper socket closed before handshake"))},c=h=>{let u;try{u=JSON.parse(h)}catch{clearTimeout(a),r.off("error",l),r.off("close",o),this.lines?.off("line",c),n(new Error("WeChat channel helper sent invalid socket handshake JSON"));return}if(!A(u))return;clearTimeout(a),r.off("error",l),r.off("close",o),this.lines?.off("line",c);const p=C(u,this.options.expectedHelperVersion,this.options.requiredCapabilities);p.ok?(this.readyState=u,this.captureWarmupSnapshot(u),i(u)):n(new Error(`${p.errorCode}: ${p.errorSummary}`))};r.once("error",l),r.once("close",o),this.lines?.on("line",c)});try{this.writeFrame(E(this.options.expectedHelperVersion,this.options.requiredCapabilities))}catch(i){throw await this.stop().catch(()=>{}),i}return s}async request(e,r,s){const i=this.requestQueueTail.catch(()=>{}).then(()=>this.sendRequest(e,r,s));return this.requestQueueTail=i.then(()=>{},()=>{}),i}async sendRequest(e,r,s){await this.guardUnsafeWindowsCommand(e,s);try{return await this.sendRawRequest(e,r,s)}finally{await this.cleanupWindowsOverlaysAfterCommand(e,s).catch(()=>{})}}async sendRawRequest(e,r,s){if((!this.hasTransport()||!this.readyState)&&await this.start(),!this.hasTransport())throw new Error("WeChat channel helper is not started");const i=x(),n=O(e),a=Date.now();this.emitRequestTrace({phase:"request",at:new Date(a).toISOString(),id:i,command:e,traceId:s,params:r,timeoutMs:n});const l=new Promise((o,c)=>{const h=setTimeout(()=>{this.pending.get(i)&&(this.pending.delete(i),this.stopAfterCommandTimeout(e).finally(()=>{c(new Error(`helper_command_timeout: ${e}`))}))},n);this.pending.set(i,{resolve:o,reject:c,timer:h})});try{this.writeFrame({id:i,command:e,params:r,traceId:s})}catch(o){const c=this.pending.get(i);throw c&&clearTimeout(c.timer),this.pending.delete(i),this.emitRequestTrace({phase:"error",at:new Date().toISOString(),id:i,command:e,traceId:s,durationMs:Date.now()-a,errorSummary:o instanceof Error?o.message:String(o)}),o}try{const o=await l;return this.emitRequestTrace({phase:"response",at:new Date().toISOString(),id:i,command:e,traceId:s,durationMs:Date.now()-a,ok:o.ok,errorCode:o.errorCode,errorSummary:o.errorSummary,latencyMs:o.latencyMs,result:o.result}),this.captureWarmupSnapshot(o),this.captureWarmupSnapshot(o.result),o}catch(o){throw this.emitRequestTrace({phase:"error",at:new Date().toISOString(),id:i,command:e,traceId:s,durationMs:Date.now()-a,errorSummary:o instanceof Error?o.message:String(o)}),o}}async guardUnsafeWindowsCommand(e,r){if(!this.options.guardUnsafeWindowsCommands||!ne(e))return;const s=L(),i=M(e)?Math.max(N,s):s;if(i>0&&this.lastGuardPassAtMs>0&&Date.now()-this.lastGuardPassAtMs<i){if(!M(e)){if(!this.options.skipUserActivityGuard&&$(e)){const o=await this.sendRawRequest("activity.snapshot",{},r);if(!o.ok)throw new Error(`${o.errorCode??"user_activity_unknown"}: ${o.errorSummary??e}`);const c=S({snapshot:k(o.result),stage:"dangerous_action"});if(!c.ok)throw new Error(`user_active:${c.reasonCode}`)}await this.cleanupWindowsOverlays("before",e,r)}return}let n=await this.sendRawRequest("permissions.check",{},r);if(!n.ok)throw new Error(`${n.errorCode??"permissions_check_failed"}: ${n.errorSummary??e}`);let a=n.result??{};if(a.wechatRunning!==!1&&I(a)&&await this.tryRecoverFromStuckShell(r)){if(n=await this.sendRawRequest("permissions.check",{},r),!n.ok)throw new Error(`${n.errorCode??"permissions_check_failed"}: ${n.errorSummary??e}`);a=n.result??{}}const l=await this.requestFirstMissingMacPermissionPrompt(a,r);if(l==="screen-recording")throw new Error("permission_screen_recording_missing");if(l==="accessibility")throw new Error("permission_accessibility_missing");if(l==="input-monitoring")throw new Error("permission_input_monitoring_missing");if(a.automation===!1)throw new Error("permission_automation_missing");if(a.wechatRunning===!1)throw new Error("wechat_not_running");if(V(a))throw new Error("wechat_login_required");if(J(a))throw new Error("windows_visible_desktop_unavailable");if(a.dpiMappingAvailable===!1||a.displayTopologySupported===!1)throw new Error("dpi_mapping_failed");if(a.wechatWindowAvailable===!1)throw new Error("wechat_window_unavailable");if(a.wechatMainWindowResponsive===!1)throw new Error("wechat_window_unresponsive");if(!this.options.skipUserActivityGuard&&$(e)){const o=await this.sendRawRequest("activity.snapshot",{},r);if(!o.ok)throw new Error(`${o.errorCode??"user_activity_unknown"}: ${o.errorSummary??e}`);const c=S({snapshot:k(o.result),stage:"dangerous_action"});if(!c.ok)throw new Error(`user_active:${c.reasonCode}`)}await this.cleanupWindowsOverlays("before",e,r),this.lastGuardPassAtMs=Date.now()}async tryRecoverFromStuckShell(e){try{const r=await this.sendRawRequest("wechat.healthProbe",{},e);if(!r.ok||r.result?.stuckShell!==!0)return!1;const s=await this.sendRawRequest("windows.recoverWeChat",{allowRestart:!0,onlyIfUnresponsive:!1,waitAfterStartMs:4e3},e);return s.ok===!0&&s.result?.started===!0}catch{return!1}}async requestFirstMissingMacPermissionPrompt(e,r){const s=re(e);if(!s||process.platform!=="darwin")return s;const i=ie(s);try{await this.sendRawRequest(i,{},r)}catch{}return s}async cleanupWindowsOverlaysAfterCommand(e,r){!this.options.guardUnsafeWindowsCommands||!oe(e)||await this.cleanupWindowsOverlays("after",e,r)}async cleanupWindowsOverlays(e,r,s){if(this.options.cleanupWindowsOverlays===!1)return;if(!this.readyState?.capabilities.includes("overlayCleanup"))throw new Error("helper_capability_missing: overlayCleanup");const i=await this.sendRawRequest("windows.cleanupOverlays",{stage:e,command:r,includeGeneratedMediaPreviews:!0,includeToolingTerminals:!1,waitMs:e==="after"?220:120},s);if(!i.ok)throw new Error(`${i.errorCode??"overlay_cleanup_failed"}: ${i.errorSummary??r}`)}async healthCheck(e){return this.request("health.check",{},e)}getReadyState(){return this.readyState?{...this.readyState,capabilities:[...this.readyState.capabilities]}:null}getWarmupState(){return this.warmupState?{warmState:this.warmupState.warmState,metrics:this.warmupState.metrics?{...this.warmupState.metrics}:void 0}:null}async stop(){const e=this.child,r=this.socket;this.child=null,this.socket=null,this.readyState=null,this.lines?.close(),this.lines=null,this.rejectAllPending(new Error("WeChat channel helper stopped")),r&&!r.destroyed&&r.destroy(),e&&await Y(e)}hasTransport(){return!!this.child||!!this.socket}writeFrame(e){const r=`${JSON.stringify(e)}
3
- `;if(this.socket){this.socket.write(r);return}if(this.child){this.child.stdin.write(r);return}throw new Error("WeChat channel helper is not started")}handleLine(e){let r;try{r=JSON.parse(e)}catch{return}if(!se(r))return;const s=this.pending.get(r.id);s&&(clearTimeout(s.timer),this.pending.delete(r.id),s.resolve(r))}captureWarmupSnapshot(e){const r=q(e);r&&(this.warmupState=r)}captureStderr(e){const r=Buffer.isBuffer(e)?e.toString("utf8"):String(e??"");r&&(this.stderrTail=(this.stderrTail+r).slice(-2e3))}formatHelperExitMessage(e,r){const s=[e===null?null:`code=${e}`,r?`signal=${r}`:null,this.stderrTail.trim()?`stderr=${this.stderrTail.trim()}`:null].filter(Boolean);return s.length?`WeChat channel helper process exited (${s.join(", ")})`:"WeChat channel helper process exited"}rejectAllPending(e){for(const[r,s]of this.pending)clearTimeout(s.timer),s.reject(e),this.pending.delete(r)}emitRequestTrace(e){try{this.options.requestLogger?.(e)}catch{}}async stopAfterCommandTimeout(e){const r=this.child?.pid;if(await this.stop().catch(()=>{}),process.platform==="win32"){const s=typeof r=="number"&&r>0?[r]:[];await U(s).catch(()=>{})}this.emitRequestTrace({phase:"error",at:new Date().toISOString(),id:`timeout-cleanup:${e}`,command:e,errorSummary:"helper process stopped after command timeout"})}async connectDarwinHelperSocket(e){try{return await b(e.runtimeFile)}catch{f.rmSync(e.runtimeFile,{force:!0})}await W(e,{},this.options.openHelperAppForTest);const r=await P(e.runtimeFile,this.options.macosRuntimeInitialReadyTimeoutMs??5e3);if(r.ok)return r.socket;f.rmSync(e.runtimeFile,{force:!0}),await W(e,{forceNewInstance:!0},this.options.openHelperAppForTest);const s=await P(e.runtimeFile,this.options.macosRuntimeRelaunchReadyTimeoutMs??1e4);if(s.ok)return s.socket;throw new Error(`WeChat channel Helper.app socket did not become ready: ${s.error.message}`)}}async function U(t=[]){if(process.platform!=="win32")return;const e=t.filter(r=>Number.isInteger(r)&&r>0);if(e.length!==0)for(const r of e)await R(["taskkill","/PID",String(r),"/T","/F"],[0,128])}function I(t){return t.wechatWindowAvailable===!1&&(t.captureCandidateCount??0)===0&&(t.restoreCandidateCount??0)===0&&(t.hiddenRestoreCandidateCount??0)===0}function V(t){return t.wechatWindowAvailable!==!1?!1:![...t.captureCandidates??[],...t.restoreCandidates??[],...t.hiddenRestoreCandidates??[]].some(j)}function J(t){return t.windowsVisibleDesktopAvailable===!1||t.rdpVisibleDesktopAvailable===!1||t.desktopSessionVisible===!1||t.screenLocked===!0||t.rdpDisconnected===!0}function z(t){const e=String(t.appName||"").toLowerCase();return e==="wechat"||e==="weixin"}function j(t){return!(!z(t)||t.visible===!1||t.minimized===!0)}function B(t,e,r=process.platform){if(r==="darwin"){const s=Q(t);if(s&&e.length===0){const i=K();return{transport:"macos-socket",command:"/usr/bin/open",args:["-g",s,"--args","--socket-runtime",i],appPath:s,runtimeDir:i,runtimeFile:d.join(i,"runtime.json")}}}return{transport:"legacy-stdio",command:t,args:e}}function Q(t){const e=d.resolve(t),r=`${d.sep}Contents${d.sep}MacOS${d.sep}`,s=e.lastIndexOf(r);if(s<0)return null;const i=e.slice(0,s);return i.endsWith(".app")?i:null}function K(){const t=X().SHENNIAN_HELPER_RUNTIME_DIR?.trim();return t?d.resolve(t):d.join(H.homedir(),"Library","Application Support","Shennian","Helper")}async function Y(t){if(T(t))return;if(process.platform==="win32"&&t.pid){t.kill("SIGTERM"),await R(["taskkill","/PID",String(t.pid),"/T","/F"],[0,128]).catch(()=>{}),await y(t,m);return}t.kill("SIGTERM"),!await y(t,m)&&t.pid&&v(t.pid)&&(t.kill("SIGKILL"),await y(t,m))}function T(t){return t.exitCode!==null||t.signalCode!==null}function y(t,e){return T(t)?Promise.resolve(!0):new Promise(r=>{const s=setTimeout(()=>{t.off("exit",i),r(!1)},e),i=()=>{clearTimeout(s),r(!0)};t.once("exit",i)})}function R(t,e){return new Promise((r,s)=>{const[i,...n]=t,a=w(i,n,{stdio:"ignore",windowsHide:!0});a.once("error",s),a.once("exit",l=>{l!==null&&e.includes(l)?r():s(new Error(`${i} exited ${l}`))})})}function X(){return globalThis.process?.[F]??{}}function Z(t){let e;try{e=JSON.parse(f.readFileSync(t,"utf8"))}catch(i){throw new Error(`runtime_file_unreadable: ${i instanceof Error?i.message:String(i)}`)}if(!e||typeof e!="object")throw new Error("runtime_file_invalid");const r=e.socketPath;if(typeof r!="string"||!r.trim())throw new Error("runtime_socket_missing");const s=e.pid;return{socketPath:r,...typeof s=="number"&&Number.isInteger(s)&&s>0?{pid:s}:{}}}async function b(t){const{socketPath:e,pid:r}=Z(t);if(r&&!v(r))throw new Error(`runtime_process_stale: ${r}`);return new Promise((s,i)=>{const n=D.createConnection(e),a=setTimeout(()=>{n.destroy(),i(new Error(`runtime_socket_connect_timeout: ${e}`))},1e3);n.once("connect",()=>{clearTimeout(a),n.off("error",l),s(n)});const l=o=>{clearTimeout(a),n.destroy(),i(o)};n.once("error",l)})}async function P(t,e){const r=Date.now()+e;let s=null;for(;Date.now()<r;)try{return{ok:!0,socket:await b(t)}}catch(i){s=i instanceof Error?i:new Error(String(i));const n=r-Date.now();n>0&&await te(Math.min(150,n))}return{ok:!1,error:s??new Error("runtime file missing")}}async function W(t,e={},r=ee){f.mkdirSync(t.runtimeDir,{recursive:!0,mode:448});const s=e.forceNewInstance?["-n",...t.args]:t.args;try{await r(t.command,s)}catch(i){if(!(i instanceof Error?i.message:String(i)).includes("-1712"))throw i;await r(t.command,["-n",...t.args])}}function v(t){try{return process.kill(t,0),!0}catch{return!1}}async function ee(t,e){await new Promise((r,s)=>{const i=w(t,e,{stdio:["ignore","ignore","pipe"],windowsHide:!0});let n="";i.stderr.on("data",a=>{n=(n+String(a)).slice(-2e3)}),i.once("error",s),i.once("exit",(a,l)=>{a===0?r():s(new Error(`open Helper.app failed (${l?`signal=${l}`:`code=${a}`}${n.trim()?`, stderr=${n.trim()}`:""})`))})})}function te(t){return new Promise(e=>setTimeout(e,t))}function re(t){return t.screenRecording===!1?"screen-recording":t.accessibility===!1?"accessibility":t.inputMonitoring===!1?"input-monitoring":null}function ie(t){return t==="screen-recording"?"permissions.requestScreenRecording":t==="accessibility"?"permissions.requestAccessibility":"permissions.requestInputMonitoring"}function A(t){if(!t||typeof t!="object")return!1;const e=t;return e.type==="ready"&&typeof e.helperVersion=="string"&&typeof e.protocolVersion=="number"&&Array.isArray(e.capabilities)&&typeof e.pid=="number"}function se(t){if(!t||typeof t!="object")return!1;const e=t;return typeof e.id=="string"&&typeof e.ok=="boolean"&&typeof e.latencyMs=="number"}function ne(t){return t==="windows.focus"||t==="windows.capture"||t==="screen.capture"||t==="ocr.recognize"||t==="image.cropHash"||t==="wechat.searchConversation"||t==="wechat.focusMessageInput"||t==="wechat.pasteAndSubmit"||t==="keyboard.primeTextPaste"||t.startsWith("mouse.")||t.startsWith("keyboard.")||t.startsWith("clipboard.")||t==="menu.pickItem"||t==="savePanel.saveToPath"}function M(t){return t==="windows.capture"||t==="screen.capture"||t==="ocr.recognize"||t==="image.cropHash"}function oe(t){return t.startsWith("mouse.")||t.startsWith("keyboard.")||t.startsWith("clipboard.")||t==="menu.pickItem"||t==="savePanel.saveToPath"}function $(t){return t==="windows.focus"||t==="wechat.searchConversation"||t==="wechat.focusMessageInput"||t==="wechat.pasteAndSubmit"||t==="keyboard.primeTextPaste"||t.startsWith("mouse.")||t.startsWith("keyboard.")||t.startsWith("clipboard.set")||t==="clipboard.restore"||t==="menu.pickItem"||t==="savePanel.saveToPath"}export{me as WeChatChannelHelperClient,B as helperLaunchSpec,U as stopWindowsWeChatChannelHelperProcesses};
1
+ import{spawn as g}from"node:child_process";import{randomUUID as O}from"node:crypto";import w from"node:fs";import N from"node:net";import G from"node:os";import d from"node:path";import{createInterface as E}from"node:readline";import{decideWeChatChannelActivityGate as C,normalizeWeChatChannelActivitySnapshot as _}from"./human-coordination.js";import{createWeChatChannelHelperHello as T,extractWeChatChannelHelperWarmupSnapshot as L,timeoutForWeChatChannelHelperCommand as U,validateWeChatChannelHelperReady as R}from"./helper-protocol.js";const I=["en","v"].join(""),m=1500,V=1500,b=8e3,J="SHENNIAN_WECHAT_DANGEROUS_GUARD_THROTTLE_MS";class P extends Error{helperPid;constructor(t,r){super(t),this.helperPid=r,this.name="HelperVersionMismatchError"}}function z(){const e=process.env[J];if(e===void 0||e==="")return b;const t=Number.parseInt(e,10);return!Number.isFinite(t)||t<0?b:t}class Ee{options;child=null;socket=null;lines=null;readyState=null;warmupState=null;stderrTail="";startPromise=null;requestQueueTail=Promise.resolve();lastGuardPassAtMs=0;pending=new Map;constructor(t){this.options=t}async start(){return this.hasTransport()&&this.readyState?this.readyState:this.startPromise?this.startPromise:(this.hasTransport()&&await this.stop(),this.startPromise=this.startFresh().catch(async t=>{throw await this.stop().catch(()=>{}),t}).finally(()=>{this.startPromise=null}),this.startPromise)}async startFresh(){const t=Z(this.options.helperPath,this.options.args??[]);return t.transport==="macos-socket"?this.startDarwinAppSocketFresh(t):this.startStdioFresh(t)}async startStdioFresh(t){const r=g(t.command,t.args,{cwd:this.options.cwd,stdio:["pipe","pipe","pipe"],windowsHide:!0});this.child=r,this.stderrTail="",this.lines=E({input:r.stdout}),this.lines.on("line",s=>this.handleLine(s)),r.stderr.on("data",s=>{this.captureStderr(s)}),r.stdin.on("error",s=>{this.rejectAllPending(s instanceof Error?s:new Error(String(s)))}),r.once("error",s=>{this.child===r&&(this.child=null,this.readyState=null,this.lines?.close(),this.lines=null),this.rejectAllPending(s instanceof Error?s:new Error(String(s)))}),r.once("exit",(s,n)=>{this.child===r&&(this.child=null,this.readyState=null,this.lines?.close(),this.lines=null),this.rejectAllPending(new Error(this.formatHelperExitMessage(s,n)))});const i=new Promise((s,n)=>{const a=setTimeout(()=>n(new Error("WeChat channel helper handshake timed out")),1e4),c=u=>{clearTimeout(a),this.lines?.off("line",l),r.off("exit",o),n(new Error(`WeChat channel helper failed to start: ${u.message}`))},o=(u,h)=>{clearTimeout(a),r.off("error",c),this.lines?.off("line",l),n(new Error(this.formatHelperExitMessage(u,h)))},l=u=>{let h;try{h=JSON.parse(u)}catch{clearTimeout(a),r.off("error",c),this.lines?.off("line",l),n(new Error("WeChat channel helper sent invalid handshake JSON"));return}if(!$(h))return;clearTimeout(a),r.off("error",c),r.off("exit",o),this.lines?.off("line",l);const p=R(h,this.options.expectedHelperVersion,this.options.requiredCapabilities);p.ok?(this.readyState=h,this.captureWarmupSnapshot(h),s(h)):n(new Error(`${p.errorCode}: ${p.errorSummary}`))};r.once("error",c),r.once("exit",o),this.lines?.on("line",l)});try{r.stdin.write(`${JSON.stringify(T(this.options.expectedHelperVersion,this.options.requiredCapabilities))}
2
+ `)}catch(s){throw await this.stop().catch(()=>{}),s}return i}async startDarwinAppSocketFresh(t,r=!0){const i=await this.connectDarwinHelperSocket(t);this.socket=i,this.stderrTail="",this.lines=E({input:i}),this.lines.on("line",n=>this.handleLine(n)),i.on("error",n=>{this.socket===i&&(this.socket=null,this.readyState=null,this.lines?.close(),this.lines=null),this.rejectAllPending(n instanceof Error?n:new Error(String(n)))}),i.once("close",()=>{this.socket===i&&(this.socket=null,this.readyState=null,this.lines?.close(),this.lines=null),this.rejectAllPending(new Error("WeChat channel helper socket closed"))});const s=new Promise((n,a)=>{const c=setTimeout(()=>a(new Error("WeChat channel helper socket handshake timed out")),1e4),o=h=>{clearTimeout(c),this.lines?.off("line",u),i.off("close",l),a(new Error(`WeChat channel helper socket failed: ${h.message}`))},l=()=>{clearTimeout(c),i.off("error",o),this.lines?.off("line",u),a(new Error("WeChat channel helper socket closed before handshake"))},u=h=>{let p;try{p=JSON.parse(h)}catch{clearTimeout(c),i.off("error",o),i.off("close",l),this.lines?.off("line",u),a(new Error("WeChat channel helper sent invalid socket handshake JSON"));return}if(!$(p))return;clearTimeout(c),i.off("error",o),i.off("close",l),this.lines?.off("line",u);const y=R(p,this.options.expectedHelperVersion,this.options.requiredCapabilities);if(y.ok)this.readyState=p,this.captureWarmupSnapshot(p),n(p);else{const k=`${y.errorCode}: ${y.errorSummary}`;a(y.errorCode==="helper_version_mismatch"?new P(k,Number.isInteger(p.pid)?p.pid:null):new Error(k))}};i.once("error",o),i.once("close",l),this.lines?.on("line",u)});try{this.writeFrame(T(this.options.expectedHelperVersion,this.options.requiredCapabilities))}catch(n){throw await this.stop().catch(()=>{}),n}try{return await s}catch(n){if(r&&n instanceof P)return await this.stop().catch(()=>{}),await ie(n.helperPid),w.rmSync(t.runtimeFile,{force:!0}),this.startDarwinAppSocketFresh(t,!1);throw n}}async request(t,r,i){const s=this.requestQueueTail.catch(()=>{}).then(()=>this.sendRequest(t,r,i));return this.requestQueueTail=s.then(()=>{},()=>{}),s}async sendRequest(t,r,i){await this.guardUnsafeWindowsCommand(t,i);try{return await this.sendRawRequest(t,r,i)}finally{await this.cleanupWindowsOverlaysAfterCommand(t,i).catch(()=>{})}}async sendRawRequest(t,r,i){if((!this.hasTransport()||!this.readyState)&&await this.start(),!this.hasTransport())throw new Error("WeChat channel helper is not started");const s=O(),n=U(t),a=Date.now();this.emitRequestTrace({phase:"request",at:new Date(a).toISOString(),id:s,command:t,traceId:i,params:r,timeoutMs:n});const c=new Promise((o,l)=>{const u=setTimeout(()=>{this.pending.get(s)&&(this.pending.delete(s),this.stopAfterCommandTimeout(t).finally(()=>{l(new Error(`helper_command_timeout: ${t}`))}))},n);this.pending.set(s,{resolve:o,reject:l,timer:u})});try{this.writeFrame({id:s,command:t,params:r,traceId:i})}catch(o){const l=this.pending.get(s);throw l&&clearTimeout(l.timer),this.pending.delete(s),this.emitRequestTrace({phase:"error",at:new Date().toISOString(),id:s,command:t,traceId:i,durationMs:Date.now()-a,errorSummary:o instanceof Error?o.message:String(o)}),o}try{const o=await c;return this.emitRequestTrace({phase:"response",at:new Date().toISOString(),id:s,command:t,traceId:i,durationMs:Date.now()-a,ok:o.ok,errorCode:o.errorCode,errorSummary:o.errorSummary,latencyMs:o.latencyMs,result:o.result}),this.captureWarmupSnapshot(o),this.captureWarmupSnapshot(o.result),o}catch(o){throw this.emitRequestTrace({phase:"error",at:new Date().toISOString(),id:s,command:t,traceId:i,durationMs:Date.now()-a,errorSummary:o instanceof Error?o.message:String(o)}),o}}async guardUnsafeWindowsCommand(t,r){if(!this.options.guardUnsafeWindowsCommands||!ue(t))return;const i=z(),s=q(t)?Math.max(V,i):i;if(s>0&&this.lastGuardPassAtMs>0&&Date.now()-this.lastGuardPassAtMs<s){if(!q(t)){if(!this.options.skipUserActivityGuard&&F(t)){const o=await this.sendRawRequest("activity.snapshot",{},r);if(!o.ok)throw new Error(`${o.errorCode??"user_activity_unknown"}: ${o.errorSummary??t}`);const l=C({snapshot:_(o.result),stage:"dangerous_action"});if(!l.ok)throw new Error(`user_active:${l.reasonCode}`)}await this.cleanupWindowsOverlays("before",t,r)}return}let n=await this.sendRawRequest("permissions.check",{},r);if(!n.ok)throw new Error(`${n.errorCode??"permissions_check_failed"}: ${n.errorSummary??t}`);let a=n.result??{};if(a.wechatRunning!==!1&&B(a)&&await this.tryRecoverFromStuckShell(r)){if(n=await this.sendRawRequest("permissions.check",{},r),!n.ok)throw new Error(`${n.errorCode??"permissions_check_failed"}: ${n.errorSummary??t}`);a=n.result??{}}const c=await this.requestFirstMissingMacPermissionPrompt(a,r);if(c==="screen-recording")throw new Error("permission_screen_recording_missing");if(c==="accessibility")throw new Error("permission_accessibility_missing");if(c==="input-monitoring")throw new Error("permission_input_monitoring_missing");if(a.automation===!1)throw new Error("permission_automation_missing");if(a.wechatRunning===!1)throw new Error("wechat_not_running");if(K(a))throw new Error("wechat_login_required");if(Q(a))throw new Error("windows_visible_desktop_unavailable");if(a.dpiMappingAvailable===!1||a.displayTopologySupported===!1)throw new Error("dpi_mapping_failed");if(a.wechatWindowAvailable===!1)throw new Error("wechat_window_unavailable");if(a.wechatMainWindowResponsive===!1)throw new Error("wechat_window_unresponsive");if(!this.options.skipUserActivityGuard&&F(t)){const o=await this.sendRawRequest("activity.snapshot",{},r);if(!o.ok)throw new Error(`${o.errorCode??"user_activity_unknown"}: ${o.errorSummary??t}`);const l=C({snapshot:_(o.result),stage:"dangerous_action"});if(!l.ok)throw new Error(`user_active:${l.reasonCode}`)}await this.cleanupWindowsOverlays("before",t,r),this.lastGuardPassAtMs=Date.now()}async tryRecoverFromStuckShell(t){try{const r=await this.sendRawRequest("wechat.healthProbe",{},t);if(!r.ok||r.result?.stuckShell!==!0)return!1;const i=await this.sendRawRequest("windows.recoverWeChat",{allowRestart:!0,onlyIfUnresponsive:!1,waitAfterStartMs:4e3},t);return i.ok===!0&&i.result?.started===!0}catch{return!1}}async requestFirstMissingMacPermissionPrompt(t,r){const i=ae(t);if(!i||process.platform!=="darwin")return i;const s=ce(i);try{await this.sendRawRequest(s,{},r)}catch{}return i}async cleanupWindowsOverlaysAfterCommand(t,r){!this.options.guardUnsafeWindowsCommands||!he(t)||await this.cleanupWindowsOverlays("after",t,r)}async cleanupWindowsOverlays(t,r,i){if(this.options.cleanupWindowsOverlays===!1)return;if(!this.readyState?.capabilities.includes("overlayCleanup"))throw new Error("helper_capability_missing: overlayCleanup");const s=await this.sendRawRequest("windows.cleanupOverlays",{stage:t,command:r,includeGeneratedMediaPreviews:!0,includeToolingTerminals:!1,waitMs:t==="after"?220:120},i);if(!s.ok)throw new Error(`${s.errorCode??"overlay_cleanup_failed"}: ${s.errorSummary??r}`)}async healthCheck(t){return this.request("health.check",{},t)}getReadyState(){return this.readyState?{...this.readyState,capabilities:[...this.readyState.capabilities]}:null}getWarmupState(){return this.warmupState?{warmState:this.warmupState.warmState,metrics:this.warmupState.metrics?{...this.warmupState.metrics}:void 0}:null}async stop(){const t=this.child,r=this.socket;this.child=null,this.socket=null,this.readyState=null,this.lines?.close(),this.lines=null,this.rejectAllPending(new Error("WeChat channel helper stopped")),r&&!r.destroyed&&r.destroy(),t&&await re(t)}hasTransport(){return!!this.child||!!this.socket}writeFrame(t){const r=`${JSON.stringify(t)}
3
+ `;if(this.socket){this.socket.write(r);return}if(this.child){this.child.stdin.write(r);return}throw new Error("WeChat channel helper is not started")}handleLine(t){let r;try{r=JSON.parse(t)}catch{return}if(!le(r))return;const i=this.pending.get(r.id);i&&(clearTimeout(i.timer),this.pending.delete(r.id),i.resolve(r))}captureWarmupSnapshot(t){const r=L(t);r&&(this.warmupState=r)}captureStderr(t){const r=Buffer.isBuffer(t)?t.toString("utf8"):String(t??"");r&&(this.stderrTail=(this.stderrTail+r).slice(-2e3))}formatHelperExitMessage(t,r){const i=[t===null?null:`code=${t}`,r?`signal=${r}`:null,this.stderrTail.trim()?`stderr=${this.stderrTail.trim()}`:null].filter(Boolean);return i.length?`WeChat channel helper process exited (${i.join(", ")})`:"WeChat channel helper process exited"}rejectAllPending(t){for(const[r,i]of this.pending)clearTimeout(i.timer),i.reject(t),this.pending.delete(r)}emitRequestTrace(t){try{this.options.requestLogger?.(t)}catch{}}async stopAfterCommandTimeout(t){const r=this.child?.pid;if(await this.stop().catch(()=>{}),process.platform==="win32"){const i=typeof r=="number"&&r>0?[r]:[];await j(i).catch(()=>{})}this.emitRequestTrace({phase:"error",at:new Date().toISOString(),id:`timeout-cleanup:${t}`,command:t,errorSummary:"helper process stopped after command timeout"})}async connectDarwinHelperSocket(t){try{return await A(t.runtimeFile)}catch{w.rmSync(t.runtimeFile,{force:!0})}await D(t,{},this.options.openHelperAppForTest);const r=await x(t.runtimeFile,this.options.macosRuntimeInitialReadyTimeoutMs??5e3);if(r.ok)return r.socket;w.rmSync(t.runtimeFile,{force:!0}),await D(t,{forceNewInstance:!0},this.options.openHelperAppForTest);const i=await x(t.runtimeFile,this.options.macosRuntimeRelaunchReadyTimeoutMs??1e4);if(i.ok)return i.socket;throw new Error(`WeChat channel Helper.app socket did not become ready: ${i.error.message}`)}}async function j(e=[]){if(process.platform!=="win32")return;const t=e.filter(r=>Number.isInteger(r)&&r>0);if(t.length!==0)for(const r of t)await M(["taskkill","/PID",String(r),"/T","/F"],[0,128])}function B(e){return e.wechatWindowAvailable===!1&&(e.captureCandidateCount??0)===0&&(e.restoreCandidateCount??0)===0&&(e.hiddenRestoreCandidateCount??0)===0}function K(e){return e.wechatWindowAvailable!==!1?!1:![...e.captureCandidates??[],...e.restoreCandidates??[],...e.hiddenRestoreCandidates??[]].some(X)}function Q(e){return e.windowsVisibleDesktopAvailable===!1||e.rdpVisibleDesktopAvailable===!1||e.desktopSessionVisible===!1||e.screenLocked===!0||e.rdpDisconnected===!0}function Y(e){const t=String(e.appName||"").toLowerCase();return t==="wechat"||t==="weixin"}function X(e){return!(!Y(e)||e.visible===!1||e.minimized===!0)}function Z(e,t,r=process.platform){if(r==="darwin"){const i=ee(e);if(i&&t.length===0){const s=te();return{transport:"macos-socket",command:"/usr/bin/open",args:["-g",i,"--args","--socket-runtime",s],appPath:i,runtimeDir:s,runtimeFile:d.join(s,"runtime.json")}}}return{transport:"legacy-stdio",command:e,args:t}}function ee(e){const t=d.resolve(e),r=`${d.sep}Contents${d.sep}MacOS${d.sep}`,i=t.lastIndexOf(r);if(i<0)return null;const s=t.slice(0,i);return s.endsWith(".app")?s:null}function te(){const e=se().SHENNIAN_HELPER_RUNTIME_DIR?.trim();return e?d.resolve(e):d.join(G.homedir(),"Library","Application Support","Shennian","Helper")}async function re(e){if(W(e))return;if(process.platform==="win32"&&e.pid){e.kill("SIGTERM"),await M(["taskkill","/PID",String(e.pid),"/T","/F"],[0,128]).catch(()=>{}),await S(e,m);return}e.kill("SIGTERM"),!await S(e,m)&&e.pid&&f(e.pid)&&(e.kill("SIGKILL"),await S(e,m))}async function ie(e){if(process.platform!=="darwin"||!e||e===process.pid||!f(e))return;try{process.kill(e,"SIGTERM")}catch{return}if(!await v(e,m)&&f(e)){try{process.kill(e,"SIGKILL")}catch{return}await v(e,m)}}async function v(e,t){const r=Date.now()+t;for(;Date.now()<r;){if(!f(e))return!0;await H(Math.min(50,r-Date.now()))}return!f(e)}function W(e){return e.exitCode!==null||e.signalCode!==null}function S(e,t){return W(e)?Promise.resolve(!0):new Promise(r=>{const i=setTimeout(()=>{e.off("exit",s),r(!1)},t),s=()=>{clearTimeout(i),r(!0)};e.once("exit",s)})}function M(e,t){return new Promise((r,i)=>{const[s,...n]=e,a=g(s,n,{stdio:"ignore",windowsHide:!0});a.once("error",i),a.once("exit",c=>{c!==null&&t.includes(c)?r():i(new Error(`${s} exited ${c}`))})})}function se(){return globalThis.process?.[I]??{}}function ne(e){let t;try{t=JSON.parse(w.readFileSync(e,"utf8"))}catch(s){throw new Error(`runtime_file_unreadable: ${s instanceof Error?s.message:String(s)}`)}if(!t||typeof t!="object")throw new Error("runtime_file_invalid");const r=t.socketPath;if(typeof r!="string"||!r.trim())throw new Error("runtime_socket_missing");const i=t.pid;return{socketPath:r,...typeof i=="number"&&Number.isInteger(i)&&i>0?{pid:i}:{}}}async function A(e){const{socketPath:t,pid:r}=ne(e);if(r&&!f(r))throw new Error(`runtime_process_stale: ${r}`);return new Promise((i,s)=>{const n=N.createConnection(t),a=setTimeout(()=>{n.destroy(),s(new Error(`runtime_socket_connect_timeout: ${t}`))},1e3);n.once("connect",()=>{clearTimeout(a),n.off("error",c),i(n)});const c=o=>{clearTimeout(a),n.destroy(),s(o)};n.once("error",c)})}async function x(e,t){const r=Date.now()+t;let i=null;for(;Date.now()<r;)try{return{ok:!0,socket:await A(e)}}catch(s){i=s instanceof Error?s:new Error(String(s));const n=r-Date.now();n>0&&await H(Math.min(150,n))}return{ok:!1,error:i??new Error("runtime file missing")}}async function D(e,t={},r=oe){w.mkdirSync(e.runtimeDir,{recursive:!0,mode:448});const i=t.forceNewInstance?["-n",...e.args]:e.args;try{await r(e.command,i)}catch(s){if(!(s instanceof Error?s.message:String(s)).includes("-1712"))throw s;await r(e.command,["-n",...e.args])}}function f(e){try{return process.kill(e,0),!0}catch{return!1}}async function oe(e,t){await new Promise((r,i)=>{const s=g(e,t,{stdio:["ignore","ignore","pipe"],windowsHide:!0});let n="";s.stderr.on("data",a=>{n=(n+String(a)).slice(-2e3)}),s.once("error",i),s.once("exit",(a,c)=>{a===0?r():i(new Error(`open Helper.app failed (${c?`signal=${c}`:`code=${a}`}${n.trim()?`, stderr=${n.trim()}`:""})`))})})}function H(e){return new Promise(t=>setTimeout(t,e))}function ae(e){return e.screenRecording===!1?"screen-recording":e.accessibility===!1?"accessibility":e.inputMonitoring===!1?"input-monitoring":null}function ce(e){return e==="screen-recording"?"permissions.requestScreenRecording":e==="accessibility"?"permissions.requestAccessibility":"permissions.requestInputMonitoring"}function $(e){if(!e||typeof e!="object")return!1;const t=e;return t.type==="ready"&&typeof t.helperVersion=="string"&&typeof t.protocolVersion=="number"&&Array.isArray(t.capabilities)&&typeof t.pid=="number"}function le(e){if(!e||typeof e!="object")return!1;const t=e;return typeof t.id=="string"&&typeof t.ok=="boolean"&&typeof t.latencyMs=="number"}function ue(e){return e==="windows.focus"||e==="windows.capture"||e==="screen.capture"||e==="ocr.recognize"||e==="image.cropHash"||e==="wechat.searchConversation"||e==="wechat.focusMessageInput"||e==="wechat.pasteAndSubmit"||e==="keyboard.primeTextPaste"||e.startsWith("mouse.")||e.startsWith("keyboard.")||e.startsWith("clipboard.")||e==="menu.pickItem"||e==="savePanel.saveToPath"}function q(e){return e==="windows.capture"||e==="screen.capture"||e==="ocr.recognize"||e==="image.cropHash"}function he(e){return e.startsWith("mouse.")||e.startsWith("keyboard.")||e.startsWith("clipboard.")||e==="menu.pickItem"||e==="savePanel.saveToPath"}function F(e){return e==="windows.focus"||e==="wechat.searchConversation"||e==="wechat.focusMessageInput"||e==="wechat.pasteAndSubmit"||e==="keyboard.primeTextPaste"||e.startsWith("mouse.")||e.startsWith("keyboard.")||e.startsWith("clipboard.set")||e==="clipboard.restore"||e==="menu.pickItem"||e==="savePanel.saveToPath"}export{Ee as WeChatChannelHelperClient,Z as helperLaunchSpec,j as stopWindowsWeChatChannelHelperProcesses};
@@ -1 +1 @@
1
- import m from"node:fs";import v from"node:os";import t from"node:path";import{spawnSync as C}from"node:child_process";import H from"chalk";import{getDefaultWeChatHelperRuntimeRoot as V,readWeChatChannelHelperRuntimePackageManifest as y,resolveWeChatChannelHelperAsset as b,SHENNIAN_HELPER_RUNTIME_DIR_ENV as U,WECHAT_CHANNEL_HELPER_DIR_ENV as T}from"../channels/wechat-channel/helper-assets.js";import{downloadOfficialHelperRuntimePackage as L}from"./helper-runtime-official-download.js";import{compareVersions as N,getCurrentVersion as j}from"../upgrade/engine.js";import{SerialWeChatAutomationLane as W}from"../channels/wechat-channel/automation-lane.js";const u="helper-runtime-package.json";function ge(e){const r=e.command("runtime").description("Install, repair, and inspect Shennian local runtimes");r.command("status").description("Print local Shennian runtime status").option("--json","Output JSON",!1).option("--platform <platform>","Platform override: darwin or win32").action(o=>{const a=R({platform:o.platform});_(a,!!o.json),a.ok||(process.exitCode=1)}),r.command("install").description("Install a Shennian runtime component").argument("<component>","Runtime component, currently only: helper").option("--source <path>","Helper runtime package/source directory").option("--channel <channel>","Official Helper runtime channel: stable or next").option("--manifest-url <url>","Official Helper runtime manifest URL override").option("--no-official-download","Do not fall back to Shennian official Helper runtime download").option("--json","Output JSON",!1).option("--platform <platform>","Platform override: darwin or win32").action(async(o,a)=>{const n=o==="helper"?await P({source:a.source,platform:a.platform,officialDownload:a.officialDownload===!1?!1:{channel:a.channel,manifestUrl:a.manifestUrl}}):D(o);_(n,!!a.json),n.ok||(process.exitCode=1)}),r.command("upgrade").description("Upgrade a Shennian runtime component").argument("<component>","Runtime component, currently only: helper").option("--source <path>","Helper runtime package/source directory").option("--channel <channel>","Official Helper runtime channel: stable or next").option("--manifest-url <url>","Official Helper runtime manifest URL override").option("--no-official-download","Do not use Shennian official Helper runtime download").option("--json","Output JSON",!1).option("--platform <platform>","Platform override: darwin or win32").action(async(o,a)=>{const n=o==="helper"?await P({source:a.source,platform:a.platform,force:!0,preferOfficialDownload:!a.source,officialDownload:a.officialDownload===!1?!1:{channel:a.channel,manifestUrl:a.manifestUrl}}):D(o);_(n,!!a.json),n.ok||(process.exitCode=1)}),r.command("repair").description("Repair a Shennian runtime component").argument("[component]","Runtime component, currently only: helper","helper").option("--source <path>","Helper runtime package/source directory").option("--channel <channel>","Official Helper runtime channel: stable or next").option("--manifest-url <url>","Official Helper runtime manifest URL override").option("--no-official-download","Do not fall back to Shennian official Helper runtime download").option("--json","Output JSON",!1).option("--platform <platform>","Platform override: darwin or win32").action(async(o,a)=>{const n=o==="helper"?await P({source:a.source,platform:a.platform,force:!0,preferOfficialDownload:!a.source,officialDownload:a.officialDownload===!1?!1:{channel:a.channel,manifestUrl:a.manifestUrl}}):D(o);_(n,!!a.json),n.ok||(process.exitCode=1)})}function R(e={}){const r=k(e.platform);if(!r)return{ok:!1,installed:!1,repairable:!1,reasonCode:"unsupported_platform",message:"Shennian Helper runtime is only available on macOS and Windows.",repairSuggestion:c("unsupported_platform")};const o=e.env??process.env,a=e.homedir,n=b({platform:r,env:o,homedir:a,includeInstalledDesktop:!1}),i=V({platform:r,env:o,homedir:a});if(!n.ok)return{ok:!1,platform:r,targetPlatform:r,installed:!1,repairable:G(n.reasonCode),reasonCode:n.reasonCode,message:n.message,runtimeRoot:i,repairSuggestion:c(n.reasonCode),checkedSources:S({platform:r,env:o,homedir:a})};const s=y({platform:r,helperDir:n.helperDir});if(!s.ok)return{ok:!1,platform:r,targetPlatform:r,installed:!1,repairable:!0,reasonCode:s.reasonCode,message:s.message,helperDir:n.helperDir,helperPath:n.helperPath,helperVersion:n.version,runtimeVersion:n.version,protocolVersion:n.manifest.protocolVersion,runtimeRoot:i,repairSuggestion:c(s.reasonCode),checkedSources:S({platform:r,env:o,homedir:a})};const l=O({platform:r,packageManifest:s.manifest,currentCliVersion:j(),helperVersion:n.version,protocolVersion:n.manifest.protocolVersion});return l.ok?{ok:!0,platform:r,targetPlatform:r,installed:!0,repairable:!1,message:`Shennian Helper runtime is installed: ${n.helperDir}`,helperDir:n.helperDir,helperPath:n.helperPath,helperVersion:n.version,runtimeVersion:n.version,protocolVersion:n.manifest.protocolVersion,minCliVersion:s.manifest.minCliVersion,sha256:s.manifest.sha256,packageManifestPath:s.manifestPath,packageKind:s.manifest.packageKind,installTarget:s.manifest.installTarget,signature:s.manifest.signature,runtimeRoot:i}:{ok:!1,platform:r,targetPlatform:r,installed:!0,repairable:l.repairable,reasonCode:l.reasonCode,message:l.message,helperDir:n.helperDir,helperPath:n.helperPath,helperVersion:n.version,runtimeVersion:n.version,protocolVersion:n.manifest.protocolVersion,minCliVersion:s.manifest.minCliVersion,sha256:s.manifest.sha256,packageManifestPath:s.manifestPath,packageKind:s.manifest.packageKind,installTarget:s.manifest.installTarget,signature:s.manifest.signature,runtimeRoot:i,repairSuggestion:c(l.reasonCode,s.manifest.minCliVersion),checkedSources:S({platform:r,env:o,homedir:a})}}function M(e={}){const r=k(e.platform);if(!r)return{ok:!1,reasonCode:"unsupported_platform",message:"Shennian Helper runtime is only available on macOS and Windows.",repairable:!1,repairSuggestion:c("unsupported_platform")};const o=e.env??process.env,a=J(e.io),n=e.homedir??a.homedir(),i=R({platform:r,env:o,homedir:n});if(i.ok&&!e.force&&i.helperDir&&i.helperPath&&i.helperVersion&&i.protocolVersion)return{ok:!0,action:"already_installed",platform:r,targetPlatform:r,installed:!0,repairable:!1,targetDir:Z(r,i.helperDir),helperDir:i.helperDir,helperPath:i.helperPath,helperVersion:i.helperVersion,runtimeVersion:i.helperVersion,protocolVersion:i.protocolVersion,minCliVersion:i.minCliVersion,sha256:i.sha256,packageManifestPath:i.packageManifestPath,packageKind:i.packageKind,installTarget:i.installTarget,signature:i.signature,message:`Shennian Helper runtime is already installed: ${i.helperDir}`};const s=e.source?[t.resolve(e.source)]:S({platform:r,env:o,homedir:n}),l=s.map(w=>q({candidate:w,platform:r,io:a})).find(w=>w!=null);if(!l)return{ok:!1,platform:r,targetPlatform:r,installed:!1,repairable:!0,reasonCode:"helper_runtime_source_missing",message:"No installable Shennian Helper runtime package was found. Open Shennian Desktop, pass --source, or download the official helper package.",repairSuggestion:c("helper_runtime_source_missing"),checkedSources:s};const h=y({platform:r,manifestPath:l.packageManifestPath});if(!h.ok)return{ok:!1,platform:r,targetPlatform:r,installed:!1,repairable:!0,reasonCode:h.reasonCode,message:h.message,repairSuggestion:c(h.reasonCode),checkedSources:s};const g=O({platform:r,packageManifest:h.manifest,currentCliVersion:j()});if(!g.ok)return{ok:!1,platform:r,targetPlatform:r,installed:!1,repairable:g.repairable,reasonCode:g.reasonCode,message:g.message,repairSuggestion:c(g.reasonCode,h.manifest.minCliVersion),checkedSources:s};const d=Y({platform:r,env:o,homedir:n,packageKind:l.packageKind});if(!d)return{ok:!1,platform:r,targetPlatform:r,installed:!1,repairable:!1,reasonCode:"helper_runtime_target_unavailable",message:"Unable to determine Helper runtime install target for this platform.",repairSuggestion:c("helper_runtime_target_unavailable"),checkedSources:s};ee({platform:r,sourceDir:l.sourceDir,targetDir:d,io:a}),te({sourceManifestPath:l.packageManifestPath,targetManifestPath:l.packageManifestPathInTarget(d),io:a});const f=b({platform:r,baseDir:l.manifestDirInTarget(d),verifyIntegrity:!0});if(!f.ok)return{ok:!1,platform:r,targetPlatform:r,installed:!1,repairable:!0,reasonCode:f.reasonCode,message:`Installed Helper runtime could not be verified: ${f.message}`,repairSuggestion:c(f.reasonCode),checkedSources:s};ie(r,f.helperPath,a);const p=y({platform:r,helperDir:f.helperDir});return p.ok?{ok:!0,action:"installed",platform:r,targetPlatform:r,installed:!0,repairable:!1,targetDir:d,helperDir:f.helperDir,helperPath:f.helperPath,helperVersion:f.version,runtimeVersion:f.version,protocolVersion:f.manifest.protocolVersion,minCliVersion:p.manifest.minCliVersion,sha256:p.manifest.sha256,packageManifestPath:p.manifestPath,packageKind:p.manifest.packageKind,installTarget:p.manifest.installTarget,signature:p.manifest.signature,message:`Installed Shennian Helper runtime to ${d}`}:{ok:!1,platform:r,targetPlatform:r,installed:!1,repairable:!0,reasonCode:p.reasonCode,message:`Installed Helper runtime package manifest could not be verified: ${p.message}`,repairSuggestion:c(p.reasonCode),checkedSources:s}}async function P(e={}){const r=new W({lockPath:K(e),owner:"helper-runtime-install",defaultWaitMs:0});try{return await r.run("helper-runtime-install",()=>B(e))}catch(o){if(F(o)){const a=k(e.platform)??void 0;return{ok:!1,platform:a,targetPlatform:a,installed:!1,repairable:!0,reasonCode:"wechat_automation_busy",message:o instanceof Error?o.message:String(o),repairSuggestion:"Wait for the current WeChat automation run to finish, then retry Helper install or repair."}}throw o}}function K(e){const r=e.env?.SHENNIAN_HOME?.trim()||process.env.SHENNIAN_HOME?.trim(),o=r?t.resolve(r):t.join(e.homedir??v.homedir(),".shennian");return t.join(o,"runtime","wechat-automation.lock")}function F(e){return e instanceof Error?e.message.includes("wechat_automation_busy"):String(e).includes("wechat_automation_busy")}async function B(e={}){if(e.preferOfficialDownload&&!e.source&&e.officialDownload!==!1)return await I(e);const r=M(e);return r.ok||e.source||e.officialDownload===!1||!z(r.reasonCode)?r.ok?{...r,source:r.source??"local"}:r:await I(e,r)}async function I(e,r){const o=k(e.platform);if(!o)return r??{ok:!1,repairable:!1,reasonCode:"unsupported_platform",message:"Shennian Helper runtime is only available on macOS and Windows.",repairSuggestion:c("unsupported_platform")};const a=e.officialDownload===!1||e.officialDownload==null?{}:e.officialDownload,n=await L({...a,platform:o,env:e.env??process.env});if(!n.ok)return{ok:!1,platform:o,targetPlatform:o,installed:!1,repairable:!0,reasonCode:n.reasonCode,message:n.message,repairSuggestion:c(n.reasonCode),checkedSources:r?.checkedSources,officialDownload:{manifestUrl:n.manifestUrl,artifactUrl:n.artifactUrl}};try{const i=M({...e,source:n.sourceDir,platform:o,force:e.force??e.preferOfficialDownload??!1});return i.ok?{...i,source:"official-download",officialDownload:{channel:n.channel,manifestUrl:n.manifestUrl,artifactUrl:n.artifactUrl,artifactSha256:n.artifactSha256,artifactSizeBytes:n.artifactSizeBytes,arch:n.arch,helperVersion:n.helperVersion,protocolVersion:n.protocolVersion,minCliVersion:n.minCliVersion}}:{...i,reasonCode:i.reasonCode==="helper_runtime_source_missing"?"helper_runtime_artifact_invalid":i.reasonCode,message:i.reasonCode==="helper_runtime_source_missing"?"Official Helper runtime artifact did not contain an installable runtime package.":i.message,repairSuggestion:c(i.reasonCode==="helper_runtime_source_missing"?"helper_runtime_artifact_invalid":i.reasonCode),officialDownload:{manifestUrl:n.manifestUrl,artifactUrl:n.artifactUrl}}}finally{n.cleanup()}}function z(e){return e==="helper_runtime_source_missing"||e==="helper_runtime_package_manifest_missing"||e==="helper_runtime_package_manifest_invalid"}function k(e){const r=e??process.platform;return r==="darwin"||r==="win32"?r:null}function O(e){return e.packageManifest.platform!==e.platform?{ok:!1,reasonCode:"helper_runtime_platform_mismatch",message:`Helper runtime package platform ${e.packageManifest.platform} does not match ${e.platform}.`,repairable:!0}:e.helperVersion&&e.packageManifest.helperVersion!==e.helperVersion?{ok:!1,reasonCode:"helper_runtime_version_mismatch",message:`Helper runtime package version ${e.packageManifest.helperVersion} does not match installed helper ${e.helperVersion}.`,repairable:!0}:e.protocolVersion&&e.packageManifest.protocolVersion!==e.protocolVersion?{ok:!1,reasonCode:"helper_runtime_protocol_mismatch",message:`Helper runtime package protocol ${e.packageManifest.protocolVersion} does not match installed helper protocol ${e.protocolVersion}.`,repairable:!0}:N(e.currentCliVersion,e.packageManifest.minCliVersion)!=="none"?{ok:!1,reasonCode:"helper_runtime_cli_too_old",message:`Shennian CLI ${e.currentCliVersion} is older than required ${e.packageManifest.minCliVersion}.`,repairable:!1}:{ok:!0}}function G(e){return e!=="unsupported_platform"&&e!=="helper_runtime_cli_too_old"}function c(e,r){if(e==="unsupported_platform")return"Use Shennian Helper runtime on macOS or Windows.";if(e==="unsupported_runtime_component")return"Use `shennian runtime install helper` or `shennian runtime repair helper`.";if(e==="helper_runtime_cli_too_old")return`Upgrade Shennian CLI${r?` to ${r} or newer`:""}, then retry.`;if(e==="helper_runtime_target_unavailable")return"Set the current user home/LOCALAPPDATA correctly, then retry.";if(e==="helper_runtime_required")return"Open Shennian Desktop or use the \u4F7F\u7528\u5FAE\u4FE1 page to install Helper.";if(e==="helper_runtime_source_missing")return"Open Shennian Desktop, retry from the \u4F7F\u7528\u5FAE\u4FE1 page, or pass `--source <path>`.";if(e==="helper_runtime_manifest_unavailable")return"Check network access to Shennian official downloads, then retry from the \u4F7F\u7528\u5FAE\u4FE1 page.";if(e==="helper_runtime_artifact_unavailable")return"Upgrade Shennian CLI or wait for this platform Helper runtime to be published.";if(e==="helper_runtime_download_failed")return"Check network access to Shennian official downloads, then retry.";if(e==="helper_runtime_artifact_integrity_mismatch")return"Retry the official Helper runtime download; the downloaded package did not match the published hash.";if(e==="helper_runtime_artifact_invalid")return"Retry after Shennian republishes a valid Helper runtime package for this platform.";if(e==="helper_runtime_package_manifest_missing"||e==="helper_runtime_package_manifest_invalid")return"Reinstall or repair the official Shennian Helper runtime package.";if(e==="helper_runtime_platform_mismatch")return"Install the Helper runtime package for this platform.";if(e==="helper_runtime_version_mismatch"||e==="helper_runtime_protocol_mismatch")return"Run `shennian runtime repair helper` with the matching official Helper runtime package.";if(e==="manifest_missing"||e==="helper_missing"||e==="integrity_mismatch"||e==="helper_not_executable")return"Run `shennian runtime repair helper` or reinstall Shennian Desktop."}function D(e){return{ok:!1,repairable:!1,reasonCode:"unsupported_runtime_component",message:`Unsupported runtime component: ${e}. Supported component: helper.`,repairSuggestion:c("unsupported_runtime_component")}}function J(e){return{existsSync:e?.existsSync??m.existsSync,lstatSync:e?.lstatSync??m.lstatSync,readFileSync:e?.readFileSync??m.readFileSync,realpathSync:e?.realpathSync??m.realpathSync,mkdirSync:e?.mkdirSync??m.mkdirSync,rmSync:e?.rmSync??m.rmSync,cpSync:e?.cpSync??m.cpSync,renameSync:e?.renameSync??m.renameSync,chmodSync:e?.chmodSync??m.chmodSync,homedir:e?.homedir??v.homedir,stopMacHelperProcesses:e?.stopMacHelperProcesses??ne,stopWindowsHelperProcesses:e?.stopWindowsHelperProcesses??oe}}function q(e){const r=t.resolve(e.candidate);return!e.io.existsSync(r)||re(r,e.io)?null:e.platform==="darwin"?X(r,e.io):Q(r,e.io)}function X(e,r){const o=e.endsWith(".app")?e:t.join(e,"Shennian Helper.app");if(r.existsSync(t.join(o,"Contents","Resources","wechat-channel","macos","manifest.json")))return{sourceDir:o,packageKind:"macos-app",packageManifestPath:$(r,[t.join(o,"Contents","Resources","helper-runtime-package.json"),t.join(e,u)]),packageManifestPathInTarget:n=>t.join(n,"Contents","Resources",u),manifestDirInTarget:n=>t.join(n,"Contents","Resources","wechat-channel","macos")};const a=r.existsSync(t.join(e,"manifest.json"))?e:t.join(e,"wechat-channel","macos");return r.existsSync(t.join(a,"manifest.json"))?{sourceDir:a,packageKind:"asset-dir",packageManifestPath:t.join(a,"helper-runtime-package.json"),packageManifestPathInTarget:n=>t.join(n,u),manifestDirInTarget:n=>n}:null}function Q(e,r){const o=t.basename(e).toLowerCase()==="shennian helper"?e:t.join(e,"Shennian Helper");if(r.existsSync(t.join(o,"resources","wechat-channel","windows","manifest.json")))return{sourceDir:o,packageKind:"windows-runtime",packageManifestPath:$(r,[t.join(o,"resources",u),t.join(e,u)]),packageManifestPathInTarget:n=>t.join(n,"resources",u),manifestDirInTarget:n=>t.join(n,"resources","wechat-channel","windows")};const a=r.existsSync(t.join(e,"manifest.json"))?e:t.join(e,"wechat-channel","windows");return r.existsSync(t.join(a,"manifest.json"))?{sourceDir:a,packageKind:"asset-dir",packageManifestPath:t.join(a,"helper-runtime-package.json"),packageManifestPathInTarget:n=>t.join(n,u),manifestDirInTarget:n=>n}:null}function Y(e){const r=V(e);if(!r)return null;if(e.platform==="darwin")return e.packageKind==="macos-app"?t.join(r,"Shennian Helper.app"):t.join(r,"wechat-channel","macos");if(e.packageKind==="windows-runtime"){const o=e.env.LOCALAPPDATA||(e.homedir?t.join(e.homedir,"AppData","Local"):"");return o?t.join(o,"Programs","Shennian Helper"):null}return t.join(r,"wechat-channel","windows")}function Z(e,r){const o=t.resolve(r);if(e==="darwin"){const n=`${t.sep}Contents${t.sep}Resources${t.sep}wechat-channel${t.sep}macos`;return o.endsWith(n)?o.slice(0,-n.length):o}const a=`${t.sep}resources${t.sep}wechat-channel${t.sep}windows`;return o.endsWith(a)?o.slice(0,-a.length):o}function ee(e){const r=t.resolve(e.sourceDir),o=t.resolve(e.targetDir);if(r===o)return;const a=A(r,e.io),n=A(o,e.io);if(a&&n&&a===n)return;const i=`${o}.tmp-${process.pid}-${Date.now()}`;e.io.rmSync(i,{recursive:!0,force:!0}),e.io.mkdirSync(t.dirname(o),{recursive:!0}),e.io.cpSync(r,i,{recursive:!0}),e.platform==="darwin"&&e.io.stopMacHelperProcesses(o),e.platform==="win32"&&e.io.stopWindowsHelperProcesses(),e.io.rmSync(o,{recursive:!0,force:!0}),e.io.renameSync(i,o)}function re(e,r){try{return r.lstatSync(e).isSymbolicLink()}catch{return!1}}function A(e,r){try{return r.realpathSync(e)}catch{return null}}function ne(e){if(process.platform!=="darwin")return;const r=t.join(t.resolve(e),"Contents","MacOS","Shennian Helper"),o=C("ps",["-axo","pid=,command="],{encoding:"utf8"});if(o.status!==0)return;const a=o.stdout.split(/\r?\n/u).map(n=>{const i=/^\s*(\d+)\s+(.+)$/u.exec(n);if(!i)return null;const s=Number(i[1]),l=i[2];return Number.isInteger(s)&&l.includes(r)?s:null}).filter(n=>!!(n&&n!==process.pid));for(const n of a)try{process.kill(n,"SIGTERM")}catch{}x(a,1e3);for(const n of a)if(E(n))try{process.kill(n,"SIGKILL")}catch{}x(a,500)}function x(e,r){const o=Date.now()+r;for(;Date.now()<o&&e.some(E);)ae(50)}function ae(e){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,e)}function E(e){try{return process.kill(e,0),!0}catch{return!1}}function oe(){if(process.platform!=="win32")return;const e=C("taskkill",["/IM","shennian-wechat-channel-helper.exe","/T","/F"],{stdio:"ignore",windowsHide:!0});if(e.status!==0&&e.status!==128)throw new Error(`taskkill shennian-wechat-channel-helper.exe exited ${e.status}`)}function te(e){const r=t.resolve(e.sourceManifestPath),o=t.resolve(e.targetManifestPath);!e.io.existsSync(r)||r===o||(e.io.mkdirSync(t.dirname(o),{recursive:!0}),e.io.cpSync(r,o))}function $(e,r){return r.find(o=>e.existsSync(o))??r[0]}function ie(e,r,o){if(e==="darwin")try{const a=m.statSync(r);(a.mode&73)===0&&o.chmodSync(r,a.mode|493)}catch{}}function S(e){const r=e.homedir||(e.platform==="win32"?e.env.USERPROFILE:e.env.HOME),o=[],a=n=>{if(!n)return;const i=t.resolve(n);o.includes(i)||o.push(i)};if(a(e.env.SHENNIAN_HELPER_PACKAGE_DIR),a(e.env[T]),a(e.env[U]),e.platform==="darwin")r&&(a(t.join(r,"Applications","Shennian.app","Contents","Resources")),a(t.join(r,"Applications","Shennian Helper.app"))),a(t.join("/Applications","Shennian.app","Contents","Resources")),a(t.join("/Applications","Shennian Helper.app"));else{const n=e.env.LOCALAPPDATA||(r?t.join(r,"AppData","Local"):""),i=e.env.ProgramFiles||e.env.PROGRAMFILES,s=e.env["ProgramFiles(x86)"]||e.env["PROGRAMFILES(X86)"];n&&(a(t.join(n,"Programs","Shennian","resources")),a(t.join(n,"Programs","Shennian Helper"))),i&&(a(t.join(i,"Shennian","resources")),a(t.join(i,"Shennian Helper"))),s&&(a(t.join(s,"Shennian","resources")),a(t.join(s,"Shennian Helper")))}return a(t.resolve(process.cwd(),"packages/helper-runtime/dist",e.platform==="darwin"?"macos":"windows")),a(t.resolve(process.cwd(),"packages/helper-runtime/wechat-channel",e.platform==="darwin"?"macos":"windows")),o}function _(e,r){if(r){console.log(JSON.stringify(e,null,2));return}if(e.ok){console.log(H.green(`\u2713 ${e.message}`)),"helperVersion"in e&&console.log(`version=${e.helperVersion} protocol=${e.protocolVersion}`),"helperPath"in e&&console.log(e.helperPath);return}console.error(H.red(`\u2717 ${e.reasonCode}`)),console.error(e.message)}export{R as getHelperRuntimeStatus,M as installHelperRuntime,P as installHelperRuntimeWithOfficialDownload,ge as registerRuntimeCommand};
1
+ import m from"node:fs";import C from"node:os";import t from"node:path";import{spawnSync as H}from"node:child_process";import V from"chalk";import{getDefaultWeChatHelperRuntimeRoot as b,readWeChatChannelHelperRuntimePackageManifest as y,resolveWeChatChannelHelperAsset as R,SHENNIAN_HELPER_RUNTIME_DIR_ENV as L,WECHAT_CHANNEL_HELPER_DIR_ENV as N}from"../channels/wechat-channel/helper-assets.js";import{downloadOfficialHelperRuntimePackage as W}from"./helper-runtime-official-download.js";import{compareVersions as K,getCurrentVersion as j}from"../upgrade/engine.js";import{SerialWeChatAutomationLane as F}from"../channels/wechat-channel/automation-lane.js";const h="helper-runtime-package.json";function ke(e){const r=e.command("runtime").description("Install, repair, and inspect Shennian local runtimes");r.command("status").description("Print local Shennian runtime status").option("--json","Output JSON",!1).option("--platform <platform>","Platform override: darwin or win32").action(o=>{const a=M({platform:o.platform});_(a,!!o.json),a.ok||(process.exitCode=1)}),r.command("install").description("Install a Shennian runtime component").argument("<component>","Runtime component, currently only: helper").option("--source <path>","Helper runtime package/source directory").option("--channel <channel>","Official Helper runtime channel: stable or next").option("--manifest-url <url>","Official Helper runtime manifest URL override").option("--no-official-download","Do not fall back to Shennian official Helper runtime download").option("--json","Output JSON",!1).option("--platform <platform>","Platform override: darwin or win32").action(async(o,a)=>{const n=o==="helper"?await P({source:a.source,platform:a.platform,officialDownload:a.officialDownload===!1?!1:{channel:a.channel,manifestUrl:a.manifestUrl}}):D(o);_(n,!!a.json),n.ok||(process.exitCode=1)}),r.command("upgrade").description("Upgrade a Shennian runtime component").argument("<component>","Runtime component, currently only: helper").option("--source <path>","Helper runtime package/source directory").option("--channel <channel>","Official Helper runtime channel: stable or next").option("--manifest-url <url>","Official Helper runtime manifest URL override").option("--no-official-download","Do not use Shennian official Helper runtime download").option("--json","Output JSON",!1).option("--platform <platform>","Platform override: darwin or win32").action(async(o,a)=>{const n=o==="helper"?await P({source:a.source,platform:a.platform,force:!0,preferOfficialDownload:!a.source,officialDownload:a.officialDownload===!1?!1:{channel:a.channel,manifestUrl:a.manifestUrl}}):D(o);_(n,!!a.json),n.ok||(process.exitCode=1)}),r.command("repair").description("Repair a Shennian runtime component").argument("[component]","Runtime component, currently only: helper","helper").option("--source <path>","Helper runtime package/source directory").option("--channel <channel>","Official Helper runtime channel: stable or next").option("--manifest-url <url>","Official Helper runtime manifest URL override").option("--no-official-download","Do not fall back to Shennian official Helper runtime download").option("--json","Output JSON",!1).option("--platform <platform>","Platform override: darwin or win32").action(async(o,a)=>{const n=o==="helper"?await P({source:a.source,platform:a.platform,force:!0,preferOfficialDownload:!a.source,officialDownload:a.officialDownload===!1?!1:{channel:a.channel,manifestUrl:a.manifestUrl}}):D(o);_(n,!!a.json),n.ok||(process.exitCode=1)})}function M(e={}){const r=S(e.platform);if(!r)return{ok:!1,installed:!1,repairable:!1,reasonCode:"unsupported_platform",message:"Shennian Helper runtime is only available on macOS and Windows.",repairSuggestion:c("unsupported_platform")};const o=e.env??process.env,a=e.homedir,n=R({platform:r,env:o,homedir:a,includeInstalledDesktop:!1}),i=b({platform:r,env:o,homedir:a});if(!n.ok)return{ok:!1,platform:r,targetPlatform:r,installed:!1,repairable:q(n.reasonCode),reasonCode:n.reasonCode,message:n.message,runtimeRoot:i,repairSuggestion:c(n.reasonCode),checkedSources:k({platform:r,env:o,homedir:a})};const s=y({platform:r,helperDir:n.helperDir});if(!s.ok)return{ok:!1,platform:r,targetPlatform:r,installed:!1,repairable:!0,reasonCode:s.reasonCode,message:s.message,helperDir:n.helperDir,helperPath:n.helperPath,helperVersion:n.version,runtimeVersion:n.version,protocolVersion:n.manifest.protocolVersion,runtimeRoot:i,repairSuggestion:c(s.reasonCode),checkedSources:k({platform:r,env:o,homedir:a})};const l=A({platform:r,packageManifest:s.manifest,currentCliVersion:j(),helperVersion:n.version,protocolVersion:n.manifest.protocolVersion});return l.ok?{ok:!0,platform:r,targetPlatform:r,installed:!0,repairable:!1,message:`Shennian Helper runtime is installed: ${n.helperDir}`,helperDir:n.helperDir,helperPath:n.helperPath,helperVersion:n.version,runtimeVersion:n.version,protocolVersion:n.manifest.protocolVersion,minCliVersion:s.manifest.minCliVersion,sha256:s.manifest.sha256,packageManifestPath:s.manifestPath,packageKind:s.manifest.packageKind,installTarget:s.manifest.installTarget,signature:s.manifest.signature,runtimeRoot:i}:{ok:!1,platform:r,targetPlatform:r,installed:!0,repairable:l.repairable,reasonCode:l.reasonCode,message:l.message,helperDir:n.helperDir,helperPath:n.helperPath,helperVersion:n.version,runtimeVersion:n.version,protocolVersion:n.manifest.protocolVersion,minCliVersion:s.manifest.minCliVersion,sha256:s.manifest.sha256,packageManifestPath:s.manifestPath,packageKind:s.manifest.packageKind,installTarget:s.manifest.installTarget,signature:s.manifest.signature,runtimeRoot:i,repairSuggestion:c(l.reasonCode,s.manifest.minCliVersion),checkedSources:k({platform:r,env:o,homedir:a})}}function I(e={}){const r=S(e.platform);if(!r)return{ok:!1,reasonCode:"unsupported_platform",message:"Shennian Helper runtime is only available on macOS and Windows.",repairable:!1,repairSuggestion:c("unsupported_platform")};const o=e.env??process.env,a=X(e.io),n=e.homedir??a.homedir(),i=M({platform:r,env:o,homedir:n});if(i.ok&&!e.force&&i.helperDir&&i.helperPath&&i.helperVersion&&i.protocolVersion)return{ok:!0,action:"already_installed",platform:r,targetPlatform:r,installed:!0,repairable:!1,targetDir:re(r,i.helperDir),helperDir:i.helperDir,helperPath:i.helperPath,helperVersion:i.helperVersion,runtimeVersion:i.helperVersion,protocolVersion:i.protocolVersion,minCliVersion:i.minCliVersion,sha256:i.sha256,packageManifestPath:i.packageManifestPath,packageKind:i.packageKind,installTarget:i.installTarget,signature:i.signature,message:`Shennian Helper runtime is already installed: ${i.helperDir}`};const s=e.source?[t.resolve(e.source)]:k({platform:r,env:o,homedir:n}),l=s.map(w=>Q({candidate:w,platform:r,io:a})).find(w=>w!=null);if(!l)return{ok:!1,platform:r,targetPlatform:r,installed:!1,repairable:!0,reasonCode:"helper_runtime_source_missing",message:"No installable Shennian Helper runtime package was found. Open Shennian Desktop, pass --source, or download the official helper package.",repairSuggestion:c("helper_runtime_source_missing"),checkedSources:s};const d=y({platform:r,manifestPath:l.packageManifestPath});if(!d.ok)return{ok:!1,platform:r,targetPlatform:r,installed:!1,repairable:!0,reasonCode:d.reasonCode,message:d.message,repairSuggestion:c(d.reasonCode),checkedSources:s};const g=A({platform:r,packageManifest:d.manifest,currentCliVersion:j()});if(!g.ok)return{ok:!1,platform:r,targetPlatform:r,installed:!1,repairable:g.repairable,reasonCode:g.reasonCode,message:g.message,repairSuggestion:c(g.reasonCode,d.manifest.minCliVersion),checkedSources:s};const u=ee({platform:r,env:o,homedir:n,packageKind:l.packageKind});if(!u)return{ok:!1,platform:r,targetPlatform:r,installed:!1,repairable:!1,reasonCode:"helper_runtime_target_unavailable",message:"Unable to determine Helper runtime install target for this platform.",repairSuggestion:c("helper_runtime_target_unavailable"),checkedSources:s};const v=a.existsSync(u);v&&x({platform:r,targetDir:u,io:a}),ne({platform:r,sourceDir:l.sourceDir,targetDir:u,io:a}),v&&x({platform:r,targetDir:u,io:a}),se({sourceManifestPath:l.packageManifestPath,targetManifestPath:l.packageManifestPathInTarget(u),io:a});const f=R({platform:r,baseDir:l.manifestDirInTarget(u),verifyIntegrity:!0});if(!f.ok)return{ok:!1,platform:r,targetPlatform:r,installed:!1,repairable:!0,reasonCode:f.reasonCode,message:`Installed Helper runtime could not be verified: ${f.message}`,repairSuggestion:c(f.reasonCode),checkedSources:s};le(r,f.helperPath,a);const p=y({platform:r,helperDir:f.helperDir});return p.ok?{ok:!0,action:"installed",platform:r,targetPlatform:r,installed:!0,repairable:!1,targetDir:u,helperDir:f.helperDir,helperPath:f.helperPath,helperVersion:f.version,runtimeVersion:f.version,protocolVersion:f.manifest.protocolVersion,minCliVersion:p.manifest.minCliVersion,sha256:p.manifest.sha256,packageManifestPath:p.manifestPath,packageKind:p.manifest.packageKind,installTarget:p.manifest.installTarget,signature:p.manifest.signature,message:`Installed Shennian Helper runtime to ${u}`}:{ok:!1,platform:r,targetPlatform:r,installed:!1,repairable:!0,reasonCode:p.reasonCode,message:`Installed Helper runtime package manifest could not be verified: ${p.message}`,repairSuggestion:c(p.reasonCode),checkedSources:s}}async function P(e={}){const r=new F({lockPath:B(e),owner:"helper-runtime-install",defaultWaitMs:0});try{return await r.run("helper-runtime-install",()=>G(e))}catch(o){if(z(o)){const a=S(e.platform)??void 0;return{ok:!1,platform:a,targetPlatform:a,installed:!1,repairable:!0,reasonCode:"wechat_automation_busy",message:o instanceof Error?o.message:String(o),repairSuggestion:"Wait for the current WeChat automation run to finish, then retry Helper install or repair."}}throw o}}function B(e){const r=e.env?.SHENNIAN_HOME?.trim()||process.env.SHENNIAN_HOME?.trim(),o=r?t.resolve(r):t.join(e.homedir??C.homedir(),".shennian");return t.join(o,"runtime","wechat-automation.lock")}function z(e){return e instanceof Error?e.message.includes("wechat_automation_busy"):String(e).includes("wechat_automation_busy")}async function G(e={}){if(e.preferOfficialDownload&&!e.source&&e.officialDownload!==!1)return await O(e);const r=I(e);return r.ok||e.source||e.officialDownload===!1||!J(r.reasonCode)?r.ok?{...r,source:r.source??"local"}:r:await O(e,r)}async function O(e,r){const o=S(e.platform);if(!o)return r??{ok:!1,repairable:!1,reasonCode:"unsupported_platform",message:"Shennian Helper runtime is only available on macOS and Windows.",repairSuggestion:c("unsupported_platform")};const a=e.officialDownload===!1||e.officialDownload==null?{}:e.officialDownload,n=await W({...a,platform:o,env:e.env??process.env});if(!n.ok)return{ok:!1,platform:o,targetPlatform:o,installed:!1,repairable:!0,reasonCode:n.reasonCode,message:n.message,repairSuggestion:c(n.reasonCode),checkedSources:r?.checkedSources,officialDownload:{manifestUrl:n.manifestUrl,artifactUrl:n.artifactUrl}};try{const i=I({...e,source:n.sourceDir,platform:o,force:e.force??e.preferOfficialDownload??!1});return i.ok?{...i,source:"official-download",officialDownload:{channel:n.channel,manifestUrl:n.manifestUrl,artifactUrl:n.artifactUrl,artifactSha256:n.artifactSha256,artifactSizeBytes:n.artifactSizeBytes,arch:n.arch,helperVersion:n.helperVersion,protocolVersion:n.protocolVersion,minCliVersion:n.minCliVersion}}:{...i,reasonCode:i.reasonCode==="helper_runtime_source_missing"?"helper_runtime_artifact_invalid":i.reasonCode,message:i.reasonCode==="helper_runtime_source_missing"?"Official Helper runtime artifact did not contain an installable runtime package.":i.message,repairSuggestion:c(i.reasonCode==="helper_runtime_source_missing"?"helper_runtime_artifact_invalid":i.reasonCode),officialDownload:{manifestUrl:n.manifestUrl,artifactUrl:n.artifactUrl}}}finally{n.cleanup()}}function J(e){return e==="helper_runtime_source_missing"||e==="helper_runtime_package_manifest_missing"||e==="helper_runtime_package_manifest_invalid"}function S(e){const r=e??process.platform;return r==="darwin"||r==="win32"?r:null}function A(e){return e.packageManifest.platform!==e.platform?{ok:!1,reasonCode:"helper_runtime_platform_mismatch",message:`Helper runtime package platform ${e.packageManifest.platform} does not match ${e.platform}.`,repairable:!0}:e.helperVersion&&e.packageManifest.helperVersion!==e.helperVersion?{ok:!1,reasonCode:"helper_runtime_version_mismatch",message:`Helper runtime package version ${e.packageManifest.helperVersion} does not match installed helper ${e.helperVersion}.`,repairable:!0}:e.protocolVersion&&e.packageManifest.protocolVersion!==e.protocolVersion?{ok:!1,reasonCode:"helper_runtime_protocol_mismatch",message:`Helper runtime package protocol ${e.packageManifest.protocolVersion} does not match installed helper protocol ${e.protocolVersion}.`,repairable:!0}:K(e.currentCliVersion,e.packageManifest.minCliVersion)!=="none"?{ok:!1,reasonCode:"helper_runtime_cli_too_old",message:`Shennian CLI ${e.currentCliVersion} is older than required ${e.packageManifest.minCliVersion}.`,repairable:!1}:{ok:!0}}function q(e){return e!=="unsupported_platform"&&e!=="helper_runtime_cli_too_old"}function c(e,r){if(e==="unsupported_platform")return"Use Shennian Helper runtime on macOS or Windows.";if(e==="unsupported_runtime_component")return"Use `shennian runtime install helper` or `shennian runtime repair helper`.";if(e==="helper_runtime_cli_too_old")return`Upgrade Shennian CLI${r?` to ${r} or newer`:""}, then retry.`;if(e==="helper_runtime_target_unavailable")return"Set the current user home/LOCALAPPDATA correctly, then retry.";if(e==="helper_runtime_required")return"Open Shennian Desktop or use the \u4F7F\u7528\u5FAE\u4FE1 page to install Helper.";if(e==="helper_runtime_source_missing")return"Open Shennian Desktop, retry from the \u4F7F\u7528\u5FAE\u4FE1 page, or pass `--source <path>`.";if(e==="helper_runtime_manifest_unavailable")return"Check network access to Shennian official downloads, then retry from the \u4F7F\u7528\u5FAE\u4FE1 page.";if(e==="helper_runtime_artifact_unavailable")return"Upgrade Shennian CLI or wait for this platform Helper runtime to be published.";if(e==="helper_runtime_download_failed")return"Check network access to Shennian official downloads, then retry.";if(e==="helper_runtime_artifact_integrity_mismatch")return"Retry the official Helper runtime download; the downloaded package did not match the published hash.";if(e==="helper_runtime_artifact_invalid")return"Retry after Shennian republishes a valid Helper runtime package for this platform.";if(e==="helper_runtime_package_manifest_missing"||e==="helper_runtime_package_manifest_invalid")return"Reinstall or repair the official Shennian Helper runtime package.";if(e==="helper_runtime_platform_mismatch")return"Install the Helper runtime package for this platform.";if(e==="helper_runtime_version_mismatch"||e==="helper_runtime_protocol_mismatch")return"Run `shennian runtime repair helper` with the matching official Helper runtime package.";if(e==="manifest_missing"||e==="helper_missing"||e==="integrity_mismatch"||e==="helper_not_executable")return"Run `shennian runtime repair helper` or reinstall Shennian Desktop."}function D(e){return{ok:!1,repairable:!1,reasonCode:"unsupported_runtime_component",message:`Unsupported runtime component: ${e}. Supported component: helper.`,repairSuggestion:c("unsupported_runtime_component")}}function X(e){return{existsSync:e?.existsSync??m.existsSync,lstatSync:e?.lstatSync??m.lstatSync,readFileSync:e?.readFileSync??m.readFileSync,realpathSync:e?.realpathSync??m.realpathSync,mkdirSync:e?.mkdirSync??m.mkdirSync,rmSync:e?.rmSync??m.rmSync,cpSync:e?.cpSync??m.cpSync,renameSync:e?.renameSync??m.renameSync,chmodSync:e?.chmodSync??m.chmodSync,homedir:e?.homedir??C.homedir,stopMacHelperProcesses:e?.stopMacHelperProcesses??oe,stopWindowsHelperProcesses:e?.stopWindowsHelperProcesses??ie}}function Q(e){const r=t.resolve(e.candidate);return!e.io.existsSync(r)||ae(r,e.io)?null:e.platform==="darwin"?Y(r,e.io):Z(r,e.io)}function Y(e,r){const o=e.endsWith(".app")?e:t.join(e,"Shennian Helper.app");if(r.existsSync(t.join(o,"Contents","Resources","wechat-channel","macos","manifest.json")))return{sourceDir:o,packageKind:"macos-app",packageManifestPath:T(r,[t.join(o,"Contents","Resources","helper-runtime-package.json"),t.join(e,h)]),packageManifestPathInTarget:n=>t.join(n,"Contents","Resources",h),manifestDirInTarget:n=>t.join(n,"Contents","Resources","wechat-channel","macos")};const a=r.existsSync(t.join(e,"manifest.json"))?e:t.join(e,"wechat-channel","macos");return r.existsSync(t.join(a,"manifest.json"))?{sourceDir:a,packageKind:"asset-dir",packageManifestPath:t.join(a,"helper-runtime-package.json"),packageManifestPathInTarget:n=>t.join(n,h),manifestDirInTarget:n=>n}:null}function Z(e,r){const o=t.basename(e).toLowerCase()==="shennian helper"?e:t.join(e,"Shennian Helper");if(r.existsSync(t.join(o,"resources","wechat-channel","windows","manifest.json")))return{sourceDir:o,packageKind:"windows-runtime",packageManifestPath:T(r,[t.join(o,"resources",h),t.join(e,h)]),packageManifestPathInTarget:n=>t.join(n,"resources",h),manifestDirInTarget:n=>t.join(n,"resources","wechat-channel","windows")};const a=r.existsSync(t.join(e,"manifest.json"))?e:t.join(e,"wechat-channel","windows");return r.existsSync(t.join(a,"manifest.json"))?{sourceDir:a,packageKind:"asset-dir",packageManifestPath:t.join(a,"helper-runtime-package.json"),packageManifestPathInTarget:n=>t.join(n,h),manifestDirInTarget:n=>n}:null}function ee(e){const r=b(e);if(!r)return null;if(e.platform==="darwin")return e.packageKind==="macos-app"?t.join(r,"Shennian Helper.app"):t.join(r,"wechat-channel","macos");if(e.packageKind==="windows-runtime"){const o=e.env.LOCALAPPDATA||(e.homedir?t.join(e.homedir,"AppData","Local"):"");return o?t.join(o,"Programs","Shennian Helper"):null}return t.join(r,"wechat-channel","windows")}function re(e,r){const o=t.resolve(r);if(e==="darwin"){const n=`${t.sep}Contents${t.sep}Resources${t.sep}wechat-channel${t.sep}macos`;return o.endsWith(n)?o.slice(0,-n.length):o}const a=`${t.sep}resources${t.sep}wechat-channel${t.sep}windows`;return o.endsWith(a)?o.slice(0,-a.length):o}function ne(e){const r=t.resolve(e.sourceDir),o=t.resolve(e.targetDir);if(r===o)return;const a=E(r,e.io),n=E(o,e.io);if(a&&n&&a===n)return;const i=`${o}.tmp-${process.pid}-${Date.now()}`;e.io.rmSync(i,{recursive:!0,force:!0}),e.io.mkdirSync(t.dirname(o),{recursive:!0}),e.io.cpSync(r,i,{recursive:!0}),e.io.rmSync(o,{recursive:!0,force:!0}),e.io.renameSync(i,o)}function x(e){e.io.existsSync(e.targetDir)&&(e.platform==="darwin"&&e.io.stopMacHelperProcesses(e.targetDir),e.platform==="win32"&&e.io.stopWindowsHelperProcesses())}function ae(e,r){try{return r.lstatSync(e).isSymbolicLink()}catch{return!1}}function E(e,r){try{return r.realpathSync(e)}catch{return null}}function oe(e){if(process.platform!=="darwin")return;const r=t.join(t.resolve(e),"Contents","MacOS","Shennian Helper"),o=H("ps",["-axo","pid=,command="],{encoding:"utf8"});if(o.status!==0)return;const a=o.stdout.split(/\r?\n/u).map(n=>{const i=/^\s*(\d+)\s+(.+)$/u.exec(n);if(!i)return null;const s=Number(i[1]),l=i[2];return Number.isInteger(s)&&l.includes(r)?s:null}).filter(n=>!!(n&&n!==process.pid));for(const n of a)try{process.kill(n,"SIGTERM")}catch{}$(a,1e3);for(const n of a)if(U(n))try{process.kill(n,"SIGKILL")}catch{}$(a,500)}function $(e,r){const o=Date.now()+r;for(;Date.now()<o&&e.some(U);)te(50)}function te(e){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,e)}function U(e){try{return process.kill(e,0),!0}catch{return!1}}function ie(){if(process.platform!=="win32")return;const e=H("taskkill",["/IM","shennian-wechat-channel-helper.exe","/T","/F"],{stdio:"ignore",windowsHide:!0});if(e.status!==0&&e.status!==128)throw new Error(`taskkill shennian-wechat-channel-helper.exe exited ${e.status}`)}function se(e){const r=t.resolve(e.sourceManifestPath),o=t.resolve(e.targetManifestPath);!e.io.existsSync(r)||r===o||(e.io.mkdirSync(t.dirname(o),{recursive:!0}),e.io.cpSync(r,o))}function T(e,r){return r.find(o=>e.existsSync(o))??r[0]}function le(e,r,o){if(e==="darwin")try{const a=m.statSync(r);(a.mode&73)===0&&o.chmodSync(r,a.mode|493)}catch{}}function k(e){const r=e.homedir||(e.platform==="win32"?e.env.USERPROFILE:e.env.HOME),o=[],a=n=>{if(!n)return;const i=t.resolve(n);o.includes(i)||o.push(i)};if(a(e.env.SHENNIAN_HELPER_PACKAGE_DIR),a(e.env[N]),a(e.env[L]),e.platform==="darwin")r&&(a(t.join(r,"Applications","Shennian.app","Contents","Resources")),a(t.join(r,"Applications","Shennian Helper.app"))),a(t.join("/Applications","Shennian.app","Contents","Resources")),a(t.join("/Applications","Shennian Helper.app"));else{const n=e.env.LOCALAPPDATA||(r?t.join(r,"AppData","Local"):""),i=e.env.ProgramFiles||e.env.PROGRAMFILES,s=e.env["ProgramFiles(x86)"]||e.env["PROGRAMFILES(X86)"];n&&(a(t.join(n,"Programs","Shennian","resources")),a(t.join(n,"Programs","Shennian Helper"))),i&&(a(t.join(i,"Shennian","resources")),a(t.join(i,"Shennian Helper"))),s&&(a(t.join(s,"Shennian","resources")),a(t.join(s,"Shennian Helper")))}return a(t.resolve(process.cwd(),"packages/helper-runtime/dist",e.platform==="darwin"?"macos":"windows")),a(t.resolve(process.cwd(),"packages/helper-runtime/wechat-channel",e.platform==="darwin"?"macos":"windows")),o}function _(e,r){if(r){console.log(JSON.stringify(e,null,2));return}if(e.ok){console.log(V.green(`\u2713 ${e.message}`)),"helperVersion"in e&&console.log(`version=${e.helperVersion} protocol=${e.protocolVersion}`),"helperPath"in e&&console.log(e.helperPath);return}console.error(V.red(`\u2717 ${e.reasonCode}`)),console.error(e.message)}export{M as getHelperRuntimeStatus,I as installHelperRuntime,P as installHelperRuntimeWithOfficialDownload,ke as registerRuntimeCommand};
@@ -1 +1 @@
1
- import o from"node:crypto";function s(e){return e==="dry_run"||e==="queued"||e==="sent"||e==="sent_unconfirmed"||e==="confirmed_echo"||e==="manual_review"||e==="pending"||e==="ok"?e:null}function c(e){return e==="queued"||e==="pending"}function u(e){switch(e){case"dry_run":return"dry_run: \u6F14\u7EC3\u5B8C\u6210\uFF0C\u672A\u771F\u6B63\u53D1\u9001\u3002";case"queued":return"queued: \u5DF2\u6392\u961F\uFF0C\u7B49\u5F85\u672C\u673A\u53D1\u9001\uFF0C\u65E0\u9700\u91CD\u53D1\u3002";case"pending":return"pending: \u5DF2\u63D0\u4EA4\u672C\u673A\u53D1\u9001\uFF0C\u65E0\u9700\u91CD\u53D1\u3002";case"sent":return"sent: \u5DF2\u53D1\u9001\uFF0C\u8BF7\u52FF\u91CD\u53D1\u3002";case"sent_unconfirmed":return"sent_unconfirmed: \u6D88\u606F\u5DF2\u53D1\u51FA\uFF0C\u8BF7\u52FF\u91CD\u53D1\u3002";case"confirmed_echo":return"confirmed_echo: \u5DF2\u53D1\u9001\u5E76\u786E\u8BA4\uFF0C\u8BF7\u52FF\u91CD\u53D1\u3002";case"manual_review":return"manual_review: \u5DF2\u63D0\u4EA4\uFF0C\u4F46\u9700\u4EBA\u5DE5\u6838\u5BF9\uFF0C\u8BF7\u52FF\u91CD\u53D1\u3002";case"ok":return"ok: \u5DF2\u53D1\u9001\uFF0C\u8BF7\u52FF\u91CD\u53D1\u3002";default:return String(e)}}function f(){if(process.platform==="darwin")return"darwin";if(process.platform==="win32")return"win32"}function a(e){return String(e||"").replace(/\s+/g," ").trim()}function p(e){try{return process.kill(e,0),!0}catch{return!1}}function d(e){if(!e||typeof e!="object")return!1;const r=e,n=typeof r.name=="string"?r.name:"",t=typeof r.message=="string"?r.message:"";return n==="AbortError"||r.code==="ABORT_ERR"||/aborted|abort/i.test(t)}function m(e,r){return`${e}:${o.createHash("sha256").update(r).digest("hex").slice(0,32)}`}function g(e){return e.trim().replace(/[^a-zA-Z0-9._-]+/g,"_").replace(/^_+|_+$/g,"")||"conversation"}function y(e,r){const n=Number(e);return!Number.isFinite(n)||n<=0?r:Math.floor(n)}function x(e){return!!e&&typeof e=="object"&&!Array.isArray(e)&&e.type==="external.message"&&typeof e.channelId=="string"&&typeof e.conversationId=="string"&&typeof e.messageId=="string"&&typeof e.text=="string"}function _(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function b(e){return typeof e=="string"&&e?e:void 0}export{y as clampPositiveInteger,a as cleanInline,f as currentWeChatPlatform,u as describeSendStatus,d as isAbortError,x as isExternalMessageEvent,c as isPendingSendStatus,_ as isRecord,s as normalizeSendStatus,p as processExists,g as safePathSegment,m as stableId,b as stringValue};
1
+ import o from"node:crypto";function s(e){return e==="dry_run"||e==="queued"||e==="sent"||e==="sent_unconfirmed"||e==="confirmed_echo"||e==="manual_review"||e==="pending"||e==="ok"?e:null}function c(e){return e==="queued"||e==="pending"}function u(e){switch(e){case"dry_run":return"dry_run: \u6F14\u7EC3\u5B8C\u6210\uFF0C\u672A\u771F\u6B63\u53D1\u9001\u3002";case"queued":return"queued: \u5DF2\u6392\u961F\uFF0C\u7B49\u5F85\u672C\u673A\u53D1\u9001\uFF0C\u65E0\u9700\u91CD\u53D1\u3002";case"pending":return"pending: \u5DF2\u63D0\u4EA4\u672C\u673A\u53D1\u9001\uFF0C\u65E0\u9700\u91CD\u53D1\u3002";case"sent":return"\u53D1\u9001\u6210\u529F\uFF0C\u8BF7\u52FF\u91CD\u590D\u53D1\u9001\u3002";case"sent_unconfirmed":return"\u53D1\u9001\u6210\u529F\uFF0C\u8BF7\u52FF\u91CD\u590D\u53D1\u9001\u3002";case"confirmed_echo":return"\u53D1\u9001\u6210\u529F\uFF0C\u5DF2\u786E\u8BA4\uFF0C\u8BF7\u52FF\u91CD\u590D\u53D1\u9001\u3002";case"manual_review":return"manual_review: \u5DF2\u63D0\u4EA4\uFF0C\u4F46\u9700\u4EBA\u5DE5\u6838\u5BF9\uFF0C\u8BF7\u52FF\u91CD\u53D1\u3002";case"ok":return"\u53D1\u9001\u6210\u529F\uFF0C\u8BF7\u52FF\u91CD\u590D\u53D1\u9001\u3002";default:return String(e)}}function a(){if(process.platform==="darwin")return"darwin";if(process.platform==="win32")return"win32"}function f(e){return String(e||"").replace(/\s+/g," ").trim()}function p(e){try{return process.kill(e,0),!0}catch{return!1}}function d(e){if(!e||typeof e!="object")return!1;const r=e,n=typeof r.name=="string"?r.name:"",t=typeof r.message=="string"?r.message:"";return n==="AbortError"||r.code==="ABORT_ERR"||/aborted|abort/i.test(t)}function m(e,r){return`${e}:${o.createHash("sha256").update(r).digest("hex").slice(0,32)}`}function g(e){return e.trim().replace(/[^a-zA-Z0-9._-]+/g,"_").replace(/^_+|_+$/g,"")||"conversation"}function y(e,r){const n=Number(e);return!Number.isFinite(n)||n<=0?r:Math.floor(n)}function x(e){return!!e&&typeof e=="object"&&!Array.isArray(e)&&e.type==="external.message"&&typeof e.channelId=="string"&&typeof e.conversationId=="string"&&typeof e.messageId=="string"&&typeof e.text=="string"}function _(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function b(e){return typeof e=="string"&&e?e:void 0}export{y as clampPositiveInteger,f as cleanInline,a as currentWeChatPlatform,u as describeSendStatus,d as isAbortError,x as isExternalMessageEvent,c as isPendingSendStatus,_ as isRecord,s as normalizeSendStatus,p as processExists,g as safePathSegment,m as stableId,b as stringValue};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shennian",
3
- "version": "0.2.121",
3
+ "version": "0.2.123",
4
4
  "description": "Shennian — AI Agent Control Plane CLI",
5
5
  "type": "module",
6
6
  "bin": {