shennian 0.3.11 → 0.3.13

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.
@@ -86,8 +86,8 @@
86
86
  },
87
87
  {
88
88
  "file": "src/agents/model-registry/parsers.js",
89
- "beforeBytes": 18471,
90
- "afterBytes": 9024
89
+ "beforeBytes": 19646,
90
+ "afterBytes": 10067
91
91
  },
92
92
  {
93
93
  "file": "src/agents/model-registry/runner.js",
@@ -156,13 +156,13 @@
156
156
  },
157
157
  {
158
158
  "file": "src/commands/daemon-windows.js",
159
- "beforeBytes": 3906,
160
- "afterBytes": 3131
159
+ "beforeBytes": 3905,
160
+ "afterBytes": 3130
161
161
  },
162
162
  {
163
163
  "file": "src/commands/daemon.js",
164
- "beforeBytes": 37965,
165
- "afterBytes": 18383
164
+ "beforeBytes": 38493,
165
+ "afterBytes": 18618
166
166
  },
167
167
  {
168
168
  "file": "src/commands/integration.js",
@@ -296,8 +296,8 @@
296
296
  },
297
297
  {
298
298
  "file": "src/integrations/room-session-hook.js",
299
- "beforeBytes": 11963,
300
- "afterBytes": 6166
299
+ "beforeBytes": 12200,
300
+ "afterBytes": 6164
301
301
  },
302
302
  {
303
303
  "file": "src/integrations/workbuddy-plugin-bundle.js",
@@ -311,8 +311,8 @@
311
311
  },
312
312
  {
313
313
  "file": "src/integrations/workbuddy-session-hook.js",
314
- "beforeBytes": 2624,
315
- "afterBytes": 1254
314
+ "beforeBytes": 2622,
315
+ "afterBytes": 1252
316
316
  },
