shennian 0.4.67 → 0.4.69

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.
@@ -2,7 +2,7 @@
2
2
  "schemaVersion": 1,
3
3
  "jsMinified": true,
4
4
  "minifier": "esbuild",
5
- "fileCount": 207,
5
+ "fileCount": 208,
6
6
  "files": [
7
7
  {
8
8
  "file": "bin/shennian.js",
@@ -11,8 +11,8 @@
11
11
  },
12
12
  {
13
13
  "file": "src/agent-env.js",
14
- "beforeBytes": 10485,
15
- "afterBytes": 4709
14
+ "beforeBytes": 10709,
15
+ "afterBytes": 4754
16
16
  },
17
17
  {
18
18
  "file": "src/agents/acp/adapter.js",
@@ -126,8 +126,8 @@
126
126
  },
127
127
  {
128
128
  "file": "src/agents/command-spec.js",
129
- "beforeBytes": 18342,
130
- "afterBytes": 8290
129
+ "beforeBytes": 19263,
130
+ "afterBytes": 8681
131
131
  },
132
132
  {
133
133
  "file": "src/agents/config-status.js",
@@ -181,18 +181,23 @@
181
181
  },
182
182
  {
183
183
  "file": "src/agents/model-registry/cache.js",
184
- "beforeBytes": 1321,
185
- "afterBytes": 575
184
+ "beforeBytes": 1491,
185
+ "afterBytes": 640
186
186
  },
187
187
  {
188
188
  "file": "src/agents/model-registry/discovery.js",
189
- "beforeBytes": 10881,
190
- "afterBytes": 5056
189
+ "beforeBytes": 11070,
190
+ "afterBytes": 5176
191
+ },
192
+ {
193
+ "file": "src/agents/model-registry/opencode-api.js",
194
+ "beforeBytes": 3026,
195
+ "afterBytes": 1539
191
196
  },
192
197
  {
193
198
  "file": "src/agents/model-registry/parsers.js",
194
- "beforeBytes": 19925,
195
- "afterBytes": 10288
199
+ "beforeBytes": 22727,
200
+ "afterBytes": 11534
196
201
  },
197
202
  {
198
203
  "file": "src/agents/model-registry/runner.js",
@@ -201,8 +206,8 @@
201
206
  },
202
207
  {
203
208
  "file": "src/agents/model-registry/service.js",
204
- "beforeBytes": 5997,
205
- "afterBytes": 2572
209
+ "beforeBytes": 6036,
210
+ "afterBytes": 2605
206
211
  },
207
212
  {
208
213
  "file": "src/agents/model-registry/types.js",
@@ -271,8 +276,8 @@
271
276
  },
272
277
  {
273
278
  "file": "src/agents/runtime-compatibility.js",
274
- "beforeBytes": 1705,
275
- "afterBytes": 810
279
+ "beforeBytes": 1587,
280
+ "afterBytes": 732
276
281
  },
277
282
  {
278
283
  "file": "src/agents/workbuddy-managed-permissions.js",
@@ -651,8 +656,8 @@
651
656
  },
652
657
  {
653
658
  "file": "src/room/managed-prompt-composer.js",
654
- "beforeBytes": 10441,
655
- "afterBytes": 11173
659
+ "beforeBytes": 10537,
660
+ "afterBytes": 11365
656
661
  },
657
662
  {
658
663
  "file": "src/room/managed-room-binding.js",
@@ -706,8 +711,8 @@
706
711
  },
707
712
  {
708
713
  "file": "src/schedules/personal-context.js",
709
- "beforeBytes": 1503,
710
- "afterBytes": 1451
714
+ "beforeBytes": 901,
715
+ "afterBytes": 501
711
716
  },
712
717
  {
713
718
  "file": "src/schedules/server-client.js",
@@ -791,8 +796,8 @@
791
796
  },
792
797
  {
793
798
  "file": "src/session/handlers/chat-adapter-config.js",
794
- "beforeBytes": 3042,
795
- "afterBytes": 1288
799
+ "beforeBytes": 2814,
800
+ "afterBytes": 1159
796
801
  },
797
802
  {
798
803
  "file": "src/session/handlers/chat-events.js",
@@ -811,8 +816,8 @@
811
816
  },
812
817
  {
813
818
  "file": "src/session/handlers/chat.js",
814
- "beforeBytes": 35576,
815
- "afterBytes": 15405
819
+ "beforeBytes": 35331,
820
+ "afterBytes": 15258
816
821
  },
817
822
  {
818
823
  "file": "src/session/handlers/control.js",
@@ -926,8 +931,8 @@
926
931
  },
927
932
  {
928
933
  "file": "src/session/queue-storage.js",
929
- "beforeBytes": 2198,
930
- "afterBytes": 1165
934
+ "beforeBytes": 2362,
935
+ "afterBytes": 1166
931
936
  },
932
937
  {
933
938
  "file": "src/session/queue-types.js",
@@ -1,8 +1,8 @@
1
- import O from"node:os";import E from"node:path";import{spawnSync as p}from"node:child_process";import{buildAugmentedPath as g}from"./env-path.js";import{buildWindowsSystemEnv as A,resolveWindowsPowerShellPath as R}from"./windows-shell.js";const N="__SHENNIAN_AGENT_ENV_START__",f="__SHENNIAN_AGENT_ENV_END__",S=["HOME","USER","LOGNAME","LANG","LANGUAGE","LC_ALL","LC_CTYPE","TMPDIR","TMP","TEMP","TZ"],m=["SystemRoot","WINDIR","ComSpec","PATHEXT","USERPROFILE","APPDATA","LOCALAPPDATA","ProgramData","ProgramFiles","ProgramFiles(x86)","TEMP","TMP","TZ"],P=["NO_COLOR","PI_CODING_AGENT_DIR"],d=["SHENNIAN_MANAGED_ROOM_CONTEXT","SHENNIAN_MANAGED_ROOM_IPC_ROOT"],v=["SHENNIAN_MANAGER_SESSION_ID","SHENNIAN_MANAGER_AGENT_SESSION_ID","SHENNIAN_MANAGER_WORKDIR","SHENNIAN_MANAGER_MODEL","SHENNIAN_MANAGER_IPC_URL","SHENNIAN_MANAGER_IPC_TOKEN"],h={codex:["OPENAI_BASE_URL","OPENAI_API_KEY"],claude:["ANTHROPIC_BASE_URL","ANTHROPIC_API_KEY"],pi:["DASHSCOPE_BASE_URL","DASHSCOPE_API_KEY"]};function T(e){return h[e]??[]}function w(e){return e==="codex"||e==="claude"||e==="pi-coding-agent"?[...d,...v]:d}function j(e=process.platform){return["PATH",...e==="win32"?m:S,...P]}function _(e){return`'${e.replace(/'/g,"'\\''")}'`}function I(e){const n=e.indexOf(N),o=e.indexOf(f,n+N.length);if(n===-1||o===-1)return null;const t=e.slice(n+N.length,o);try{const s=JSON.parse(t),i={};for(const[c,r]of Object.entries(s))typeof r=="string"&&(i[c]=r);return i}catch{return null}}function G(){const e=process.env.SHELL?.trim()||"/bin/sh",n=[`printf ${_(N)}`,`${_(process.execPath)} -e ${_("process.stdout.write(JSON.stringify(process.env))")}`,`printf ${_(f)}`].join("; ");for(const o of[["-ilc",n],["-lc",n]]){const t=p(e,o,{env:process.env,encoding:"utf-8",stdio:["ignore","pipe","ignore"],timeout:1500,windowsHide:!0}),s=typeof t.stdout=="string"?I(t.stdout):null;if(s)return s}return null}function M(){const e=`
1
+ import O from"node:os";import E from"node:path";import{spawnSync as p}from"node:child_process";import{buildAugmentedPath as g}from"./env-path.js";import{buildWindowsSystemEnv as A,resolveWindowsPowerShellPath as T}from"./windows-shell.js";const N="__SHENNIAN_AGENT_ENV_START__",d="__SHENNIAN_AGENT_ENV_END__",S=["HOME","USER","LOGNAME","LANG","LANGUAGE","LC_ALL","LC_CTYPE","TMPDIR","TMP","TEMP","TZ"],m=["SystemRoot","WINDIR","ComSpec","PATHEXT","USERPROFILE","APPDATA","LOCALAPPDATA","ProgramData","ProgramFiles","ProgramFiles(x86)","TEMP","TMP","TZ"],v=["NO_COLOR","PI_CODING_AGENT_DIR"],f=["SHENNIAN_MANAGED_ROOM_CONTEXT","SHENNIAN_MANAGED_ROOM_IPC_ROOT"],P=["SHENNIAN_MANAGER_SESSION_ID","SHENNIAN_MANAGER_AGENT_SESSION_ID","SHENNIAN_MANAGER_WORKDIR","SHENNIAN_MANAGER_MODEL","SHENNIAN_MANAGER_IPC_URL","SHENNIAN_MANAGER_IPC_TOKEN"],R={codex:["OPENAI_BASE_URL","OPENAI_API_KEY"],claude:["ANTHROPIC_BASE_URL","ANTHROPIC_API_KEY"],pi:["DASHSCOPE_BASE_URL","DASHSCOPE_API_KEY"]};function h(e){return R[e]??[]}function w(e){return e==="codex"||e==="claude"||e==="pi-coding-agent"?[...f,...P]:f}function j(e=process.platform){return["PATH",...e==="win32"?m:S,...v]}function _(e){return`'${e.replace(/'/g,"'\\''")}'`}function I(e){const n=e.indexOf(N),o=e.indexOf(d,n+N.length);if(n===-1||o===-1)return null;const t=e.slice(n+N.length,o);try{const s=JSON.parse(t),i={};for(const[c,r]of Object.entries(s))typeof r=="string"&&(i[c]=r);return i}catch{return null}}function G(){const e=process.env.SHELL?.trim()||"/bin/sh",n=[`printf ${_(N)}`,`${_(process.execPath)} -e ${_("process.stdout.write(JSON.stringify(process.env))")}`,`printf ${_(d)}`].join("; ");for(const o of[["-ilc",n],["-lc",n]]){const t=p(e,o,{env:process.env,encoding:"utf-8",stdio:["ignore","pipe","ignore"],timeout:1500,windowsHide:!0}),s=typeof t.stdout=="string"?I(t.stdout):null;if(s)return s}return null}function M(){const e=`
2
2
  $envs = @{}
3
3
  [Environment]::GetEnvironmentVariables('Machine').GetEnumerator() | ForEach-Object { $envs[$_.Key] = [string]$_.Value }
4
4
  [Environment]::GetEnvironmentVariables('User').GetEnumerator() | ForEach-Object { $envs[$_.Key] = [string]$_.Value }
5
5
  Write-Output '${N}'
6
6
  $envs | ConvertTo-Json -Compress
7
- Write-Output '${f}'
8
- `,n=p(R(),["-NoProfile","-Command",e],{env:{...process.env,...A(process.env)},encoding:"utf-8",stdio:["ignore","pipe","ignore"],timeout:1500,windowsHide:!0});return typeof n.stdout=="string"?I(n.stdout):null}function y(){return(O.platform()==="win32"?M():G())??{}}function D(e){const n={...e.daemonEnv,...e.userEnv,...e.extra};return process.platform==="win32"&&Object.assign(n,A(n)),n.PATH=b(e.daemonEnv,e.userEnv,e.extra,n),delete n.Path,delete n.path,n}function H(e={}){return D({daemonEnv:process.env,userEnv:y(),extra:e})}function $(e={}){const n=H(e),o=new Set([...d,...v]);for(const t of Object.keys(n))t.startsWith("SHENNIAN_")&&!o.has(t)&&delete n[t];return n}function U(e){const n=e.daemonEnv??process.env,o=e.platform??process.platform,t={};return l(t,n,o==="win32"?m:S,o),l(t,e.providerEnv,T(e.agentType),o),l(t,e.sessionEnv,w(e.agentType),o),l(t,e.runtimeEnv,P,o),o==="win32"&&Object.assign(t,A({...n,...t})),t.PATH=L(n,t,o),delete t.Path,delete t.path,t}function l(e,n,o,t){if(!n)return;const s=Object.entries(n);for(const i of o){const r=(t==="win32"?s.find(([a])=>a.toUpperCase()===i.toUpperCase()):s.find(([a])=>a===i))?.[1];typeof r=="string"&&r.length>0&&(e[i]=r)}}function L(e,n,o){const t=o==="win32"?E.win32.delimiter:E.posix.delimiter,s=[],i=(c,r=!1)=>{if(c)for(const a of c.split(t))!a||s.includes(a)||(r?s.unshift(a):s.push(a))};if(i(u(e)),i(E.dirname(process.execPath),!0),o==="win32"){const c=A({...e,...n}),r=c.SystemRoot??c.WINDIR??"C:\\Windows";i(E.win32.join(r,"System32")),i(E.win32.join(r,"System32","WindowsPowerShell","v1.0")),i(r)}else i("/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin");return s.join(t)}function u(e){return e?.PATH??e?.Path??e?.path}function b(e,n,o,t){const s=[];for(const c of[u(e),u(n),u(o)])for(const r of(c??"").split(E.delimiter))r&&!s.includes(r)&&s.push(r);if(process.platform==="win32"){const c=t.SystemRoot||t.WINDIR||process.env.SystemRoot||process.env.WINDIR||"C:\\Windows";for(const r of[E.win32.join(c,"System32"),E.win32.join(c,"System32","WindowsPowerShell","v1.0"),E.win32.join(c)])r&&!s.includes(r)&&s.push(r)}const i=E.dirname(process.execPath);return i&&!s.includes(i)&&s.unshift(i),g({pathValue:s.join(E.delimiter),env:t})}export{d as MANAGED_AGENT_SESSION_ENV_KEYS,H as buildAgentProcessEnv,U as buildManagedAgentProcessEnv,$ as buildManagedNativeFullProcessEnv,j as getManagedAgentBaseEnvKeys,T as getManagedAgentProviderEnvKeys,w as getManagedAgentSessionEnvKeys,D as mergeAgentProcessEnv,y as readLatestUserEnv};
7
+ Write-Output '${d}'
8
+ `,n=p(T(),["-NoProfile","-Command",e],{env:{...process.env,...A(process.env)},encoding:"utf-8",stdio:["ignore","pipe","ignore"],timeout:1500,windowsHide:!0});return typeof n.stdout=="string"?I(n.stdout):null}function D(){return(O.platform()==="win32"?M():G())??{}}function y(e){const n={...e.daemonEnv,...e.userEnv,...e.extra};return process.platform==="win32"&&Object.assign(n,A(n)),n.PATH=L(e.daemonEnv,e.userEnv,e.extra,n),delete n.Path,delete n.path,n}function H(e={}){const n=y({daemonEnv:process.env,userEnv:D(),extra:e});return delete n.SHENNIAN_SCHEDULE_CONTEXT,n}function $(e={}){const n=H(e),o=new Set([...f,...P]);for(const t of Object.keys(n))t.startsWith("SHENNIAN_")&&!o.has(t)&&delete n[t];return n}function U(e){const n=e.daemonEnv??process.env,o=e.platform??process.platform,t={};return l(t,n,o==="win32"?m:S,o),l(t,e.providerEnv,h(e.agentType),o),l(t,e.sessionEnv,w(e.agentType),o),l(t,e.runtimeEnv,v,o),o==="win32"&&Object.assign(t,A({...n,...t})),t.PATH=C(n,t,o),delete t.Path,delete t.path,t}function l(e,n,o,t){if(!n)return;const s=Object.entries(n);for(const i of o){const r=(t==="win32"?s.find(([a])=>a.toUpperCase()===i.toUpperCase()):s.find(([a])=>a===i))?.[1];typeof r=="string"&&r.length>0&&(e[i]=r)}}function C(e,n,o){const t=o==="win32"?E.win32.delimiter:E.posix.delimiter,s=[],i=(c,r=!1)=>{if(c)for(const a of c.split(t))!a||s.includes(a)||(r?s.unshift(a):s.push(a))};if(i(u(e)),i(E.dirname(process.execPath),!0),o==="win32"){const c=A({...e,...n}),r=c.SystemRoot??c.WINDIR??"C:\\Windows";i(E.win32.join(r,"System32")),i(E.win32.join(r,"System32","WindowsPowerShell","v1.0")),i(r)}else i("/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin");return s.join(t)}function u(e){return e?.PATH??e?.Path??e?.path}function L(e,n,o,t){const s=[];for(const c of[u(e),u(n),u(o)])for(const r of(c??"").split(E.delimiter))r&&!s.includes(r)&&s.push(r);if(process.platform==="win32"){const c=t.SystemRoot||t.WINDIR||process.env.SystemRoot||process.env.WINDIR||"C:\\Windows";for(const r of[E.win32.join(c,"System32"),E.win32.join(c,"System32","WindowsPowerShell","v1.0"),E.win32.join(c)])r&&!s.includes(r)&&s.push(r)}const i=E.dirname(process.execPath);return i&&!s.includes(i)&&s.unshift(i),g({pathValue:s.join(E.delimiter),env:t})}export{f as MANAGED_AGENT_SESSION_ENV_KEYS,H as buildAgentProcessEnv,U as buildManagedAgentProcessEnv,$ as buildManagedNativeFullProcessEnv,j as getManagedAgentBaseEnvKeys,h as getManagedAgentProviderEnvKeys,w as getManagedAgentSessionEnvKeys,y as mergeAgentProcessEnv,D as readLatestUserEnv};
@@ -17,6 +17,8 @@ type LaunchSpec = {
17
17
  };
