shennian 0.3.10 → 0.3.12
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.
- package/dist/publish-build-manifest.json +47 -42
- package/dist/src/agents/model-registry/parsers.js +4 -4
- package/dist/src/commands/daemon-windows.d.ts +7 -0
- package/dist/src/commands/daemon-windows.js +12 -8
- package/dist/src/commands/daemon.d.ts +4 -1
- package/dist/src/commands/daemon.js +9 -9
- package/dist/src/commands/room.d.ts +9 -0
- package/dist/src/commands/room.js +8 -4
- package/dist/src/index.js +2 -2
- package/dist/src/integrations/room-plugin-shared.js +2 -2
- package/dist/src/integrations/workbuddy-plugin-lifecycle.d.ts +10 -0
- package/dist/src/integrations/workbuddy-plugin-lifecycle.js +2 -2
- package/dist/src/room/activation-service.d.ts +3 -0
- package/dist/src/room/activation-service.js +9 -5
- package/dist/src/room/agent-tool.d.ts +1 -0
- package/dist/src/room/agent-tool.js +1 -1
- package/dist/src/room/managed-room-binding.d.ts +23 -1
- package/dist/src/room/managed-room-binding.js +1 -1
- package/dist/src/room/managed-room-session-runtime.d.ts +18 -0
- package/dist/src/room/managed-room-session-runtime.js +1 -0
- package/dist/src/room/mirror-sync-service.d.ts +3 -1
- package/dist/src/room/mirror-sync-service.js +1 -1
- package/dist/src/room/operator-ipc.d.ts +2 -0
- package/dist/src/room/operator-ipc.js +1 -1
- package/dist/src/room/room-action-client.d.ts +2 -0
- package/dist/src/room/room-action-ipc.d.ts +1 -0
- package/dist/src/room/room-action-ipc.js +1 -1
- package/dist/src/room/room-binding-client.d.ts +9 -0
- package/dist/src/room/room-binding-client.js +1 -1
- package/dist/src/room/room-binding-ipc.d.ts +3 -1
- package/dist/src/room/session-registry.d.ts +7 -1
- package/dist/src/room/session-registry.js +2 -2
- package/dist/src/room/tool-schema.d.ts +1 -1
- package/dist/src/room/tool-schema.js +1 -1
- package/dist/src/session/handlers/chat.d.ts +8 -1
- package/dist/src/session/handlers/chat.js +1 -1
- package/dist/src/session/handlers/room-managed.d.ts +1 -0
- package/dist/src/session/handlers/room-managed.js +1 -1
- package/dist/src/session/manager.d.ts +20 -0
- package/dist/src/session/manager.js +1 -1
- package/dist/src/upgrade/engine.d.ts +5 -0
- package/dist/src/upgrade/engine.js +2 -2
- package/node_modules/@shennian/wire/dist/agent-workspace.d.ts +1 -0
- package/node_modules/@shennian/wire/dist/agent-workspace.d.ts.map +1 -1
- package/node_modules/@shennian/wire/dist/methods.d.ts +1 -1
- package/node_modules/@shennian/wire/dist/methods.d.ts.map +1 -1
- package/node_modules/@shennian/wire/dist/room.d.ts +2 -0
- package/node_modules/@shennian/wire/dist/room.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"jsMinified": true,
|
|
4
4
|
"minifier": "esbuild",
|
|
5
|
-
"fileCount":
|
|
5
|
+
"fileCount": 129,
|
|
6
6
|
"files": [
|
|
7
7
|
{
|
|
8
8
|
"file": "bin/shennian.js",
|
|
@@ -86,8 +86,8 @@
|
|
|
86
86
|
},
|
|
87
87
|
{
|
|
88
88
|
"file": "src/agents/model-registry/parsers.js",
|
|
89
|
-
"beforeBytes":
|
|
90
|
-
"afterBytes":
|
|
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":
|
|
160
|
-
"afterBytes":
|
|
159
|
+
"beforeBytes": 3905,
|
|
160
|
+
"afterBytes": 3130
|
|
161
161
|
},
|
|
162
162
|
{
|
|
163
163
|
"file": "src/commands/daemon.js",
|
|
164
|
-
"beforeBytes":
|
|
165
|
-
"afterBytes":
|
|
164
|
+
"beforeBytes": 38493,
|
|
165
|
+
"afterBytes": 18618
|
|
166
166
|
},
|
|
167
167
|
{
|
|
168
168
|
"file": "src/commands/integration.js",
|
|
@@ -191,8 +191,8 @@
|
|
|
191
191
|
},
|
|
192
192
|
{
|
|
193
193
|
"file": "src/commands/room.js",
|
|
194
|
-
"beforeBytes":
|
|
195
|
-
"afterBytes":
|
|
194
|
+
"beforeBytes": 11089,
|
|
195
|
+
"afterBytes": 5750
|
|
196
196
|
},
|
|
197
197
|
{
|
|
198
198
|
"file": "src/commands/tools.js",
|
|
@@ -266,8 +266,8 @@
|
|
|
266
266
|
},
|
|
267
267
|
{
|
|
268
268
|
"file": "src/index.js",
|
|
269
|
-
"beforeBytes":
|
|
270
|
-
"afterBytes":
|
|
269
|
+
"beforeBytes": 26361,
|
|
270
|
+
"afterBytes": 13566
|
|
271
271
|
},
|
|
272
272
|
{
|
|
273
273
|
"file": "src/integrations/claude-room-plugin-lifecycle.js",
|
|
@@ -291,8 +291,8 @@
|
|
|
291
291
|
},
|
|
292
292
|
{
|
|
293
293
|
"file": "src/integrations/room-plugin-shared.js",
|
|
294
|
-
"beforeBytes":
|
|
295
|
-
"afterBytes":
|
|
294
|
+
"beforeBytes": 8919,
|
|
295
|
+
"afterBytes": 6095
|
|
296
296
|
},
|
|
297
297
|
{
|
|
298
298
|
"file": "src/integrations/room-session-hook.js",
|
|
@@ -306,8 +306,8 @@
|
|
|
306
306
|
},
|
|
307
307
|
{
|
|
308
308
|
"file": "src/integrations/workbuddy-plugin-lifecycle.js",
|
|
309
|
-
"beforeBytes":
|
|
310
|
-
"afterBytes":
|
|
309
|
+
"beforeBytes": 15998,
|
|
310
|
+
"afterBytes": 8237
|
|
311
311
|
},
|
|
312
312
|
{
|
|
313
313
|
"file": "src/integrations/workbuddy-session-hook.js",
|
|
@@ -401,13 +401,13 @@
|
|
|
401
401
|
},
|
|
402
402
|
{
|
|
403
403
|
"file": "src/room/activation-service.js",
|
|
404
|
-
"beforeBytes":
|
|
405
|
-
"afterBytes":
|
|
404
|
+
"beforeBytes": 13148,
|
|
405
|
+
"afterBytes": 8188
|
|
406
406
|
},
|
|
407
407
|
{
|
|
408
408
|
"file": "src/room/agent-tool.js",
|
|
409
|
-
"beforeBytes":
|
|
410
|
-
"afterBytes":
|
|
409
|
+
"beforeBytes": 5020,
|
|
410
|
+
"afterBytes": 3009
|
|
411
411
|
},
|
|
412
412
|
{
|
|
413
413
|
"file": "src/room/attachment-cache.js",
|
|
@@ -466,8 +466,13 @@
|
|
|
466
466
|
},
|
|
467
467
|
{
|
|
468
468
|
"file": "src/room/managed-room-binding.js",
|
|
469
|
-
"beforeBytes":
|
|
470
|
-
"afterBytes":
|
|
469
|
+
"beforeBytes": 6069,
|
|
470
|
+
"afterBytes": 3316
|
|
471
|
+
},
|
|
472
|
+
{
|
|
473
|
+
"file": "src/room/managed-room-session-runtime.js",
|
|
474
|
+
"beforeBytes": 6336,
|
|
475
|
+
"afterBytes": 3257
|
|
471
476
|
},
|
|
472
477
|
{
|
|
473
478
|
"file": "src/room/managed-room-session.js",
|
|
@@ -476,13 +481,13 @@
|
|
|
476
481
|
},
|
|
477
482
|
{
|
|
478
483
|
"file": "src/room/mirror-sync-service.js",
|
|
479
|
-
"beforeBytes":
|
|
480
|
-
"afterBytes":
|
|
484
|
+
"beforeBytes": 7686,
|
|
485
|
+
"afterBytes": 3515
|
|
481
486
|
},
|
|
482
487
|
{
|
|
483
488
|
"file": "src/room/operator-ipc.js",
|
|
484
|
-
"beforeBytes":
|
|
485
|
-
"afterBytes":
|
|
489
|
+
"beforeBytes": 8566,
|
|
490
|
+
"afterBytes": 4401
|
|
486
491
|
},
|
|
487
492
|
{
|
|
488
493
|
"file": "src/room/pending-authorized-actions.js",
|
|
@@ -491,13 +496,13 @@
|
|
|
491
496
|
},
|
|
492
497
|
{
|
|
493
498
|
"file": "src/room/room-action-client.js",
|
|
494
|
-
"beforeBytes":
|
|
499
|
+
"beforeBytes": 22556,
|
|
495
500
|
"afterBytes": 11355
|
|
496
501
|
},
|
|
497
502
|
{
|
|
498
503
|
"file": "src/room/room-action-ipc.js",
|
|
499
|
-
"beforeBytes":
|
|
500
|
-
"afterBytes":
|
|
504
|
+
"beforeBytes": 15565,
|
|
505
|
+
"afterBytes": 6951
|
|
501
506
|
},
|
|
502
507
|
{
|
|
503
508
|
"file": "src/room/room-action-schema.js",
|
|
@@ -511,8 +516,8 @@
|
|
|
511
516
|
},
|
|
512
517
|
{
|
|
513
518
|
"file": "src/room/room-binding-client.js",
|
|
514
|
-
"beforeBytes":
|
|
515
|
-
"afterBytes":
|
|
519
|
+
"beforeBytes": 6716,
|
|
520
|
+
"afterBytes": 3894
|
|
516
521
|
},
|
|
517
522
|
{
|
|
518
523
|
"file": "src/room/room-binding-ipc.js",
|
|
@@ -526,13 +531,13 @@
|
|
|
526
531
|
},
|
|
527
532
|
{
|
|
528
533
|
"file": "src/room/session-registry.js",
|
|
529
|
-
"beforeBytes":
|
|
530
|
-
"afterBytes":
|
|
534
|
+
"beforeBytes": 23644,
|
|
535
|
+
"afterBytes": 13190
|
|
531
536
|
},
|
|
532
537
|
{
|
|
533
538
|
"file": "src/room/tool-schema.js",
|
|
534
|
-
"beforeBytes":
|
|
535
|
-
"afterBytes":
|
|
539
|
+
"beforeBytes": 4993,
|
|
540
|
+
"afterBytes": 3063
|
|
536
541
|
},
|
|
537
542
|
{
|
|
538
543
|
"file": "src/room/tool-server.js",
|
|
@@ -561,8 +566,8 @@
|
|
|
561
566
|
},
|
|
562
567
|
{
|
|
563
568
|
"file": "src/session/handlers/chat.js",
|
|
564
|
-
"beforeBytes":
|
|
565
|
-
"afterBytes":
|
|
569
|
+
"beforeBytes": 31069,
|
|
570
|
+
"afterBytes": 13554
|
|
566
571
|
},
|
|
567
572
|
{
|
|
568
573
|
"file": "src/session/handlers/control.js",
|
|
@@ -576,8 +581,8 @@
|
|
|
576
581
|
},
|
|
577
582
|
{
|
|
578
583
|
"file": "src/session/handlers/room-managed.js",
|
|
579
|
-
"beforeBytes":
|
|
580
|
-
"afterBytes":
|
|
584
|
+
"beforeBytes": 3173,
|
|
585
|
+
"afterBytes": 1972
|
|
581
586
|
},
|
|
582
587
|
{
|
|
583
588
|
"file": "src/session/handlers/session-refresh.js",
|
|
@@ -596,8 +601,8 @@
|
|
|
596
601
|
},
|
|
597
602
|
{
|
|
598
603
|
"file": "src/session/manager.js",
|
|
599
|
-
"beforeBytes":
|
|
600
|
-
"afterBytes":
|
|
604
|
+
"beforeBytes": 20500,
|
|
605
|
+
"afterBytes": 10670
|
|
601
606
|
},
|
|
602
607
|
{
|
|
603
608
|
"file": "src/session/projection.js",
|
|
@@ -631,8 +636,8 @@
|
|
|
631
636
|
},
|
|
632
637
|
{
|
|
633
638
|
"file": "src/upgrade/engine.js",
|
|
634
|
-
"beforeBytes":
|
|
635
|
-
"afterBytes":
|
|
639
|
+
"beforeBytes": 15579,
|
|
640
|
+
"afterBytes": 6624
|
|
636
641
|
},
|
|
637
642
|
{
|
|
638
643
|
"file": "src/upgrade/scheduler.js",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
function
|
|
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
|
|
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
|
|
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,
|
|
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};
|
|
@@ -13,4 +13,11 @@ export declare function buildWindowsScheduledTaskXml(input: {
|
|
|
13
13
|
command: string;
|
|
14
14
|
arguments: string[];
|
|
15
15
|
}): string;
|
|
16
|
+
export declare function buildWindowsScheduledTaskCommands(input: {
|
|
17
|
+
taskName: string;
|
|
18
|
+
xmlPath: string;
|
|
19
|
+
}): {
|
|
20
|
+
create: string;
|
|
21
|
+
run: string;
|
|
22
|
+
};
|
|
16
23
|
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import a from"node:path";function i(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}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">
|
|
@@ -6,9 +6,13 @@ import i from"node:path";function a(e){return e.replace(/&/g,"&").replace(/<
|
|
|
6
6
|
<Description>Shennian Agent Daemon</Description>
|
|
7
7
|
</RegistrationInfo>
|
|
8
8
|
<Triggers>
|
|
9
|
+
<BootTrigger>
|
|
10
|
+
<Enabled>true</Enabled>
|
|
11
|
+
<Delay>PT15S</Delay>
|
|
12
|
+
</BootTrigger>
|
|
9
13
|
<LogonTrigger>
|
|
10
14
|
<Enabled>true</Enabled>
|
|
11
|
-
<UserId>${
|
|
15
|
+
<UserId>${r(e.userId)}</UserId>
|
|
12
16
|
</LogonTrigger>
|
|
13
17
|
<EventTrigger>
|
|
14
18
|
<Enabled>true</Enabled>
|
|
@@ -22,8 +26,8 @@ import i from"node:path";function a(e){return e.replace(/&/g,"&").replace(/<
|
|
|
22
26
|
</Triggers>
|
|
23
27
|
<Principals>
|
|
24
28
|
<Principal id="Author">
|
|
25
|
-
<UserId>${
|
|
26
|
-
<LogonType>
|
|
29
|
+
<UserId>${r(e.userId)}</UserId>
|
|
30
|
+
<LogonType>S4U</LogonType>
|
|
27
31
|
<RunLevel>LeastPrivilege</RunLevel>
|
|
28
32
|
</Principal>
|
|
29
33
|
</Principals>
|
|
@@ -42,7 +46,7 @@ import i from"node:path";function a(e){return e.replace(/&/g,"&").replace(/<
|
|
|
42
46
|
<Enabled>true</Enabled>
|
|
43
47
|
<Hidden>true</Hidden>
|
|
44
48
|
<RunOnlyIfIdle>false</RunOnlyIfIdle>
|
|
45
|
-
<WakeToRun>
|
|
49
|
+
<WakeToRun>true</WakeToRun>
|
|
46
50
|
<ExecutionTimeLimit>PT0S</ExecutionTimeLimit>
|
|
47
51
|
<Priority>7</Priority>
|
|
48
52
|
<RestartOnFailure>
|
|
@@ -52,8 +56,8 @@ import i from"node:path";function a(e){return e.replace(/&/g,"&").replace(/<
|
|
|
52
56
|
</Settings>
|
|
53
57
|
<Actions Context="Author">
|
|
54
58
|
<Exec>
|
|
55
|
-
<Command>${
|
|
56
|
-
<Arguments>${
|
|
59
|
+
<Command>${r(e.command)}</Command>
|
|
60
|
+
<Arguments>${r(t)}</Arguments>
|
|
57
61
|
</Exec>
|
|
58
62
|
</Actions>
|
|
59
|
-
</Task>`}export{m as buildWindowsLauncherCommand,p as buildWindowsScheduledTaskXml,g as buildWindowsStartupVbs,
|
|
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};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
2
|
import type { Command } from 'commander';
|
|
3
|
-
export { buildWindowsLauncherCommand, buildWindowsScheduledTaskXml, buildWindowsStartupVbs, } from './daemon-windows.js';
|
|
3
|
+
export { buildWindowsLauncherCommand, buildWindowsScheduledTaskCommands, buildWindowsScheduledTaskXml, buildWindowsStartupVbs, } from './daemon-windows.js';
|
|
4
4
|
export { isShennianRunServiceCommand } from './daemon-process.js';
|
|
5
5
|
export declare function isSafeSnapshotEnvKey(key: string): boolean;
|
|
6
6
|
type Platform = 'darwin' | 'linux' | 'win32';
|
|
@@ -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,13 +1,13 @@
|
|
|
1
|
-
import s from"chalk";import
|
|
2
|
-
`)}function
|
|
3
|
-
<string>${
|
|
4
|
-
`),r=[n.command,...n.args].map(
|
|
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">
|
|
8
8
|
<dict>
|
|
9
9
|
<key>Label</key>
|
|
10
|
-
<string>${
|
|
10
|
+
<string>${H}</string>
|
|
11
11
|
<key>ProgramArguments</key>
|
|
12
12
|
<array>
|
|
13
13
|
${r}
|
|
@@ -27,8 +27,8 @@ ${t}
|
|
|
27
27
|
<key>StandardErrorPath</key>
|
|
28
28
|
<string>${d}</string>
|
|
29
29
|
</dict>
|
|
30
|
-
</plist>`}const D=c.join(u.homedir(),".config/systemd/user/shennian.service");function
|
|
31
|
-
`),r=[n.command,...n.args].map(
|
|
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
|
|
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
|
|
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};
|
|
@@ -6,8 +6,17 @@ type RoomCommandIo = {
|
|
|
6
6
|
stderr: (text: string) => void;
|
|
7
7
|
fail: () => void;
|
|
8
8
|
};
|
|
9
|
+
type ConfirmManagedAgent = (summary: string) => Promise<boolean>;
|
|
10
|
+
type ManagedAgentIntentStore = {
|
|
11
|
+
acquire: (intentKey: string) => string;
|
|
12
|
+
complete: (intentKey: string, operationId: string) => void;
|
|
13
|
+
};
|
|
9
14
|
export declare function registerRoomCommand(program: Command, options?: {
|
|
10
15
|
invoke?: InvokeDaemon;
|
|
11
16
|
io?: RoomCommandIo;
|
|
17
|
+
confirmManagedAgent?: ConfirmManagedAgent;
|
|
18
|
+
managedAgentIntents?: ManagedAgentIntentStore;
|
|
19
|
+
interactive?: boolean;
|
|
12
20
|
}): void;
|
|
21
|
+
export declare function createFileManagedAgentIntentStore(directory?: string): ManagedAgentIntentStore;
|
|
13
22
|
export {};
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import{callDaemonIpc as
|
|
2
|
-
`)}catch(
|
|
3
|
-
`)}catch(
|
|
4
|
-
`),
|
|
1
|
+
import g from"node:crypto";import i from"node:fs";import v from"node:path";import{createInterface as I}from"node:readline/promises";import{loadConfig as _,resolveShennianPath as k}from"../config/index.js";import{callDaemonIpc as R}from"../daemon-ipc/client.js";import{DaemonIpcError as u}from"../daemon-ipc/protocol.js";const $={stdout:e=>process.stdout.write(e),stderr:e=>process.stderr.write(e),fail:()=>{process.exitCode=1}};function G(e,n={}){const t=n.invoke??R,o=n.io??$,r=e.command("room").description("Inspect locally observed Shennian Rooms and manage safe Room operations");r.command("status").description("Show local Room integration status").action(async()=>{await w("status",t,o)}),r.command("list").description("List Rooms observed by this daemon on this machine").action(async()=>{await w("list",t,o)}),r.command("create").description("Create a private Room owned by the signed-in Shennian account").requiredOption("--name <name>","Room name").action(async a=>{await N(a.name,t,o)}),r.command("agent").description("Manage Agent conversations for a Room").command("create").description("Create a managed Agent conversation and join it to an explicit Room invite").requiredOption("--room <invite-url>","Exact Room invite URL; recent Rooms are never guessed").requiredOption("--agent <runtime>","codex, claude-code, or workbuddy").requiredOption("--workdir <absolute-path>","Absolute working directory for the new Agent").option("--model <model>","Agent model").option("--name <alias>","Agent display name").option("--mode <mode>","auto, mention, or paused","auto").option("--yes","Confirm creation in a non-interactive environment",!1).action(async a=>{await M(a,t,o,{confirm:n.confirmManagedAgent??D,interactive:n.interactive??!!(process.stdin.isTTY&&process.stdout.isTTY),intents:n.managedAgentIntents??b})})}async function w(e,n,t){try{const o=await n({method:"room-operator.inspect",params:{action:e}});t.stdout(`${JSON.stringify({ok:!0,command:`room.${e}`,result:o})}
|
|
2
|
+
`)}catch(o){s(o,t)}}async function N(e,n,t){const o=e.trim();if(!o||o.length>80){s(new u("invalid_params","Room name must contain 1 to 80 characters."),t);return}try{const r=await n({method:"room-operator.create",params:{name:o},timeoutMs:15e3});t.stdout(`${JSON.stringify({ok:!0,command:"room.create",result:r})}
|
|
3
|
+
`)}catch(r){s(r,t)}}async function M(e,n,t,o){const r=e.agent.trim().toLowerCase(),c=r==="claude-code"?"claude":r,a=e.mode.trim().toLowerCase(),y=a==="auto"?"auto_follow":a==="mention"?"mention_only":a,p=e.name?.trim()||T(c),m={room:e.room.trim(),agent:c,workDir:e.workdir.trim(),...e.model?.trim()?{modelId:e.model.trim()}:{},alias:p,activationMode:y};if(!["codex","claude","workbuddy"].includes(c)||!["auto_follow","mention_only","paused"].includes(y)||!m.room||!m.workDir||!p||p.length>80){s(new u("invalid_params","Managed Agent parameters are invalid."),t);return}if(!e.yes){if(!o.interactive){s(new u("confirmation_required","Creating an Agent starts a model process. Re-run with --yes after reviewing the target."),t);return}if(!await o.confirm(["Create and start this managed Agent?",`Room: ${x(m.room)}`,`Agent: ${r}`,`Workdir: ${m.workDir}`,`Model: ${e.model?.trim()||"(default)"}`,`Name: ${p}`,`Mode: ${a}`].join(`
|
|
4
|
+
`))){s(new u("cancelled","Managed Agent creation was cancelled."),t);return}}const h=g.createHash("sha256").update(JSON.stringify({machineId:_().machineId??null,...m}),"utf8").digest("hex");let f;try{f=o.intents.acquire(h)}catch(d){s(d,t);return}try{const d=await n({method:"room-operator.agent-create",params:{...m,operationId:f},timeoutMs:9e4});try{o.intents.complete(h,f)}catch{}t.stdout(`${JSON.stringify({ok:!0,command:"room.agent.create",result:d})}
|
|
5
|
+
`)}catch(d){s(d,t)}}const O=/^room_agent_[a-f0-9]{48}$/,E=k("runtime","room-agent-create-intents");function C(e=E){return{acquire:n=>{const t=A(e,n);try{return S(t)}catch(a){if(a.code!=="ENOENT")throw a}i.mkdirSync(e,{recursive:!0,mode:448});const o=i.lstatSync(e);if(!o.isDirectory()||o.isSymbolicLink())throw l();process.platform!=="win32"&&i.chmodSync(e,448);const r=`room_agent_${g.randomBytes(24).toString("hex")}`,c=`${t}.tmp-${process.pid}-${g.randomBytes(6).toString("hex")}`;try{return i.writeFileSync(c,`${JSON.stringify({operationId:r})}
|
|
6
|
+
`,{encoding:"utf8",mode:384,flag:"wx"}),process.platform!=="win32"&&i.chmodSync(c,384),i.linkSync(c,t),r}catch(a){if(a.code!=="EEXIST")throw a;return S(t)}finally{try{i.unlinkSync(c)}catch{}}},complete:(n,t)=>{const o=A(e,n);try{const r=i.lstatSync(o);if(!r.isFile()||r.isSymbolicLink())throw l();JSON.parse(i.readFileSync(o,"utf8")).operationId===t&&i.unlinkSync(o)}catch(r){if(r.code!=="ENOENT")throw r}}}}function S(e){const n=i.lstatSync(e);if(!n.isFile()||n.isSymbolicLink())throw l();const t=JSON.parse(i.readFileSync(e,"utf8"));if(typeof t.operationId!="string"||!O.test(t.operationId))throw l();return t.operationId}const b=C();function A(e,n){if(!/^[a-f0-9]{64}$/.test(n))throw l();return v.join(e,`${n}.json`)}function l(){return Object.assign(new Error("Managed Agent create intent storage is unsafe or corrupt."),{code:"unsafe_managed_agent_intent_store"})}function T(e){return e==="claude"?"Claude Code":e==="workbuddy"?"WorkBuddy":"Codex"}function x(e){try{return`${new URL(e).origin}/spaces/join/[capability]`}catch{return"[invalid Room reference]"}}async function D(e){const n=I({input:process.stdin,output:process.stdout});try{const t=await n.question(`${e}
|
|
7
|
+
Continue? (y/N) `);return/^(?:y|yes)$/i.test(t.trim())}finally{n.close()}}function s(e,n){const t=e instanceof u?{code:e.code,message:e.message}:{code:"room_command_failed",message:"Shennian Room command failed."};n.stdout(`${JSON.stringify({ok:!1,error:t})}
|
|
8
|
+
`),n.fail()}export{C as createFileManagedAgentIntentStore,G as registerRoomCommand};
|