317
317
  {
318
318
  "file": "src/log-reporter.js",
@@ -1,4 +1,4 @@
1
- function m(e){return e.replace(/\u001b\[[0-9;?]*[a-zA-Z]/g,"").replace(/\u001b\][^\u0007]*\u0007/g,"").replace(/[\u0000-\u0008\u000b-\u001f\u007f]/g,"")}function d(e){const n=new Set,t=[];for(const o of e)!o.id||n.has(o.id)||(n.add(o.id),t.push(o));return t}function h(e){return e&&e[0].toUpperCase()+e.slice(1)}function b(e){return e.split("-").map(n=>n==="gpt"?"GPT":n==="codex"?"Codex":/^\d/.test(n)?n:h(n)).join("-")}function A(e){switch(e){case"low":return"Low";case"medium":return"Medium";case"high":return"High";case"xhigh":return"Extra High";default:return h(e)}}const D=[{id:"gpt-5.6-sol",name:"GPT-5.6 Sol",description:"Latest GPT-5.6 Codex model.",provider:"openai"},{id:"gpt-5.6-terra",name:"GPT-5.6 Terra",description:"Latest GPT-5.6 Codex model.",provider:"openai"},{id:"gpt-5.6-luna",name:"GPT-5.6 Luna",description:"Latest GPT-5.6 Codex model.",provider:"openai"}];function x(e){const n={...e};return e.supportedReasoningEfforts&&(n.supportedReasoningEfforts=e.supportedReasoningEfforts.map(t=>({...t}))),e.additionalSpeedTiers&&(n.additionalSpeedTiers=[...e.additionalSpeedTiers]),n}function R(e,n){const t=n??e.find(i=>i.isDefault)?.id,o=d([...e.map(x),...D.map(i=>x(i))]);return t?o.map(i=>({...i,isDefault:i.id===t})):o}function H(){return D.map((e,n)=>({...x(e),...n===0?{isDefault:!0}:{}}))}function F(){return[{id:"auto",name:"Auto",provider:"workbuddy",isDefault:!0,supportedReasoningEfforts:["minimal","low","medium","high","xhigh","max"].map(e=>({id:e,name:A(e)})),defaultReasoningEffort:"medium"}]}function k(e){return e.split("-").map(n=>/^\d/.test(n)?n:h(n)).join(" ")}function _(e,n,t=!1){const o=n.toLowerCase().replace(/\s+/g,"-");return`gemini-${e}-${o}${t?"-preview":""}`}function I(e){const n=[],t=m(e);for(const o of t.split(`
2
- `)){const i=o.trim().match(/^(\S+)\s+-\s+(.+?)(?:\s+\(([^)]+)\))?$/);if(!i)continue;const[,s,r,a]=i,u=a?.split(",").map(c=>c.trim().toLowerCase())??[];n.push({id:s,name:r.trim()||k(s),description:a?.trim(),isDefault:u.includes("default")||u.includes("current")})}return d(n)}function U(e){try{const t=(JSON.parse(e).models??[]).filter(o=>o.available).map(o=>({id:o.key,name:o.name?.trim()||o.key,provider:o.key.split("/")[0],description:o.tags?.join(", "),isDefault:o.tags?.includes("default")??!1}));return d(t)}catch{return[]}}function j(e){const n=m(e).split(`
3
- `).map(t=>t.trim()).filter(Boolean).filter(t=>!t.includes(" ")).map(t=>({id:t,name:t,provider:t.includes("/")?t.split("/")[0]:void 0}));return d(n)}function B(e){const n=m(e).replace(/\s+/g," "),t=[[/\d+\.Default\(recommended\).*?(?:Sonnet|currently\s*Sonnet)\s*([\d.]+)/i,"default","Default (recommended)"],[/\d+\.Sonnet.*?Sonnet\s*([\d.]+)/i,"sonnet","Sonnet"],[/\d+\.Opus.*?Opus\s*([\d.]+)/i,"opus","Opus"],[/\d+\.Haiku.*?Haiku\s*([\d.]+)/i,"haiku","Haiku"]],o=[];for(const[a,u,c]of t){const l=n.match(a);l&&o.push(g({id:u,name:c,description:`v${l[1]}`,provider:"anthropic",isDefault:u==="default"}))}if(o.length>0)return d(o);const i=[],s=n.match(/currently\s*(Sonnet|Opus|Haiku)\s*([34](?:\.\d)?)/i),r={sonnet:"sonnet",opus:"opus",haiku:"haiku"};for(const a of n.matchAll(/\b(Sonnet|Opus|Haiku)\s*([34](?:\.\d)?)\b/gi)){const u=(a[1]??"").toLowerCase(),c=r[u];if(!c)continue;const l=a[2]??"",C=s&&s[1]?.toLowerCase()===u&&s[2]===l;i.push(g({id:c,name:`${h(u)} ${l}`,provider:"anthropic",isDefault:!!C}))}return d(i)}function T(e,n){const t=Math.max(e.length,n.length);for(let o=0;o<t;o++){const i=e[o]??-1,s=n[o]??-1;if(i!==s)return i-s}return 0}function w(e,n){const t=e.match(new RegExp(`^claude-${n}-([0-9]+(?:-[0-9]+)*)$`,"i"));if(!t?.[1])return null;const o=t[1].split("-").map(i=>Number.parseInt(i,10)).filter(i=>Number.isFinite(i));return o.length===0||o.length>2?null:o}function $(e){if(e?.length)return`v${e.join(".")}`}const y={default:"Default (recommended)",sonnet:"Sonnet",opus:"Opus",haiku:"Haiku"},L={default:"ANTHROPIC_MODEL",sonnet:"ANTHROPIC_DEFAULT_SONNET_MODEL",opus:"ANTHROPIC_DEFAULT_OPUS_MODEL",haiku:"ANTHROPIC_DEFAULT_HAIKU_MODEL"},G=[{id:"max",name:"Max"}],N=[{id:"low",name:"Low"},{id:"medium",name:"Medium"},{id:"high",name:"High"},{id:"xhigh",name:"Extra High"},{id:"max",name:"Max"}];function g(e){return{...e,supportedReasoningEfforts:N,defaultReasoningEffort:"medium"}}function E(e,n){return e[n]?.trim()||null}function M(e,n){const t=E(n,"ANTHROPIC_BASE_URL")?.toLowerCase()??"";return t.includes("deepseek.com")||e.toLowerCase().startsWith("deepseek-")?"deepseek":t?"custom":"anthropic"}function S(e){const n=new Set;for(const o of Object.values(L)){const i=E(e,o);i&&n.add(i)}const t=Array.from(n).map((o,i)=>{const s=M(o,e),r={id:o,name:o,provider:s,isDefault:i===0};return s==="deepseek"?{...r,supportedReasoningEfforts:G,defaultReasoningEffort:E(e,"CLAUDE_CODE_EFFORT_LEVEL")??"max"}:g(r)});return d(t)}function V(e=process.env){return S(e)}function P(e,n=process.env){return e.map(t=>{if(!["default","sonnet","opus","haiku"].includes(t.id))return t;const o=t.id,i=E(n,L[o]);if(!i)return t;const r=`Claude Code alias: ${y[o]}`;return{...t,name:i,description:t.description?`${r} \xB7 ${t.description}`:r,provider:M(i,n)}})}function z(e){const n=m(e),t=new Map;for(const i of["sonnet","opus","haiku"])for(const s of n.matchAll(new RegExp(`\\bclaude-${i}-[0-9.-]+\\b`,"gi"))){const r=s[0].trim().toLowerCase().replace(/\./g,"-").replace(/-+$/g,""),a=w(r,i);if(!a)continue;const u=t.get(i);(!u||T(u,a)<0)&&t.set(i,a)}const o=[];for(const i of["default","sonnet","opus","haiku"]){if(!new RegExp(`\\b${i}\\b`,"i").test(n))continue;const s=(i==="default"?t.get("sonnet"):t.get(i))??null;o.push(g({id:i,name:y[i],description:$(s),provider:"anthropic",isDefault:i==="default"}))}return d(o)}function q(e=process.env){const n=S(e);return n.length>0?n:P([{id:"default",name:"Default (recommended)",provider:"anthropic",isDefault:!0},{id:"sonnet",name:"Sonnet",provider:"anthropic"},{id:"opus",name:"Opus",provider:"anthropic"},{id:"haiku",name:"Haiku",provider:"anthropic"}],e).map(g)}function K(e){const n=m(e),t=[];for(const o of n.split(`
4
- `)){const i=o.match(/\b(gpt-[a-z0-9][a-z0-9.-]*)\b/i);if(!i)continue;const s=i[1].trim(),r=o.replace(s,"").replace(/^[^\w]+/,"").trim()||void 0;t.push({id:s,name:b(s),description:r,provider:"openai",isDefault:/\bcurrent\b/i.test(o)||/\bselected\b/i.test(o)})}return d(t)}function W(e){const n=typeof e=="object"&&e!==null?e:{},t=typeof n.config?.model=="string"?n.config.model:void 0,o=typeof n.config?.model_reasoning_effort=="string"?n.config.model_reasoning_effort:void 0,i=[];for(const s of n.data??[]){if(typeof s!="object"||s===null)continue;const r=s,a=typeof r.id=="string"?r.id:typeof r.model=="string"?r.model:"";if(!a)continue;const u=typeof r.displayName=="string"?r.displayName:typeof r.name=="string"?r.name:void 0,c=typeof r.description=="string"?r.description:void 0,l=typeof r.defaultReasoningEffort=="string"?r.defaultReasoningEffort:void 0,C=Array.isArray(r.supportedReasoningEfforts)?r.supportedReasoningEfforts.map(f=>{if(typeof f!="object"||f===null)return null;const p=f,v=typeof p.reasoningEffort=="string"?p.reasoningEffort:typeof p.id=="string"?p.id:"";return v?{id:v,name:A(v),description:typeof p.description=="string"?p.description:void 0}:null}).filter(f=>f!=null):void 0,O=Array.isArray(r.additionalSpeedTiers)?r.additionalSpeedTiers.filter(f=>typeof f=="string"):void 0;i.push({id:a,name:u||b(a),description:c,provider:"openai",isDefault:t?t===a:r.isDefault===!0,supportedReasoningEfforts:C,defaultReasoningEffort:l,additionalSpeedTiers:O})}return t&&!i.some(s=>s.id===t)&&i.unshift({id:t,name:b(t),provider:"openai",isDefault:!0,defaultReasoningEffort:o}),R(d(i),t)}function J(e){const n=m(e),t=[];for(const o of n.matchAll(/\b(?:auto-)?gemini-[a-z0-9.-]+\b/gi)){const i=o[0].trim();t.push({id:i,name:i,provider:"google",isDefault:/\bcurrent\b/i.test(n)&&n.includes(i)})}for(const o of n.matchAll(/\bGemini\s*(\d(?:\.\d)?)\s*(Pro|Flash(?:[- ]Lite)?)\s*(Preview)?\b/gi)){const i=o[1]??"",s=(o[2]??"").replace(/\s+/g,"-"),r=!!o[3],a=_(i,s,r);t.push({id:a,name:`Gemini ${i} ${s.replace(/-/g," ")}`.trim(),provider:"google",isDefault:/\bcurrent\b/i.test(n)&&n.includes(o[0]??"")})}for(const o of n.matchAll(/\bAuto\s*Gemini\s*(\d(?:\.\d)?)\b/gi)){const i=o[1]??"",s=`auto-gemini-${i}`;t.push({id:s,name:`Auto Gemini ${i}`,provider:"google",isDefault:/\bcurrent\b/i.test(n)&&n.includes(o[0]??"")})}return d(t)}function X(){return[{id:"gemini-2.5-pro",name:"Gemini 2.5 Pro",provider:"google",isDefault:!0},{id:"gemini-2.5-flash",name:"Gemini 2.5 Flash",provider:"google"},{id:"auto-gemini-2.5",name:"Auto Gemini 2.5",provider:"google"}]}export{P as applyClaudeModelEnvOverrides,V as discoverClaudeAliasModelsFromEnv,q as fallbackClaudeAliasModels,H as fallbackCodexModels,X as fallbackGeminiModels,F as fallbackWorkBuddyModels,M as inferClaudeOverrideProvider,z as parseClaudeBinaryModels,B as parseClaudeModels,W as parseCodexAppServerModels,K as parseCodexModels,I as parseCursorModels,J as parseGeminiModels,U as parseOpenClawModels,j as parseOpenCodeModels,E as readEnvValue,m as stripAnsi};
1
+ function g(e){return e.replace(/\u001b\[[0-9;?]*[a-zA-Z]/g,"").replace(/\u001b\][^\u0007]*\u0007/g,"").replace(/[\u0000-\u0008\u000b-\u001f\u007f]/g,"")}function d(e){const n=new Set,t=[];for(const o of e)!o.id||n.has(o.id)||(n.add(o.id),t.push(o));return t}function E(e){return e&&e[0].toUpperCase()+e.slice(1)}function b(e){return e.split("-").map(n=>n==="gpt"?"GPT":n==="codex"?"Codex":/^\d/.test(n)?n:E(n)).join("-")}function M(e){switch(e){case"low":return"Low";case"medium":return"Medium";case"high":return"High";case"xhigh":return"Extra High";default:return E(e)}}const O=[{id:"gpt-5.6-sol",name:"GPT-5.6 Sol",description:"Latest GPT-5.6 Codex model.",provider:"openai"},{id:"gpt-5.6-terra",name:"GPT-5.6 Terra",description:"Latest GPT-5.6 Codex model.",provider:"openai"},{id:"gpt-5.6-luna",name:"GPT-5.6 Luna",description:"Latest GPT-5.6 Codex model.",provider:"openai"}];function C(e){const n={...e};return e.supportedReasoningEfforts&&(n.supportedReasoningEfforts=e.supportedReasoningEfforts.map(t=>({...t}))),e.additionalSpeedTiers&&(n.additionalSpeedTiers=[...e.additionalSpeedTiers]),n}function R(e,n){const t=n??e.find(i=>i.isDefault)?.id,o=d([...e.map(C),...O.map(i=>C(i))]);return t?o.map(i=>({...i,isDefault:i.id===t})):o}function H(){return O.map((e,n)=>({...C(e),...n===0?{isDefault:!0}:{}}))}function F(){return[{id:"auto",name:"Auto",provider:"workbuddy",isDefault:!0,supportedReasoningEfforts:["minimal","low","medium","high","xhigh","max"].map(e=>({id:e,name:M(e)})),defaultReasoningEffort:"medium"}]}function k(e){return e.split("-").map(n=>/^\d/.test(n)?n:E(n)).join(" ")}function _(e,n,t=!1){const o=n.toLowerCase().replace(/\s+/g,"-");return`gemini-${e}-${o}${t?"-preview":""}`}function I(e){const n=[],t=g(e);for(const o of t.split(`
2
+ `)){const i=o.trim().match(/^(\S+)\s+-\s+(.+?)(?:\s+\(([^)]+)\))?$/);if(!i)continue;const[,s,r,a]=i,u=a?.split(",").map(c=>c.trim().toLowerCase())??[];n.push({id:s,name:r.trim()||k(s),description:a?.trim(),isDefault:u.includes("default")||u.includes("current")})}return d(n)}function U(e){try{const t=(JSON.parse(e).models??[]).filter(o=>o.available).map(o=>({id:o.key,name:o.name?.trim()||o.key,provider:o.key.split("/")[0],description:o.tags?.join(", "),isDefault:o.tags?.includes("default")??!1}));return d(t)}catch{return[]}}function B(e){const n=g(e).split(`
3
+ `).map(t=>t.trim()).filter(Boolean).filter(t=>!t.includes(" ")).map(t=>({id:t,name:t,provider:t.includes("/")?t.split("/")[0]:void 0}));return d(n)}function j(e){const n=g(e).replace(/\s+/g," "),t=[[/\d+\.Default\(recommended\).*?(?:Sonnet|currently\s*Sonnet)\s*([\d.]+)/i,"default","Default (recommended)"],[/\d+\.Best.*?Opus\s*([\d.]+)/i,"best","Best","Most capable available model"],[/\d+\.Opus\(1Mcontext\).*?Opus\s*([\d.]+)/i,"opus[1m]","Opus (1M context)"],[/\d+\.OpusPlan.*?Opus\s*([\d.]+)/i,"opusplan","Opus Plan","Opus for planning \xB7 Sonnet for execution"],[/\d+\.Opus(?!\(1Mcontext\)).*?Opus\s*([\d.]+)/i,"opus","Opus"],[/\d+\.Sonnet\(1Mcontext\).*?Sonnet\s*([\d.]+)/i,"sonnet[1m]","Sonnet (1M context)"],[/\d+\.Sonnet(?!\(1Mcontext\)).*?Sonnet\s*([\d.]+)/i,"sonnet","Sonnet"],[/\d+\.Haiku.*?Haiku\s*([\d.]+)/i,"haiku","Haiku"]],o=[];for(const[a,u,c,l]of t){const p=n.match(a);p&&o.push(h({id:u,name:c,description:l?`${l} \xB7 v${p[1]}`:`v${p[1]}`,provider:"anthropic",isDefault:u==="default"}))}if(o.length>0)return d(o);const i=[],s=n.match(/currently\s*(Sonnet|Opus|Haiku)\s*([34](?:\.\d)?)/i),r={sonnet:"sonnet",opus:"opus",haiku:"haiku"};for(const a of n.matchAll(/\b(Sonnet|Opus|Haiku)\s*([34](?:\.\d)?)\b/gi)){const u=(a[1]??"").toLowerCase(),c=r[u];if(!c)continue;const l=a[2]??"",p=s&&s[1]?.toLowerCase()===u&&s[2]===l;i.push(h({id:c,name:`${E(u)} ${l}`,provider:"anthropic",isDefault:!!p}))}return d(i)}function T(e,n){const t=Math.max(e.length,n.length);for(let o=0;o<t;o++){const i=e[o]??-1,s=n[o]??-1;if(i!==s)return i-s}return 0}function w(e,n){const t=e.match(new RegExp(`^claude-${n}-([0-9]+(?:-[0-9]+)*)$`,"i"));if(!t?.[1])return null;const o=t[1].split("-").map(i=>Number.parseInt(i,10)).filter(i=>Number.isFinite(i));return o.length===0||o.length>2?null:o}function $(e){if(e?.length)return`v${e.join(".")}`}const y={default:"Default (recommended)",sonnet:"Sonnet",opus:"Opus",haiku:"Haiku"},L={default:"ANTHROPIC_MODEL",sonnet:"ANTHROPIC_DEFAULT_SONNET_MODEL",opus:"ANTHROPIC_DEFAULT_OPUS_MODEL",haiku:"ANTHROPIC_DEFAULT_HAIKU_MODEL"},P=[{id:"max",name:"Max"}],G=[{id:"low",name:"Low"},{id:"medium",name:"Medium"},{id:"high",name:"High"},{id:"xhigh",name:"Extra High"},{id:"max",name:"Max"}];function h(e){return{...e,supportedReasoningEfforts:G,defaultReasoningEffort:"medium"}}function x(e,n){return e[n]?.trim()||null}function A(e,n){const t=x(n,"ANTHROPIC_BASE_URL")?.toLowerCase()??"";return t.includes("deepseek.com")||e.toLowerCase().startsWith("deepseek-")?"deepseek":t?"custom":"anthropic"}function D(e){const n=new Set;for(const o of Object.values(L)){const i=x(e,o);i&&n.add(i)}const t=Array.from(n).map((o,i)=>{const s=A(o,e),r={id:o,name:o,provider:s,isDefault:i===0};return s==="deepseek"?{...r,supportedReasoningEfforts:P,defaultReasoningEffort:x(e,"CLAUDE_CODE_EFFORT_LEVEL")??"max"}:h(r)});return d(t)}function V(e=process.env){return D(e)}function N(e,n=process.env){return e.map(t=>{if(!["default","sonnet","opus","haiku"].includes(t.id))return t;const o=t.id,i=x(n,L[o]);if(!i)return t;const r=`Claude Code alias: ${y[o]}`;return{...t,name:i,description:t.description?`${r} \xB7 ${t.description}`:r,provider:A(i,n)}})}function z(e){const n=g(e),t=new Map;for(const i of["sonnet","opus","haiku"])for(const s of n.matchAll(new RegExp(`\\bclaude-${i}-[0-9.-]+\\b`,"gi"))){const r=s[0].trim().toLowerCase().replace(/\./g,"-").replace(/-+$/g,""),a=w(r,i);if(!a)continue;const u=t.get(i);(!u||T(u,a)<0)&&t.set(i,a)}const o=[];for(const i of["default","sonnet","opus","haiku"]){if(!new RegExp(`\\b${i}\\b`,"i").test(n))continue;const s=(i==="default"?t.get("sonnet"):t.get(i))??null;o.push(h({id:i,name:y[i],description:$(s),provider:"anthropic",isDefault:i==="default"}))}return d(o)}function q(e=process.env){const n=D(e);return n.length>0?n:N([{id:"default",name:"Default (recommended)",description:"Recommended model for your account",provider:"anthropic",isDefault:!0},{id:"best",name:"Best",description:"Most capable available model \xB7 currently Opus",provider:"anthropic"},{id:"opus",name:"Opus",description:"Latest Opus \xB7 complex reasoning",provider:"anthropic"},{id:"opus[1m]",name:"Opus (1M context)",description:"Latest Opus \xB7 long sessions",provider:"anthropic"},{id:"sonnet",name:"Sonnet",description:"Latest Sonnet \xB7 everyday coding",provider:"anthropic"},{id:"sonnet[1m]",name:"Sonnet (1M context)",description:"Latest Sonnet \xB7 long sessions",provider:"anthropic"},{id:"haiku",name:"Haiku",description:"Fast and efficient \xB7 simple tasks",provider:"anthropic"},{id:"opusplan",name:"Opus Plan",description:"Opus for planning \xB7 Sonnet for execution",provider:"anthropic"}],e).map(h)}function K(e){const n=g(e),t=[];for(const o of n.split(`
4
+ `)){const i=o.match(/\b(gpt-[a-z0-9][a-z0-9.-]*)\b/i);if(!i)continue;const s=i[1].trim(),r=o.replace(s,"").replace(/^[^\w]+/,"").trim()||void 0;t.push({id:s,name:b(s),description:r,provider:"openai",isDefault:/\bcurrent\b/i.test(o)||/\bselected\b/i.test(o)})}return d(t)}function W(e){const n=typeof e=="object"&&e!==null?e:{},t=typeof n.config?.model=="string"?n.config.model:void 0,o=typeof n.config?.model_reasoning_effort=="string"?n.config.model_reasoning_effort:void 0,i=[];for(const s of n.data??[]){if(typeof s!="object"||s===null)continue;const r=s,a=typeof r.id=="string"?r.id:typeof r.model=="string"?r.model:"";if(!a)continue;const u=typeof r.displayName=="string"?r.displayName:typeof r.name=="string"?r.name:void 0,c=typeof r.description=="string"?r.description:void 0,l=typeof r.defaultReasoningEffort=="string"?r.defaultReasoningEffort:void 0,p=Array.isArray(r.supportedReasoningEfforts)?r.supportedReasoningEfforts.map(f=>{if(typeof f!="object"||f===null)return null;const m=f,v=typeof m.reasoningEffort=="string"?m.reasoningEffort:typeof m.id=="string"?m.id:"";return v?{id:v,name:M(v),description:typeof m.description=="string"?m.description:void 0}:null}).filter(f=>f!=null):void 0,S=Array.isArray(r.additionalSpeedTiers)?r.additionalSpeedTiers.filter(f=>typeof f=="string"):void 0;i.push({id:a,name:u||b(a),description:c,provider:"openai",isDefault:t?t===a:r.isDefault===!0,supportedReasoningEfforts:p,defaultReasoningEffort:l,additionalSpeedTiers:S})}return t&&!i.some(s=>s.id===t)&&i.unshift({id:t,name:b(t),provider:"openai",isDefault:!0,defaultReasoningEffort:o}),R(d(i),t)}function J(e){const n=g(e),t=[];for(const o of n.matchAll(/\b(?:auto-)?gemini-[a-z0-9.-]+\b/gi)){const i=o[0].trim();t.push({id:i,name:i,provider:"google",isDefault:/\bcurrent\b/i.test(n)&&n.includes(i)})}for(const o of n.matchAll(/\bGemini\s*(\d(?:\.\d)?)\s*(Pro|Flash(?:[- ]Lite)?)\s*(Preview)?\b/gi)){const i=o[1]??"",s=(o[2]??"").replace(/\s+/g,"-"),r=!!o[3],a=_(i,s,r);t.push({id:a,name:`Gemini ${i} ${s.replace(/-/g," ")}`.trim(),provider:"google",isDefault:/\bcurrent\b/i.test(n)&&n.includes(o[0]??"")})}for(const o of n.matchAll(/\bAuto\s*Gemini\s*(\d(?:\.\d)?)\b/gi)){const i=o[1]??"",s=`auto-gemini-${i}`;t.push({id:s,name:`Auto Gemini ${i}`,provider:"google",isDefault:/\bcurrent\b/i.test(n)&&n.includes(o[0]??"")})}return d(t)}function X(){return[{id:"gemini-2.5-pro",name:"Gemini 2.5 Pro",provider:"google",isDefault:!0},{id:"gemini-2.5-flash",name:"Gemini 2.5 Flash",provider:"google"},{id:"auto-gemini-2.5",name:"Auto Gemini 2.5",provider:"google"}]}export{N as applyClaudeModelEnvOverrides,V as discoverClaudeAliasModelsFromEnv,q as fallbackClaudeAliasModels,H as fallbackCodexModels,X as fallbackGeminiModels,F as fallbackWorkBuddyModels,A as inferClaudeOverrideProvider,z as parseClaudeBinaryModels,j as parseClaudeModels,W as parseCodexAppServerModels,K as parseCodexModels,I as parseCursorModels,J as parseGeminiModels,U as parseOpenClawModels,B as parseOpenCodeModels,x as readEnvValue,g as stripAnsi};
@@ -1,4 +1,4 @@
1
- import a from"node:path";function i(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}function u(e){return`"${e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`}function n(e){return`"${e.replace(/"/g,'""')}"`}function l(e){return e.replace(/"/g,'""')}function r(e){return i(e)}function s(e){const t=a.extname(e).toLowerCase();return t===".cmd"||t===".bat"}function m(e,t){const o=[e.command,...e.args].map(n).join(" ");return["@echo off","setlocal",'if not defined SHENNIAN_HOME set "SHENNIAN_HOME=%~dp0."',`${s(e.command)?`call ${o}`:o} >> ${n(t)} 2>&1`,""].join(`\r
1
+ import a from"node:path";function i(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}function d(e){return`"${e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`}function n(e){return`"${e.replace(/"/g,'""')}"`}function l(e){return e.replace(/"/g,'""')}function r(e){return i(e)}function s(e){const t=a.extname(e).toLowerCase();return t===".cmd"||t===".bat"}function m(e,t){const o=[e.command,...e.args].map(n).join(" ");return["@echo off","setlocal",'if not defined SHENNIAN_HOME set "SHENNIAN_HOME=%~dp0."',`${s(e.command)?`call ${o}`:o} >> ${n(t)} 2>&1`,""].join(`\r
2
2
  `)}function g(e){return['Set shell = CreateObject("WScript.Shell")',`shell.Run Chr(34) & "${l(e)}" & Chr(34), 0, False`,""].join(`\r
3
3
  `)}function p(e){const t=e.arguments.join(" ");return`<?xml version="1.0" encoding="UTF-16"?>
4
4
  <Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
@@ -46,7 +46,7 @@ import a from"node:path";function i(e){return e.replace(/&/g,"&amp;").replace(/<
46
46
  <Enabled>true</Enabled>
47
47
  <Hidden>true</Hidden>
48
48
  <RunOnlyIfIdle>false</RunOnlyIfIdle>
49
- <WakeToRun>false</WakeToRun>
49
+ <WakeToRun>true</WakeToRun>
50
50
  <ExecutionTimeLimit>PT0S</ExecutionTimeLimit>
51
51
  <Priority>7</Priority>
52
52
  <RestartOnFailure>
@@ -60,4 +60,4 @@ import a from"node:path";function i(e){return e.replace(/&/g,"&amp;").replace(/<
60
60
  <Arguments>${r(t)}</Arguments>
61
61
  </Exec>
62
62
  </Actions>
63
- </Task>`}function S(e){return{create:`schtasks /create /tn ${n(e.taskName)} /xml ${n(e.xmlPath)} /f`,run:`schtasks /run /tn ${n(e.taskName)}`}}export{m as buildWindowsLauncherCommand,S as buildWindowsScheduledTaskCommands,p as buildWindowsScheduledTaskXml,g as buildWindowsStartupVbs,i as escapeXml,s as isWindowsCmdScript,n as quoteCmdArg,u as quoteSystemdArg};
63
+ </Task>`}function S(e){return{create:`schtasks /create /tn ${n(e.taskName)} /xml ${n(e.xmlPath)} /f`,run:`schtasks /run /tn ${n(e.taskName)}`}}export{m as buildWindowsLauncherCommand,S as buildWindowsScheduledTaskCommands,p as buildWindowsScheduledTaskXml,g as buildWindowsStartupVbs,i as escapeXml,s as isWindowsCmdScript,n as quoteCmdArg,d as quoteSystemdArg};
@@ -70,6 +70,9 @@ export declare function saveEnvSnapshot(): void;
70
70
  export declare function startDaemonProcess(opts?: {
71
71
  quiet?: boolean;
72
72
  }): void;
73
+ export declare function shouldReplaceRunningDaemon(status: Pick<DaemonStatus, 'pid' | 'running' | 'adopted'>, record?: {
74
+ version?: string;
75
+ } | null, currentVersion?: string): boolean;
73
76
  /**
74
77
  * Install the platform-native auto-start service.
75
78
  * Returns true if the service was immediately started (so caller can skip startDaemonProcess).
@@ -1,7 +1,7 @@
1
- import s from"chalk";import o from"node:fs";import c from"node:path";import u from"node:os";import{execSync as a,spawn as ae}from"node:child_process";import{randomUUID as ce}from"node:crypto";import{fileURLToPath as ue}from"node:url";import{getShennianDir as de,loadConfig as j,resolveShennianPath as h,saveConfig as le}from"../config/index.js";import{buildAugmentedPath as pe}from"../env-path.js";import{buildWindowsLauncherCommand as me,buildWindowsScheduledTaskCommands as fe,buildWindowsScheduledTaskXml as Se,buildWindowsStartupVbs as he,escapeXml as N,isWindowsCmdScript as ge,quoteCmdArg as W,quoteSystemdArg as ye}from"./daemon-windows.js";import{waitForDaemonReadyStatus as b}from"./daemon-start-wait.js";import{findRunningWindowsDaemonProcessIds as we,isShennianRunServiceCommand as Ee}from"./daemon-process.js";import{buildWindowsLauncherCommand as hn,buildWindowsScheduledTaskCommands as gn,buildWindowsScheduledTaskXml as yn,buildWindowsStartupVbs as wn}from"./daemon-windows.js";import{isShennianRunServiceCommand as vn}from"./daemon-process.js";const ve=c.dirname(ue(import.meta.url)),g=de(),p=h("daemon.pid"),d=h("daemon.log"),L=h("remote-access.disabled"),k=h("daemon-launcher.json"),F=c.resolve(ve,"../../bin/shennian.js"),B=process.execPath,V=new Set(["PATH","HOME","USERPROFILE","HOMEDRIVE","HOMEPATH","USERNAME","USERDOMAIN","COMPUTERNAME","USER","LOGNAME","SHELL","TMPDIR","LANG","LC_ALL","LC_CTYPE","SSH_AUTH_SOCK","XDG_CONFIG_HOME","XDG_DATA_HOME","TEMP","TMP","APPDATA","LOCALAPPDATA","SHENNIAN_DESKTOP_SERVER_URL","SHENNIAN_WECHAT_CHANNEL_HELPER_DIR","SHENNIAN_HOME","SHENNIAN_NATIVE_FUSION_DISABLED","SHENNIAN_WECHAT_DELIVERABILITY_TRACE"]);function Ae(e){return V.has(e)}function l(){const e=u.platform();return e==="darwin"||e==="linux"||e==="win32"?e:"linux"}function R(e){const n=e.replace(/\\/g,"/").toLowerCase(),t=u.tmpdir().replace(/\\/g,"/").toLowerCase();return n.includes("/_npx/")||n.includes("/npm-cache/_npx/")||n.includes("/pnpm/dlx/")||n.startsWith(t.endsWith("/")?t:`${t}/`)}function Ie(e){return o.existsSync(e.scriptPath)&&!R(e.scriptPath)?{command:e.nodeExec,args:[e.scriptPath,"run-service"],mode:"direct"}:e.shennianCommandPath&&!R(e.shennianCommandPath)?{command:e.shennianCommandPath,args:["run-service"],mode:"global-shim"}:e.npxPath?{command:e.npxPath,args:["--yes","shennian","run-service"],mode:"npx"}:{command:e.nodeExec,args:[e.scriptPath,"run-service"],mode:"direct"}}function ke(e){const n=e.trim();if(!n)return null;if(n.startsWith("{"))try{const r=JSON.parse(n),i=Number(r.pid);return!Number.isInteger(i)||i<=0?null:{pid:i,...typeof r.instanceId=="string"?{instanceId:r.instanceId}:{},...typeof r.version=="string"?{version:r.version}:{},...r.launcher==="desktop-managed"||r.launcher==="global-cli"||r.launcher==="unknown"?{launcher:r.launcher}:{},...typeof r.startedAt=="string"?{startedAt:r.startedAt}:{},...r.adopted===!0?{adopted:!0}:{}}}catch{return null}const t=parseInt(n,10);return isNaN(t)?null:{pid:t}}function O(){try{return ke(o.readFileSync(p,"utf-8"))}catch{return null}}function Pe(){return O()?.pid??null}function w(e){try{return process.kill(e,0),!0}catch{return!1}}function De(e,n=3e3){const t=Date.now();for(;Date.now()-t<n;){if(!w(e))return!0;Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,100)}return!w(e)}function Ne(){return o.existsSync(L)}function be(){try{o.unlinkSync(L)}catch{}}function J(){return"global-cli"}function Le(){return`${process.pid}-${Date.now()}-${ce()}`}function Re(e,n,t={}){o.mkdirSync(g,{recursive:!0}),o.writeFileSync(p,JSON.stringify({pid:e,instanceId:n,...t.version?{version:t.version}:{},launcher:t.launcher??J(),...t.adopted?{adopted:!0}:{},startedAt:new Date().toISOString()},null,2))}function ln(e,n){const t=O();if(!(t?.pid!==e||t.instanceId!==n))try{o.unlinkSync(p)}catch{}}function G(e,n=J(),t){o.mkdirSync(g,{recursive:!0}),o.writeFileSync(k,JSON.stringify({pid:e,launcher:n,...t?{instanceId:t}:{},updatedAt:new Date().toISOString()},null,2))}function T(e){if(e)try{if(JSON.parse(o.readFileSync(k,"utf-8")).instanceId!==e)return}catch{return}try{o.unlinkSync(k)}catch{}}function Oe(e){e&&G(e)}function Te(e,n){if(!e||!n)return"unknown";try{const t=JSON.parse(o.readFileSync(k,"utf-8"));if(t.pid!==e)return"unknown";if(t.launcher==="desktop-managed"||t.launcher==="global-cli")return t.launcher}catch{}return x(e)}function x(e){if(l()==="win32")return"unknown";try{const n=a(`ps -p ${e} -o command=`,{encoding:"utf-8",stdio:["ignore","pipe","ignore"],timeout:1e3,windowsHide:!0}).replace(/\\/g,"/");if(n.includes("/node_modules/shennian/")||n.includes("/bin/shennian")||n.includes(" shennian run-service")||n.includes(" shennian.js run-service"))return"global-cli"}catch{}return"unknown"}function K(e=process.pid){if(l()==="win32")return we(e);try{return a("ps -axo pid=,command=",{encoding:"utf-8",stdio:["ignore","pipe","ignore"],timeout:1e3,windowsHide:!0}).split(/\r?\n/).map(t=>{const r=t.trim().match(/^(\d+)\s+(.+)$/);if(!r)return null;const i=Number(r[1]),S=r[2];return!Number.isInteger(i)||i===e?null:Ee(S)?i:null}).filter(t=>typeof t=="number")}catch{return[]}}function pn(e=process.env,n=g,t=u.tmpdir()){if(e.SHENNIAN_E2E_ISOLATED_DAEMON!=="1"||!e.SHENNIAN_HOME?.trim())return!1;const r=c.relative(c.resolve(t),c.resolve(n));return r!==""&&r!==".."&&!r.startsWith(`..${c.sep}`)&&!c.isAbsolute(r)}function f(e={}){let n=O(),t=n?.pid??null,r=t!==null&&w(t),i=t!==null&&!r,S=n?.adopted===!0;const E=j();if(i&&e.cleanupStale){try{o.unlinkSync(p)}catch{}n=null,t=null,r=!1,i=!1}if(!r){const y=K()[0];if(y&&(t=y,r=!0,i=!1,S=!0,e.cleanupStale)){const U=Le();Re(y,U,{launcher:x(y),adopted:!0}),G(y,x(y)),n={pid:y,instanceId:U,adopted:!0}}}return{running:r,pid:t,stale:i,remoteAccessDisabled:Ne(),launcher:Te(t,r),platform:l(),shennianDir:g,pidFile:p,logFile:d,...n?.instanceId?{instanceId:n.instanceId}:{},...S?{adopted:!0}:{},...E.machineId?{machineId:E.machineId}:{},paired:!!(E.machineToken&&E.machineId),...E.serverUrl?{serverUrl:E.serverUrl}:{}}}function v(e){process.stdout.write(`${JSON.stringify(e,null,2)}
2
- `)}function X(e){const n=e?.trim();if(!n)return;const t=j();t.serverUrl=n,le(t)}function q(e){return e?.trim()||process.env.SHENNIAN_DESKTOP_SERVER_URL?.trim()||void 0}const H="com.shennian.agent",m=c.join(u.homedir(),"Library/LaunchAgents",`${H}.plist`),xe=c.join(u.homedir(),"AppData","Roaming","Microsoft","Windows","Start Menu","Programs","Startup"),_=h("autostart.cmd"),$=h("autostart.vbs"),C=h("autostart.xml"),He=c.join(xe,"ShennianAgent.vbs");function Y(e){const n=l()==="win32"?`where ${e}`:`command -v ${e}`;try{return a(n,{stdio:["ignore","pipe","pipe"],encoding:"utf-8",windowsHide:!0}).split(/\r?\n/).map(i=>i.trim()).find(Boolean)??null}catch{return null}}function _e(){const e=l()==="win32"?"npx.cmd":"npx",n=c.join(c.dirname(B),e);return o.existsSync(n)?n:Y("npx")}function A(){return Ie({nodeExec:B,scriptPath:F,shennianCommandPath:Y("shennian"),npxPath:_e()})}function z(){try{a(`schtasks /delete /tn "${D}" /f`,{stdio:"pipe",windowsHide:!0})}catch{}}function Q(){try{o.unlinkSync(He)}catch{}}function $e(){const e=process.env.USERDOMAIN?.trim(),n=process.env.COMPUTERNAME?.trim(),t=process.env.USERNAME?.trim()||u.userInfo().username;return e&&e.toUpperCase()!=="WORKGROUP"?`${e}\\${t}`:n?`${n}\\${t}`:t}function Ce(e){if(l()==="win32"&&ge(e.command)){const n=[e.command,...e.args].map(W).join(" ");return{command:process.env.ComSpec||"cmd.exe",args:["/d","/s","/c",`"${n}"`],windowsVerbatimArguments:!0}}return{command:e.command,args:e.args}}function Me(e,n,t=process.env){return{detached:!0,stdio:["ignore",n,n],env:t,windowsHide:!0,...e.windowsVerbatimArguments?{windowsVerbatimArguments:!0}:{}}}function Ue(){const e=A();o.writeFileSync(_,me(e,d)),o.writeFileSync($,he(_)),Q(),z();const n=Se({userId:$e(),command:c.join(process.env.SystemRoot||"C:\\Windows","System32","wscript.exe"),arguments:[W($)]});o.writeFileSync(C,n,"utf8");const t=fe({taskName:D,xmlPath:C});try{return a(t.create,{stdio:"pipe",windowsHide:!0}),a(t.run,{stdio:"pipe",windowsHide:!0}),!0}catch{return!1}}function Z(){const e={};for(const n of V)process.env[n]&&(e[n]=process.env[n]);if(e.HOME??=u.homedir(),e.PATH=pe({pathValue:e.PATH,env:e}),e.USER??=u.userInfo().username,l()==="win32"){const n=process.env.TEMP||process.env.TMP||u.tmpdir(),t=u.homedir();e.USERPROFILE??=t;const r=c.win32.parse(t);e.HOMEDRIVE??=r.root.replace(/[\\/]$/,"")||process.env.HOMEDRIVE||"",e.HOMEPATH??=t.slice((e.HOMEDRIVE||"").length)||process.env.HOMEPATH||"",e.USERNAME??=process.env.USERNAME||u.userInfo().username,e.COMPUTERNAME??=process.env.COMPUTERNAME||"",e.TMPDIR??=n,e.TEMP??=n,e.TMP??=n}else e.TMPDIR??="/tmp";return e}function je(){const e=Z(),n=A(),t=Object.entries(e).map(([i,S])=>` <key>${N(i)}</key>
3
- <string>${N(S)}</string>`).join(`
4
- `),r=[n.command,...n.args].map(i=>` <string>${N(i)}</string>`).join(`
1
+ import s from"chalk";import i from"node:fs";import c from"node:path";import u from"node:os";import{execSync as a,spawn as ue}from"node:child_process";import{randomUUID as de}from"node:crypto";import{fileURLToPath as le}from"node:url";import{getShennianDir as pe,loadConfig as j,resolveShennianPath as h,saveConfig as me}from"../config/index.js";import{buildAugmentedPath as fe}from"../env-path.js";import{buildWindowsLauncherCommand as Se,buildWindowsScheduledTaskCommands as he,buildWindowsScheduledTaskXml as ge,buildWindowsStartupVbs as ye,escapeXml as b,isWindowsCmdScript as we,quoteCmdArg as W,quoteSystemdArg as Ee}from"./daemon-windows.js";import{waitForDaemonReadyStatus as L}from"./daemon-start-wait.js";import{findRunningWindowsDaemonProcessIds as ve,isShennianRunServiceCommand as Ie}from"./daemon-process.js";import{getCurrentVersion as ke}from"../upgrade/engine.js";import{buildWindowsLauncherCommand as wn,buildWindowsScheduledTaskCommands as En,buildWindowsScheduledTaskXml as vn,buildWindowsStartupVbs as In}from"./daemon-windows.js";import{isShennianRunServiceCommand as An}from"./daemon-process.js";const Ae=c.dirname(le(import.meta.url)),g=pe(),p=h("daemon.pid"),d=h("daemon.log"),R=h("remote-access.disabled"),P=h("daemon-launcher.json"),F=c.resolve(Ae,"../../bin/shennian.js"),B=process.execPath,V=new Set(["PATH","HOME","USERPROFILE","HOMEDRIVE","HOMEPATH","USERNAME","USERDOMAIN","COMPUTERNAME","USER","LOGNAME","SHELL","TMPDIR","LANG","LC_ALL","LC_CTYPE","SSH_AUTH_SOCK","XDG_CONFIG_HOME","XDG_DATA_HOME","TEMP","TMP","APPDATA","LOCALAPPDATA","SHENNIAN_DESKTOP_SERVER_URL","SHENNIAN_WECHAT_CHANNEL_HELPER_DIR","SHENNIAN_HOME","SHENNIAN_NATIVE_FUSION_DISABLED","SHENNIAN_WECHAT_DELIVERABILITY_TRACE"]);function Pe(e){return V.has(e)}function l(){const e=u.platform();return e==="darwin"||e==="linux"||e==="win32"?e:"linux"}function O(e){const n=e.replace(/\\/g,"/").toLowerCase(),t=u.tmpdir().replace(/\\/g,"/").toLowerCase();return n.includes("/_npx/")||n.includes("/npm-cache/_npx/")||n.includes("/pnpm/dlx/")||n.startsWith(t.endsWith("/")?t:`${t}/`)}function De(e){return i.existsSync(e.scriptPath)&&!O(e.scriptPath)?{command:e.nodeExec,args:[e.scriptPath,"run-service"],mode:"direct"}:e.shennianCommandPath&&!O(e.shennianCommandPath)?{command:e.shennianCommandPath,args:["run-service"],mode:"global-shim"}:e.npxPath?{command:e.npxPath,args:["--yes","shennian","run-service"],mode:"npx"}:{command:e.nodeExec,args:[e.scriptPath,"run-service"],mode:"direct"}}function Ne(e){const n=e.trim();if(!n)return null;if(n.startsWith("{"))try{const r=JSON.parse(n),o=Number(r.pid);return!Number.isInteger(o)||o<=0?null:{pid:o,...typeof r.instanceId=="string"?{instanceId:r.instanceId}:{},...typeof r.version=="string"?{version:r.version}:{},...r.launcher==="desktop-managed"||r.launcher==="global-cli"||r.launcher==="unknown"?{launcher:r.launcher}:{},...typeof r.startedAt=="string"?{startedAt:r.startedAt}:{},...r.adopted===!0?{adopted:!0}:{}}}catch{return null}const t=parseInt(n,10);return isNaN(t)?null:{pid:t}}function I(){try{return Ne(i.readFileSync(p,"utf-8"))}catch{return null}}function be(){return I()?.pid??null}function w(e){try{return process.kill(e,0),!0}catch{return!1}}function G(e,n=3e3){const t=Date.now();for(;Date.now()-t<n;){if(!w(e))return!0;Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,100)}return!w(e)}function Le(){return i.existsSync(R)}function Re(){try{i.unlinkSync(R)}catch{}}function J(){return"global-cli"}function Oe(){return`${process.pid}-${Date.now()}-${de()}`}function Te(e,n,t={}){i.mkdirSync(g,{recursive:!0}),i.writeFileSync(p,JSON.stringify({pid:e,instanceId:n,...t.version?{version:t.version}:{},launcher:t.launcher??J(),...t.adopted?{adopted:!0}:{},startedAt:new Date().toISOString()},null,2))}function fn(e,n){const t=I();if(!(t?.pid!==e||t.instanceId!==n))try{i.unlinkSync(p)}catch{}}function K(e,n=J(),t){i.mkdirSync(g,{recursive:!0}),i.writeFileSync(P,JSON.stringify({pid:e,launcher:n,...t?{instanceId:t}:{},updatedAt:new Date().toISOString()},null,2))}function T(e){if(e)try{if(JSON.parse(i.readFileSync(P,"utf-8")).instanceId!==e)return}catch{return}try{i.unlinkSync(P)}catch{}}function xe(e){e&&K(e)}function He(e,n){if(!e||!n)return"unknown";try{const t=JSON.parse(i.readFileSync(P,"utf-8"));if(t.pid!==e)return"unknown";if(t.launcher==="desktop-managed"||t.launcher==="global-cli")return t.launcher}catch{}return x(e)}function x(e){if(l()==="win32")return"unknown";try{const n=a(`ps -p ${e} -o command=`,{encoding:"utf-8",stdio:["ignore","pipe","ignore"],timeout:1e3,windowsHide:!0}).replace(/\\/g,"/");if(n.includes("/node_modules/shennian/")||n.includes("/bin/shennian")||n.includes(" shennian run-service")||n.includes(" shennian.js run-service"))return"global-cli"}catch{}return"unknown"}function X(e=process.pid){if(l()==="win32")return ve(e);try{return a("ps -axo pid=,command=",{encoding:"utf-8",stdio:["ignore","pipe","ignore"],timeout:1e3,windowsHide:!0}).split(/\r?\n/).map(t=>{const r=t.trim().match(/^(\d+)\s+(.+)$/);if(!r)return null;const o=Number(r[1]),S=r[2];return!Number.isInteger(o)||o===e?null:Ie(S)?o:null}).filter(t=>typeof t=="number")}catch{return[]}}function Sn(e=process.env,n=g,t=u.tmpdir()){if(e.SHENNIAN_E2E_ISOLATED_DAEMON!=="1"||!e.SHENNIAN_HOME?.trim())return!1;const r=c.relative(c.resolve(t),c.resolve(n));return r!==""&&r!==".."&&!r.startsWith(`..${c.sep}`)&&!c.isAbsolute(r)}function f(e={}){let n=I(),t=n?.pid??null,r=t!==null&&w(t),o=t!==null&&!r,S=n?.adopted===!0;const E=j();if(o&&e.cleanupStale){try{i.unlinkSync(p)}catch{}n=null,t=null,r=!1,o=!1}if(!r){const y=X()[0];if(y&&(t=y,r=!0,o=!1,S=!0,e.cleanupStale)){const U=Oe();Te(y,U,{launcher:x(y),adopted:!0}),K(y,x(y)),n={pid:y,instanceId:U,adopted:!0}}}return{running:r,pid:t,stale:o,remoteAccessDisabled:Le(),launcher:He(t,r),platform:l(),shennianDir:g,pidFile:p,logFile:d,...n?.instanceId?{instanceId:n.instanceId}:{},...S?{adopted:!0}:{},...E.machineId?{machineId:E.machineId}:{},paired:!!(E.machineToken&&E.machineId),...E.serverUrl?{serverUrl:E.serverUrl}:{}}}function v(e){process.stdout.write(`${JSON.stringify(e,null,2)}
2
+ `)}function q(e){const n=e?.trim();if(!n)return;const t=j();t.serverUrl=n,me(t)}function Y(e){return e?.trim()||process.env.SHENNIAN_DESKTOP_SERVER_URL?.trim()||void 0}const H="com.shennian.agent",m=c.join(u.homedir(),"Library/LaunchAgents",`${H}.plist`),_e=c.join(u.homedir(),"AppData","Roaming","Microsoft","Windows","Start Menu","Programs","Startup"),_=h("autostart.cmd"),$=h("autostart.vbs"),C=h("autostart.xml"),$e=c.join(_e,"ShennianAgent.vbs");function z(e){const n=l()==="win32"?`where ${e}`:`command -v ${e}`;try{return a(n,{stdio:["ignore","pipe","pipe"],encoding:"utf-8",windowsHide:!0}).split(/\r?\n/).map(o=>o.trim()).find(Boolean)??null}catch{return null}}function Ce(){const e=l()==="win32"?"npx.cmd":"npx",n=c.join(c.dirname(B),e);return i.existsSync(n)?n:z("npx")}function k(){return De({nodeExec:B,scriptPath:F,shennianCommandPath:z("shennian"),npxPath:Ce()})}function Q(){try{a(`schtasks /delete /tn "${N}" /f`,{stdio:"pipe",windowsHide:!0})}catch{}}function Z(){try{i.unlinkSync($e)}catch{}}function Me(){const e=process.env.USERDOMAIN?.trim(),n=process.env.COMPUTERNAME?.trim(),t=process.env.USERNAME?.trim()||u.userInfo().username;return e&&e.toUpperCase()!=="WORKGROUP"?`${e}\\${t}`:n?`${n}\\${t}`:t}function Ue(e){if(l()==="win32"&&we(e.command)){const n=[e.command,...e.args].map(W).join(" ");return{command:process.env.ComSpec||"cmd.exe",args:["/d","/s","/c",`"${n}"`],windowsVerbatimArguments:!0}}return{command:e.command,args:e.args}}function je(e,n,t=process.env){return{detached:!0,stdio:["ignore",n,n],env:t,windowsHide:!0,...e.windowsVerbatimArguments?{windowsVerbatimArguments:!0}:{}}}function We(){const e=k();i.writeFileSync(_,Se(e,d)),i.writeFileSync($,ye(_)),Z(),Q();const n=ge({userId:Me(),command:c.join(process.env.SystemRoot||"C:\\Windows","System32","wscript.exe"),arguments:[W($)]});i.writeFileSync(C,n,"utf8");const t=he({taskName:N,xmlPath:C});try{return a(t.create,{stdio:"pipe",windowsHide:!0}),a(t.run,{stdio:"pipe",windowsHide:!0}),!0}catch{return!1}}function ee(){const e={};for(const n of V)process.env[n]&&(e[n]=process.env[n]);if(e.HOME??=u.homedir(),e.PATH=fe({pathValue:e.PATH,env:e}),e.USER??=u.userInfo().username,l()==="win32"){const n=process.env.TEMP||process.env.TMP||u.tmpdir(),t=u.homedir();e.USERPROFILE??=t;const r=c.win32.parse(t);e.HOMEDRIVE??=r.root.replace(/[\\/]$/,"")||process.env.HOMEDRIVE||"",e.HOMEPATH??=t.slice((e.HOMEDRIVE||"").length)||process.env.HOMEPATH||"",e.USERNAME??=process.env.USERNAME||u.userInfo().username,e.COMPUTERNAME??=process.env.COMPUTERNAME||"",e.TMPDIR??=n,e.TEMP??=n,e.TMP??=n}else e.TMPDIR??="/tmp";return e}function Fe(){const e=ee(),n=k(),t=Object.entries(e).map(([o,S])=>` <key>${b(o)}</key>
3
+ <string>${b(S)}</string>`).join(`
4
+ `),r=[n.command,...n.args].map(o=>` <string>${b(o)}</string>`).join(`
5
5
  `);return`<?xml version="1.0" encoding="UTF-8"?>
6
6
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
7
7
  <plist version="1.0">
@@ -27,8 +27,8 @@ ${t}
27
27
  <key>StandardErrorPath</key>
28
28
  <string>${d}</string>
29
29
  </dict>
30
- </plist>`}const P=c.join(u.homedir(),".config/systemd/user/shennian.service");function We(){const e=Z(),n=A(),t=Object.entries(e).map(([i,S])=>`Environment=${i}=${S}`).join(`
31
- `),r=[n.command,...n.args].map(ye).join(" ");return`[Unit]
30
+ </plist>`}const D=c.join(u.homedir(),".config/systemd/user/shennian.service");function Be(){const e=ee(),n=k(),t=Object.entries(e).map(([o,S])=>`Environment=${o}=${S}`).join(`
31
+ `),r=[n.command,...n.args].map(Ee).join(" ");return`[Unit]
32
32
  Description=Shennian Agent Daemon
33
33
  After=network.target
34
34
 
@@ -41,6 +41,6 @@ StandardOutput=append:${d}
41
41
  StandardError=append:${d}
42
42
 
43
43
  [Install]
44
- WantedBy=default.target`}const D="ShennianAgent";function Fe(e){a(e,{stdio:"pipe",windowsHide:!0})}function Be(){const e=process.getuid?.();if(typeof e=="number")return e;const n=u.userInfo();return typeof n.uid=="number"?n.uid:n.username}function ee(e=Be()){return`gui/${e}/${H}`}function Ve(e=Fe){try{return e(`launchctl unload "${m}" 2>/dev/null; launchctl load -w "${m}"`),e(`launchctl kickstart -k "${ee()}"`),!0}catch{try{return e(`launchctl load -w "${m}"`),e(`launchctl kickstart -k "${ee()}"`),!0}catch{return!1}}}function Je(){o.mkdirSync(g,{recursive:!0});const e={};for(const[n,t]of Object.entries(process.env))t!==void 0&&Ae(n)&&(e[n]=t);o.writeFileSync(h("env.json"),JSON.stringify(e,null,2))}function ne(e={}){o.mkdirSync(g,{recursive:!0});const n=f({cleanupStale:!0});if(n.pid!==null&&n.running&&!n.adopted){e.quiet||console.log(s.green(`\u2713 Background service already running (PID ${n.pid})`));return}te(n);const t=o.openSync(d,"a"),r=Ce(A()),i=ae(r.command,r.args,Me(r,t));i.unref(),o.closeSync(t),Oe(i.pid),e.quiet||(console.log(s.green(`\u2713 Background service started (PID ${i.pid})`)),console.log(s.gray(` Logs: ${d}`)))}function te(e=f({cleanupStale:!0})){if(!(e.pid===null||!e.running||!e.adopted))try{process.kill(e.pid,"SIGTERM"),De(e.pid);try{o.unlinkSync(p)}catch{}}catch{}}function re(){o.mkdirSync(g,{recursive:!0});const e=l();switch(A().mode==="direct"&&R(F)&&console.warn(s.yellow("\u26A0 Warning: Current CLI path is temporary (npx). Auto-start may not work after reboot.\n Run `npm install -g shennian@latest` for reliable auto-start.")),e){case"darwin":{const t=c.dirname(m);return o.mkdirSync(t,{recursive:!0}),o.writeFileSync(m,je()),Ve()}case"linux":{const t=c.dirname(P);o.mkdirSync(t,{recursive:!0}),o.writeFileSync(P,We());try{a("systemctl --user daemon-reload && systemctl --user enable shennian",{stdio:"pipe",windowsHide:!0})}catch{return!1}try{a(`loginctl enable-linger ${u.userInfo().username}`,{stdio:"pipe",windowsHide:!0})}catch{}try{return a("systemctl --user restart shennian",{stdio:"pipe",windowsHide:!0}),!0}catch{return!1}}case"win32":return Ue()}}function Ge(){const n=f({cleanupStale:!0}).pid;if(n===null)return{};if(!w(n)){try{o.unlinkSync(p)}catch{}return{stalePid:n}}try{return process.kill(n,"SIGTERM"),{stoppedPid:n}}catch(t){return{error:t instanceof Error?t.message:String(t)}}}async function Ke(e=5e3){const n=Ge();if(!n.stoppedPid)return n;if(!await I(n.stoppedPid,e))try{process.kill(n.stoppedPid,"SIGKILL"),await I(n.stoppedPid,2e3)}catch(r){return{...n,error:r instanceof Error?r.message:String(r)}}try{o.unlinkSync(p)}catch{}T();for(const r of K())if(r!==n.stoppedPid)try{process.kill(r,"SIGTERM"),await I(r,2e3)}catch{}return n}function Xe(e={}){X(q(e.api)),be(),te(),re()||ne({quiet:e.json}),e.json?v(b(()=>f({cleanupStale:!0}))):console.log(s.green("\u2713 Background service started"))}async function qe(e={}){switch(o.mkdirSync(g,{recursive:!0}),o.writeFileSync(L,new Date().toISOString()),l()){case"darwin":{if(o.existsSync(m))try{a(`launchctl unload -w "${m}"`,{stdio:"pipe",windowsHide:!0})}catch{}break}case"linux":{try{a("systemctl --user disable --now shennian",{stdio:"pipe",windowsHide:!0})}catch{}break}case"win32":{try{a(`schtasks /change /tn "${D}" /disable`,{stdio:"pipe",windowsHide:!0})}catch{}try{a(`schtasks /end /tn "${D}"`,{stdio:"pipe",windowsHide:!0})}catch{}break}}const t=await Ke(),r=f({cleanupStale:!0});if(e.json){v(t.error?{...r,error:t.error}:r);return}t.error?console.error(s.red(`\u2717 Failed to stop: ${t.error}`)):console.log(s.green("\u2713 Background service stopped"))}function oe(e){Je(),Xe(e)}async function M(e={}){await qe(e)}async function I(e,n=5e3){const t=Date.now();for(;Date.now()-t<n;){if(!w(e))return!0;await new Promise(r=>setTimeout(r,100))}return!w(e)}async function Ye(e={}){X(q(e.api));const n=Pe();if(n!==null&&w(n))try{process.kill(n,"SIGTERM"),await I(n)||(process.kill(n,"SIGKILL"),await I(n,2e3));try{o.unlinkSync(p)}catch{}T(),e.json||console.log(s.green(`\u2713 Background service stopped (PID ${n})`))}catch(t){const r=t instanceof Error?t.message:String(t);e.json?v({...f(),error:r}):console.error(s.red(`\u2717 Failed to stop: ${r}`));return}else if(n!==null){try{o.unlinkSync(p)}catch{}T(),e.json||console.log(s.yellow(`\u26A0 Service process no longer exists, cleaned up stale PID ${n}`))}else e.json||console.log(s.gray("\u25CF Background service not running, starting it now"));if(l()==="linux"&&re()){e.json&&v(b(()=>f({cleanupStale:!0})));return}ne({quiet:e.json}),e.json&&v(b(()=>f({cleanupStale:!0})))}function ie(e={}){const n=f({cleanupStale:!0});if(e.json){v(n);return}if(n.pid===null){console.log(s.gray("\u25CF Background service not running"));return}n.running?(console.log(s.green(`\u25CF Background service running (PID ${n.pid})`)),console.log(s.gray(` Logs: ${d}`))):console.log(s.yellow(`\u25CF Background service stopped (PID ${n.pid} is stale)`))}function se(e){if(!o.existsSync(d)){console.log(s.gray("No logs yet"));return}try{const n=a(u.platform()==="win32"?`powershell Get-Content -Tail ${e.lines} "${d}"`:`tail -n ${e.lines} "${d}"`,{encoding:"utf-8",windowsHide:!0});process.stdout.write(n)}catch{const n=o.readFileSync(d,"utf-8").split(`
44
+ WantedBy=default.target`}const N="ShennianAgent";function Ve(e){a(e,{stdio:"pipe",windowsHide:!0})}function Ge(){const e=process.getuid?.();if(typeof e=="number")return e;const n=u.userInfo();return typeof n.uid=="number"?n.uid:n.username}function ne(e=Ge()){return`gui/${e}/${H}`}function Je(e=Ve){try{return e(`launchctl unload "${m}" 2>/dev/null; launchctl load -w "${m}"`),e(`launchctl kickstart -k "${ne()}"`),!0}catch{try{return e(`launchctl load -w "${m}"`),e(`launchctl kickstart -k "${ne()}"`),!0}catch{return!1}}}function Ke(){i.mkdirSync(g,{recursive:!0});const e={};for(const[n,t]of Object.entries(process.env))t!==void 0&&Pe(n)&&(e[n]=t);i.writeFileSync(h("env.json"),JSON.stringify(e,null,2))}function te(e={}){i.mkdirSync(g,{recursive:!0});const n=f({cleanupStale:!0});if(n.pid!==null&&n.running&&!re(n)){e.quiet||console.log(s.green(`\u2713 Background service already running (PID ${n.pid})`));return}ie(n);const t=i.openSync(d,"a"),r=Ue(k()),o=ue(r.command,r.args,je(r,t));o.unref(),i.closeSync(t),xe(o.pid),e.quiet||(console.log(s.green(`\u2713 Background service started (PID ${o.pid})`)),console.log(s.gray(` Logs: ${d}`)))}function re(e,n=I(),t=ke()){return e.pid===null||!e.running?!1:e.adopted===!0||n?.version!==t}function ie(e=f({cleanupStale:!0})){if(!(!re(e)||e.pid===null))try{process.kill(e.pid,"SIGTERM"),G(e.pid,5e3)||(process.kill(e.pid,"SIGKILL"),G(e.pid,2e3));try{I()?.pid===e.pid&&i.unlinkSync(p)}catch{}}catch{}}function oe(){i.mkdirSync(g,{recursive:!0});const e=l();switch(k().mode==="direct"&&O(F)&&console.warn(s.yellow("\u26A0 Warning: Current CLI path is temporary (npx). Auto-start may not work after reboot.\n Run `npm install -g shennian@latest` for reliable auto-start.")),e){case"darwin":{const t=c.dirname(m);return i.mkdirSync(t,{recursive:!0}),i.writeFileSync(m,Fe()),Je()}case"linux":{const t=c.dirname(D);i.mkdirSync(t,{recursive:!0}),i.writeFileSync(D,Be());try{a("systemctl --user daemon-reload && systemctl --user enable shennian",{stdio:"pipe",windowsHide:!0})}catch{return!1}try{a(`loginctl enable-linger ${u.userInfo().username}`,{stdio:"pipe",windowsHide:!0})}catch{}try{return a("systemctl --user restart shennian",{stdio:"pipe",windowsHide:!0}),!0}catch{return!1}}case"win32":return We()}}function Xe(){const n=f({cleanupStale:!0}).pid;if(n===null)return{};if(!w(n)){try{i.unlinkSync(p)}catch{}return{stalePid:n}}try{return process.kill(n,"SIGTERM"),{stoppedPid:n}}catch(t){return{error:t instanceof Error?t.message:String(t)}}}async function qe(e=5e3){const n=Xe();if(!n.stoppedPid)return n;if(!await A(n.stoppedPid,e))try{process.kill(n.stoppedPid,"SIGKILL"),await A(n.stoppedPid,2e3)}catch(r){return{...n,error:r instanceof Error?r.message:String(r)}}try{i.unlinkSync(p)}catch{}T();for(const r of X())if(r!==n.stoppedPid)try{process.kill(r,"SIGTERM"),await A(r,2e3)}catch{}return n}function Ye(e={}){q(Y(e.api)),Re(),ie(),oe()||te({quiet:e.json}),e.json?v(L(()=>f({cleanupStale:!0}))):console.log(s.green("\u2713 Background service started"))}async function ze(e={}){switch(i.mkdirSync(g,{recursive:!0}),i.writeFileSync(R,new Date().toISOString()),l()){case"darwin":{if(i.existsSync(m))try{a(`launchctl unload -w "${m}"`,{stdio:"pipe",windowsHide:!0})}catch{}break}case"linux":{try{a("systemctl --user disable --now shennian",{stdio:"pipe",windowsHide:!0})}catch{}break}case"win32":{try{a(`schtasks /change /tn "${N}" /disable`,{stdio:"pipe",windowsHide:!0})}catch{}try{a(`schtasks /end /tn "${N}"`,{stdio:"pipe",windowsHide:!0})}catch{}break}}const t=await qe(),r=f({cleanupStale:!0});if(e.json){v(t.error?{...r,error:t.error}:r);return}t.error?console.error(s.red(`\u2717 Failed to stop: ${t.error}`)):console.log(s.green("\u2713 Background service stopped"))}function se(e){Ke(),Ye(e)}async function M(e={}){await ze(e)}async function A(e,n=5e3){const t=Date.now();for(;Date.now()-t<n;){if(!w(e))return!0;await new Promise(r=>setTimeout(r,100))}return!w(e)}async function Qe(e={}){q(Y(e.api));const n=be();if(n!==null&&w(n))try{process.kill(n,"SIGTERM"),await A(n)||(process.kill(n,"SIGKILL"),await A(n,2e3));try{i.unlinkSync(p)}catch{}T(),e.json||console.log(s.green(`\u2713 Background service stopped (PID ${n})`))}catch(t){const r=t instanceof Error?t.message:String(t);e.json?v({...f(),error:r}):console.error(s.red(`\u2717 Failed to stop: ${r}`));return}else if(n!==null){try{i.unlinkSync(p)}catch{}T(),e.json||console.log(s.yellow(`\u26A0 Service process no longer exists, cleaned up stale PID ${n}`))}else e.json||console.log(s.gray("\u25CF Background service not running, starting it now"));if(l()==="linux"&&oe()){e.json&&v(L(()=>f({cleanupStale:!0})));return}te({quiet:e.json}),e.json&&v(L(()=>f({cleanupStale:!0})))}function ae(e={}){const n=f({cleanupStale:!0});if(e.json){v(n);return}if(n.pid===null){console.log(s.gray("\u25CF Background service not running"));return}n.running?(console.log(s.green(`\u25CF Background service running (PID ${n.pid})`)),console.log(s.gray(` Logs: ${d}`))):console.log(s.yellow(`\u25CF Background service stopped (PID ${n.pid} is stale)`))}function ce(e){if(!i.existsSync(d)){console.log(s.gray("No logs yet"));return}try{const n=a(u.platform()==="win32"?`powershell Get-Content -Tail ${e.lines} "${d}"`:`tail -n ${e.lines} "${d}"`,{encoding:"utf-8",windowsHide:!0});process.stdout.write(n)}catch{const n=i.readFileSync(d,"utf-8").split(`
45
45
  `).slice(-e.lines);console.log(n.join(`
46
- `))}}async function ze(){switch(await M(),l()){case"darwin":{if(o.existsSync(m)){try{a(`launchctl unload -w "${m}"`,{stdio:"pipe",windowsHide:!0})}catch{}o.unlinkSync(m),console.log(s.green("\u2713 Auto-start uninstalled (launchd)"))}break}case"linux":{try{a("systemctl --user disable --now shennian",{stdio:"pipe",windowsHide:!0})}catch{}if(o.existsSync(P)){o.unlinkSync(P);try{a("systemctl --user daemon-reload",{stdio:"pipe",windowsHide:!0})}catch{}}console.log(s.green("\u2713 Auto-start uninstalled (systemd)"));break}case"win32":{z();try{o.unlinkSync(_)}catch{}try{o.unlinkSync($)}catch{}try{o.unlinkSync(C)}catch{}Q(),console.log(s.green("\u2713 Auto-start uninstalled (Task Scheduler)"));break}}}function mn(e){e.command("start").description("Start the background service").option("--json","Print machine-readable status JSON").option("--api <url>","Server URL override").action(r=>oe(r)),e.command("stop").description("Stop the background service").option("--json","Print machine-readable status JSON").action(r=>M(r)),e.command("status").description("Show background service status").option("--json","Print machine-readable status JSON").action(r=>ie(r)),e.command("logs").description("Show recent logs").option("-n, --lines <n>","Number of lines","50").action(r=>se({lines:parseInt(r.lines,10)}));const n=e.command("daemon",{hidden:!0}).description("Deprecated: use top-level start/stop/status/logs"),t=(r,i)=>{i||console.error(s.yellow(`\u26A0 Deprecated command. Use \`shennian ${r}\` instead.`))};n.command("start").description("Start the background service").option("--json","Print machine-readable status JSON").option("--api <url>","Server URL override").action(r=>{t("start",r.json),oe(r)}),n.command("stop").description("Stop the background service").option("--json","Print machine-readable status JSON").action(async r=>{t("stop",r.json),await M(r)}),n.command("restart").description("Restart the background service").option("--json","Print machine-readable status JSON").option("--api <url>","Server URL override").action(r=>{t("stop && shennian start",r.json),Ye(r)}),n.command("status").description("Show background service status").option("--json","Print machine-readable status JSON").action(r=>{t("status",r.json),ie(r)}),n.command("logs").description("Show recent logs").option("-n, --lines <n>","Number of lines","50").action(r=>{t("logs"),se({lines:parseInt(r.lines,10)})}),n.command("uninstall").description("Uninstall auto-start service").action(ze)}export{Me as buildDaemonSpawnOptions,hn as buildWindowsLauncherCommand,gn as buildWindowsScheduledTaskCommands,yn as buildWindowsScheduledTaskXml,wn as buildWindowsStartupVbs,Z as captureEnvForService,T as clearDaemonLauncher,ln as clearDaemonPidIfOwner,be as clearRemoteAccessDisabled,Le as createDaemonInstanceId,K as findRunningDaemonProcessIds,J as getCurrentProcessDaemonLauncher,f as getDaemonStatus,ee as getLaunchdServiceTarget,re as installService,R as isEphemeralCliPath,pn as isIsolatedDaemonE2eInstance,Ne as isRemoteAccessDisabled,Ae as isSafeSnapshotEnvKey,vn as isShennianRunServiceCommand,Oe as recordStartedDaemon,mn as registerDaemonCommand,Ve as reloadLaunchdAgent,Ie as resolveServiceLaunchSpec,Je as saveEnvSnapshot,ne as startDaemonProcess,G as writeDaemonLauncher,Re as writeDaemonPid};
46
+ `))}}async function Ze(){switch(await M(),l()){case"darwin":{if(i.existsSync(m)){try{a(`launchctl unload -w "${m}"`,{stdio:"pipe",windowsHide:!0})}catch{}i.unlinkSync(m),console.log(s.green("\u2713 Auto-start uninstalled (launchd)"))}break}case"linux":{try{a("systemctl --user disable --now shennian",{stdio:"pipe",windowsHide:!0})}catch{}if(i.existsSync(D)){i.unlinkSync(D);try{a("systemctl --user daemon-reload",{stdio:"pipe",windowsHide:!0})}catch{}}console.log(s.green("\u2713 Auto-start uninstalled (systemd)"));break}case"win32":{Q();try{i.unlinkSync(_)}catch{}try{i.unlinkSync($)}catch{}try{i.unlinkSync(C)}catch{}Z(),console.log(s.green("\u2713 Auto-start uninstalled (Task Scheduler)"));break}}}function hn(e){e.command("start").description("Start the background service").option("--json","Print machine-readable status JSON").option("--api <url>","Server URL override").action(r=>se(r)),e.command("stop").description("Stop the background service").option("--json","Print machine-readable status JSON").action(r=>M(r)),e.command("status").description("Show background service status").option("--json","Print machine-readable status JSON").action(r=>ae(r)),e.command("logs").description("Show recent logs").option("-n, --lines <n>","Number of lines","50").action(r=>ce({lines:parseInt(r.lines,10)}));const n=e.command("daemon",{hidden:!0}).description("Deprecated: use top-level start/stop/status/logs"),t=(r,o)=>{o||console.error(s.yellow(`\u26A0 Deprecated command. Use \`shennian ${r}\` instead.`))};n.command("start").description("Start the background service").option("--json","Print machine-readable status JSON").option("--api <url>","Server URL override").action(r=>{t("start",r.json),se(r)}),n.command("stop").description("Stop the background service").option("--json","Print machine-readable status JSON").action(async r=>{t("stop",r.json),await M(r)}),n.command("restart").description("Restart the background service").option("--json","Print machine-readable status JSON").option("--api <url>","Server URL override").action(r=>{t("stop && shennian start",r.json),Qe(r)}),n.command("status").description("Show background service status").option("--json","Print machine-readable status JSON").action(r=>{t("status",r.json),ae(r)}),n.command("logs").description("Show recent logs").option("-n, --lines <n>","Number of lines","50").action(r=>{t("logs"),ce({lines:parseInt(r.lines,10)})}),n.command("uninstall").description("Uninstall auto-start service").action(Ze)}export{je as buildDaemonSpawnOptions,wn as buildWindowsLauncherCommand,En as buildWindowsScheduledTaskCommands,vn as buildWindowsScheduledTaskXml,In as buildWindowsStartupVbs,ee as captureEnvForService,T as clearDaemonLauncher,fn as clearDaemonPidIfOwner,Re as clearRemoteAccessDisabled,Oe as createDaemonInstanceId,X as findRunningDaemonProcessIds,J as getCurrentProcessDaemonLauncher,f as getDaemonStatus,ne as getLaunchdServiceTarget,oe as installService,O as isEphemeralCliPath,Sn as isIsolatedDaemonE2eInstance,Le as isRemoteAccessDisabled,Pe as isSafeSnapshotEnvKey,An as isShennianRunServiceCommand,xe as recordStartedDaemon,hn as registerDaemonCommand,Je as reloadLaunchdAgent,De as resolveServiceLaunchSpec,Ke as saveEnvSnapshot,re as shouldReplaceRunningDaemon,te as startDaemonProcess,K as writeDaemonLauncher,Te as writeDaemonPid};
@@ -8,7 +8,7 @@ declare const LIFECYCLE_BY_EVENT: {
8
8
  readonly PostCompact: "active";
9
9
  readonly PreToolUse: "active";
10
10
  readonly Stop: "idle";
11
- readonly SessionEnd: "closed";
11
+ readonly SessionEnd: "idle";
12
12
  };
13
13
  type HookEventName = keyof typeof LIFECYCLE_BY_EVENT;
14
14
  type InvokeDaemon = typeof callDaemonIpc;
@@ -1,2 +1,2 @@
1
- import I from"node:crypto";import{callDaemonIpc as b}from"../daemon-ipc/client.js";import{DaemonIpcError as f}from"../daemon-ipc/protocol.js";import{normalizeRoomActionParameters as E}from"../room/room-action-schema.js";import{SHENNIAN_ROOM_TOOL_NAME as T}from"../room/tool-schema.js";import{roomMcpHostToolName as z}from"./room-plugin-shared.js";const N=256*1024,_={SessionStart:"active",UserPromptSubmit:"active",PreCompact:"active",PostCompact:"active",PreToolUse:"active",Stop:"idle",SessionEnd:"closed"};async function Y(t,o=process.stdin,e=process.stdout,r=b){let s="";for await(const a of o)if(s+=Buffer.isBuffer(a)?a.toString("utf8"):String(a),Buffer.byteLength(s,"utf8")>N)return"ignored";const n=O(t,s);if(!n)return"ignored";let l=!1;try{await r({method:"room-host-session.observe",params:{runtimeAdapter:n.runtimeAdapter,sourceSessionKey:n.sourceSessionKey,hostContextHash:n.hostContextHash,workspaceHash:n.workspaceHash,workspacePath:n.workspacePath,lifecycleState:n.lifecycleState,eventName:n.eventName},timeoutMs:2e3})}catch(a){if(a instanceof f&&a.code==="machine_not_authorized")l=!0;else return"unavailable"}if(n.eventName!=="PreToolUse")return"observed";if(n.toolName!==z(n.runtimeAdapter)||!n.toolInput)return"ignored";let i=null,c="";try{if(i=H(n.toolInput),c=v(n,i),i.action==="room.create"||i.action==="room.join")try{const u=await r({method:"authorized-action.status",params:{idempotencyKey:c},timeoutMs:2e3}),k=A(u);return S(e,n.toolInput,k),"authorized"}catch(u){if(!(u instanceof f)||u.code!=="pending_action_not_found")throw u}if(l)return await w(n,i,c,e,r);const a=await r({method:"room-session.resolve",params:{runtimeAdapter:n.runtimeAdapter,sourceSessionKey:n.sourceSessionKey},timeoutMs:2e3}),d=K(a),g=await r({method:"room-invocation.issue",params:{registryKey:d,action:i.action,targetTool:T,actionParameters:i.actionParameters},timeoutMs:2e3}),P=$(g);return y(e,{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow",permissionDecisionReason:"Authorized by the local Shennian daemon for this Agent conversation.",updatedInput:{...n.toolInput,_shennianRegistryKey:d,_shennianInvocationToken:P}}}),"authorized"}catch(a){if(a instanceof f&&a.code==="machine_not_authorized"&&i&&(i.action==="room.create"||i.action==="room.join"))try{return await w(n,i,c,e,r)}catch{}return y(e,{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:"This Agent conversation is not connected to Shennian yet. Open it from Shennian or use the repair connection action."}}),"denied"}}async function w(t,o,e,r,s){if(o.action!=="room.create"&&o.action!=="room.join")throw new Error("authorization_requires_onboarding_action");const n=await s({method:"authorized-action.create",params:{actionType:o.action,actionSummary:R(o.action,o.actionParameters),actionPayload:x(t,o),idempotencyKey:e,returnTo:"/spaces"},timeoutMs:12e3});return S(r,t.toolInput,A(n)),"authorized"}function O(t,o){if(t!=="codex"&&t!=="claude_code"&&t!=="workbuddy")return null;let e;try{e=JSON.parse(o)}catch{return null}if(!e||typeof e!="object"||Array.isArray(e))return null;const r=e,s=m(r.session_id,1024),n=U(r.hook_event_name);if(!s||!n)return null;const l=m(r.transcript_path,4096)??"",i=m(r.cwd,4096)??"",c=n==="PreToolUse"?m(r.tool_name,256):null,a=n==="PreToolUse"?C(r.tool_input):null,d=n==="PreToolUse"?m(r.tool_use_id??r.tool_call_id,512):null;return{runtimeAdapter:t,sourceSessionKey:s,hostContextHash:h(`${s}\0${l}`),workspaceHash:i?h(i):null,workspacePath:i||null,lifecycleState:_[n],eventName:n,toolName:c,toolInput:a,toolRequestId:d}}function H(t){const o=j(t.action);if(Object.keys(t).some(r=>r.startsWith("_shennian")))throw new Error("hidden_input");const e=Object.fromEntries(Object.entries(t).filter(([r])=>r!=="action"));return{action:o,actionParameters:E(o,e)}}function j(t){const o={create:"room.create",join:"room.join",read:"room.read",send:"room.send",mode:"room.mode",status:"room.status"};if(typeof t!="string"||!(t in o))throw new Error("invalid_action");return o[t]}function K(t){const o=p(t,"registryKey");if(!/^[a-f0-9]{64}$/.test(o))throw new Error("invalid_registry");return o}function $(t){const o=p(t,"invocationToken");if(!/^sni_v1_[A-Za-z0-9_-]{40,80}$/.test(o))throw new Error("invalid_token");return o}function A(t){const o=p(t,"id");if(!/^[A-Za-z0-9_-]{8,128}$/.test(o))throw new Error("invalid_pending_action");return o}function v(t,o){const e=t.toolRequestId??h(JSON.stringify(o.actionParameters));return`${o.action.replace(".","-")}-auth:${h(`${t.runtimeAdapter}\0${t.sourceSessionKey}\0${e}`)}`}function x(t,o){return{schemaVersion:1,runtimeAdapter:t.runtimeAdapter,sourceSessionKey:t.sourceSessionKey,hostContextHash:t.hostContextHash,workspaceHash:t.workspaceHash,workspacePath:t.workspacePath,lifecycleState:t.lifecycleState,action:o.action,actionParameters:o.actionParameters}}function R(t,o){if(!o||Array.isArray(o)||typeof o!="object")throw new Error("invalid_authorized_action");const e=typeof o.agentAlias=="string"?o.agentAlias:"";return t==="room.create"?`\u521B\u5EFA\u7FA4\u804A\u300C${typeof o.name=="string"?o.name:""}\u300D\uFF0C\u5E76\u4EE5 Agent\u300C${e}\u300D\u52A0\u5165`:`\u4F7F\u7528\u5F53\u524D\u9080\u8BF7\u52A0\u5165\u7FA4\u804A\uFF0C\u5E76\u4EE5 Agent\u300C${e}\u300D\u53C2\u4E0E`}function S(t,o,e){y(t,{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow",permissionDecisionReason:"Shennian will open a secure browser authorization and continue this action automatically.",updatedInput:{...o,_shennianAuthorizedActionId:e}}})}function p(t,o){if(!t||Array.isArray(t)||typeof t!="object")throw new Error("invalid_response");const e=t[o];if(typeof e!="string")throw new Error("invalid_response");return e}function U(t){return typeof t=="string"&&t in _?t:null}function m(t,o){if(typeof t!="string")return null;const e=t.trim();return!e||e.length>o||/[\0\r\n]/.test(e)?null:e}function C(t){return!t||typeof t!="object"||Array.isArray(t)?null:t}function y(t,o){t.write(`${JSON.stringify(o)}
1
+ import I from"node:crypto";import{callDaemonIpc as b}from"../daemon-ipc/client.js";import{DaemonIpcError as f}from"../daemon-ipc/protocol.js";import{normalizeRoomActionParameters as E}from"../room/room-action-schema.js";import{SHENNIAN_ROOM_TOOL_NAME as T}from"../room/tool-schema.js";import{roomMcpHostToolName as z}from"./room-plugin-shared.js";const N=256*1024,_={SessionStart:"active",UserPromptSubmit:"active",PreCompact:"active",PostCompact:"active",PreToolUse:"active",Stop:"idle",SessionEnd:"idle"};async function Y(t,o=process.stdin,e=process.stdout,r=b){let s="";for await(const a of o)if(s+=Buffer.isBuffer(a)?a.toString("utf8"):String(a),Buffer.byteLength(s,"utf8")>N)return"ignored";const n=O(t,s);if(!n)return"ignored";let l=!1;try{await r({method:"room-host-session.observe",params:{runtimeAdapter:n.runtimeAdapter,sourceSessionKey:n.sourceSessionKey,hostContextHash:n.hostContextHash,workspaceHash:n.workspaceHash,workspacePath:n.workspacePath,lifecycleState:n.lifecycleState,eventName:n.eventName},timeoutMs:2e3})}catch(a){if(a instanceof f&&a.code==="machine_not_authorized")l=!0;else return"unavailable"}if(n.eventName!=="PreToolUse")return"observed";if(n.toolName!==z(n.runtimeAdapter)||!n.toolInput)return"ignored";let i=null,c="";try{if(i=H(n.toolInput),c=v(n,i),i.action==="room.create"||i.action==="room.join")try{const u=await r({method:"authorized-action.status",params:{idempotencyKey:c},timeoutMs:2e3}),k=A(u);return S(e,n.toolInput,k),"authorized"}catch(u){if(!(u instanceof f)||u.code!=="pending_action_not_found")throw u}if(l)return await w(n,i,c,e,r);const a=await r({method:"room-session.resolve",params:{runtimeAdapter:n.runtimeAdapter,sourceSessionKey:n.sourceSessionKey},timeoutMs:2e3}),d=K(a),g=await r({method:"room-invocation.issue",params:{registryKey:d,action:i.action,targetTool:T,actionParameters:i.actionParameters},timeoutMs:2e3}),P=$(g);return y(e,{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow",permissionDecisionReason:"Authorized by the local Shennian daemon for this Agent conversation.",updatedInput:{...n.toolInput,_shennianRegistryKey:d,_shennianInvocationToken:P}}}),"authorized"}catch(a){if(a instanceof f&&a.code==="machine_not_authorized"&&i&&(i.action==="room.create"||i.action==="room.join"))try{return await w(n,i,c,e,r)}catch{}return y(e,{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:"This Agent conversation is not connected to Shennian yet. Open it from Shennian or use the repair connection action."}}),"denied"}}async function w(t,o,e,r,s){if(o.action!=="room.create"&&o.action!=="room.join")throw new Error("authorization_requires_onboarding_action");const n=await s({method:"authorized-action.create",params:{actionType:o.action,actionSummary:R(o.action,o.actionParameters),actionPayload:x(t,o),idempotencyKey:e,returnTo:"/spaces"},timeoutMs:12e3});return S(r,t.toolInput,A(n)),"authorized"}function O(t,o){if(t!=="codex"&&t!=="claude_code"&&t!=="workbuddy")return null;let e;try{e=JSON.parse(o)}catch{return null}if(!e||typeof e!="object"||Array.isArray(e))return null;const r=e,s=m(r.session_id,1024),n=U(r.hook_event_name);if(!s||!n)return null;const l=m(r.transcript_path,4096)??"",i=m(r.cwd,4096)??"",c=n==="PreToolUse"?m(r.tool_name,256):null,a=n==="PreToolUse"?C(r.tool_input):null,d=n==="PreToolUse"?m(r.tool_use_id??r.tool_call_id,512):null;return{runtimeAdapter:t,sourceSessionKey:s,hostContextHash:h(`${s}\0${l}`),workspaceHash:i?h(i):null,workspacePath:i||null,lifecycleState:_[n],eventName:n,toolName:c,toolInput:a,toolRequestId:d}}function H(t){const o=j(t.action);if(Object.keys(t).some(r=>r.startsWith("_shennian")))throw new Error("hidden_input");const e=Object.fromEntries(Object.entries(t).filter(([r])=>r!=="action"));return{action:o,actionParameters:E(o,e)}}function j(t){const o={create:"room.create",join:"room.join",read:"room.read",send:"room.send",mode:"room.mode",status:"room.status"};if(typeof t!="string"||!(t in o))throw new Error("invalid_action");return o[t]}function K(t){const o=p(t,"registryKey");if(!/^[a-f0-9]{64}$/.test(o))throw new Error("invalid_registry");return o}function $(t){const o=p(t,"invocationToken");if(!/^sni_v1_[A-Za-z0-9_-]{40,80}$/.test(o))throw new Error("invalid_token");return o}function A(t){const o=p(t,"id");if(!/^[A-Za-z0-9_-]{8,128}$/.test(o))throw new Error("invalid_pending_action");return o}function v(t,o){const e=t.toolRequestId??h(JSON.stringify(o.actionParameters));return`${o.action.replace(".","-")}-auth:${h(`${t.runtimeAdapter}\0${t.sourceSessionKey}\0${e}`)}`}function x(t,o){return{schemaVersion:1,runtimeAdapter:t.runtimeAdapter,sourceSessionKey:t.sourceSessionKey,hostContextHash:t.hostContextHash,workspaceHash:t.workspaceHash,workspacePath:t.workspacePath,lifecycleState:t.lifecycleState,action:o.action,actionParameters:o.actionParameters}}function R(t,o){if(!o||Array.isArray(o)||typeof o!="object")throw new Error("invalid_authorized_action");const e=typeof o.agentAlias=="string"?o.agentAlias:"";return t==="room.create"?`\u521B\u5EFA\u7FA4\u804A\u300C${typeof o.name=="string"?o.name:""}\u300D\uFF0C\u5E76\u4EE5 Agent\u300C${e}\u300D\u52A0\u5165`:`\u4F7F\u7528\u5F53\u524D\u9080\u8BF7\u52A0\u5165\u7FA4\u804A\uFF0C\u5E76\u4EE5 Agent\u300C${e}\u300D\u53C2\u4E0E`}function S(t,o,e){y(t,{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow",permissionDecisionReason:"Shennian will open a secure browser authorization and continue this action automatically.",updatedInput:{...o,_shennianAuthorizedActionId:e}}})}function p(t,o){if(!t||Array.isArray(t)||typeof t!="object")throw new Error("invalid_response");const e=t[o];if(typeof e!="string")throw new Error("invalid_response");return e}function U(t){return typeof t=="string"&&t in _?t:null}function m(t,o){if(typeof t!="string")return null;const e=t.trim();return!e||e.length>o||/[\0\r\n]/.test(e)?null:e}function C(t){return!t||typeof t!="object"||Array.isArray(t)?null:t}function y(t,o){t.write(`${JSON.stringify(o)}
2
2
  `)}function h(t){return I.createHash("sha256").update(t,"utf8").digest("hex")}export{O as parseRoomSessionHookInput,Y as runRoomSessionHook};
@@ -6,7 +6,7 @@ declare const LIFECYCLE_BY_EVENT: {
6
6
  readonly PreCompact: "active";
7
7
  readonly PostCompact: "active";
8
8
  readonly Stop: "idle";
9
- readonly SessionEnd: "closed";
9
+ readonly SessionEnd: "idle";
10
10
  };
11
11
  type SupportedHookEvent = keyof typeof LIFECYCLE_BY_EVENT;
12
12
  export type WorkBuddyHookObservation = {
@@ -1 +1 @@
1
- import f from"node:crypto";import{callDaemonIpc as d}from"../daemon-ipc/client.js";const p=256*1024,a={SessionStart:"active",UserPromptSubmit:"active",PreCompact:"active",PostCompact:"active",Stop:"idle",SessionEnd:"closed"};async function S(e=process.stdin,r=d){let t="";for await(const n of e)if(t+=Buffer.isBuffer(n)?n.toString("utf8"):String(n),Buffer.byteLength(t,"utf8")>p)return"ignored";const o=l(t);if(!o)return"ignored";try{return await r({method:"room-host-session.observe",params:o,timeoutMs:2e3}),"observed"}catch{return"unavailable"}}function l(e){let r;try{r=JSON.parse(e)}catch{return null}if(!r||typeof r!="object"||Array.isArray(r))return null;const t=r,o=s(t.session_id,1024),n=m(t.hook_event_name);if(!o||!n)return null;const u=s(t.transcript_path,4096)??"",i=s(t.cwd,4096)??"";return{runtimeAdapter:"workbuddy",sourceSessionKey:o,hostContextHash:c(`${o}\0${u}`),workspaceHash:i?c(i):null,lifecycleState:a[n],eventName:n}}function m(e){return typeof e=="string"&&e in a?e:null}function s(e,r){if(typeof e!="string")return null;const t=e.trim();return!t||t.length>r||/[\0\r\n]/.test(t)?null:t}function c(e){return f.createHash("sha256").update(e,"utf8").digest("hex")}export{l as parseWorkBuddyHookInput,S as runWorkBuddySessionHook};
1
+ import f from"node:crypto";import{callDaemonIpc as d}from"../daemon-ipc/client.js";const p=256*1024,a={SessionStart:"active",UserPromptSubmit:"active",PreCompact:"active",PostCompact:"active",Stop:"idle",SessionEnd:"idle"};async function S(e=process.stdin,r=d){let t="";for await(const n of e)if(t+=Buffer.isBuffer(n)?n.toString("utf8"):String(n),Buffer.byteLength(t,"utf8")>p)return"ignored";const o=l(t);if(!o)return"ignored";try{return await r({method:"room-host-session.observe",params:o,timeoutMs:2e3}),"observed"}catch{return"unavailable"}}function l(e){let r;try{r=JSON.parse(e)}catch{return null}if(!r||typeof r!="object"||Array.isArray(r))return null;const t=r,o=s(t.session_id,1024),n=m(t.hook_event_name);if(!o||!n)return null;const u=s(t.transcript_path,4096)??"",i=s(t.cwd,4096)??"";return{runtimeAdapter:"workbuddy",sourceSessionKey:o,hostContextHash:c(`${o}\0${u}`),workspaceHash:i?c(i):null,lifecycleState:a[n],eventName:n}}function m(e){return typeof e=="string"&&e in a?e:null}function s(e,r){if(typeof e!="string")return null;const t=e.trim();return!t||t.length>r||/[\0\r\n]/.test(t)?null:t}function c(e){return f.createHash("sha256").update(e,"utf8").digest("hex")}export{l as parseWorkBuddyHookInput,S as runWorkBuddySessionHook};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shennian",
3
- "version": "0.3.11",
3
+ "version": "0.3.13",
4
4
  "description": "Shennian — AI Agent Control Plane CLI",
5
5
  "type": "module",
6
6
  "bin": {