18
18
  export declare function resetCommandSpecCache(): void;
19
19
  export declare function getProcessPlatform(): NodeJS.Platform;
20
+ /** macOS Codex desktop ships a directly runnable CLI; Windows Store does not. */
21
+ export declare function getCodexDesktopCommandCandidates(platform?: NodeJS.Platform, home?: string): string[];
20
22
  export declare function windowsPathToWsl(input: string): string | undefined;
21
23
  export declare function commandExists(command: string): boolean;
22
24
  /** Stable, non-secret identity used to invalidate local capability caches. */
@@ -1,3 +1,3 @@
1
- import{spawn as k,spawnSync as C}from"node:child_process";import p from"node:fs";import j from"node:crypto";import E from"node:os";import s from"node:path";const N={claude:[{command:"claude",args:[],display:"claude"}],codex:[{command:"codex",args:[],display:"codex"}],workbuddy:[{command:"codebuddy",args:[],display:"WorkBuddy"}],gemini:[{command:"gemini",args:[],display:"gemini"}],cursor:[{command:"agent",args:[],display:"agent"},{command:"cursor",args:["agent"],display:"cursor agent"}],openclaw:[],opencode:[{command:"opencode",args:[],display:"opencode"}],pi:[{command:"shennian",args:[],display:"shennian"}],"pi-coding-agent":[{command:"pi",args:[],display:"pi"}],manager:[{command:"shennian",args:["manager"],display:"shennian manager"}]},m=new Map,f=new Map,h=new Map,u=new Map;function X(){m.clear(),f.clear(),h.clear(),u.clear()}function c(){return process.platform}function R(n){return n.split(/\r?\n/).map(e=>e.trim()).filter(Boolean)}function b(n){if(s.basename(n)!==n)return[n];const e=E.homedir();if(c()==="win32"){const o=s.win32,r=s.extname(n)?[n]:[n,`${n}.cmd`,`${n}.exe`,`${n}.bat`],a=process.env.APPDATA||o.join(e,"AppData","Roaming"),l=process.env.LOCALAPPDATA||o.join(e,"AppData","Local"),y=[o.join(e,".shennian","node"),o.join("C:\\","nvm4w","nodejs"),o.join(l,"npm-global"),o.join(a,"npm"),o.join(l,"pnpm"),o.join(e,"scoop","shims"),o.join("C:\\","Program Files","nodejs")].flatMap(w=>r.map(g=>o.join(w,g)));if(n==="codebuddy"){const w=[o.join(l,"Programs","WorkBuddy"),o.join(l,"WorkBuddy"),o.join("C:\\","Program Files","WorkBuddy")];for(const g of w)for(const F of["codebuddy.exe","codebuddy.cmd","codebuddy"])y.push(o.join(g,"resources","app.asar.unpacked","cli","bin",F))}return y}const i=[s.join(e,".npm-global","bin"),s.join(e,".local","bin"),s.join(e,".bun","bin"),"/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin"].map(o=>s.join(o,n));return n==="claude"&&c()==="darwin"&&i.push(...V(e)),n==="codebuddy"&&c()==="darwin"&&i.push("/Applications/WorkBuddy.app/Contents/Resources/app.asar.unpacked/cli/bin/codebuddy",s.join(e,"Applications","WorkBuddy.app","Contents","Resources","app.asar.unpacked","cli","bin","codebuddy")),i}function V(n){const e=[s.join(n,"Library","Application Support","Claude","claude-code")],t=[];for(const i of e){let o;try{o=p.readdirSync(i,{withFileTypes:!0}).filter(r=>r.isDirectory()).map(r=>r.name).sort((r,a)=>a.localeCompare(r,void 0,{numeric:!0}))}catch{continue}for(const r of o)t.push(s.join(i,r,"claude.app","Contents","MacOS","claude"))}return t}function P(n,e){const t=n?.split(s.delimiter).filter(Boolean)??[];if(c()==="win32"){if(e&&s.basename(e)!==e){const i=s.win32.dirname(e);t.includes(i)||t.unshift(i)}for(const i of b("shennian")){const o=s.win32.dirname(i);t.includes(o)||t.push(o)}return t.join(s.delimiter)}if(e&&s.basename(e)!==e){const i=s.dirname(e);t.includes(i)||t.unshift(i)}for(const i of b("shennian")){const o=s.dirname(i);t.includes(o)||t.push(o)}return t.join(s.delimiter)}function d(n){if(h.has(n))return h.get(n)??[];const e=c()==="win32",i=C(e?"where":"which",[n],{encoding:"utf-8",stdio:["ignore","pipe","pipe"],timeout:3e3,windowsHide:!0,env:{...process.env,PATH:e?process.env.PATH:P(process.env.PATH,n)}}),r=[...i.status===0?R(i.stdout??""):[]];for(const a of b(n))p.existsSync(a)&&!r.includes(a)&&r.push(a);return h.set(n,r),r}function A(){return process.env.ComSpec||"cmd.exe"}function $(n){const e=s.extname(n).toLowerCase();return e===".exe"||e===".com"}function x(n){const e=s.extname(n).toLowerCase();return e===".cmd"||e===".bat"}function S(n){const e=s.extname(n).toLowerCase();return e===".js"||e===".mjs"||e===".cjs"}function W(){return d("node.exe")[0]??d("node")[0]??"node"}function B(n){return`"${n.replace(/"/g,'""')}"`}function v(n){return`'${n.replace(/'/g,"'\\''")}'`}function z(n){if(!n)return;const e=n.replace(/\//g,"\\"),t=e.match(/^([A-Za-z]):\\(.*)$/);if(t){const[,i,o]=t,r=o.replace(/\\/g,"/");return`/mnt/${i.toLowerCase()}/${r}`}if(e.startsWith("\\\\wsl$\\"))return`/${e.replace(/^\\\\wsl\$\\[^\\]+\\?/,"").replace(/\\/g,"/")}`;if(n.startsWith("/"))return n}function H(n){const e=n.trim();if(!e)throw new Error("Command string is empty");if(/[\\/]/.test(e)||/^[A-Za-z]:/.test(e))return x(e)?{kind:"cmd-shim",path:e}:{kind:"direct",path:e};const i=d(e),o=i.find($);if(o)return{kind:"direct",path:o};const r=i.find(x);return r?{kind:"cmd-shim",path:r}:{kind:"direct",path:e}}function L(n){if(u.has(n))return u.get(n)??!1;const e=d("wsl.exe")[0]??d("wsl")[0];if(!e)return u.set(n,!1),!1;const i=C(e,["-e","sh","-lc",`command -v ${v(n)} >/dev/null 2>&1`],{stdio:"ignore",timeout:5e3,windowsHide:!0}).status===0;return u.set(n,i),i}function Y(n){if(m.has(n))return m.get(n)??!1;const e=d(n).length>0||c()==="win32"&&L(n);return m.set(n,e),e}function nn(n){const e=d(n)[0];if(!e)return null;try{const t=p.realpathSync(e),i=p.statSync(t,{bigint:!0}),o=j.createHash("sha256").update(t).digest("hex"),r=j.createHash("sha256").update(`${i.dev}:${i.ino}:${i.size}:${i.mtimeNs}`).digest("hex");return{pathHash:o,fingerprint:r}}catch{return null}}function en(n){return d(n)[0]??null}function I(n){const e=d(n.command),t=e.find($);if(t)return{...n,kind:"native",path:t};const i=e.find(x);if(i)return{...n,kind:"cmd-shim",path:i};if(L(n.command)){const o=d("wsl.exe")[0]??d("wsl")[0];if(o)return{...n,kind:"wsl-bridge",path:o}}return null}function tn(n){if(f.has(n))return f.get(n)??null;const e=N[n].map(t=>{if(c()==="win32")return I(t);const i=d(t.command)[0];return i?{...t,kind:"native",path:i}:null}).find(Boolean)??null;return f.set(n,e),e}function D(n,e,t){if(n.kind==="native")return c()==="win32"&&S(n.path)?{command:W(),args:[n.path,...n.args,...e],cwd:t}:{command:n.path,args:[...n.args,...e],cwd:t};if(n.kind==="cmd-shim"){const r=[n.path,...n.args,...e].map(B).join(" ");return{command:A(),args:["/d","/s","/c",`"${r}"`],cwd:t}}const i=t?z(t):void 0;if(t&&!i)throw new Error(`Cannot map Windows path to WSL workDir: ${t}`);const o=[i?`cd ${v(i)}`:"",`exec ${[n.command,...n.args,...e].map(v).join(" ")}`].filter(Boolean).join(" && ");return{command:n.path,args:["-e","sh","-lc",o],cwd:void 0}}function O(n,e,t={}){const i=D(n,e,t.cwd);return k(i.command,i.args,{...t,cwd:i.cwd,windowsHide:t.windowsHide??!0,...c()==="win32"&&n.kind==="cmd-shim"?{windowsVerbatimArguments:!0}:{}})}function on(n,e,t={}){return O(n,e,t)}function T(n,e,t={}){const i=D(n,e,t.cwd);return C(i.command,i.args,{...t,cwd:i.cwd,windowsHide:t.windowsHide??!0,...c()==="win32"&&n.kind==="cmd-shim"?{windowsVerbatimArguments:!0}:{}})}function M(n){const e=[];let t="",i=!1,o=!1;for(const r of n){if(r==="'"&&!o){i=!i;continue}if(r==='"'&&!i){o=!o;continue}if(r===" "&&!i&&!o){t&&(e.push(t),t="");continue}t+=r}return t&&e.push(t),e}function q(n,e,t){const i=M(n),o=i[0];if(!o)throw new Error("Command string is empty");const r=i.slice(1);if(c()!=="win32")return{command:o,args:[...r,...e],cwd:t};const a=H(o);return a.kind==="cmd-shim"?{command:A(),args:["/d","/s","/c",`"${[a.path,...r,...e].map(B).join(" ")}"`],cwd:t}:S(a.path)?{command:W(),args:[a.path,...r,...e],cwd:t}:{command:a.path,args:[...r,...e],cwd:t}}function rn(n,e,t={}){const i=q(n,e,t.cwd),o=M(n),r=c()==="win32"&&o[0]?H(o[0]):null;return k(i.command,i.args,{...t,cwd:i.cwd,windowsHide:t.windowsHide??!0,env:{...t.env,PATH:P(t.env?.PATH??process.env.PATH,o[0])},...c()==="win32"&&r?.kind==="cmd-shim"?{windowsVerbatimArguments:!0}:{}})}function U(n,e="--version"){const t=T(n,[e],{encoding:"utf-8",stdio:["ignore","pipe","pipe"],timeout:5e3});return t.status!==0?void 0:`${t.stdout??""}
2
- ${t.stderr??""}`.trim().match(/\d+\.\d+[\w.-]*/)?.[0]}function sn(n,e){if(n!=="cursor")return U(e);const t=T(e,["about"],{encoding:"utf-8",stdio:["ignore","pipe","pipe"],timeout:5e3});return t.status!==0?void 0:`${t.stdout??""}
3
- ${t.stderr??""}`.match(/^\s*CLI Version\s+(\d+\.\d+(?:\.\d+)?[\w.-]*)\s*$/im)?.[1]}export{q as buildCommandStringLaunchSpec,D as buildLaunchSpec,Y as commandExists,sn as getBuiltinAgentVersion,U as getCommandVersion,c as getProcessPlatform,M as parseCommandString,X as resetCommandSpecCache,tn as resolveBuiltinCommand,nn as resolveCommandFileIdentity,en as resolveCommandFilePath,on as spawnAgentCommand,rn as spawnCommandString,O as spawnResolvedCommand,T as spawnResolvedCommandSync,z as windowsPathToWsl};
1
+ import{spawn as k,spawnSync as x}from"node:child_process";import u from"node:fs";import j from"node:crypto";import P from"node:os";import s from"node:path";const A={claude:[{command:"claude",args:[],display:"claude"}],codex:[{command:"codex",args:[],display:"codex"}],workbuddy:[{command:"codebuddy",args:[],display:"WorkBuddy"}],gemini:[{command:"gemini",args:[],display:"gemini"}],cursor:[{command:"agent",args:[],display:"agent"},{command:"cursor",args:["agent"],display:"cursor agent"}],openclaw:[],opencode:[{command:"opencode",args:[],display:"opencode"}],pi:[{command:"shennian",args:[],display:"shennian"}],"pi-coding-agent":[{command:"pi",args:[],display:"pi"}],manager:[{command:"shennian",args:["manager"],display:"shennian manager"}]},m=new Map,f=new Map,h=new Map,l=new Map;function Y(){m.clear(),f.clear(),h.clear(),l.clear()}function a(){return process.platform}function V(n){return n.split(/\r?\n/).map(e=>e.trim()).filter(Boolean)}function C(n){if(s.basename(n)!==n)return[n];const e=P.homedir();if(a()==="win32"){const o=s.win32,r=s.extname(n)?[n]:[n,`${n}.cmd`,`${n}.exe`,`${n}.bat`],d=process.env.APPDATA||o.join(e,"AppData","Roaming"),p=process.env.LOCALAPPDATA||o.join(e,"AppData","Local"),y=[o.join(e,".shennian","node"),o.join("C:\\","nvm4w","nodejs"),o.join(p,"npm-global"),o.join(d,"npm"),o.join(p,"pnpm"),o.join(e,"scoop","shims"),o.join("C:\\","Program Files","nodejs")].flatMap(w=>r.map(g=>o.join(w,g)));if(n==="codebuddy"){const w=[o.join(p,"Programs","WorkBuddy"),o.join(p,"WorkBuddy"),o.join("C:\\","Program Files","WorkBuddy")];for(const g of w)for(const N of["codebuddy.exe","codebuddy.cmd","codebuddy"])y.push(o.join(g,"resources","app.asar.unpacked","cli","bin",N))}return y}const i=[s.join(e,".npm-global","bin"),s.join(e,".local","bin"),s.join(e,".bun","bin"),"/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin"].map(o=>s.join(o,n));return n==="claude"&&a()==="darwin"&&i.push(...I(e)),n==="codebuddy"&&a()==="darwin"&&i.push("/Applications/WorkBuddy.app/Contents/Resources/app.asar.unpacked/cli/bin/codebuddy",s.join(e,"Applications","WorkBuddy.app","Contents","Resources","app.asar.unpacked","cli","bin","codebuddy")),i}function z(n=a(),e=P.homedir()){return n!=="darwin"?[]:["/Applications",s.join(e,"Applications")].flatMap(t=>["ChatGPT.app","Codex.app"].map(i=>s.join(t,i,"Contents","Resources","codex")))}function I(n){const e=[s.join(n,"Library","Application Support","Claude","claude-code")],t=[];for(const i of e){let o;try{o=u.readdirSync(i,{withFileTypes:!0}).filter(r=>r.isDirectory()).map(r=>r.name).sort((r,d)=>d.localeCompare(r,void 0,{numeric:!0}))}catch{continue}for(const r of o)t.push(s.join(i,r,"claude.app","Contents","MacOS","claude"))}return t}function $(n,e){const t=n?.split(s.delimiter).filter(Boolean)??[];if(a()==="win32"){if(e&&s.basename(e)!==e){const i=s.win32.dirname(e);t.includes(i)||t.unshift(i)}for(const i of C("shennian")){const o=s.win32.dirname(i);t.includes(o)||t.push(o)}return t.join(s.delimiter)}if(e&&s.basename(e)!==e){const i=s.dirname(e);t.includes(i)||t.unshift(i)}for(const i of C("shennian")){const o=s.dirname(i);t.includes(o)||t.push(o)}return t.join(s.delimiter)}function c(n){if(h.has(n))return h.get(n)??[];const e=a()==="win32",i=x(e?"where":"which",[n],{encoding:"utf-8",stdio:["ignore","pipe","pipe"],timeout:3e3,windowsHide:!0,env:{...process.env,PATH:e?process.env.PATH:$(process.env.PATH,n)}}),r=[...i.status===0?V(i.stdout??""):[]];for(const d of C(n))u.existsSync(d)&&!r.includes(d)&&r.push(d);return h.set(n,r),r}function S(){return process.env.ComSpec||"cmd.exe"}function W(n){const e=s.extname(n).toLowerCase();return e===".exe"||e===".com"}function b(n){const e=s.extname(n).toLowerCase();return e===".cmd"||e===".bat"}function B(n){const e=s.extname(n).toLowerCase();return e===".js"||e===".mjs"||e===".cjs"}function H(){return c("node.exe")[0]??c("node")[0]??"node"}function L(n){return`"${n.replace(/"/g,'""')}"`}function v(n){return`'${n.replace(/'/g,"'\\''")}'`}function O(n){if(!n)return;const e=n.replace(/\//g,"\\"),t=e.match(/^([A-Za-z]):\\(.*)$/);if(t){const[,i,o]=t,r=o.replace(/\\/g,"/");return`/mnt/${i.toLowerCase()}/${r}`}if(e.startsWith("\\\\wsl$\\"))return`/${e.replace(/^\\\\wsl\$\\[^\\]+\\?/,"").replace(/\\/g,"/")}`;if(n.startsWith("/"))return n}function D(n){const e=n.trim();if(!e)throw new Error("Command string is empty");if(/[\\/]/.test(e)||/^[A-Za-z]:/.test(e))return b(e)?{kind:"cmd-shim",path:e}:{kind:"direct",path:e};const i=c(e),o=i.find(W);if(o)return{kind:"direct",path:o};const r=i.find(b);return r?{kind:"cmd-shim",path:r}:{kind:"direct",path:e}}function T(n){if(l.has(n))return l.get(n)??!1;const e=c("wsl.exe")[0]??c("wsl")[0];if(!e)return l.set(n,!1),!1;const i=x(e,["-e","sh","-lc",`command -v ${v(n)} >/dev/null 2>&1`],{stdio:"ignore",timeout:5e3,windowsHide:!0}).status===0;return l.set(n,i),i}function nn(n){if(m.has(n))return m.get(n)??!1;const e=c(n).length>0||a()==="win32"&&T(n);return m.set(n,e),e}function en(n){const e=c(n)[0];if(!e)return null;try{const t=u.realpathSync(e),i=u.statSync(t,{bigint:!0}),o=j.createHash("sha256").update(t).digest("hex"),r=j.createHash("sha256").update(`${i.dev}:${i.ino}:${i.size}:${i.mtimeNs}`).digest("hex");return{pathHash:o,fingerprint:r}}catch{return null}}function tn(n){return c(n)[0]??null}function q(n){const e=c(n.command),t=e.find(W);if(t)return{...n,kind:"native",path:t};const i=e.find(b);if(i)return{...n,kind:"cmd-shim",path:i};if(T(n.command)){const o=c("wsl.exe")[0]??c("wsl")[0];if(o)return{...n,kind:"wsl-bridge",path:o}}return null}function on(n){if(f.has(n))return f.get(n)??null;const e=n==="codex"?z().find(i=>u.existsSync(i)?!!R({command:i,args:[],display:"Codex Desktop",kind:"native",path:i}):!1):void 0,t=e?{...A.codex[0],kind:"native",path:e}:A[n].map(i=>{if(a()==="win32")return q(i);const o=c(i.command)[0];return o?{...i,kind:"native",path:o}:null}).find(Boolean)??null;return f.set(n,t),t}function M(n,e,t){if(n.kind==="native")return a()==="win32"&&B(n.path)?{command:H(),args:[n.path,...n.args,...e],cwd:t}:{command:n.path,args:[...n.args,...e],cwd:t};if(n.kind==="cmd-shim"){const r=[n.path,...n.args,...e].map(L).join(" ");return{command:S(),args:["/d","/s","/c",`"${r}"`],cwd:t}}const i=t?O(t):void 0;if(t&&!i)throw new Error(`Cannot map Windows path to WSL workDir: ${t}`);const o=[i?`cd ${v(i)}`:"",`exec ${[n.command,...n.args,...e].map(v).join(" ")}`].filter(Boolean).join(" && ");return{command:n.path,args:["-e","sh","-lc",o],cwd:void 0}}function U(n,e,t={}){const i=M(n,e,t.cwd);return k(i.command,i.args,{...t,cwd:i.cwd,windowsHide:t.windowsHide??!0,...a()==="win32"&&n.kind==="cmd-shim"?{windowsVerbatimArguments:!0}:{}})}function rn(n,e,t={}){return U(n,e,t)}function F(n,e,t={}){const i=M(n,e,t.cwd);return x(i.command,i.args,{...t,cwd:i.cwd,windowsHide:t.windowsHide??!0,...a()==="win32"&&n.kind==="cmd-shim"?{windowsVerbatimArguments:!0}:{}})}function E(n){const e=[];let t="",i=!1,o=!1;for(const r of n){if(r==="'"&&!o){i=!i;continue}if(r==='"'&&!i){o=!o;continue}if(r===" "&&!i&&!o){t&&(e.push(t),t="");continue}t+=r}return t&&e.push(t),e}function Z(n,e,t){const i=E(n),o=i[0];if(!o)throw new Error("Command string is empty");const r=i.slice(1);if(a()!=="win32")return{command:o,args:[...r,...e],cwd:t};const d=D(o);return d.kind==="cmd-shim"?{command:S(),args:["/d","/s","/c",`"${[d.path,...r,...e].map(L).join(" ")}"`],cwd:t}:B(d.path)?{command:H(),args:[d.path,...r,...e],cwd:t}:{command:d.path,args:[...r,...e],cwd:t}}function sn(n,e,t={}){const i=Z(n,e,t.cwd),o=E(n),r=a()==="win32"&&o[0]?D(o[0]):null;return k(i.command,i.args,{...t,cwd:i.cwd,windowsHide:t.windowsHide??!0,env:{...t.env,PATH:$(t.env?.PATH??process.env.PATH,o[0])},...a()==="win32"&&r?.kind==="cmd-shim"?{windowsVerbatimArguments:!0}:{}})}function R(n,e="--version"){const t=F(n,[e],{encoding:"utf-8",stdio:["ignore","pipe","pipe"],timeout:5e3});return t.status!==0?void 0:`${t.stdout??""}
2
+ ${t.stderr??""}`.trim().match(/\d+\.\d+[\w.-]*/)?.[0]}function an(n,e){if(n!=="cursor")return R(e);const t=F(e,["about"],{encoding:"utf-8",stdio:["ignore","pipe","pipe"],timeout:5e3});return t.status!==0?void 0:`${t.stdout??""}
3
+ ${t.stderr??""}`.match(/^\s*CLI Version\s+(\d+\.\d+(?:\.\d+)?[\w.-]*)\s*$/im)?.[1]}export{Z as buildCommandStringLaunchSpec,M as buildLaunchSpec,nn as commandExists,an as getBuiltinAgentVersion,z as getCodexDesktopCommandCandidates,R as getCommandVersion,a as getProcessPlatform,E as parseCommandString,Y as resetCommandSpecCache,on as resolveBuiltinCommand,en as resolveCommandFileIdentity,tn as resolveCommandFilePath,rn as spawnAgentCommand,sn as spawnCommandString,U as spawnResolvedCommand,F as spawnResolvedCommandSync,O as windowsPathToWsl};
@@ -1 +1 @@
1
- import e from"node:fs";import o from"node:path";import{CACHE_TTL_MS as f,CACHE_VERSION as n,MODEL_CACHE_PATH as t}from"./types.js";function a(){e.mkdirSync(o.dirname(t),{recursive:!0})}function C(){try{const r=JSON.parse(e.readFileSync(t,"utf-8"));if(r.version===n&&r.agents&&typeof r.agents=="object")return r}catch{}return{version:n,agents:{}}}function h(r){try{a(),e.writeFileSync(t,JSON.stringify(r,null,2))}catch{}}function m(r,s,i){return!r||r.version!==s||i&&r.sourceRevision!==i?!1:Date.now()-r.refreshedAt<f}export{m as isCacheFresh,C as readCache,h as writeCache};
1
+ import t from"node:fs";import c from"node:path";import{CACHE_TTL_MS as a,CACHE_VERSION as i,MODEL_CACHE_PATH as n}from"./types.js";function f(){t.mkdirSync(c.dirname(n),{recursive:!0})}function C(){try{const e=JSON.parse(t.readFileSync(n,"utf-8"));if(e.version===i&&e.agents&&typeof e.agents=="object")return e}catch{}return{version:i,agents:{}}}function d(e){try{f(),t.writeFileSync(n,JSON.stringify(e,null,2))}catch{}}function l(e,o,r){if(!e||e.version!==o||r&&e.sourceRevision!==r)return!1;const s=r?.startsWith("opencode-connected-")?900*1e3:a;return Date.now()-e.refreshedAt<s}export{l as isCacheFresh,C as readCache,d as writeCache};
@@ -1,3 +1,3 @@
1
- import{createInterface as b}from"node:readline";import{resolveBuiltinCommand as l,spawnResolvedCommand as M}from"../command-spec.js";import{fallbackClaudeAliasModels as k,discoverClaudeAliasModelsFromEnv as E,fallbackCodexModels as R,fallbackWorkBuddyModels as x,fallbackGeminiModels as _,parseCodexAppServerModels as O,parseCursorModels as A,parseOpenCodeModels as I}from"./parsers.js";import{runResolvedCommand as m}from"./runner.js";import{DISCOVERY_WORKDIR as w}from"./types.js";import{buildAgentProcessEnv as C,readLatestUserEnv as S}from"../../agent-env.js";import{CODEX_APP_SERVER_CLIENT_INFO as T}from"../codex-utils.js";import{PiRpcClient as P}from"../pi-rpc-client.js";import{loadConfig as $}from"../../config/index.js";function v(r,e,t,s,n,i){return r.stdin?new Promise((o,a)=>{const c=setTimeout(()=>{e.delete(t),a(new Error(`codex app-server request timed out: ${s}`))},i);e.set(t,{resolve:o,reject:a,timer:c}),r.stdin.write(`${JSON.stringify({id:t,method:s,params:n})}
2
- `,p=>{p&&(clearTimeout(c),e.delete(t),a(p))})}):Promise.reject(new Error("codex app-server stdin unavailable"))}async function D(r){const e=M(r,["app-server","--listen","stdio://"],{cwd:w,stdio:["pipe","pipe","pipe"],env:C({NO_COLOR:"1"})}),t=new Map;let s=1;b({input:e.stdout}).on("line",i=>{if(!i.trim())return;let o;try{o=JSON.parse(i)}catch{return}if(o.id==null)return;const a=t.get(o.id);a&&(clearTimeout(a.timer),t.delete(o.id),o.error?a.reject(new Error(o.error.message||`codex app-server error ${o.error.code??""}`.trim())):a.resolve(o.result))});try{await v(e,t,s++,"initialize",{clientInfo:T,capabilities:{experimentalApi:!0}},1e4);const[i,o]=await Promise.all([v(e,t,s++,"model/list",{},15e3),v(e,t,s++,"config/read",{},15e3).catch(()=>null)]),a=typeof o=="object"&&o!==null&&"config"in o?o.config:void 0;return O({...typeof i=="object"&&i!==null?i:{},config:a})}finally{for(const[i,o]of t)clearTimeout(o.timer),o.reject(new Error("codex app-server stopped")),t.delete(i);e.kill("SIGTERM"),setTimeout(()=>e.kill("SIGKILL"),1e3).unref()}}async function L(){const r=l("cursor");if(!r)return[];const e=await m(r,["--list-models"]);return A(e.stdout)}async function q(){const r=l("opencode");if(!r)return[];const e=await m(r,["models"]);return I(e.stdout)}async function j(){const r={id:"shennian-dashscope/deepseek-v4-flash-0731",name:"DeepSeek V4 Flash",provider:"shennian-dashscope",isDefault:!0,supportedReasoningEfforts:["low","high","max"].map(n=>({id:n,name:n})),defaultReasoningEffort:"high"},e=l("pi-coding-agent");if(!e)return[];if($().machineToken?.trim())return[r];const t=M(e,["--mode","rpc","--no-session","--offline","--no-extensions","--no-skills","--no-prompt-templates","--no-context-files","--no-tools"],{cwd:w,stdio:["pipe","pipe","pipe"],env:C({NO_COLOR:"1"})}),s=new P(t,{requestTimeoutMs:1e4});try{const[n,i]=await Promise.all([s.request("get_available_models"),s.request("get_state")]),o=n.data&&typeof n.data=="object"?n.data:{},a=i.data&&typeof i.data=="object"?i.data:{},c=typeof a.model?.id=="string"&&typeof a.model.provider=="string"?`${a.model.provider}/${a.model.id}`:null;return Array.isArray(o.models)?o.models.flatMap(f=>{if(!f||typeof f!="object")return[];const d=f;if(typeof d.id!="string"||typeof d.provider!="string")return[];const g=`${d.provider}/${d.id}`,h=d.reasoning===!0?["off","minimal","low","medium","high","xhigh","max"].map(y=>({id:y,name:y})):void 0;return[{id:g,name:typeof d.name=="string"&&d.name.trim()?d.name:d.id,provider:d.provider,isDefault:g===c,...h?{supportedReasoningEfforts:h,defaultReasoningEffort:"medium"}:{}}]}):[]}catch{return[]}finally{s.close(),t.kill("SIGTERM"),setTimeout(()=>t.kill("SIGKILL"),1e3).unref()}}async function G(){const r=l("claude");if(!r)return[];const e=S(),t=E(e);if(t.length>0)return t;const s=k(e),n=await m(r,["--help"],3e3).catch(()=>null);return!n||/\bfable\b/i.test(`${n.stdout}
3
- ${n.stderr}`)?s:s.filter(i=>i.id!=="fable")}async function N(){const r=l("codex");if(!r)return[];const e=await D(r).catch(()=>[]);return e.length>0?e:R()}async function B(){return l("gemini")?_():[]}const u=[{id:"qwen3.6-plus",name:"Qwen 3.6 Plus",provider:"dashscope",isDefault:!0}],F=[{id:"codex",name:"Codex",provider:"shennian",isDefault:!0},{id:"claude",name:"Claude Code",provider:"shennian"}];async function V(r){if(!r.serverUrl||!r.authToken)return u;try{const e=await fetch(`${r.serverUrl.replace(/\/$/,"")}/api/models`,{headers:{Authorization:`Bearer ${r.authToken}`}});if(!e.ok)return u;const t=await e.json(),s=(t.models??[]).map(n=>({id:n.id,name:n.name?.trim()||n.id,provider:n.provider,isDefault:n.id===t.default}));return s.length>0?s:u}catch{return u}}async function K(r,e){switch(r){case"claude":return G();case"codex":return N();case"workbuddy":return l("workbuddy")?x():[];case"gemini":return B();case"cursor":return L();case"openclaw":return[];case"opencode":return q();case"pi":return V(e);case"pi-coding-agent":return j();case"manager":return F}}async function ee(r,e){return r.type.startsWith("custom:")?r.models??[]:K(r.type,e)}export{ee as discoverModelsForAgent};
1
+ import{createInterface as b}from"node:readline";import{resolveBuiltinCommand as l,spawnResolvedCommand as M}from"../command-spec.js";import{fallbackClaudeAliasModels as k,discoverClaudeAliasModelsFromEnv as E,fallbackCodexModels as R,fallbackWorkBuddyModels as x,fallbackGeminiModels as _,parseCodexAppServerModels as O,parseCursorModels as A,parseOpenCodeModels as I}from"./parsers.js";import{runResolvedCommand as m}from"./runner.js";import{DISCOVERY_WORKDIR as w}from"./types.js";import{buildAgentProcessEnv as C,readLatestUserEnv as S}from"../../agent-env.js";import{CODEX_APP_SERVER_CLIENT_INFO as T}from"../codex-utils.js";import{PiRpcClient as P}from"../pi-rpc-client.js";import{loadConfig as $}from"../../config/index.js";import{discoverOpenCodeModelsViaApi as D}from"./opencode-api.js";function v(r,e,t,s,n,i){return r.stdin?new Promise((o,a)=>{const c=setTimeout(()=>{e.delete(t),a(new Error(`codex app-server request timed out: ${s}`))},i);e.set(t,{resolve:o,reject:a,timer:c}),r.stdin.write(`${JSON.stringify({id:t,method:s,params:n})}
2
+ `,p=>{p&&(clearTimeout(c),e.delete(t),a(p))})}):Promise.reject(new Error("codex app-server stdin unavailable"))}async function L(r){const e=M(r,["app-server","--listen","stdio://"],{cwd:w,stdio:["pipe","pipe","pipe"],env:C({NO_COLOR:"1"})}),t=new Map;let s=1;b({input:e.stdout}).on("line",i=>{if(!i.trim())return;let o;try{o=JSON.parse(i)}catch{return}if(o.id==null)return;const a=t.get(o.id);a&&(clearTimeout(a.timer),t.delete(o.id),o.error?a.reject(new Error(o.error.message||`codex app-server error ${o.error.code??""}`.trim())):a.resolve(o.result))});try{await v(e,t,s++,"initialize",{clientInfo:T,capabilities:{experimentalApi:!0}},1e4);const[i,o]=await Promise.all([v(e,t,s++,"model/list",{},15e3),v(e,t,s++,"config/read",{},15e3).catch(()=>null)]),a=typeof o=="object"&&o!==null&&"config"in o?o.config:void 0;return O({...typeof i=="object"&&i!==null?i:{},config:a})}finally{for(const[i,o]of t)clearTimeout(o.timer),o.reject(new Error("codex app-server stopped")),t.delete(i);e.kill("SIGTERM"),setTimeout(()=>e.kill("SIGKILL"),1e3).unref()}}async function q(){const r=l("cursor");if(!r)return[];const e=await m(r,["--list-models"]);return A(e.stdout)}async function j(){const r=l("opencode");if(!r)return[];const e=await D().catch(()=>[]);if(e.length>0)return e;const t=await m(r,["models"]);return I(t.stdout)}async function G(){const r={id:"shennian-dashscope/deepseek-v4-flash-0731",name:"DeepSeek V4 Flash",provider:"shennian-dashscope",isDefault:!0,supportedReasoningEfforts:["low","high","max"].map(n=>({id:n,name:n})),defaultReasoningEffort:"high"},e=l("pi-coding-agent");if(!e)return[];if($().machineToken?.trim())return[r];const t=M(e,["--mode","rpc","--no-session","--offline","--no-extensions","--no-skills","--no-prompt-templates","--no-context-files","--no-tools"],{cwd:w,stdio:["pipe","pipe","pipe"],env:C({NO_COLOR:"1"})}),s=new P(t,{requestTimeoutMs:1e4});try{const[n,i]=await Promise.all([s.request("get_available_models"),s.request("get_state")]),o=n.data&&typeof n.data=="object"?n.data:{},a=i.data&&typeof i.data=="object"?i.data:{},c=typeof a.model?.id=="string"&&typeof a.model.provider=="string"?`${a.model.provider}/${a.model.id}`:null;return Array.isArray(o.models)?o.models.flatMap(f=>{if(!f||typeof f!="object")return[];const d=f;if(typeof d.id!="string"||typeof d.provider!="string")return[];const h=`${d.provider}/${d.id}`,g=d.reasoning===!0?["off","minimal","low","medium","high","xhigh","max"].map(y=>({id:y,name:y})):void 0;return[{id:h,name:typeof d.name=="string"&&d.name.trim()?d.name:d.id,provider:d.provider,isDefault:h===c,...g?{supportedReasoningEfforts:g,defaultReasoningEffort:"medium"}:{}}]}):[]}catch{return[]}finally{s.close(),t.kill("SIGTERM"),setTimeout(()=>t.kill("SIGKILL"),1e3).unref()}}async function N(){const r=l("claude");if(!r)return[];const e=S(),t=E(e);if(t.length>0)return t;const s=k(e),n=await m(r,["--help"],3e3).catch(()=>null);return!n||/\bfable\b/i.test(`${n.stdout}
3
+ ${n.stderr}`)?s:s.filter(i=>i.id!=="fable")}async function V(){const r=l("codex");if(!r)return[];const e=await L(r).catch(()=>[]);return e.length>0?e:R()}async function B(){return l("gemini")?_():[]}const u=[{id:"qwen3.6-plus",name:"Qwen 3.6 Plus",provider:"dashscope",isDefault:!0}],F=[{id:"codex",name:"Codex",provider:"shennian",isDefault:!0},{id:"claude",name:"Claude Code",provider:"shennian"}];async function K(r){if(!r.serverUrl||!r.authToken)return u;try{const e=await fetch(`${r.serverUrl.replace(/\/$/,"")}/api/models`,{headers:{Authorization:`Bearer ${r.authToken}`}});if(!e.ok)return u;const t=await e.json(),s=(t.models??[]).map(n=>({id:n.id,name:n.name?.trim()||n.id,provider:n.provider,isDefault:n.id===t.default}));return s.length>0?s:u}catch{return u}}async function U(r,e){switch(r){case"claude":return N();case"codex":return V();case"workbuddy":return l("workbuddy")?x():[];case"gemini":return B();case"cursor":return q();case"openclaw":return[];case"opencode":return j();case"pi":return K(e);case"pi-coding-agent":return G();case"manager":return F}}async function te(r,e){return r.type.startsWith("custom:")?r.models??[]:U(r.type,e)}export{te as discoverModelsForAgent};
@@ -0,0 +1,2 @@
1
+ import type { ModelInfo } from '@shennian/wire';
2
+ export declare function discoverOpenCodeModelsViaApi(): Promise<ModelInfo[]>;
@@ -0,0 +1 @@
1
+ import{randomBytes as m}from"node:crypto";import{createServer as u}from"node:net";import{resolveBuiltinCommand as f,spawnResolvedCommand as w}from"../command-spec.js";import{buildAgentProcessEnv as v}from"../../agent-env.js";import{DISCOVERY_WORKDIR as g}from"./types.js";import{parseOpenCodeProviderModels as h}from"./parsers.js";async function O(){return new Promise((s,r)=>{const o=u();o.once("error",r),o.listen(0,"127.0.0.1",()=>{const e=o.address(),t=e&&typeof e!="string"?e.port:0;o.close(()=>t?s(t):r(new Error("OpenCode discovery port unavailable")))})})}async function _(){const s=f("opencode");if(!s)return[];const r=await O(),o=m(24).toString("hex"),e=w(s,["serve","--hostname","127.0.0.1","--port",String(r)],{cwd:g,stdio:["ignore","pipe","pipe"],env:v({NO_COLOR:"1",OPENCODE_SERVER_PASSWORD:o})});e.stdout?.resume(),e.stderr?.resume();const t=`Basic ${Buffer.from(`opencode:${o}`).toString("base64")}`,a=`http://127.0.0.1:${r}`;let i=!1;e.once("close",()=>{i=!0}),e.once("error",()=>{i=!0});try{const d=Date.now()+1e4;for(;Date.now()<d&&!i;){try{const n=new AbortController,p=setTimeout(()=>n.abort(),2e3);try{const[c,l]=await Promise.all([fetch(`${a}/provider`,{headers:{Authorization:t},signal:n.signal}),fetch(`${a}/config`,{headers:{Authorization:t},signal:n.signal})]);if(c.ok&&l.ok)return h(await c.json(),await l.json())}finally{clearTimeout(p)}}catch{}await new Promise(n=>setTimeout(n,200))}return[]}finally{e.kill("SIGTERM"),setTimeout(()=>e.kill("SIGKILL"),1e3).unref()}}export{_ as discoverOpenCodeModelsViaApi};
@@ -5,6 +5,7 @@ export declare function fallbackWorkBuddyModels(): ModelInfo[];
5
5
  export declare function parseCursorModels(raw: string): ModelInfo[];
6
6
  export declare function parseOpenClawModels(raw: string): ModelInfo[];
7
7
  export declare function parseOpenCodeModels(raw: string): ModelInfo[];
8
+ export declare function parseOpenCodeProviderModels(providerResponse: unknown, configResponse: unknown): ModelInfo[];
8
9
  export declare function parseClaudeModels(raw: string): ModelInfo[];
9
10
  export type EnvLike = Record<string, string | undefined>;
10
11
  export declare function readEnvValue(env: EnvLike, key: string): string | null;
@@ -1,4 +1,4 @@
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 x(e){return e.split("-").map(n=>n==="gpt"?"GPT":n==="codex"?"Codex":/^\d/.test(n)?n:E(n)).join("-")}function C(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 M(e){const n={...e};return e.supportedReasoningEfforts&&(n.supportedReasoningEfforts=e.supportedReasoningEfforts.map(t=>({...t}))),e.additionalSpeedTiers&&(n.additionalSpeedTiers=[...e.additionalSpeedTiers]),n}function k(e,n){const t=n??e.find(i=>i.isDefault)?.id,o=d([...e.map(M),...O.map(i=>M(i))]);return t?o.map(i=>({...i,isDefault:i.id===t})):o}function N(){return O.map((e,n)=>({...M(e),...n===0?{isDefault:!0}:{}}))}function H(){return[{id:"auto",name:"Auto",provider:"workbuddy",isDefault:!0,supportedReasoningEfforts:["minimal","low","medium","high","xhigh","max"].map(e=>({id:e,name:C(e)})),defaultReasoningEffort:"medium"}]}function R(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()||R(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+\.Fable.*?Fable\s*([\d.]+)/i,"fable","Fable","Most capable for the hardest, longest-running tasks"],[/\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"}],F=[{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:F,defaultReasoningEffort:"medium"}}function b(e,n){return e[n]?.trim()||null}function A(e,n){const t=b(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=b(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:b(e,"CLAUDE_CODE_EFFORT_LEVEL")??"max"}:h(r)});return d(t)}function V(e=process.env){return D(e)}function G(e,n=process.env){return e.map(t=>{if(!["default","sonnet","opus","haiku"].includes(t.id))return t;const o=t.id,i=b(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:G([{id:"default",name:"Default (recommended)",description:"Recommended model for your account",provider:"anthropic",isDefault:!0},{id:"sonnet",name:"Sonnet",description:"Latest Sonnet \xB7 everyday coding",provider:"anthropic"},{id:"fable",name:"Fable",description:"Most capable for the hardest, longest-running tasks",provider:"anthropic"},{id:"opus",name:"Opus",description:"Latest Opus \xB7 complex reasoning",provider:"anthropic"},{id:"haiku",name:"Haiku",description:"Fast and efficient \xB7 simple tasks",provider:"anthropic"},{id:"best",name:"Best",description:"Most capable available model",provider:"anthropic"},{id:"opus[1m]",name:"Opus (1M context)",description:"Latest Opus \xB7 long sessions",provider:"anthropic"},{id:"sonnet[1m]",name:"Sonnet (1M context)",description:"Latest Sonnet \xB7 long sessions",provider:"anthropic"},{id:"opusplan",name:"Opus Plan",description:"Opus for planning \xB7 Sonnet for execution",provider:"anthropic"}],e).map(t=>t.id==="haiku"?t:h(t))}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:x(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:C(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||x(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:x(t),provider:"openai",isDefault:!0,defaultReasoningEffort:o}),k(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{G as applyClaudeModelEnvOverrides,V as discoverClaudeAliasModelsFromEnv,q as fallbackClaudeAliasModels,N as fallbackCodexModels,X as fallbackGeminiModels,H 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,b as readEnvValue,g as stripAnsi};
1
+ function b(e){return e.replace(/\u001b\[[0-9;?]*[a-zA-Z]/g,"").replace(/\u001b\][^\u0007]*\u0007/g,"").replace(/[\u0000-\u0008\u000b-\u001f\u007f]/g,"")}function m(e){const t=new Set,n=[];for(const o of e)!o.id||t.has(o.id)||(t.add(o.id),n.push(o));return n}function y(e){return e&&e[0].toUpperCase()+e.slice(1)}function x(e){return e.split("-").map(t=>t==="gpt"?"GPT":t==="codex"?"Codex":/^\d/.test(t)?t:y(t)).join("-")}function O(e){switch(e){case"low":return"Low";case"medium":return"Medium";case"high":return"High";case"xhigh":return"Extra High";default:return y(e)}}const C=[{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 M(e){const t={...e};return e.supportedReasoningEfforts&&(t.supportedReasoningEfforts=e.supportedReasoningEfforts.map(n=>({...n}))),e.additionalSpeedTiers&&(t.additionalSpeedTiers=[...e.additionalSpeedTiers]),t}function k(e,t){const n=t??e.find(i=>i.isDefault)?.id,o=m([...e.map(M),...C.map(i=>M(i))]);return n?o.map(i=>({...i,isDefault:i.id===n})):o}function G(){return C.map((e,t)=>({...M(e),...t===0?{isDefault:!0}:{}}))}function I(){return[{id:"auto",name:"Auto",provider:"workbuddy",isDefault:!0,supportedReasoningEfforts:["minimal","low","medium","high","xhigh","max"].map(e=>({id:e,name:O(e)})),defaultReasoningEffort:"medium"}]}function w(e){return e.split("-").map(t=>/^\d/.test(t)?t:y(t)).join(" ")}function _(e,t,n=!1){const o=t.toLowerCase().replace(/\s+/g,"-");return`gemini-${e}-${o}${n?"-preview":""}`}function N(e){const t=[],n=b(e);for(const o of n.split(`
2
+ `)){const i=o.trim().match(/^(\S+)\s+-\s+(.+?)(?:\s+\(([^)]+)\))?$/);if(!i)continue;const[,s,r,d]=i,l=d?.split(",").map(u=>u.trim().toLowerCase())??[];t.push({id:s,name:r.trim()||w(s),description:d?.trim(),isDefault:l.includes("default")||l.includes("current")})}return m(t)}function H(e){try{const n=(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 m(n)}catch{return[]}}function U(e){const t=b(e).split(`
3
+ `).map(n=>n.trim()).filter(Boolean).filter(n=>!n.includes(" ")).map(n=>({id:n,name:n,provider:n.includes("/")?n.split("/")[0]:void 0}));return m(t)}function B(e,t){if(!e||typeof e!="object")return[];const n=e;if(!Array.isArray(n.all)||!Array.isArray(n.connected))return[];const o=new Set(n.connected.filter(u=>typeof u=="string")),i=t&&typeof t=="object"?t:{},s=typeof i.model=="string"?i.model:"",r=i.provider&&typeof i.provider=="object"?i.provider:{},d=new Set;for(const[u,a]of Object.entries(r)){if(!a||typeof a!="object")continue;const p=a.models;if(!(!p||typeof p!="object"))for(const f of Object.keys(p))d.add(`${u}/${f}`)}const l=[];for(const u of n.all){if(!u||typeof u!="object")continue;const a=u;if(!(typeof a.id!="string"||!o.has(a.id))&&!(!a.models||typeof a.models!="object"))for(const[p,f]of Object.entries(a.models)){if(!f||typeof f!="object")continue;const c=f;if(c.status==="deprecated"||c.status==="unavailable"||c.capabilities?.input?.text===!1||c.capabilities?.output?.text===!1||c.capabilities?.toolcall===!1)continue;const g=typeof c.id=="string"&&c.id?c.id:p,h=`${a.id}/${g}`;l.push({id:h,name:typeof c.name=="string"&&c.name.trim()?c.name:h,provider:a.id,...h===s?{isDefault:!0}:{}})}}return m(l).sort((u,a)=>{const p=f=>f.id===s?0:d.has(f.id)?1:f.provider&&Object.hasOwn(r,f.provider)?2:3;return p(u)-p(a)||u.id.localeCompare(a.id)})}function V(e){const t=b(e).replace(/\s+/g," "),n=[[/\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+\.Fable.*?Fable\s*([\d.]+)/i,"fable","Fable","Most capable for the hardest, longest-running tasks"],[/\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[d,l,u,a]of n){const p=t.match(d);p&&o.push(v({id:l,name:u,description:a?`${a} \xB7 v${p[1]}`:`v${p[1]}`,provider:"anthropic",isDefault:l==="default"}))}if(o.length>0)return m(o);const i=[],s=t.match(/currently\s*(Sonnet|Opus|Haiku)\s*([34](?:\.\d)?)/i),r={sonnet:"sonnet",opus:"opus",haiku:"haiku"};for(const d of t.matchAll(/\b(Sonnet|Opus|Haiku)\s*([34](?:\.\d)?)\b/gi)){const l=(d[1]??"").toLowerCase(),u=r[l];if(!u)continue;const a=d[2]??"",p=s&&s[1]?.toLowerCase()===l&&s[2]===a;i.push(v({id:u,name:`${y(l)} ${a}`,provider:"anthropic",isDefault:!!p}))}return m(i)}function R(e,t){const n=Math.max(e.length,t.length);for(let o=0;o<n;o++){const i=e[o]??-1,s=t[o]??-1;if(i!==s)return i-s}return 0}function T(e,t){const n=e.match(new RegExp(`^claude-${t}-([0-9]+(?:-[0-9]+)*)$`,"i"));if(!n?.[1])return null;const o=n[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 A={default:"Default (recommended)",sonnet:"Sonnet",opus:"Opus",haiku:"Haiku"},S={default:"ANTHROPIC_MODEL",sonnet:"ANTHROPIC_DEFAULT_SONNET_MODEL",opus:"ANTHROPIC_DEFAULT_OPUS_MODEL",haiku:"ANTHROPIC_DEFAULT_HAIKU_MODEL"},P=[{id:"max",name:"Max"}],j=[{id:"low",name:"Low"},{id:"medium",name:"Medium"},{id:"high",name:"High"},{id:"xhigh",name:"Extra High"},{id:"max",name:"Max"}];function v(e){return{...e,supportedReasoningEfforts:j,defaultReasoningEffort:"medium"}}function E(e,t){return e[t]?.trim()||null}function D(e,t){const n=E(t,"ANTHROPIC_BASE_URL")?.toLowerCase()??"";return n.includes("deepseek.com")||e.toLowerCase().startsWith("deepseek-")?"deepseek":n?"custom":"anthropic"}function L(e){const t=new Set;for(const o of Object.values(S)){const i=E(e,o);i&&t.add(i)}const n=Array.from(t).map((o,i)=>{const s=D(o,e),r={id:o,name:o,provider:s,isDefault:i===0};return s==="deepseek"?{...r,supportedReasoningEfforts:P,defaultReasoningEffort:E(e,"CLAUDE_CODE_EFFORT_LEVEL")??"max"}:v(r)});return m(n)}function z(e=process.env){return L(e)}function F(e,t=process.env){return e.map(n=>{if(!["default","sonnet","opus","haiku"].includes(n.id))return n;const o=n.id,i=E(t,S[o]);if(!i)return n;const r=`Claude Code alias: ${A[o]}`;return{...n,name:i,description:n.description?`${r} \xB7 ${n.description}`:r,provider:D(i,t)}})}function K(e){const t=b(e),n=new Map;for(const i of["sonnet","opus","haiku"])for(const s of t.matchAll(new RegExp(`\\bclaude-${i}-[0-9.-]+\\b`,"gi"))){const r=s[0].trim().toLowerCase().replace(/\./g,"-").replace(/-+$/g,""),d=T(r,i);if(!d)continue;const l=n.get(i);(!l||R(l,d)<0)&&n.set(i,d)}const o=[];for(const i of["default","sonnet","opus","haiku"]){if(!new RegExp(`\\b${i}\\b`,"i").test(t))continue;const s=(i==="default"?n.get("sonnet"):n.get(i))??null;o.push(v({id:i,name:A[i],description:$(s),provider:"anthropic",isDefault:i==="default"}))}return m(o)}function q(e=process.env){const t=L(e);return t.length>0?t:F([{id:"default",name:"Default (recommended)",description:"Recommended model for your account",provider:"anthropic",isDefault:!0},{id:"sonnet",name:"Sonnet",description:"Latest Sonnet \xB7 everyday coding",provider:"anthropic"},{id:"fable",name:"Fable",description:"Most capable for the hardest, longest-running tasks",provider:"anthropic"},{id:"opus",name:"Opus",description:"Latest Opus \xB7 complex reasoning",provider:"anthropic"},{id:"haiku",name:"Haiku",description:"Fast and efficient \xB7 simple tasks",provider:"anthropic"},{id:"best",name:"Best",description:"Most capable available model",provider:"anthropic"},{id:"opus[1m]",name:"Opus (1M context)",description:"Latest Opus \xB7 long sessions",provider:"anthropic"},{id:"sonnet[1m]",name:"Sonnet (1M context)",description:"Latest Sonnet \xB7 long sessions",provider:"anthropic"},{id:"opusplan",name:"Opus Plan",description:"Opus for planning \xB7 Sonnet for execution",provider:"anthropic"}],e).map(n=>n.id==="haiku"?n:v(n))}function W(e){const t=b(e),n=[];for(const o of t.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;n.push({id:s,name:x(s),description:r,provider:"openai",isDefault:/\bcurrent\b/i.test(o)||/\bselected\b/i.test(o)})}return m(n)}function J(e){const t=typeof e=="object"&&e!==null?e:{},n=typeof t.config?.model=="string"?t.config.model:void 0,o=typeof t.config?.model_reasoning_effort=="string"?t.config.model_reasoning_effort:void 0,i=[];for(const s of t.data??[]){if(typeof s!="object"||s===null)continue;const r=s,d=typeof r.id=="string"?r.id:typeof r.model=="string"?r.model:"";if(!d)continue;const l=typeof r.displayName=="string"?r.displayName:typeof r.name=="string"?r.name:void 0,u=typeof r.description=="string"?r.description:void 0,a=typeof r.defaultReasoningEffort=="string"?r.defaultReasoningEffort:void 0,p=Array.isArray(r.supportedReasoningEfforts)?r.supportedReasoningEfforts.map(c=>{if(typeof c!="object"||c===null)return null;const g=c,h=typeof g.reasoningEffort=="string"?g.reasoningEffort:typeof g.id=="string"?g.id:"";return h?{id:h,name:O(h),description:typeof g.description=="string"?g.description:void 0}:null}).filter(c=>c!=null):void 0,f=Array.isArray(r.additionalSpeedTiers)?r.additionalSpeedTiers.filter(c=>typeof c=="string"):void 0;i.push({id:d,name:l||x(d),description:u,provider:"openai",isDefault:n?n===d:r.isDefault===!0,supportedReasoningEfforts:p,defaultReasoningEffort:a,additionalSpeedTiers:f})}return n&&!i.some(s=>s.id===n)&&i.unshift({id:n,name:x(n),provider:"openai",isDefault:!0,defaultReasoningEffort:o}),k(m(i),n)}function X(e){const t=b(e),n=[];for(const o of t.matchAll(/\b(?:auto-)?gemini-[a-z0-9.-]+\b/gi)){const i=o[0].trim();n.push({id:i,name:i,provider:"google",isDefault:/\bcurrent\b/i.test(t)&&t.includes(i)})}for(const o of t.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],d=_(i,s,r);n.push({id:d,name:`Gemini ${i} ${s.replace(/-/g," ")}`.trim(),provider:"google",isDefault:/\bcurrent\b/i.test(t)&&t.includes(o[0]??"")})}for(const o of t.matchAll(/\bAuto\s*Gemini\s*(\d(?:\.\d)?)\b/gi)){const i=o[1]??"",s=`auto-gemini-${i}`;n.push({id:s,name:`Auto Gemini ${i}`,provider:"google",isDefault:/\bcurrent\b/i.test(t)&&t.includes(o[0]??"")})}return m(n)}function Z(){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{F as applyClaudeModelEnvOverrides,z as discoverClaudeAliasModelsFromEnv,q as fallbackClaudeAliasModels,G as fallbackCodexModels,Z as fallbackGeminiModels,I as fallbackWorkBuddyModels,D as inferClaudeOverrideProvider,K as parseClaudeBinaryModels,V as parseClaudeModels,J as parseCodexAppServerModels,W as parseCodexModels,N as parseCursorModels,X as parseGeminiModels,H as parseOpenClawModels,U as parseOpenCodeModels,B as parseOpenCodeProviderModels,E as readEnvValue,b as stripAnsi};
@@ -1 +1 @@
1
- import{getAgentConfigSummary as m}from"../config-status.js";import{isCacheFresh as v,readCache as l,writeCache as y}from"./cache.js";import{discoverModelsForAgent as A}from"./discovery.js";import{getAgentRuntimeSummary as f}from"../runtime-compatibility.js";import{resolveManagedAgentRuntimeProtection as C}from"../../security/managed-agent-runtime.js";const M={claude:"claude-alias-v2"};function S(i){const s=new Set,t=[];for(const o of i)!o.id||s.has(o.id)||(s.add(o.id),t.push(o));return t}function g(i){const s=i.type!=="pi"&&i.type!=="openclaw",t=s&&!i.type.startsWith("acp:"),o=s?C({agentType:i.type,runtimeVersion:i.version,platform:i.runtimePlatform,isWsl:i.runtimeIsWsl,executableFingerprint:i.executableFingerprint,requireExecutableFingerprint:!0}):null;return{supportsManagedAgent:t&&(o?.level==="hard"||o?.level==="partial"),supportsManagedNativeFull:s,supportsWorker:i.type!=="pi"&&i.type!=="openclaw"&&!i.type.startsWith("acp:"),supportsManagerMode:i.type==="codex"||i.type==="claude"||i.type==="pi-coding-agent",...o?{managedAgentProtection:o}:{}}}function E(i){const s=l();return i.map(t=>{const o=m(t.type),n=f(t);return{type:t.type,models:s.agents[t.type]?.models??t.models??[],...t.integration?{integration:t.integration}:{},...t.display?{display:t.display}:{},...t.acpCapabilities?{acpCapabilities:t.acpCapabilities}:{},...t.authState?{authState:t.authState}:{},...t.acpAuthMethods?{acpAuthMethods:t.acpAuthMethods}:{},...t.catalogRevision?{catalogRevision:t.catalogRevision}:{},...g(t),...o?{config:o}:{},...n?{runtime:n}:{}}})}async function O(i,s){const t=l();for(const o of i)delete t.agents[o.type];return y(t),R(i,s)}async function R(i,s){const t=l();let o=!1;const n=[];for(const e of i){const a=t.agents[e.type],p=M[e.type];let r;if(v(a,e.version,p))r=a.models;else{let c=null;try{c=S(await A(e,s)),r=c.length>0?c:a?.models??e.models??[]}catch{r=a?.models??e.models??[]}if(c&&c.length>0){const h={version:e.version,...p?{sourceRevision:p}:{},refreshedAt:Date.now(),models:r};JSON.stringify(a)!==JSON.stringify(h)&&(t.agents[e.type]=h,o=!0)}}const u=m(e.type),d=f(e);n.push({type:e.type,models:r,...e.integration?{integration:e.integration}:{},...e.display?{display:e.display}:{},...e.acpCapabilities?{acpCapabilities:e.acpCapabilities}:{},...e.authState?{authState:e.authState}:{},...e.acpAuthMethods?{acpAuthMethods:e.acpAuthMethods}:{},...e.catalogRevision?{catalogRevision:e.catalogRevision}:{},...g(e),...u?{config:u}:{},...d?{runtime:d}:{}})}return o&&y(t),n}export{E as getCachedAgentInfos,O as refreshAgentInfos,R as resolveAgentInfos};
1
+ import{getAgentConfigSummary as m}from"../config-status.js";import{isCacheFresh as g,readCache as l,writeCache as y}from"./cache.js";import{discoverModelsForAgent as A}from"./discovery.js";import{getAgentRuntimeSummary as f}from"../runtime-compatibility.js";import{resolveManagedAgentRuntimeProtection as C}from"../../security/managed-agent-runtime.js";const M={claude:"claude-alias-v2",opencode:"opencode-connected-v1"};function S(o){const s=new Set,e=[];for(const i of o)!i.id||s.has(i.id)||(s.add(i.id),e.push(i));return e}function v(o){const s=o.type!=="pi"&&o.type!=="openclaw",e=s&&!o.type.startsWith("acp:"),i=s?C({agentType:o.type,runtimeVersion:o.version,platform:o.runtimePlatform,isWsl:o.runtimeIsWsl,executableFingerprint:o.executableFingerprint,requireExecutableFingerprint:!0}):null;return{supportsManagedAgent:e&&(i?.level==="hard"||i?.level==="partial"),supportsManagedNativeFull:s,supportsWorker:o.type!=="pi"&&o.type!=="openclaw"&&!o.type.startsWith("acp:"),supportsManagerMode:o.type==="codex"||o.type==="claude"||o.type==="pi-coding-agent",...i?{managedAgentProtection:i}:{}}}function E(o){const s=l();return o.map(e=>{const i=m(e.type),n=f(e);return{type:e.type,models:s.agents[e.type]?.models??e.models??[],...e.integration?{integration:e.integration}:{},...e.display?{display:e.display}:{},...e.acpCapabilities?{acpCapabilities:e.acpCapabilities}:{},...e.authState?{authState:e.authState}:{},...e.acpAuthMethods?{acpAuthMethods:e.acpAuthMethods}:{},...e.catalogRevision?{catalogRevision:e.catalogRevision}:{},...v(e),...i?{config:i}:{},...n?{runtime:n}:{}}})}async function O(o,s){const e=l();for(const i of o)delete e.agents[i.type];return y(e),R(o,s)}async function R(o,s){const e=l();let i=!1;const n=[];for(const t of o){const a=e.agents[t.type],p=M[t.type];let r;if(g(a,t.version,p))r=a.models;else{let c=null;try{c=S(await A(t,s)),r=c.length>0?c:a?.models??t.models??[]}catch{r=a?.models??t.models??[]}if(c&&c.length>0){const h={version:t.version,...p?{sourceRevision:p}:{},refreshedAt:Date.now(),models:r};JSON.stringify(a)!==JSON.stringify(h)&&(e.agents[t.type]=h,i=!0)}}const u=m(t.type),d=f(t);n.push({type:t.type,models:r,...t.integration?{integration:t.integration}:{},...t.display?{display:t.display}:{},...t.acpCapabilities?{acpCapabilities:t.acpCapabilities}:{},...t.authState?{authState:t.authState}:{},...t.acpAuthMethods?{acpAuthMethods:t.acpAuthMethods}:{},...t.catalogRevision?{catalogRevision:t.catalogRevision}:{},...v(t),...u?{config:u}:{},...d?{runtime:d}:{}})}return i&&y(e),n}export{E as getCachedAgentInfos,O as refreshAgentInfos,R as resolveAgentInfos};
@@ -1 +1 @@
1
- import r from"node:fs";import c from"node:os";import s from"node:path";import{getCommandVersion as d}from"./command-spec.js";function m(e){const i=s.join("ChatGPT.app","Contents","Resources","codex");return[s.join("/Applications",i),s.join(e,"Applications",i)]}function a(e){if((e.platform??process.platform)!=="darwin")return;const i=e.exists??r.existsSync,t=e.getVersion??d,n=m(e.homeDir??c.homedir()).find(i);if(n)return t({command:n,args:[],display:"Codex Desktop",kind:"native",path:n})}function l(e,i={}){const t=e.version,n=e.type==="codex"?a(i):void 0;if(!t&&!n)return;const o=t&&n?t===n?"compatible":"version_mismatch":void 0;return{...t?{cliVersion:t}:{},...n?{desktopVersion:n}:{},...o?{compatibility:o}:{},...o==="version_mismatch"?{upgradeAction:"manual"}:{}}}export{l as getAgentRuntimeSummary};
1
+ import r from"node:fs";import m from"node:os";import{getCodexDesktopCommandCandidates as d,getCommandVersion as c}from"./command-spec.js";function a(e){const i=e.platform??process.platform;if(i!=="darwin")return;const n=e.exists??r.existsSync,t=e.getVersion??c;for(const o of d(i,e.homeDir??m.homedir())){if(!n(o))continue;const s=t({command:o,args:[],display:"Codex Desktop",kind:"native",path:o});if(s)return s}}function l(e,i={}){const n=e.version,t=e.type==="codex"?a(i):void 0;if(!n&&!t)return;const o=n&&t?n===t?"compatible":"version_mismatch":void 0;return{...n?{cliVersion:n}:{},...t?{desktopVersion:t}:{},...o?{compatibility:o}:{},...o==="version_mismatch"?{upgradeAction:"manual"}:{}}}export{l as getAgentRuntimeSummary};
@@ -18,7 +18,7 @@ ${o.length?o.join(`
18
18
  ${u?`\u53EA\u5728\u5185\u90E8\u5BF9\u8BDD\u4E2D\u751F\u6210\u6587\u5B57\u4E0D\u7B49\u4E8E\u5DF2\u7ECF\u56DE\u590D\u7FA4\u804A\uFF0C\u5B8C\u6210\u7FA4\u804A\u53D1\u9001\u5FC5\u987B\u8C03\u7528\u5F53\u524D\u7FA4\u804A\u5DE5\u5177\u3002
19
19
  \u672C\u5730\u9644\u4EF6\u4E0A\u4F20\u5F53\u524D\u4E0D\u53EF\u7528\uFF1B\u9700\u8981\u53D1\u9001\u957F\u6587\u6863\u65F6\uFF0C\u5148\u53D1\u9001\u7B80\u77ED\u6458\u8981\u5E76\u8BF4\u660E\u6B64\u9650\u5236\u3002`:`\u53EA\u5728\u5185\u90E8\u5BF9\u8BDD\u4E2D\u751F\u6210\u6587\u5B57\u4E0D\u7B49\u4E8E\u5DF2\u7ECF\u56DE\u590D\u7FA4\u804A\uFF0C\u5B8C\u6210\u7FA4\u804A\u53D1\u9001\u5FC5\u987B\u6267\u884C Shennian CLI\u3002
20
20
  \u957F\u6587\u6863\u4F18\u5148\u4F5C\u4E3A\u9644\u4EF6\u53D1\u9001\uFF0C\u5E76\u9644\u7B80\u77ED\u7EAF\u6587\u672C\u8BF4\u660E\u3002`}
21
- \u6536\u5230\u9700\u8981\u5904\u7406\u7684\u4EFB\u52A1\u540E\uFF0C\u5148\u5728\u7FA4\u91CC\u7B80\u77ED\u8BF4\u660E\u5DF2\u6536\u5230\u548C\u51C6\u5907\u600E\u4E48\u505A\uFF0C\u518D\u5F00\u59CB\u6267\u884C\uFF1B\u8017\u65F6\u8F83\u957F\u65F6\u9002\u5F53\u540C\u6B65\u8FDB\u5C55\uFF0C\u5B8C\u6210\u540E\u56DE\u590D\u7ED3\u679C\u3002\u7B80\u5355\u95EE\u9898\u53EF\u76F4\u63A5\u56DE\u7B54\u3002
21
+ \u6536\u5230\u9700\u8981\u5904\u7406\u7684\u4EFB\u52A1\u65F6\uFF0C\u5148\u5728\u7FA4\u91CC\u7B80\u77ED\u786E\u8BA4\u4E00\u6B21\uFF0C\u5E76\u8BF4\u660E\u63A5\u4E0B\u6765\u505A\u4EC0\u4E48\uFF0C\u518D\u5F00\u59CB\u6267\u884C\uFF1B\u5B8C\u6210\u540E\u518D\u56DE\u590D\u7ED3\u679C\u3002\u53EA\u6709\u4EFB\u52A1\u660E\u663E\u8017\u65F6\u4E14\u51FA\u73B0\u503C\u5F97\u544A\u77E5\u7528\u6237\u7684\u5B9E\u9645\u8FDB\u5C55\u65F6\uFF0C\u624D\u5728\u4E2D\u9014\u540C\u6B65\u8FDB\u5C55\u3002\u7B80\u5355\u95EE\u9898\u53EF\u76F4\u63A5\u56DE\u7B54\uFF0C\u4E0D\u9700\u8981\u5148\u786E\u8BA4\u3002
22
22
  Room \u6B63\u6587\u5F53\u524D\u6309\u7EAF\u6587\u672C\u663E\u793A\uFF1B\u53D1\u9001\u65F6\u4F7F\u7528\u77ED\u6BB5\u843D\u548C\u81EA\u7136\u6362\u884C\uFF0C\u4E0D\u8981\u4F7F\u7528 Markdown \u6807\u8BB0\u3002`,l,a?`[\u4F1A\u8BDD\u6A21\u5F0F]
23
23
  ${a}`:"",i?`[\u667A\u80FD\u4F53\u79C1\u6709\u7CFB\u7EDF\u63D0\u793A\u8BCD]
24
24
  ${i}`:"",c,`[\u7FA4\u6D88\u606F\u683C\u5F0F]
@@ -1,3 +1,2 @@
1
1
  export declare function issuePersonalScheduleContext(sessionId: string): string;
2
2
  export declare function resolvePersonalScheduleContext(value: unknown): string;
3
- export declare const PERSONAL_SCHEDULE_INSTRUCTIONS = "\u5982\u7528\u6237\u5B89\u6392\u7A0D\u540E\u6216\u5B9A\u671F\u5DE5\u4F5C\uFF0C\u4F7F\u7528 shennian schedule --operation create --operation-id <\u7A33\u5B9AID> --time-description <\u65F6\u95F4\u63CF\u8FF0> --timezone <IANA\u65F6\u533A> --prompt <\u5DE5\u4F5C\u5185\u5BB9>\u3002\u652F\u6301\u6BCF\u592909:00\u3001\u6BCF\u5468\u4E0009:00\u3001\u6BCF\u67081\u65E509:00\u3001\u6BCF\u969424\u5C0F\u65F6\u300130\u5206\u949F\u540E\u6216ISO\u65F6\u95F4\u3002\u67E5\u8BE2\u7528 --operation list\uFF1B\u4FEE\u6539/\u6682\u505C/\u6062\u590D/\u5220\u9664\u7528 update/pause/resume/delete\uFF0C\u5E76\u5E26\u67E5\u8BE2\u5F97\u5230\u7684 --id \u548C --version\u3002\u53EA\u5728\u771F\u5B9E\u4FDD\u5B58\u6210\u529F\u540E\u7528\u666E\u901A\u6587\u672C\u786E\u8BA4\u3002\u65F6\u95F4\u548C\u5DE5\u4F5C\u5185\u5BB9\u5206\u5F00\uFF0C\u4E0D\u5728\u5DE5\u4F5CPrompt\u91CC\u91CD\u590D\u521B\u5EFA\u5B9A\u65F6\u4EFB\u52A1\u3002";
@@ -1 +1 @@
1
- import{randomBytes as i}from"node:crypto";const o=new Map;function a(t){const e=Date.now();for(const[s,n]of o)if(n.expires<=e)o.delete(s);else if(n.sessionId===t)return n.expires=e+30*6e4,s;const r=i(32).toString("base64url");return o.set(r,{sessionId:t,expires:e+30*6e4}),r}function c(t){const e=typeof t=="string"?o.get(t):null;if(!e||e.expires<=Date.now())throw new Error("schedule_context_expired");return e.sessionId}const u="\u5982\u7528\u6237\u5B89\u6392\u7A0D\u540E\u6216\u5B9A\u671F\u5DE5\u4F5C\uFF0C\u4F7F\u7528 shennian schedule --operation create --operation-id <\u7A33\u5B9AID> --time-description <\u65F6\u95F4\u63CF\u8FF0> --timezone <IANA\u65F6\u533A> --prompt <\u5DE5\u4F5C\u5185\u5BB9>\u3002\u652F\u6301\u6BCF\u592909:00\u3001\u6BCF\u5468\u4E0009:00\u3001\u6BCF\u67081\u65E509:00\u3001\u6BCF\u969424\u5C0F\u65F6\u300130\u5206\u949F\u540E\u6216ISO\u65F6\u95F4\u3002\u67E5\u8BE2\u7528 --operation list\uFF1B\u4FEE\u6539/\u6682\u505C/\u6062\u590D/\u5220\u9664\u7528 update/pause/resume/delete\uFF0C\u5E76\u5E26\u67E5\u8BE2\u5F97\u5230\u7684 --id \u548C --version\u3002\u53EA\u5728\u771F\u5B9E\u4FDD\u5B58\u6210\u529F\u540E\u7528\u666E\u901A\u6587\u672C\u786E\u8BA4\u3002\u65F6\u95F4\u548C\u5DE5\u4F5C\u5185\u5BB9\u5206\u5F00\uFF0C\u4E0D\u5728\u5DE5\u4F5CPrompt\u91CC\u91CD\u590D\u521B\u5EFA\u5B9A\u65F6\u4EFB\u52A1\u3002";export{u as PERSONAL_SCHEDULE_INSTRUCTIONS,a as issuePersonalScheduleContext,c as resolvePersonalScheduleContext};
1
+ import{randomBytes as i}from"node:crypto";const n=new Map;function l(t){const e=Date.now();for(const[s,r]of n)if(r.expires<=e)n.delete(s);else if(r.sessionId===t)return r.expires=e+30*6e4,s;const o=i(32).toString("base64url");return n.set(o,{sessionId:t,expires:e+30*6e4}),o}function p(t){const e=typeof t=="string"?n.get(t):null;if(!e||e.expires<=Date.now())throw new Error("schedule_context_expired");return e.sessionId}export{l as issuePersonalScheduleContext,p as resolvePersonalScheduleContext};
@@ -1 +1 @@
1
- import{issuePersonalScheduleContext as i}from"../../schedules/personal-context.js";import{buildManagedAgentEnv as m}from"../../agents/config-status.js";import{lookupClaudeTranscriptCwd as p}from"../../native-fusion/parsers.js";import{getManagedRoomIpcRoot as d,MANAGED_ROOM_IPC_ROOT_ENV as f}from"../../daemon-ipc/paths.js";function x(n){return m(n)}function C(n,e,o){return{}}function N(n,e,o,t,a,r,u,c){const l=o==="codex";n.configure?.({sessionId:e,externalChannel:t??null,env:{...x(o),...!r&&!u?{SHENNIAN_SCHEDULE_CONTEXT:i(e)}:{},...C(e,t,a),...r&&!l?{SHENNIAN_MANAGED_ROOM_CONTEXT:r,[f]:d()}:{}},...u?{managedAgentPolicy:u}:{},...l?{managedRoomContextToken:r??null,managedRoomExecutor:r?c??null:null}:{}})}function g(n,e,o){const t=e.managedRoomContextToken;t&&t!==o&&n.revokeManagedRoomContextToken?.(t),e.managedRoomContextToken=o}function k(n,e){const o=e?.managedRoomContextToken;!e||!o||(e.managedRoomContextToken=null,n.revokeManagedRoomContextToken?.(o))}function v(n,e,o){if(n!=="claude"||!o)return e;const t=e.trim();return!!t&&t.startsWith("-")&&!t.includes("/")?p(o)??e:e}export{N as configureAdapterForSession,C as externalChannelEnv,x as managedProviderEnv,v as maybeResolveClaudeImportedWorkDir,g as replaceManagedRoomContextToken,k as revokeManagedRoomContextToken};
1
+ import{buildManagedAgentEnv as c}from"../../agents/config-status.js";import{lookupClaudeTranscriptCwd as i}from"../../native-fusion/parsers.js";import{getManagedRoomIpcRoot as d,MANAGED_ROOM_IPC_ROOT_ENV as p}from"../../daemon-ipc/paths.js";function x(n){return c(n)}function f(n,o,e){return{}}function T(n,o,e,t,a,r,u,m){const l=e==="codex";n.configure?.({sessionId:o,externalChannel:t??null,env:{...x(e),...f(o,t,a),...r&&!l?{SHENNIAN_MANAGED_ROOM_CONTEXT:r,[p]:d()}:{}},...u?{managedAgentPolicy:u}:{},...l?{managedRoomContextToken:r??null,managedRoomExecutor:r?m??null:null}:{}})}function k(n,o,e){const t=o.managedRoomContextToken;t&&t!==e&&n.revokeManagedRoomContextToken?.(t),o.managedRoomContextToken=e}function v(n,o){const e=o?.managedRoomContextToken;!o||!e||(o.managedRoomContextToken=null,n.revokeManagedRoomContextToken?.(e))}function M(n,o,e){if(n!=="claude"||!e)return o;const t=o.trim();return!!t&&t.startsWith("-")&&!t.includes("/")?i(e)??o:o}export{T as configureAdapterForSession,f as externalChannelEnv,x as managedProviderEnv,M as maybeResolveClaudeImportedWorkDir,k as replaceManagedRoomContextToken,v as revokeManagedRoomContextToken};
@@ -1,3 +1 @@
1
- import{PERSONAL_SCHEDULE_INSTRUCTIONS as Ae}from"../../schedules/personal-context.js";import de from"node:os";import{createHash as Z,randomUUID as Me}from"node:crypto";import{buildUserMessagePayload as le}from"@shennian/wire";import{reportLog as T}from"../../log-reporter.js";import{appendMessage as ce,getDaemonInstallationId as ge,getMessageDeliveryStatus as Ee,recordSession as De,upsertMessage as _}from"../store.js";import{mergeProjectedSessions as Te}from"../projection.js";import{parsePersonalAttachmentReferences as be}from"../attachment-reference.js";import{assertFinishedAttachmentReferences as Ce,markAttachmentReferences as $e}from"../attachment-transfer-store.js";import{requestSessionIndexPublish as R}from"../index-publisher.js";import{getPersonalSyncIdentity as We}from"../../personal-sync/epoch.js";import{isTrustedManagerEvent as xe}from"../manager-event-authority.js";import{buildManagedAgentPermissionPrompt as qe}from"../../room/managed-prompt-composer.js";import{getNativeSourceAgentType as je}from"./chat-events.js";import{configureAdapterForSession as ue,maybeResolveClaudeImportedWorkDir as Oe,replaceManagedRoomContextToken as me,revokeManagedRoomContextToken as pe}from"./chat-adapter-config.js";import{createActiveSession as Be,disposeSession as W,prepareAdapterTurn as Fe,rememberProcessedReqId as He,sendAdapterTurn as fe}from"./chat-session-lifecycle.js";function Je(e,n,a){if(e.source!=="room_activation")throw new Error("managed_room_execution_context_required");if(!e.managedAgentPolicy)throw new Error("managed_agent_policy_missing");const l=e.managedRoomPromptSnapshot;if(!l)throw new Error("managed_room_prompt_snapshot_missing");if(!n?.trim())throw new Error("managed_room_prompt_incomplete");if(!a||!/^mrc_[A-Za-z0-9_-]{43}$/.test(a))throw new Error("managed_room_context_unavailable");const o=Z("sha256").update(JSON.stringify({requestedPolicy:e.managedAgentPolicy.requestedPolicy,enforcement:e.managedAgentPolicy.enforcement})).digest("hex"),b=Z("sha256").update(e.managedAgentPolicy.adapterPolicy.workDir).digest("hex");if(l.runtimePermissionPolicyHash!==o||l.resolvedWorkDirHash!==b||l.enforcementLevel!==e.managedAgentPolicy.enforcement.level)throw new Error("managed_room_prompt_snapshot_mismatch")}function ye(e,n){return`Agent send failed: ${n instanceof Error?n.message:String(n)}`}function ze(e,n){De({sessionId:n.sessionId,agentType:n.agentType,sessionMode:n.sessionMode,managerConfig:n.managerConfig,workDir:n.workDir,agentSessionId:n.agentSessionId??null,modelId:n.modelId??null,managerDefaultWorkerAgentType:n.managerDefaultWorkerAgentType,managerDefaultWorkerModelId:n.managerDefaultWorkerModelId}),e.client.sendEvent({type:"event",event:"session.update",payload:{session:{id:n.sessionId,agentType:n.agentType,sessionMode:n.sessionMode,managerConfig:n.managerConfig,agentSessionId:n.agentSessionId??null,modelId:n.modelId??null,workDir:n.workDir,status:"active",externalChannel:null}}})}function Ne(e,n){const a=e.sessions.get(n),l=a?.currentRunId;if(!a||!l)return;const o=a.nextEventSeq;e.runTextAcc.delete(`${n}:${l}`),pe(e,a),a.pendingTextEvent=null,a.currentRunId=null,a.currentRunPhase=null,a.nextEventSeq=0,a.heartbeatTimer&&(clearInterval(a.heartbeatTimer),a.heartbeatTimer=null),e.client.sendAgentEvent({type:"event",event:"agent",payload:{state:"aborted",sessionId:n,runId:l,seq:o},seq:o,id:`agent-evt-${l}-${o}`}),a.journalRunId&&(e.runJournal?.remove(n,a.journalRunId),e.recoveryBarrier?.end(n),a.journalRunId=null),e.chatQueue?.noteTerminal(n)}async function cn(e,n,a){const l=a?n.params.managedRoomContextToken??null:null;let o=!1;try{await Ue(e,n,a,()=>{o=!0})}finally{l&&!o&&e.revokeManagedRoomContextToken?.(l)}}async function Ue(e,n,a,l){if(e.processedReqIds.has(n.id)){e.client.sendRes({type:"res",id:n.id,ok:!0});return}const{sessionId:o,text:b,agentType:A,sessionMode:ve,managerConfig:G,workDir:he,agentSessionId:m,modelId:h,systemPrompt:x,managerDefaultWorkerAgentType:q,managerDefaultWorkerModelId:j,reasoningEffort:O,clientMessageId:Ie,sessionListProjection:_e,waitForDispatch:X,responseId:Re,managedRoomContextToken:I,suppressExternalOwnerEcho:we,queuedBatchItems:B,managedWorkerParentSessionId:c,managerWorkerRoomOrigin:F,managerWorkerNativeFull:H,managedRecoverySource:M}=n.params,g=Re||n.id,Y=n.params;if((Y.managerEventId||Y.managerEventRoomOrigin||c||F||H||M)&&!xe(n))throw new Error("manager_event_source_untrusted");Te(_e);const C=null,J="";if(a?.source==="room_activation"&&(Je(a,x,I),A==="manager"))throw new Error("managed_agent_manager_mode_unsupported");if(a?.source==="manager_event"){if(!a.managedAgentPolicy)throw new Error("managed_agent_policy_missing");if(!I||!/^mrc_[A-Za-z0-9_-]{43}$/.test(I))throw new Error("managed_room_context_unavailable")}if(He(e,n.id),!o||!b){e.processedReqIds.delete(n.id),e.client.sendRes({type:"res",id:g,ok:!1,error:"sessionId and text are required"});return}if(e.recoveryBarrier?.isDispatchFrozen()){e.processedReqIds.delete(n.id),e.client.sendRes({type:"res",id:g,ok:!1,error:"upgrade_in_progress"});return}e.recoveryBarrier?.isRecovering(o)&&await e.recoveryBarrier.wait(o);const i=A,w=i==="manager"||ve==="manager"?"manager":"standard";w==="manager"&&e.managerRuntime?.setManagerWorkerDefaults(o,q??null,j??null);const E=(i==="claude"||i==="codex"||i==="workbuddy"||i==="pi-coding-agent"||i.startsWith("acp:"))&&typeof O=="string"&&O.trim()?O.trim():void 0,f=e.resolvePath(Oe(i,he||de.homedir(),m)||de.homedir()),y=a?.managedAgentPolicy??(c?e.managerRuntime?.getManagedAgentPolicyForWorker(c,f)??null:null);if(c&&!H&&!y)throw new Error("managed_worker_permission_context_unavailable");const z=i==="codex"&&(a?.source==="room_activation"||a?.source==="manager_event"||c)?"internal":"user",N=c&&y?qe({requestedPolicy:y.requestedPolicy,enforcement:y.enforcement,resolvedWorkDir:y.adapterPolicy.workDir}):!a&&!c&&!i.startsWith("custom:")?[x,Ae].filter(Boolean).join(`
2
-
3
- `):x,Se=f,$=be(n.params.attachments);$?.length&&Ce(f,$);const p={text:b,attachments:$,localized:!1};let t=e.sessions.get(o);if(t){if(t.lastActiveAt=Date.now(),t.agentType!==i||(t.sessionMode??(t.agentType==="manager"?"manager":"standard"))!==w||t.workDir!==f||(t.nativeSessionVisibility??"user")!==z||JSON.stringify(t.externalChannel??null)!==JSON.stringify(C??null)){e.sessions.delete(o);try{await W(e,t)}catch{e.processedReqIds.delete(n.id)}t=void 0}else if(m&&t.agentSessionId!==m)try{await t.adapter.resume(m),t.agentSessionId=m}catch{e.sessions.delete(o);try{await W(e,t)}catch{e.processedReqIds.delete(n.id)}t=void 0}}if(!t)try{t=await Be(e,o,i,w,f,m,C,J,y,z)}catch(r){const d=r instanceof Error&&r.message.startsWith("Unsupported agent:")?r.message:`Failed to start ${A}: ${r instanceof Error?r.message:String(r)}`;console.error(`[chat.send] start failed reqId=${n.id} sessionId=${o} agentType=${A} workDir=${f} agentSessionId=${m??""}: ${d}`),e.client.sendEvent({type:"event",event:"agent",payload:{state:"error",sessionId:o,message:d,runId:"",seq:0}}),e.processedReqIds.delete(n.id),e.client.sendRes({type:"res",id:g,ok:!1,error:d});return}const u={id:Ie??`user-${n.id}`,sessionId:o,role:"user",ts:Date.now(),payload:le(p.text,p.attachments)},ee=Array.isArray(B)&&B.length>0?B.map(r=>({id:r.clientMessageId??r.id,sessionId:o,role:M==="manager_event"||n.params.scheduledDelivery===!0?"agent":"user",ts:M==="manager_event"?Date.parse(r.createdAt):u.ts,payload:le(r.text,r.attachments)})):null,S=ee??[u],U=Ee(o,u.id),ne=U.state==="queued";if(U.state!=="not_found"&&!ne){e.client.sendRes({type:"res",id:g,ok:!0,payload:U});return}if(X){(a?.source==="room_activation"||a?.source==="manager_event")&&ue(t.adapter,o,i,C,J,I,a.managedAgentPolicy,e.managedRoomExecutor);try{await Fe(t.adapter,p.text,h,E,p.attachments,N,a?.source==="room_activation"?{source:"room_activation"}:a?.source==="manager_event"?{source:"managed_private"}:void 0)}catch(r){e.processedReqIds.delete(n.id),e.sessions.delete(o),await W(e,t),e.client.sendRes({type:"res",id:g,ok:!1,error:r instanceof Error?r.message:String(r)});return}}T({level:"info",sessionId:o,wsEvent:"chat.send.start",metadata:{reqId:n.id,agentType:i,sessionMode:w,managerConfig:G??null,modelId:h,managerDefaultWorkerAgentType:q??null,managerDefaultWorkerModelId:j??null,reasoningEffort:E,...a?.source==="room_activation"?{managedRoomPromptSnapshot:a.managedRoomPromptSnapshot}:{}}});const k=(r,d)=>({...We(ge()),sessionId:o,clientMessageId:u.id,messageId:u.id,deliveryState:r,bodyRevision:d,committedAt:new Date(u.ts).toISOString()}),L=r=>{e.nativeFusion?.registerManagedSend({sessionId:o,agentType:i,sourceAgentType:je(i,h),canonicalMessageId:u.id,sourceSessionKey:t.agentSessionId??m??null,text:p.text,managedEchoPolicy:r?.deliveryMode==="external_owner_queue"&&!we?"import_following":"suppress_following",externalRunId:r?.deliveryMode==="external_owner_queue"?`codex-external-${r.queuedSubmissionId??u.id}`:null})},ae=()=>{t.currentRunId||(t.currentRunId=`dispatch:${n.id}`,t.currentRunPhase="thinking",t.nextEventSeq=0)},oe=()=>{if(!e.runJournal||t.journalRunId)return;const r=`run:${Me()}`;e.runJournal.begin({daemonInstallationId:ge(),sessionId:o,runId:r,clientMessageId:u.id,agentType:i,sessionMode:w,workDir:f,agentSessionId:t.agentSessionId??m??null,modelId:h??null,reasoningEffort:E??null,nativeSessionVisibility:z,providerRunId:null,source:M==="manager_event"?"manager_event":a?.source==="room_activation"?M==="managed_direct"?"managed_direct":"managed_room":c?"manager_worker":"personal",parentSessionId:c??null,managerWorkerNativeFull:H===!0,roomContextRegistryKey:typeof n.params.roomContextRegistryKey=="string"?n.params.roomContextRegistryKey:null,activationCauseMessageId:typeof n.params.activationCauseMessageId=="string"?n.params.activationCauseMessageId:null,rootCauseMessageId:typeof n.params.rootCauseMessageId=="string"?n.params.rootCauseMessageId:null,activationSequence:typeof n.params.activationSequence=="string"?n.params.activationSequence:null,activationHopCount:typeof n.params.activationHopCount=="number"?n.params.activationHopCount:null,managedPolicyVersion:a?.source==="room_activation"?a.managedRoomPromptSnapshot.managedRoomPolicyVersion:a?.source==="manager_event"?a.managedRoomPolicyVersion:null,managedRuntimePolicyHash:(a?.source==="room_activation"?a.managedRoomPromptSnapshot.runtimePermissionPolicyHash:a?.source==="manager_event"?a.managedRuntimePolicyHash:null)??(y?Z("sha256").update(JSON.stringify({requestedPolicy:y.requestedPolicy,enforcement:y.enforcement})).digest("hex"):null)}),t.journalRunId=r},re=()=>{if(L(),ne){let r=0;for(const[d,s]of S.entries()){const v=_(o,s,"queued");d===0&&(r=v)}return k("queued",r)}try{ze(e,{sessionId:o,agentType:i,sessionMode:w,managerConfig:G??null,workDir:Se,agentSessionId:t.agentSessionId??m??null,modelId:h,managerDefaultWorkerAgentType:q??null,managerDefaultWorkerModelId:j??null});let r=0;for(const[d,s]of S.entries()){const v=ee?_(o,s,"committed"):ce(o,s,"committed");d===0&&(r=v)}return $e(f,$??[]),R(e.client),k("committed",r)}catch(r){throw e.nativeFusion?.cancelManagedSend?.(u.id),r}},te=r=>{t.journalRunId&&e.runJournal?.update(o,t.journalRunId,{deliveryMode:r?.deliveryMode==="external_owner_queue"?"external_owner_queue":"direct",externalRunId:r?.deliveryMode==="external_owner_queue"?`codex-external-${r.queuedSubmissionId??u.id}`:null})},se=r=>{t.currentRunId||(t.nextEventSeq=0),te(r),L(r);const d=r?.deliveryMode==="external_owner_queue"?"queued":"executing";let s=0;for(const[v,D]of S.entries()){const P=_(o,D,d);v===0&&(s=P)}return R(e.client),k(d,s)},V=async(r,d)=>{e.nativeFusion?.cancelManagedSend?.(u.id);const s=ye(i,r);if(console.error(`[chat.send] send failed reqId=${n.id} sessionId=${o} agentType=${A} workDir=${f} agentSessionId=${t.agentSessionId??m??""}: ${s}`),t.adapter.hasPendingAuthenticationRetry?.()===!0){d&&e.client.sendRes({type:"res",id:g,ok:!0,payload:k("queued",0)});return}e.sessions.delete(o),t.journalRunId&&(e.runJournal?.update(o,t.journalRunId,{phase:"terminal"}),e.runJournal?.remove(o,t.journalRunId),e.recoveryBarrier?.end(o),t.journalRunId=null);try{await W(e,t)}catch{}if(e.client.sendEvent({type:"event",event:"agent",payload:{state:"error",sessionId:o,message:s,runId:"",seq:0}}),!d){const D={id:`agent-error-${n.id}-${Date.now()}`,sessionId:o,role:"agent",ts:Date.now(),payload:s};ce(o,D),R(e.client)}d&&(e.processedReqIds.delete(n.id),e.client.sendRes({type:"res",id:g,ok:!1,error:s}))};if(X){try{re()}catch(s){e.processedReqIds.delete(n.id),e.client.sendRes({type:"res",id:g,ok:!1,error:`Durable message commit failed: ${s instanceof Error?s.message:String(s)}`});return}oe(),ae();let r;try{(a?.source==="room_activation"||a?.source==="manager_event")&&(me(e,t,I),l());const s=p.attachments;c&&e.managerRuntime?.prepareWorkerTurnOrigin(o,F),r=await fe(t.adapter,p.text,h,E,s,N,a?.source==="room_activation"?{source:"room_activation"}:a?.source==="manager_event"?{source:"managed_private"}:void 0),T({level:"info",sessionId:o,wsEvent:"chat.send.done",metadata:{reqId:n.id}})}catch(s){if(c&&e.managerRuntime?.prepareWorkerTurnOrigin(o),t.adapter.hasPendingAuthenticationRetry?.()){let P=0;for(const[K,Q]of S.entries()){const Pe=_(o,Q,"queued");K===0&&(P=Pe)}R(e.client),await V(s,!1),e.client.sendRes({type:"res",id:g,ok:!0,payload:k("queued",P)});return}let v=0;for(const[P,K]of S.entries()){const Q=_(o,K,"failed");P===0&&(v=Q)}R(e.client);const D=ye(i,s);await V(s,!1),e.client.sendRes({type:"res",id:g,ok:!0,payload:{...k("failed",v),failureMessage:D}});return}const d=se(r??void 0);e.client.sendRes({type:"res",id:g,ok:!0,payload:{...d,...p.localized?{localizedAttachments:!0}:{},...r?.deliveryMode==="external_owner_queue"?{queued:!0,deliveryMode:r.deliveryMode,queuedSubmissionId:r.queuedSubmissionId}:{}}}),T({level:"info",sessionId:o,wsEvent:"chat.send.res",metadata:{reqId:n.id,ok:!0}});return}let ie;try{ie=re()}catch(r){e.processedReqIds.delete(n.id),e.client.sendRes({type:"res",id:g,ok:!1,error:`Durable message commit failed: ${r instanceof Error?r.message:String(r)}`});return}oe(),ae(),(a?.source==="room_activation"||a?.source==="manager_event")&&(ue(t.adapter,o,i,C,J,I,a.managedAgentPolicy,e.managedRoomExecutor),me(e,t,I),l()),se(),e.client.sendRes({type:"res",id:g,ok:!0,payload:{...ie,...p.localized?{localizedAttachments:!0}:{}}}),T({level:"info",sessionId:o,wsEvent:"chat.send.res",metadata:{reqId:n.id,ok:!0}});const ke=p.attachments;c&&e.managerRuntime?.prepareWorkerTurnOrigin(o,F),fe(t.adapter,p.text,h,E,ke,N,a?.source==="room_activation"?{source:"room_activation"}:a?.source==="manager_event"?{source:"managed_private"}:void 0).then(r=>{if(r?.deliveryMode==="external_owner_queue"){te(r),L(r);for(const d of S)_(o,d,"queued");R(e.client)}T({level:"info",sessionId:o,wsEvent:"chat.send.done",metadata:{reqId:n.id}})}).catch(r=>{c&&e.managerRuntime?.prepareWorkerTurnOrigin(o),_(o,u,t.adapter.hasPendingAuthenticationRetry?.()?"queued":"failed"),R(e.client),V(r,!1)})}async function gn(e,n){const{sessionId:a,discardPending:l}=n.params,o=e.sessions.get(a);if(o){o.journalRunId&&e.runJournal?.markAborted(a,o.journalRunId),pe(e,o);try{await o.adapter.stop()}catch{e.client.sendRes({type:"res",id:n.id,ok:!1,error:"agent_stop_failed"});return}Ne(e,a),e.activityPublisher?.publish(a,null)}l===!0&&e.chatQueue?.purgeSession(a),e.client.sendRes({type:"res",id:n.id,ok:!0})}export{gn as handleChatAbort,cn as handleChatSend,ze as sendSessionUpdateEvent,Je as validateManagedRoomExecutionContext};
1
+ import de from"node:os";import{createHash as Q,randomUUID as Ae}from"node:crypto";import{buildUserMessagePayload as le}from"@shennian/wire";import{reportLog as T}from"../../log-reporter.js";import{appendMessage as ce,getDaemonInstallationId as ge,getMessageDeliveryStatus as Me,recordSession as Ee,upsertMessage as _}from"../store.js";import{mergeProjectedSessions as De}from"../projection.js";import{parsePersonalAttachmentReferences as Te}from"../attachment-reference.js";import{assertFinishedAttachmentReferences as be,markAttachmentReferences as Ce}from"../attachment-transfer-store.js";import{requestSessionIndexPublish as R}from"../index-publisher.js";import{getPersonalSyncIdentity as $e}from"../../personal-sync/epoch.js";import{isTrustedManagerEvent as xe}from"../manager-event-authority.js";import{buildManagedAgentPermissionPrompt as We}from"../../room/managed-prompt-composer.js";import{getNativeSourceAgentType as qe}from"./chat-events.js";import{configureAdapterForSession as ue,maybeResolveClaudeImportedWorkDir as je,replaceManagedRoomContextToken as me,revokeManagedRoomContextToken as pe}from"./chat-adapter-config.js";import{createActiveSession as Fe,disposeSession as x,prepareAdapterTurn as Be,rememberProcessedReqId as Je,sendAdapterTurn as fe}from"./chat-session-lifecycle.js";function Oe(e,n,o){if(e.source!=="room_activation")throw new Error("managed_room_execution_context_required");if(!e.managedAgentPolicy)throw new Error("managed_agent_policy_missing");const l=e.managedRoomPromptSnapshot;if(!l)throw new Error("managed_room_prompt_snapshot_missing");if(!n?.trim())throw new Error("managed_room_prompt_incomplete");if(!o||!/^mrc_[A-Za-z0-9_-]{43}$/.test(o))throw new Error("managed_room_context_unavailable");const a=Q("sha256").update(JSON.stringify({requestedPolicy:e.managedAgentPolicy.requestedPolicy,enforcement:e.managedAgentPolicy.enforcement})).digest("hex"),b=Q("sha256").update(e.managedAgentPolicy.adapterPolicy.workDir).digest("hex");if(l.runtimePermissionPolicyHash!==a||l.resolvedWorkDirHash!==b||l.enforcementLevel!==e.managedAgentPolicy.enforcement.level)throw new Error("managed_room_prompt_snapshot_mismatch")}function ye(e,n){return`Agent send failed: ${n instanceof Error?n.message:String(n)}`}function He(e,n){Ee({sessionId:n.sessionId,agentType:n.agentType,sessionMode:n.sessionMode,managerConfig:n.managerConfig,workDir:n.workDir,agentSessionId:n.agentSessionId??null,modelId:n.modelId??null,managerDefaultWorkerAgentType:n.managerDefaultWorkerAgentType,managerDefaultWorkerModelId:n.managerDefaultWorkerModelId}),e.client.sendEvent({type:"event",event:"session.update",payload:{session:{id:n.sessionId,agentType:n.agentType,sessionMode:n.sessionMode,managerConfig:n.managerConfig,agentSessionId:n.agentSessionId??null,modelId:n.modelId??null,workDir:n.workDir,status:"active",externalChannel:null}}})}function ze(e,n){const o=e.sessions.get(n),l=o?.currentRunId;if(!o||!l)return;const a=o.nextEventSeq;e.runTextAcc.delete(`${n}:${l}`),pe(e,o),o.pendingTextEvent=null,o.currentRunId=null,o.currentRunPhase=null,o.nextEventSeq=0,o.heartbeatTimer&&(clearInterval(o.heartbeatTimer),o.heartbeatTimer=null),e.client.sendAgentEvent({type:"event",event:"agent",payload:{state:"aborted",sessionId:n,runId:l,seq:a},seq:a,id:`agent-evt-${l}-${a}`}),o.journalRunId&&(e.runJournal?.remove(n,o.journalRunId),e.recoveryBarrier?.end(n),o.journalRunId=null),e.chatQueue?.noteTerminal(n)}async function dn(e,n,o){const l=o?n.params.managedRoomContextToken??null:null;let a=!1;try{await Ne(e,n,o,()=>{a=!0})}finally{l&&!a&&e.revokeManagedRoomContextToken?.(l)}}async function Ne(e,n,o,l){if(e.processedReqIds.has(n.id)){e.client.sendRes({type:"res",id:n.id,ok:!0});return}const{sessionId:a,text:b,agentType:A,sessionMode:ve,managerConfig:Z,workDir:he,agentSessionId:m,modelId:h,systemPrompt:G,managerDefaultWorkerAgentType:W,managerDefaultWorkerModelId:q,reasoningEffort:j,clientMessageId:Ie,sessionListProjection:_e,waitForDispatch:X,responseId:Re,managedRoomContextToken:I,suppressExternalOwnerEcho:we,queuedBatchItems:F,managedWorkerParentSessionId:u,managerWorkerRoomOrigin:B,managerWorkerNativeFull:J,managedRecoverySource:M}=n.params,c=Re||n.id,Y=n.params;if((Y.managerEventId||Y.managerEventRoomOrigin||u||B||J||M)&&!xe(n))throw new Error("manager_event_source_untrusted");De(_e);const C=null,O="";if(o?.source==="room_activation"&&(Oe(o,G,I),A==="manager"))throw new Error("managed_agent_manager_mode_unsupported");if(o?.source==="manager_event"){if(!o.managedAgentPolicy)throw new Error("managed_agent_policy_missing");if(!I||!/^mrc_[A-Za-z0-9_-]{43}$/.test(I))throw new Error("managed_room_context_unavailable")}if(Je(e,n.id),!a||!b){e.processedReqIds.delete(n.id),e.client.sendRes({type:"res",id:c,ok:!1,error:"sessionId and text are required"});return}if(e.recoveryBarrier?.isDispatchFrozen()){e.processedReqIds.delete(n.id),e.client.sendRes({type:"res",id:c,ok:!1,error:"upgrade_in_progress"});return}e.recoveryBarrier?.isRecovering(a)&&await e.recoveryBarrier.wait(a);const d=A,w=d==="manager"||ve==="manager"?"manager":"standard";w==="manager"&&e.managerRuntime?.setManagerWorkerDefaults(a,W??null,q??null);const E=(d==="claude"||d==="codex"||d==="workbuddy"||d==="pi-coding-agent"||d.startsWith("acp:"))&&typeof j=="string"&&j.trim()?j.trim():void 0,f=e.resolvePath(je(d,he||de.homedir(),m)||de.homedir()),y=o?.managedAgentPolicy??(u?e.managerRuntime?.getManagedAgentPolicyForWorker(u,f)??null:null);if(u&&!J&&!y)throw new Error("managed_worker_permission_context_unavailable");const H=d==="codex"&&(o?.source==="room_activation"||o?.source==="manager_event"||u)?"internal":"user",z=u&&y?We({requestedPolicy:y.requestedPolicy,enforcement:y.enforcement,resolvedWorkDir:y.adapterPolicy.workDir}):G??null,ke=f,$=Te(n.params.attachments);$?.length&&be(f,$);const p={text:b,attachments:$,localized:!1};let t=e.sessions.get(a);if(t){if(t.lastActiveAt=Date.now(),t.agentType!==d||(t.sessionMode??(t.agentType==="manager"?"manager":"standard"))!==w||t.workDir!==f||(t.nativeSessionVisibility??"user")!==H||JSON.stringify(t.externalChannel??null)!==JSON.stringify(C??null)){e.sessions.delete(a);try{await x(e,t)}catch{e.processedReqIds.delete(n.id)}t=void 0}else if(m&&t.agentSessionId!==m)try{await t.adapter.resume(m),t.agentSessionId=m}catch{e.sessions.delete(a);try{await x(e,t)}catch{e.processedReqIds.delete(n.id)}t=void 0}}if(!t)try{t=await Fe(e,a,d,w,f,m,C,O,y,H)}catch(r){const i=r instanceof Error&&r.message.startsWith("Unsupported agent:")?r.message:`Failed to start ${A}: ${r instanceof Error?r.message:String(r)}`;console.error(`[chat.send] start failed reqId=${n.id} sessionId=${a} agentType=${A} workDir=${f} agentSessionId=${m??""}: ${i}`),e.client.sendEvent({type:"event",event:"agent",payload:{state:"error",sessionId:a,message:i,runId:"",seq:0}}),e.processedReqIds.delete(n.id),e.client.sendRes({type:"res",id:c,ok:!1,error:i});return}const g={id:Ie??`user-${n.id}`,sessionId:a,role:"user",ts:Date.now(),payload:le(p.text,p.attachments)},ee=Array.isArray(F)&&F.length>0?F.map(r=>({id:r.clientMessageId??r.id,sessionId:a,role:M==="manager_event"||n.params.scheduledDelivery===!0?"agent":"user",ts:M==="manager_event"?Date.parse(r.createdAt):g.ts,payload:le(r.text,r.attachments)})):null,k=ee??[g],N=Me(a,g.id),ne=N.state==="queued";if(N.state!=="not_found"&&!ne){e.client.sendRes({type:"res",id:c,ok:!0,payload:N});return}if(X){(o?.source==="room_activation"||o?.source==="manager_event")&&ue(t.adapter,a,d,C,O,I,o.managedAgentPolicy,e.managedRoomExecutor);try{await Be(t.adapter,p.text,h,E,p.attachments,z,o?.source==="room_activation"?{source:"room_activation"}:o?.source==="manager_event"?{source:"managed_private"}:void 0)}catch(r){e.processedReqIds.delete(n.id),e.sessions.delete(a),await x(e,t),e.client.sendRes({type:"res",id:c,ok:!1,error:r instanceof Error?r.message:String(r)});return}}T({level:"info",sessionId:a,wsEvent:"chat.send.start",metadata:{reqId:n.id,agentType:d,sessionMode:w,managerConfig:Z??null,modelId:h,managerDefaultWorkerAgentType:W??null,managerDefaultWorkerModelId:q??null,reasoningEffort:E,...o?.source==="room_activation"?{managedRoomPromptSnapshot:o.managedRoomPromptSnapshot}:{}}});const S=(r,i)=>({...$e(ge()),sessionId:a,clientMessageId:g.id,messageId:g.id,deliveryState:r,bodyRevision:i,committedAt:new Date(g.ts).toISOString()}),U=r=>{e.nativeFusion?.registerManagedSend({sessionId:a,agentType:d,sourceAgentType:qe(d,h),canonicalMessageId:g.id,sourceSessionKey:t.agentSessionId??m??null,text:p.text,managedEchoPolicy:r?.deliveryMode==="external_owner_queue"&&!we?"import_following":"suppress_following",externalRunId:r?.deliveryMode==="external_owner_queue"?`codex-external-${r.queuedSubmissionId??g.id}`:null})},ae=()=>{t.currentRunId||(t.currentRunId=`dispatch:${n.id}`,t.currentRunPhase="thinking",t.nextEventSeq=0)},oe=()=>{if(!e.runJournal||t.journalRunId)return;const r=`run:${Ae()}`;e.runJournal.begin({daemonInstallationId:ge(),sessionId:a,runId:r,clientMessageId:g.id,agentType:d,sessionMode:w,workDir:f,agentSessionId:t.agentSessionId??m??null,modelId:h??null,reasoningEffort:E??null,nativeSessionVisibility:H,providerRunId:null,source:M==="manager_event"?"manager_event":o?.source==="room_activation"?M==="managed_direct"?"managed_direct":"managed_room":u?"manager_worker":"personal",parentSessionId:u??null,managerWorkerNativeFull:J===!0,roomContextRegistryKey:typeof n.params.roomContextRegistryKey=="string"?n.params.roomContextRegistryKey:null,activationCauseMessageId:typeof n.params.activationCauseMessageId=="string"?n.params.activationCauseMessageId:null,rootCauseMessageId:typeof n.params.rootCauseMessageId=="string"?n.params.rootCauseMessageId:null,activationSequence:typeof n.params.activationSequence=="string"?n.params.activationSequence:null,activationHopCount:typeof n.params.activationHopCount=="number"?n.params.activationHopCount:null,managedPolicyVersion:o?.source==="room_activation"?o.managedRoomPromptSnapshot.managedRoomPolicyVersion:o?.source==="manager_event"?o.managedRoomPolicyVersion:null,managedRuntimePolicyHash:(o?.source==="room_activation"?o.managedRoomPromptSnapshot.runtimePermissionPolicyHash:o?.source==="manager_event"?o.managedRuntimePolicyHash:null)??(y?Q("sha256").update(JSON.stringify({requestedPolicy:y.requestedPolicy,enforcement:y.enforcement})).digest("hex"):null)}),t.journalRunId=r},re=()=>{if(U(),ne){let r=0;for(const[i,s]of k.entries()){const v=_(a,s,"queued");i===0&&(r=v)}return S("queued",r)}try{He(e,{sessionId:a,agentType:d,sessionMode:w,managerConfig:Z??null,workDir:ke,agentSessionId:t.agentSessionId??m??null,modelId:h,managerDefaultWorkerAgentType:W??null,managerDefaultWorkerModelId:q??null});let r=0;for(const[i,s]of k.entries()){const v=ee?_(a,s,"committed"):ce(a,s,"committed");i===0&&(r=v)}return Ce(f,$??[]),R(e.client),S("committed",r)}catch(r){throw e.nativeFusion?.cancelManagedSend?.(g.id),r}},te=r=>{t.journalRunId&&e.runJournal?.update(a,t.journalRunId,{deliveryMode:r?.deliveryMode==="external_owner_queue"?"external_owner_queue":"direct",externalRunId:r?.deliveryMode==="external_owner_queue"?`codex-external-${r.queuedSubmissionId??g.id}`:null})},se=r=>{t.currentRunId||(t.nextEventSeq=0),te(r),U(r);const i=r?.deliveryMode==="external_owner_queue"?"queued":"executing";let s=0;for(const[v,D]of k.entries()){const P=_(a,D,i);v===0&&(s=P)}return R(e.client),S(i,s)},V=async(r,i)=>{e.nativeFusion?.cancelManagedSend?.(g.id);const s=ye(d,r);if(console.error(`[chat.send] send failed reqId=${n.id} sessionId=${a} agentType=${A} workDir=${f} agentSessionId=${t.agentSessionId??m??""}: ${s}`),t.adapter.hasPendingAuthenticationRetry?.()===!0){i&&e.client.sendRes({type:"res",id:c,ok:!0,payload:S("queued",0)});return}e.sessions.delete(a),t.journalRunId&&(e.runJournal?.update(a,t.journalRunId,{phase:"terminal"}),e.runJournal?.remove(a,t.journalRunId),e.recoveryBarrier?.end(a),t.journalRunId=null);try{await x(e,t)}catch{}if(e.client.sendEvent({type:"event",event:"agent",payload:{state:"error",sessionId:a,message:s,runId:"",seq:0}}),!i){const D={id:`agent-error-${n.id}-${Date.now()}`,sessionId:a,role:"agent",ts:Date.now(),payload:s};ce(a,D),R(e.client)}i&&(e.processedReqIds.delete(n.id),e.client.sendRes({type:"res",id:c,ok:!1,error:s}))};if(X){try{re()}catch(s){e.processedReqIds.delete(n.id),e.client.sendRes({type:"res",id:c,ok:!1,error:`Durable message commit failed: ${s instanceof Error?s.message:String(s)}`});return}oe(),ae();let r;try{(o?.source==="room_activation"||o?.source==="manager_event")&&(me(e,t,I),l());const s=p.attachments;u&&e.managerRuntime?.prepareWorkerTurnOrigin(a,B),r=await fe(t.adapter,p.text,h,E,s,z,o?.source==="room_activation"?{source:"room_activation"}:o?.source==="manager_event"?{source:"managed_private"}:void 0),T({level:"info",sessionId:a,wsEvent:"chat.send.done",metadata:{reqId:n.id}})}catch(s){if(u&&e.managerRuntime?.prepareWorkerTurnOrigin(a),t.adapter.hasPendingAuthenticationRetry?.()){let P=0;for(const[K,L]of k.entries()){const Pe=_(a,L,"queued");K===0&&(P=Pe)}R(e.client),await V(s,!1),e.client.sendRes({type:"res",id:c,ok:!0,payload:S("queued",P)});return}let v=0;for(const[P,K]of k.entries()){const L=_(a,K,"failed");P===0&&(v=L)}R(e.client);const D=ye(d,s);await V(s,!1),e.client.sendRes({type:"res",id:c,ok:!0,payload:{...S("failed",v),failureMessage:D}});return}const i=se(r??void 0);e.client.sendRes({type:"res",id:c,ok:!0,payload:{...i,...p.localized?{localizedAttachments:!0}:{},...r?.deliveryMode==="external_owner_queue"?{queued:!0,deliveryMode:r.deliveryMode,queuedSubmissionId:r.queuedSubmissionId}:{}}}),T({level:"info",sessionId:a,wsEvent:"chat.send.res",metadata:{reqId:n.id,ok:!0}});return}let ie;try{ie=re()}catch(r){e.processedReqIds.delete(n.id),e.client.sendRes({type:"res",id:c,ok:!1,error:`Durable message commit failed: ${r instanceof Error?r.message:String(r)}`});return}oe(),ae(),(o?.source==="room_activation"||o?.source==="manager_event")&&(ue(t.adapter,a,d,C,O,I,o.managedAgentPolicy,e.managedRoomExecutor),me(e,t,I),l()),se(),e.client.sendRes({type:"res",id:c,ok:!0,payload:{...ie,...p.localized?{localizedAttachments:!0}:{}}}),T({level:"info",sessionId:a,wsEvent:"chat.send.res",metadata:{reqId:n.id,ok:!0}});const Se=p.attachments;u&&e.managerRuntime?.prepareWorkerTurnOrigin(a,B),fe(t.adapter,p.text,h,E,Se,z,o?.source==="room_activation"?{source:"room_activation"}:o?.source==="manager_event"?{source:"managed_private"}:void 0).then(r=>{if(r?.deliveryMode==="external_owner_queue"){te(r),U(r);for(const i of k)_(a,i,"queued");R(e.client)}T({level:"info",sessionId:a,wsEvent:"chat.send.done",metadata:{reqId:n.id}})}).catch(r=>{u&&e.managerRuntime?.prepareWorkerTurnOrigin(a),_(a,g,t.adapter.hasPendingAuthenticationRetry?.()?"queued":"failed"),R(e.client),V(r,!1)})}async function ln(e,n){const{sessionId:o,discardPending:l}=n.params,a=e.sessions.get(o);if(a){a.journalRunId&&e.runJournal?.markAborted(o,a.journalRunId),pe(e,a);try{await a.adapter.stop()}catch{e.client.sendRes({type:"res",id:n.id,ok:!1,error:"agent_stop_failed"});return}ze(e,o),e.activityPublisher?.publish(o,null)}l===!0&&e.chatQueue?.purgeSession(o),e.client.sendRes({type:"res",id:n.id,ok:!0})}export{ln as handleChatAbort,dn as handleChatSend,He as sendSessionUpdateEvent,Oe as validateManagedRoomExecutionContext};
@@ -1,2 +1,2 @@
1
1
  import r from"node:fs";import{randomUUID as a}from"node:crypto";import{resolvePersonalSyncV1Path as i}from"../personal-sync/paths.js";function c(){try{const e=JSON.parse(r.readFileSync(i("outbound-queue.json"),"utf-8"));return{sessions:e.sessions&&typeof e.sessions=="object"?e.sessions:{}}}catch(e){if(e.code==="ENOENT"||e instanceof Error&&e.message.startsWith("ENOENT:"))return{sessions:{}};throw e}}function u(e){const o=i();r.mkdirSync(o,{recursive:!0,mode:448});const t=i("outbound-queue.json"),s=`${t}.tmp-${process.pid}-${a()}`;try{r.writeFileSync(s,`${JSON.stringify(e,null,2)}
2
- `,{encoding:"utf8",mode:384,flag:"wx"});const n=r.openSync(s,"r");if(typeof n=="number")try{r.fsyncSync(n)}finally{r.closeSync(n)}r.renameSync(s,t)}finally{try{r.unlinkSync(s)}catch{}}}function y(e){const o=c();o.sessions[e]&&(delete o.sessions[e],u(o))}function g(){const e=c();let o=!1;for(const t of Object.values(e.sessions))for(const s of t){const n=s.trigger;!n||n.kind!=="manager_event"&&n.kind!=="manager_worker"||!n.roomOrigin||(delete n.roomOrigin,o=!0)}o&&u(e)}export{g as clearPersistedManagerRoomOrigins,y as purgeQueuedSessionData,c as readQueue,u as writeQueue};
2
+ `,{encoding:"utf8",mode:384,flag:"wx"});const n=r.openSync(s,"r+");if(typeof n=="number")try{r.fsyncSync(n)}finally{r.closeSync(n)}r.renameSync(s,t)}finally{try{r.unlinkSync(s)}catch{}}}function y(e){const o=c();o.sessions[e]&&(delete o.sessions[e],u(o))}function g(){const e=c();let o=!1;for(const t of Object.values(e.sessions))for(const s of t){const n=s.trigger;!n||n.kind!=="manager_event"&&n.kind!=="manager_worker"||!n.roomOrigin||(delete n.roomOrigin,o=!0)}o&&u(e)}export{g as clearPersistedManagerRoomOrigins,y as purgeQueuedSessionData,c as readQueue,u as writeQueue};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shennian",
3
- "version": "0.4.67",
3
+ "version": "0.4.69",
4
4
  "description": "Shennian — AI Agent Control Plane CLI",
5
5
  "type": "module",
6
6
  "bin": {