shennian 0.2.135 → 0.2.137

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": 137,
5
+ "fileCount": 138,
6
6
  "files": [
7
7
  {
8
8
  "file": "bin/shennian.js",
@@ -86,13 +86,13 @@
86
86
  },
87
87
  {
88
88
  "file": "src/agents/model-registry/discovery.js",
89
- "beforeBytes": 6872,
90
- "afterBytes": 3206
89
+ "beforeBytes": 6946,
90
+ "afterBytes": 3266
91
91
  },
92
92
  {
93
93
  "file": "src/agents/model-registry/parsers.js",
94
- "beforeBytes": 16473,
95
- "afterBytes": 8011
94
+ "beforeBytes": 18044,
95
+ "afterBytes": 8783
96
96
  },
97
97
  {
98
98
  "file": "src/agents/model-registry/runner.js",
@@ -111,8 +111,8 @@
111
111
  },
112
112
  {
113
113
  "file": "src/agents/model-registry.js",
114
- "beforeBytes": 918,
115
- "afterBytes": 829
114
+ "beforeBytes": 964,
115
+ "afterBytes": 876
116
116
  },
117
117
  {
118
118
  "file": "src/agents/openclaw.js",
@@ -534,6 +534,11 @@
534
534
  "beforeBytes": 68372,
535
535
  "afterBytes": 34842
536
536
  },
537
+ {
538
+ "file": "src/native-fusion/codex-parser.js",
539
+ "beforeBytes": 27013,
540
+ "afterBytes": 11324
541
+ },
537
542
  {
538
543
  "file": "src/native-fusion/config.js",
539
544
  "beforeBytes": 225,
@@ -551,8 +556,8 @@
551
556
  },
552
557
  {
553
558
  "file": "src/native-fusion/parsers.js",
554
- "beforeBytes": 30717,
555
- "afterBytes": 13191
559
+ "beforeBytes": 5325,
560
+ "afterBytes": 2730
556
561
  },
557
562
  {
558
563
  "file": "src/native-fusion/service.js",
@@ -1,2 +1,2 @@
1
- import{createInterface as m}from"node:readline";import{resolveBuiltinCommand as c,spawnResolvedCommand as v}from"../command-spec.js";import{fallbackClaudeAliasModels as M,discoverClaudeAliasModelsFromEnv as w,fallbackGeminiModels as C,parseCodexAppServerModels as y,parseCursorModels as h,parseOpenCodeModels as g}from"./parsers.js";import{runResolvedCommand as f}from"./runner.js";import{DISCOVERY_WORKDIR as E}from"./types.js";import{buildAgentProcessEnv as O,readLatestUserEnv as R}from"../../agent-env.js";import{CODEX_APP_SERVER_CLIENT_INFO as S}from"../codex-utils.js";function l(e,r,o,i,a,n){return e.stdin?new Promise((t,s)=>{const u=setTimeout(()=>{r.delete(o),s(new Error(`codex app-server request timed out: ${i}`))},n);r.set(o,{resolve:t,reject:s,timer:u}),e.stdin.write(`${JSON.stringify({id:o,method:i,params:a})}
2
- `,p=>{p&&(clearTimeout(u),r.delete(o),s(p))})}):Promise.reject(new Error("codex app-server stdin unavailable"))}async function x(e){const r=v(e,["app-server","--listen","stdio://"],{cwd:E,stdio:["pipe","pipe","pipe"],env:O({NO_COLOR:"1"})}),o=new Map;let i=1;m({input:r.stdout}).on("line",n=>{if(!n.trim())return;let t;try{t=JSON.parse(n)}catch{return}if(t.id==null)return;const s=o.get(t.id);s&&(clearTimeout(s.timer),o.delete(t.id),t.error?s.reject(new Error(t.error.message||`codex app-server error ${t.error.code??""}`.trim())):s.resolve(t.result))});try{await l(r,o,i++,"initialize",{clientInfo:S,capabilities:{experimentalApi:!0}},1e4);const[n,t]=await Promise.all([l(r,o,i++,"model/list",{},15e3),l(r,o,i++,"config/read",{},15e3).catch(()=>null)]),s=typeof t=="object"&&t!==null&&"config"in t?t.config:void 0;return y({...typeof n=="object"&&n!==null?n:{},config:s})}finally{for(const[n,t]of o)clearTimeout(t.timer),t.reject(new Error("codex app-server stopped")),o.delete(n);r.kill("SIGTERM"),setTimeout(()=>r.kill("SIGKILL"),1e3).unref()}}async function A(){const e=c("cursor");if(!e)return[];const r=await f(e,["--list-models"]);return h(r.stdout)}async function I(){const e=c("opencode");if(!e)return[];const r=await f(e,["models"]);return g(r.stdout)}async function P(){if(!c("claude"))return[];const e=w(R());return e.length>0?e:M()}async function T(){const e=c("codex");return e?await x(e).catch(()=>[]):[]}async function _(){return c("gemini")?C():[]}const d=[{id:"qwen3.6-plus",name:"Qwen 3.6 Plus",provider:"dashscope",isDefault:!0}],b=[{id:"codex",name:"Codex",provider:"shennian",isDefault:!0},{id:"claude",name:"Claude Code",provider:"shennian"}];async function k(e){if(!e.serverUrl||!e.authToken)return d;try{const r=await fetch(`${e.serverUrl.replace(/\/$/,"")}/api/models`,{headers:{Authorization:`Bearer ${e.authToken}`}});if(!r.ok)return d;const o=await r.json(),i=(o.models??[]).map(a=>({id:a.id,name:a.name?.trim()||a.id,provider:a.provider,isDefault:a.id===o.default}));return i.length>0?i:d}catch{return d}}async function D(e,r){switch(e){case"claude":return P();case"codex":return T();case"gemini":return _();case"cursor":return A();case"openclaw":return[];case"opencode":return I();case"pi":return k(r);case"manager":return b}}async function F(e,r){return e.type.startsWith("custom:")?e.models??[]:D(e.type,r)}export{F as discoverModelsForAgent};
1
+ import{createInterface as m}from"node:readline";import{resolveBuiltinCommand as c,spawnResolvedCommand as v}from"../command-spec.js";import{fallbackClaudeAliasModels as M,discoverClaudeAliasModelsFromEnv as C,fallbackCodexModels as w,fallbackGeminiModels as y,parseCodexAppServerModels as h,parseCursorModels as g,parseOpenCodeModels as E}from"./parsers.js";import{runResolvedCommand as f}from"./runner.js";import{DISCOVERY_WORKDIR as x}from"./types.js";import{buildAgentProcessEnv as O,readLatestUserEnv as R}from"../../agent-env.js";import{CODEX_APP_SERVER_CLIENT_INFO as A}from"../codex-utils.js";function d(e,r,o,i,a,n){return e.stdin?new Promise((t,s)=>{const u=setTimeout(()=>{r.delete(o),s(new Error(`codex app-server request timed out: ${i}`))},n);r.set(o,{resolve:t,reject:s,timer:u}),e.stdin.write(`${JSON.stringify({id:o,method:i,params:a})}
2
+ `,p=>{p&&(clearTimeout(u),r.delete(o),s(p))})}):Promise.reject(new Error("codex app-server stdin unavailable"))}async function S(e){const r=v(e,["app-server","--listen","stdio://"],{cwd:x,stdio:["pipe","pipe","pipe"],env:O({NO_COLOR:"1"})}),o=new Map;let i=1;m({input:r.stdout}).on("line",n=>{if(!n.trim())return;let t;try{t=JSON.parse(n)}catch{return}if(t.id==null)return;const s=o.get(t.id);s&&(clearTimeout(s.timer),o.delete(t.id),t.error?s.reject(new Error(t.error.message||`codex app-server error ${t.error.code??""}`.trim())):s.resolve(t.result))});try{await d(r,o,i++,"initialize",{clientInfo:A,capabilities:{experimentalApi:!0}},1e4);const[n,t]=await Promise.all([d(r,o,i++,"model/list",{},15e3),d(r,o,i++,"config/read",{},15e3).catch(()=>null)]),s=typeof t=="object"&&t!==null&&"config"in t?t.config:void 0;return h({...typeof n=="object"&&n!==null?n:{},config:s})}finally{for(const[n,t]of o)clearTimeout(t.timer),t.reject(new Error("codex app-server stopped")),o.delete(n);r.kill("SIGTERM"),setTimeout(()=>r.kill("SIGKILL"),1e3).unref()}}async function b(){const e=c("cursor");if(!e)return[];const r=await f(e,["--list-models"]);return g(r.stdout)}async function k(){const e=c("opencode");if(!e)return[];const r=await f(e,["models"]);return E(r.stdout)}async function I(){if(!c("claude"))return[];const e=C(R());return e.length>0?e:M()}async function P(){const e=c("codex");if(!e)return[];const r=await S(e).catch(()=>[]);return r.length>0?r:w()}async function T(){return c("gemini")?y():[]}const l=[{id:"qwen3.6-plus",name:"Qwen 3.6 Plus",provider:"dashscope",isDefault:!0}],_=[{id:"codex",name:"Codex",provider:"shennian",isDefault:!0},{id:"claude",name:"Claude Code",provider:"shennian"}];async function D(e){if(!e.serverUrl||!e.authToken)return l;try{const r=await fetch(`${e.serverUrl.replace(/\/$/,"")}/api/models`,{headers:{Authorization:`Bearer ${e.authToken}`}});if(!r.ok)return l;const o=await r.json(),i=(o.models??[]).map(a=>({id:a.id,name:a.name?.trim()||a.id,provider:a.provider,isDefault:a.id===o.default}));return i.length>0?i:l}catch{return l}}async function L(e,r){switch(e){case"claude":return I();case"codex":return P();case"gemini":return T();case"cursor":return b();case"openclaw":return[];case"opencode":return k();case"pi":return D(r);case"manager":return _}}async function U(e,r){return e.type.startsWith("custom:")?e.models??[]:L(e.type,r)}export{U as discoverModelsForAgent};
@@ -1,5 +1,6 @@
1
1
  import type { ModelInfo } from '@shennian/wire';
2
2
  export declare function stripAnsi(text: string): string;
3
+ export declare function fallbackCodexModels(): ModelInfo[];
3
4
  export declare function parseCursorModels(raw: string): ModelInfo[];
4
5
  export declare function parseOpenClawModels(raw: string): ModelInfo[];
5
6
  export declare function parseOpenCodeModels(raw: string): ModelInfo[];
@@ -1,4 +1,4 @@
1
- function m(n){return n.replace(/\u001b\[[0-9;?]*[a-zA-Z]/g,"").replace(/\u001b\][^\u0007]*\u0007/g,"").replace(/[\u0000-\u0008\u000b-\u001f\u007f]/g,"")}function c(n){const e=new Set,o=[];for(const t of n)!t.id||e.has(t.id)||(e.add(t.id),o.push(t));return o}function h(n){return n&&n[0].toUpperCase()+n.slice(1)}function A(n){return n.split("-").map(e=>e==="gpt"?"GPT":e==="codex"?"Codex":/^\d/.test(e)?e:h(e)).join("-")}function M(n){switch(n){case"low":return"Low";case"medium":return"Medium";case"high":return"High";case"xhigh":return"Extra High";default:return h(n)}}function O(n){return n.split("-").map(e=>/^\d/.test(e)?e:h(e)).join(" ")}function S(n,e,o=!1){const t=e.toLowerCase().replace(/\s+/g,"-");return`gemini-${n}-${t}${o?"-preview":""}`}function H(n){const e=[],o=m(n);for(const t of o.split(`
2
- `)){const i=t.trim().match(/^(\S+)\s+-\s+(.+?)(?:\s+\(([^)]+)\))?$/);if(!i)continue;const[,s,r,a]=i,u=a?.split(",").map(d=>d.trim().toLowerCase())??[];e.push({id:s,name:r.trim()||O(s),description:a?.trim(),isDefault:u.includes("default")||u.includes("current")})}return c(e)}function T(n){try{const o=(JSON.parse(n).models??[]).filter(t=>t.available).map(t=>({id:t.key,name:t.name?.trim()||t.key,provider:t.key.split("/")[0],description:t.tags?.join(", "),isDefault:t.tags?.includes("default")??!1}));return c(o)}catch{return[]}}function F(n){const e=m(n).split(`
3
- `).map(o=>o.trim()).filter(Boolean).filter(o=>!o.includes(" ")).map(o=>({id:o,name:o,provider:o.includes("/")?o.split("/")[0]:void 0}));return c(e)}function G(n){const e=m(n).replace(/\s+/g," "),o=[[/\d+\.Default\(recommended\).*?(?:Sonnet|currently\s*Sonnet)\s*([\d.]+)/i,"default","Default (recommended)"],[/\d+\.Sonnet.*?Sonnet\s*([\d.]+)/i,"sonnet","Sonnet"],[/\d+\.Opus.*?Opus\s*([\d.]+)/i,"opus","Opus"],[/\d+\.Haiku.*?Haiku\s*([\d.]+)/i,"haiku","Haiku"]],t=[];for(const[a,u,d]of o){const l=e.match(a);l&&t.push(g({id:u,name:d,description:`v${l[1]}`,provider:"anthropic",isDefault:u==="default"}))}if(t.length>0)return c(t);const i=[],s=e.match(/currently\s*(Sonnet|Opus|Haiku)\s*([34](?:\.\d)?)/i),r={sonnet:"sonnet",opus:"opus",haiku:"haiku"};for(const a of e.matchAll(/\b(Sonnet|Opus|Haiku)\s*([34](?:\.\d)?)\b/gi)){const u=(a[1]??"").toLowerCase(),d=r[u];if(!d)continue;const l=a[2]??"",v=s&&s[1]?.toLowerCase()===u&&s[2]===l;i.push(g({id:d,name:`${h(u)} ${l}`,provider:"anthropic",isDefault:!!v}))}return c(i)}function _(n,e){const o=Math.max(n.length,e.length);for(let t=0;t<o;t++){const i=n[t]??-1,s=e[t]??-1;if(i!==s)return i-s}return 0}function R(n,e){const o=n.match(new RegExp(`^claude-${e}-([0-9]+(?:-[0-9]+)*)$`,"i"));if(!o?.[1])return null;const t=o[1].split("-").map(i=>Number.parseInt(i,10)).filter(i=>Number.isFinite(i));return t.length===0||t.length>2?null:t}function k(n){if(n?.length)return`v${n.join(".")}`}const C={default:"Default (recommended)",sonnet:"Sonnet",opus:"Opus",haiku:"Haiku"},y={default:"ANTHROPIC_MODEL",sonnet:"ANTHROPIC_DEFAULT_SONNET_MODEL",opus:"ANTHROPIC_DEFAULT_OPUS_MODEL",haiku:"ANTHROPIC_DEFAULT_HAIKU_MODEL"},w=[{id:"max",name:"Max"}],$=[{id:"low",name:"Low"},{id:"medium",name:"Medium"},{id:"high",name:"High"},{id:"xhigh",name:"Extra High"},{id:"max",name:"Max"}];function g(n){return{...n,supportedReasoningEfforts:$,defaultReasoningEffort:"medium"}}function E(n,e){return n[e]?.trim()||null}function D(n,e){const o=E(e,"ANTHROPIC_BASE_URL")?.toLowerCase()??"";return o.includes("deepseek.com")||n.toLowerCase().startsWith("deepseek-")?"deepseek":o?"custom":"anthropic"}function x(n){const e=new Set;for(const t of Object.values(y)){const i=E(n,t);i&&e.add(i)}const o=Array.from(e).map((t,i)=>{const s=D(t,n),r={id:t,name:t,provider:s,isDefault:i===0};return s==="deepseek"?{...r,supportedReasoningEfforts:w,defaultReasoningEffort:E(n,"CLAUDE_CODE_EFFORT_LEVEL")??"max"}:g(r)});return c(o)}function I(n=process.env){return x(n)}function N(n,e=process.env){return n.map(o=>{if(!["default","sonnet","opus","haiku"].includes(o.id))return o;const t=o.id,i=E(e,y[t]);if(!i)return o;const r=`Claude Code alias: ${C[t]}`;return{...o,name:i,description:o.description?`${r} \xB7 ${o.description}`:r,provider:D(i,e)}})}function U(n){const e=m(n),o=new Map;for(const i of["sonnet","opus","haiku"])for(const s of e.matchAll(new RegExp(`\\bclaude-${i}-[0-9.-]+\\b`,"gi"))){const r=s[0].trim().toLowerCase().replace(/\./g,"-").replace(/-+$/g,""),a=R(r,i);if(!a)continue;const u=o.get(i);(!u||_(u,a)<0)&&o.set(i,a)}const t=[];for(const i of["default","sonnet","opus","haiku"]){if(!new RegExp(`\\b${i}\\b`,"i").test(e))continue;const s=(i==="default"?o.get("sonnet"):o.get(i))??null;t.push(g({id:i,name:C[i],description:k(s),provider:"anthropic",isDefault:i==="default"}))}return c(t)}function P(n=process.env){const e=x(n);return e.length>0?e:N([{id:"default",name:"Default (recommended)",provider:"anthropic",isDefault:!0},{id:"sonnet",name:"Sonnet",provider:"anthropic"},{id:"opus",name:"Opus",provider:"anthropic"},{id:"haiku",name:"Haiku",provider:"anthropic"}],n).map(g)}function j(n){const e=m(n),o=[];for(const t of e.split(`
4
- `)){const i=t.match(/\b(gpt-[a-z0-9][a-z0-9.-]*)\b/i);if(!i)continue;const s=i[1].trim(),r=t.replace(s,"").replace(/^[^\w]+/,"").trim()||void 0;o.push({id:s,name:A(s),description:r,provider:"openai",isDefault:/\bcurrent\b/i.test(t)||/\bselected\b/i.test(t)})}return c(o)}function V(n){const e=typeof n=="object"&&n!==null?n:{},o=typeof e.config?.model=="string"?e.config.model:void 0,t=typeof e.config?.model_reasoning_effort=="string"?e.config.model_reasoning_effort:void 0,i=[];for(const s of e.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,d=typeof r.description=="string"?r.description:void 0,l=typeof r.defaultReasoningEffort=="string"?r.defaultReasoningEffort:void 0,v=Array.isArray(r.supportedReasoningEfforts)?r.supportedReasoningEfforts.map(f=>{if(typeof f!="object"||f===null)return null;const p=f,b=typeof p.reasoningEffort=="string"?p.reasoningEffort:typeof p.id=="string"?p.id:"";return b?{id:b,name:M(b),description:typeof p.description=="string"?p.description:void 0}:null}).filter(f=>f!=null):void 0,L=Array.isArray(r.additionalSpeedTiers)?r.additionalSpeedTiers.filter(f=>typeof f=="string"):void 0;i.push({id:a,name:u||A(a),description:d,provider:"openai",isDefault:o?o===a:r.isDefault===!0,supportedReasoningEfforts:v,defaultReasoningEffort:l,additionalSpeedTiers:L})}return o&&!i.some(s=>s.id===o)&&i.unshift({id:o,name:A(o),provider:"openai",isDefault:!0,defaultReasoningEffort:t}),c(i)}function z(n){const e=m(n),o=[];for(const t of e.matchAll(/\b(?:auto-)?gemini-[a-z0-9.-]+\b/gi)){const i=t[0].trim();o.push({id:i,name:i,provider:"google",isDefault:/\bcurrent\b/i.test(e)&&e.includes(i)})}for(const t of e.matchAll(/\bGemini\s*(\d(?:\.\d)?)\s*(Pro|Flash(?:[- ]Lite)?)\s*(Preview)?\b/gi)){const i=t[1]??"",s=(t[2]??"").replace(/\s+/g,"-"),r=!!t[3],a=S(i,s,r);o.push({id:a,name:`Gemini ${i} ${s.replace(/-/g," ")}`.trim(),provider:"google",isDefault:/\bcurrent\b/i.test(e)&&e.includes(t[0]??"")})}for(const t of e.matchAll(/\bAuto\s*Gemini\s*(\d(?:\.\d)?)\b/gi)){const i=t[1]??"",s=`auto-gemini-${i}`;o.push({id:s,name:`Auto Gemini ${i}`,provider:"google",isDefault:/\bcurrent\b/i.test(e)&&e.includes(t[0]??"")})}return c(o)}function B(){return[{id:"gemini-2.5-pro",name:"Gemini 2.5 Pro",provider:"google",isDefault:!0},{id:"gemini-2.5-flash",name:"Gemini 2.5 Flash",provider:"google"},{id:"auto-gemini-2.5",name:"Auto Gemini 2.5",provider:"google"}]}export{N as applyClaudeModelEnvOverrides,I as discoverClaudeAliasModelsFromEnv,P as fallbackClaudeAliasModels,B as fallbackGeminiModels,D as inferClaudeOverrideProvider,U as parseClaudeBinaryModels,G as parseClaudeModels,V as parseCodexAppServerModels,j as parseCodexModels,H as parseCursorModels,z as parseGeminiModels,T as parseOpenClawModels,F as parseOpenCodeModels,E as readEnvValue,m as stripAnsi};
1
+ function m(e){return e.replace(/\u001b\[[0-9;?]*[a-zA-Z]/g,"").replace(/\u001b\][^\u0007]*\u0007/g,"").replace(/[\u0000-\u0008\u000b-\u001f\u007f]/g,"")}function d(e){const n=new Set,t=[];for(const o of e)!o.id||n.has(o.id)||(n.add(o.id),t.push(o));return t}function h(e){return e&&e[0].toUpperCase()+e.slice(1)}function b(e){return e.split("-").map(n=>n==="gpt"?"GPT":n==="codex"?"Codex":/^\d/.test(n)?n:h(n)).join("-")}function O(e){switch(e){case"low":return"Low";case"medium":return"Medium";case"high":return"High";case"xhigh":return"Extra High";default:return h(e)}}const D=[{id:"gpt-5.6-sol",name:"GPT-5.6 Sol",description:"Latest GPT-5.6 Codex model.",provider:"openai"},{id:"gpt-5.6-terra",name:"GPT-5.6 Terra",description:"Latest GPT-5.6 Codex model.",provider:"openai"},{id:"gpt-5.6-luna",name:"GPT-5.6 Luna",description:"Latest GPT-5.6 Codex model.",provider:"openai"}];function A(e){const n={...e};return e.supportedReasoningEfforts&&(n.supportedReasoningEfforts=e.supportedReasoningEfforts.map(t=>({...t}))),e.additionalSpeedTiers&&(n.additionalSpeedTiers=[...e.additionalSpeedTiers]),n}function R(e,n){const t=n??e.find(i=>i.isDefault)?.id,o=d([...e.map(A),...D.map(i=>A(i))]);return t?o.map(i=>({...i,isDefault:i.id===t})):o}function H(){return D.map((e,n)=>({...A(e),...n===0?{isDefault:!0}:{}}))}function _(e){return e.split("-").map(n=>/^\d/.test(n)?n:h(n)).join(" ")}function k(e,n,t=!1){const o=n.toLowerCase().replace(/\s+/g,"-");return`gemini-${e}-${o}${t?"-preview":""}`}function F(e){const n=[],t=m(e);for(const o of t.split(`
2
+ `)){const i=o.trim().match(/^(\S+)\s+-\s+(.+?)(?:\s+\(([^)]+)\))?$/);if(!i)continue;const[,s,r,a]=i,u=a?.split(",").map(c=>c.trim().toLowerCase())??[];n.push({id:s,name:r.trim()||_(s),description:a?.trim(),isDefault:u.includes("default")||u.includes("current")})}return d(n)}function I(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 U(e){const n=m(e).split(`
3
+ `).map(t=>t.trim()).filter(Boolean).filter(t=>!t.includes(" ")).map(t=>({id:t,name:t,provider:t.includes("/")?t.split("/")[0]:void 0}));return d(n)}function j(e){const n=m(e).replace(/\s+/g," "),t=[[/\d+\.Default\(recommended\).*?(?:Sonnet|currently\s*Sonnet)\s*([\d.]+)/i,"default","Default (recommended)"],[/\d+\.Sonnet.*?Sonnet\s*([\d.]+)/i,"sonnet","Sonnet"],[/\d+\.Opus.*?Opus\s*([\d.]+)/i,"opus","Opus"],[/\d+\.Haiku.*?Haiku\s*([\d.]+)/i,"haiku","Haiku"]],o=[];for(const[a,u,c]of t){const l=n.match(a);l&&o.push(g({id:u,name:c,description:`v${l[1]}`,provider:"anthropic",isDefault:u==="default"}))}if(o.length>0)return d(o);const i=[],s=n.match(/currently\s*(Sonnet|Opus|Haiku)\s*([34](?:\.\d)?)/i),r={sonnet:"sonnet",opus:"opus",haiku:"haiku"};for(const a of n.matchAll(/\b(Sonnet|Opus|Haiku)\s*([34](?:\.\d)?)\b/gi)){const u=(a[1]??"").toLowerCase(),c=r[u];if(!c)continue;const l=a[2]??"",C=s&&s[1]?.toLowerCase()===u&&s[2]===l;i.push(g({id:c,name:`${h(u)} ${l}`,provider:"anthropic",isDefault:!!C}))}return d(i)}function T(e,n){const t=Math.max(e.length,n.length);for(let o=0;o<t;o++){const i=e[o]??-1,s=n[o]??-1;if(i!==s)return i-s}return 0}function w(e,n){const t=e.match(new RegExp(`^claude-${n}-([0-9]+(?:-[0-9]+)*)$`,"i"));if(!t?.[1])return null;const o=t[1].split("-").map(i=>Number.parseInt(i,10)).filter(i=>Number.isFinite(i));return o.length===0||o.length>2?null:o}function $(e){if(e?.length)return`v${e.join(".")}`}const x={default:"Default (recommended)",sonnet:"Sonnet",opus:"Opus",haiku:"Haiku"},y={default:"ANTHROPIC_MODEL",sonnet:"ANTHROPIC_DEFAULT_SONNET_MODEL",opus:"ANTHROPIC_DEFAULT_OPUS_MODEL",haiku:"ANTHROPIC_DEFAULT_HAIKU_MODEL"},G=[{id:"max",name:"Max"}],N=[{id:"low",name:"Low"},{id:"medium",name:"Medium"},{id:"high",name:"High"},{id:"xhigh",name:"Extra High"},{id:"max",name:"Max"}];function g(e){return{...e,supportedReasoningEfforts:N,defaultReasoningEffort:"medium"}}function E(e,n){return e[n]?.trim()||null}function L(e,n){const t=E(n,"ANTHROPIC_BASE_URL")?.toLowerCase()??"";return t.includes("deepseek.com")||e.toLowerCase().startsWith("deepseek-")?"deepseek":t?"custom":"anthropic"}function M(e){const n=new Set;for(const o of Object.values(y)){const i=E(e,o);i&&n.add(i)}const t=Array.from(n).map((o,i)=>{const s=L(o,e),r={id:o,name:o,provider:s,isDefault:i===0};return s==="deepseek"?{...r,supportedReasoningEfforts:G,defaultReasoningEffort:E(e,"CLAUDE_CODE_EFFORT_LEVEL")??"max"}:g(r)});return d(t)}function V(e=process.env){return M(e)}function P(e,n=process.env){return e.map(t=>{if(!["default","sonnet","opus","haiku"].includes(t.id))return t;const o=t.id,i=E(n,y[o]);if(!i)return t;const r=`Claude Code alias: ${x[o]}`;return{...t,name:i,description:t.description?`${r} \xB7 ${t.description}`:r,provider:L(i,n)}})}function z(e){const n=m(e),t=new Map;for(const i of["sonnet","opus","haiku"])for(const s of n.matchAll(new RegExp(`\\bclaude-${i}-[0-9.-]+\\b`,"gi"))){const r=s[0].trim().toLowerCase().replace(/\./g,"-").replace(/-+$/g,""),a=w(r,i);if(!a)continue;const u=t.get(i);(!u||T(u,a)<0)&&t.set(i,a)}const o=[];for(const i of["default","sonnet","opus","haiku"]){if(!new RegExp(`\\b${i}\\b`,"i").test(n))continue;const s=(i==="default"?t.get("sonnet"):t.get(i))??null;o.push(g({id:i,name:x[i],description:$(s),provider:"anthropic",isDefault:i==="default"}))}return d(o)}function B(e=process.env){const n=M(e);return n.length>0?n:P([{id:"default",name:"Default (recommended)",provider:"anthropic",isDefault:!0},{id:"sonnet",name:"Sonnet",provider:"anthropic"},{id:"opus",name:"Opus",provider:"anthropic"},{id:"haiku",name:"Haiku",provider:"anthropic"}],e).map(g)}function q(e){const n=m(e),t=[];for(const o of n.split(`
4
+ `)){const i=o.match(/\b(gpt-[a-z0-9][a-z0-9.-]*)\b/i);if(!i)continue;const s=i[1].trim(),r=o.replace(s,"").replace(/^[^\w]+/,"").trim()||void 0;t.push({id:s,name:b(s),description:r,provider:"openai",isDefault:/\bcurrent\b/i.test(o)||/\bselected\b/i.test(o)})}return d(t)}function K(e){const n=typeof e=="object"&&e!==null?e:{},t=typeof n.config?.model=="string"?n.config.model:void 0,o=typeof n.config?.model_reasoning_effort=="string"?n.config.model_reasoning_effort:void 0,i=[];for(const s of n.data??[]){if(typeof s!="object"||s===null)continue;const r=s,a=typeof r.id=="string"?r.id:typeof r.model=="string"?r.model:"";if(!a)continue;const u=typeof r.displayName=="string"?r.displayName:typeof r.name=="string"?r.name:void 0,c=typeof r.description=="string"?r.description:void 0,l=typeof r.defaultReasoningEffort=="string"?r.defaultReasoningEffort:void 0,C=Array.isArray(r.supportedReasoningEfforts)?r.supportedReasoningEfforts.map(f=>{if(typeof f!="object"||f===null)return null;const p=f,v=typeof p.reasoningEffort=="string"?p.reasoningEffort:typeof p.id=="string"?p.id:"";return v?{id:v,name:O(v),description:typeof p.description=="string"?p.description:void 0}:null}).filter(f=>f!=null):void 0,S=Array.isArray(r.additionalSpeedTiers)?r.additionalSpeedTiers.filter(f=>typeof f=="string"):void 0;i.push({id:a,name:u||b(a),description:c,provider:"openai",isDefault:t?t===a:r.isDefault===!0,supportedReasoningEfforts:C,defaultReasoningEffort:l,additionalSpeedTiers:S})}return t&&!i.some(s=>s.id===t)&&i.unshift({id:t,name:b(t),provider:"openai",isDefault:!0,defaultReasoningEffort:o}),R(d(i),t)}function J(e){const n=m(e),t=[];for(const o of n.matchAll(/\b(?:auto-)?gemini-[a-z0-9.-]+\b/gi)){const i=o[0].trim();t.push({id:i,name:i,provider:"google",isDefault:/\bcurrent\b/i.test(n)&&n.includes(i)})}for(const o of n.matchAll(/\bGemini\s*(\d(?:\.\d)?)\s*(Pro|Flash(?:[- ]Lite)?)\s*(Preview)?\b/gi)){const i=o[1]??"",s=(o[2]??"").replace(/\s+/g,"-"),r=!!o[3],a=k(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 W(){return[{id:"gemini-2.5-pro",name:"Gemini 2.5 Pro",provider:"google",isDefault:!0},{id:"gemini-2.5-flash",name:"Gemini 2.5 Flash",provider:"google"},{id:"auto-gemini-2.5",name:"Auto Gemini 2.5",provider:"google"}]}export{P as applyClaudeModelEnvOverrides,V as discoverClaudeAliasModelsFromEnv,B as fallbackClaudeAliasModels,H as fallbackCodexModels,W as fallbackGeminiModels,L as inferClaudeOverrideProvider,z as parseClaudeBinaryModels,j as parseClaudeModels,K as parseCodexAppServerModels,q as parseCodexModels,F as parseCursorModels,J as parseGeminiModels,I as parseOpenClawModels,U as parseOpenCodeModels,E as readEnvValue,m as stripAnsi};
@@ -1,9 +1,10 @@
1
1
  export { getCachedAgentInfos, refreshAgentInfos, resolveAgentInfos, } from './model-registry/service.js';
2
- import { applyClaudeModelEnvOverrides, discoverClaudeAliasModelsFromEnv, fallbackClaudeAliasModels, parseClaudeBinaryModels, parseClaudeModels, parseCodexModels, parseCodexAppServerModels, parseCursorModels, parseGeminiModels, parseOpenClawModels, stripAnsi } from './model-registry/parsers.js';
2
+ import { applyClaudeModelEnvOverrides, discoverClaudeAliasModelsFromEnv, fallbackCodexModels, fallbackClaudeAliasModels, parseClaudeBinaryModels, parseClaudeModels, parseCodexModels, parseCodexAppServerModels, parseCursorModels, parseGeminiModels, parseOpenClawModels, stripAnsi } from './model-registry/parsers.js';
3
3
  /** Used by Vitest / `model-switching-e2e.ts` — not a stable public API. */
4
4
  export declare const modelSwitchingTestExports: {
5
5
  readonly applyClaudeModelEnvOverrides: typeof applyClaudeModelEnvOverrides;
6
6
  readonly discoverClaudeAliasModelsFromEnv: typeof discoverClaudeAliasModelsFromEnv;
7
+ readonly fallbackCodexModels: typeof fallbackCodexModels;
7
8
  readonly fallbackClaudeAliasModels: typeof fallbackClaudeAliasModels;
8
9
  readonly parseClaudeBinaryModels: typeof parseClaudeBinaryModels;
9
10
  readonly parseClaudeModels: typeof parseClaudeModels;
@@ -1 +1 @@
1
- import{getCachedAgentInfos as m,refreshAgentInfos as u,resolveAgentInfos as v}from"./model-registry/service.js";import{applyClaudeModelEnvOverrides as e,discoverClaudeAliasModelsFromEnv as s,fallbackClaudeAliasModels as o,parseClaudeBinaryModels as r,parseClaudeModels as l,parseCodexModels as d,parseCodexAppServerModels as a,parseCursorModels as p,parseGeminiModels as n,parseOpenClawModels as i,stripAnsi as t}from"./model-registry/parsers.js";const M={applyClaudeModelEnvOverrides:e,discoverClaudeAliasModelsFromEnv:s,fallbackClaudeAliasModels:o,parseClaudeBinaryModels:r,parseClaudeModels:l,parseCodexModels:d,parseCodexAppServerModels:a,parseCursorModels:p,parseOpenClawModels:i,parseGeminiModels:n,stripAnsi:t};export{m as getCachedAgentInfos,M as modelSwitchingTestExports,u as refreshAgentInfos,v as resolveAgentInfos};
1
+ import{getCachedAgentInfos as m,refreshAgentInfos as u,resolveAgentInfos as v}from"./model-registry/service.js";import{applyClaudeModelEnvOverrides as e,discoverClaudeAliasModelsFromEnv as s,fallbackCodexModels as o,fallbackClaudeAliasModels as l,parseClaudeBinaryModels as r,parseClaudeModels as d,parseCodexModels as a,parseCodexAppServerModels as p,parseCursorModels as n,parseGeminiModels as i,parseOpenClawModels as t,stripAnsi as C}from"./model-registry/parsers.js";const f={applyClaudeModelEnvOverrides:e,discoverClaudeAliasModelsFromEnv:s,fallbackCodexModels:o,fallbackClaudeAliasModels:l,parseClaudeBinaryModels:r,parseClaudeModels:d,parseCodexModels:a,parseCodexAppServerModels:p,parseCursorModels:n,parseOpenClawModels:t,parseGeminiModels:i,stripAnsi:C};export{m as getCachedAgentInfos,f as modelSwitchingTestExports,u as refreshAgentInfos,v as resolveAgentInfos};
@@ -0,0 +1,6 @@
1
+ import type { ParsedNativeEvent } from './types.js';
2
+ export declare function listCodexRolloutFiles(): string[];
3
+ export declare function parseCodexRolloutChunk(filePath: string, startOffset: number): {
4
+ nextOffset: number;
5
+ events: ParsedNativeEvent[];
6
+ };
@@ -0,0 +1,6 @@
1
+ import y from"node:fs";import S from"node:os";import b from"node:path";import{buildApprovalPendingPayload as G,buildUserMessagePayload as W,isSystemControlPayload as C,isToolPayload as q}from"@shennian/wire";import{buildImagePayload as Q,buildToolPayload as V,inferMimeType as v,makeCursor as X,makeEventKey as Y,normalizeText as x,parseStructuredString as Z,readJsonlLines as N,readTimestamp as P,safeParse as E}from"./parser-common.js";function D(e){if(typeof e=="string"){const i=e.trim();return i?{path:i,name:b.basename(i)||"image.png",mimeType:v(i),kind:"image"}:null}if(typeof e!="object"||e===null)return null;const r=e,n=typeof r.path=="string"?r.path:typeof r.file_path=="string"?r.file_path:typeof r.saved_path=="string"?r.saved_path:"";if(!n.trim())return null;const t=typeof r.name=="string"&&r.name.trim()?r.name:b.basename(n)||"image.png",o=typeof r.mimeType=="string"&&r.mimeType.trim()?r.mimeType:v(n);return{path:n,name:t,mimeType:o,kind:"image"}}function R(e){return Array.isArray(e)?e.map(n=>{if(typeof n=="string")return n;if(typeof n=="object"&&n!==null){const t=n;return typeof t.text=="string"?t.text:""}return""}).map(n=>x(n)).filter(Boolean).join(`
2
+
3
+ `):""}function U(e){const r=x(e);if(!r)return{text:"",strippedWrapper:!1};const n=r.match(/My request for Codex:\s*([\s\S]*)$/i);return n&&n[1]?{text:O(n[1]),strippedWrapper:!0}:{text:r,strippedWrapper:!1}}function O(e){return x(e.replace(/<image>\s*<\/image>/gi,""))}function k(e){const r=x(e);if(!r)return!1;if(C(r)||/^<environment_context>[\s\S]*<\/environment_context>$/i.test(r)&&r.includes("<current_date>")&&r.includes("<timezone>")&&r.includes("<workspace_roots>"))return!0;const n=r.startsWith("# AGENTS.md instructions for ")&&r.includes("<INSTRUCTIONS>")&&r.includes("</INSTRUCTIONS>"),t=r.includes("<environment_context>")&&r.includes("</environment_context>");return n&&t}function w(e){const r=R(e.text_elements),n=Array.isArray(e.input)?R(e.input):"",t=typeof e.message=="string"?U(e.message):{text:"",strippedWrapper:!1},o=t.text,i=r||n||o,c=t.strippedWrapper?"codex_app_context_wrapper":void 0,f=Array.isArray(e.local_images)?e.local_images.map(D).filter(a=>a!=null):[];return!i&&f.length===0||C(i)&&f.length===0||k(i)&&f.length===0?null:f.length>0?{payload:W(i,f),titleText:i,repairHint:c}:{payload:i,titleText:i,repairHint:c}}function K(e){return e==="turn_completed"||e==="turn_complete"||e==="task_complete"}function tt(e){return/approval|permission|confirm|user[_-]?input|input[_-]?required/i.test(e)}function et(e){const r=typeof e.command=="string"?e.command:Array.isArray(e.command)?e.command.join(" "):"",n=typeof e.prompt=="string"?e.prompt:typeof e.reason=="string"?e.reason:typeof e.message=="string"?e.message:r?`Codex \u8BF7\u6C42\u6267\u884C\u547D\u4EE4\uFF1A${r}`:"Codex \u6B63\u5728\u7B49\u5F85\u7528\u6237\u786E\u8BA4\u540E\u7EE7\u7EED\u3002";return G({title:"\u9700\u8981\u7528\u6237\u786E\u8BA4",content:n,source:"codex",actionHint:"\u5F53\u524D\u795E\u5FF5\u6682\u4E0D\u652F\u6301\u8FDC\u7A0B\u786E\u8BA4\uFF0C\u8BF7\u56DE\u5230\u8FD0\u884C Codex \u7684\u7535\u8111/\u7EC8\u7AEF\u5B8C\u6210\u786E\u8BA4\u3002"})}function F(e,r){return Array.isArray(e)?x(e.map(n=>{if(typeof n=="string")return n;if(typeof n!="object"||n===null)return"";const t=n;return t.type!==r?"":typeof t.text=="string"?t.text:""}).filter(Boolean).join(`
4
+
5
+ `)):""}function nt(e){if(!Array.isArray(e))return[];const r=[];for(const n of e){if(typeof n!="object"||n===null)continue;const t=n;if(t.type!=="input_image")continue;const o=typeof t.path=="string"?t.path:typeof t.file_path=="string"?t.file_path:typeof t.saved_path=="string"?t.saved_path:typeof t.image_path=="string"?t.image_path:"";o.trim()&&r.push({path:o,name:b.basename(o)||"image.png",mimeType:v(o),kind:"image"})}return r}function $(e){if(e.type!=="message")return null;const r=e.role==="assistant"?"agent":e.role==="user"?"user":null;if(!r)return null;if(r==="agent"){const i=F(e.content,"output_text");return C(i)?null:i?{role:r,payload:i,titleText:i}:null}const n=U(F(e.content,"input_text")),t=n.text,o=nt(e.content);return!t&&o.length===0||C(t)&&o.length===0||k(t)&&o.length===0?null:{role:r,payload:o.length>0?W(t,o):t,titleText:t,repairHint:n.strippedWrapper?"codex_app_context_wrapper":void 0}}function z(e){if(!e)return"";try{const r=JSON.parse(e);if(typeof r=="object"&&r!==null){const n=r;if(n.type==="user"&&typeof n.content=="string")return x(n.content)}}catch{}return x(e)}function rt(e,r,n,t){return e.agentType!=="codex"||e.role!==r||q(e.payload)||Math.abs(e.ts-t)>300*1e3?!1:z(e.payload)===z(n)}function I(e,r,n,t){for(let o=e.length-1;o>=0;o-=1){const i=e[o];if(i){if(rt(i,r,n,t))return o;if(i.agentType==="codex"&&Math.abs(i.ts-t)>300*1e3)break}}return-1}function T(e,r,n,t,o,i,c,f,a,u,s="agent",m=!1,p){c&&e.push({agentType:"codex",sourceMode:"codex_rollout_import",sourceSessionKey:o,sourceEventKey:Y(r,n,t),cursor:X(r,n),role:s,ts:i,payload:c,title:f,modelId:a,workDir:u,terminal:m,repairHint:p})}function _(e,r,n,t,o,i,c,f,a,u,s,m){T(e,r,n,t,o,i,V(c,s,m),f,a,u)}function ot(e,r,n,t,o,i,c,f,a){const u=typeof t.type=="string"?t.type:"";if(u){if(u==="message"){const s=$(t);if(!s||I(e,s.role,s.payload,i)>=0)return;T(e,r,n,`${u}:${s.role}`,o,i,s.payload,c,f,a,s.role,!1,s.repairHint);return}if(u==="function_call"){const s=typeof t.name=="string"?t.name:"function_call";_(e,r,n,u,o,i,s,c,f,a,Z(t.arguments));return}if(u==="function_call_output"){_(e,r,n,u,o,i,"function_call_output",c,f,a,t.call_id,t.output);return}if(u==="custom_tool_call"){const s=typeof t.name=="string"?t.name:"custom_tool_call",m=t.input!==void 0?{input:t.input}:void 0;_(e,r,n,u,o,i,s,c,f,a,m);return}if(u==="custom_tool_call_output"){const s=typeof t.name=="string"?t.name:"custom_tool_call_output",m=t.output??t.result??t.content;_(e,r,n,u,o,i,s,c,f,a,t.call_id,m);return}if(u==="web_search_call"){const s=typeof t.action=="object"&&t.action!==null?t.action:null;_(e,r,n,u,o,i,"web_search",c,f,a,s??t.query);return}}}function it(e,r,n,t,o,i,c,f,a){const u=typeof t.type=="string"?t.type:"";if(u){if(u==="user_message"){const s=w(t);if(!s)return;T(e,r,n,u,o,i,s.payload,c,f,a,"user",!1,s.repairHint);return}if(u==="agent_message"){const s=typeof t.message=="string"?x(t.message):"";if(!s||C(s))return;T(e,r,n,u,o,i,s,c,f,a);return}if(u==="turn_aborted"||u==="error"){const s=typeof t.message=="string"?x(t.message):typeof t.error=="string"?x(t.error):"";if(!s)return;T(e,r,n,u,o,i,s,c,f,a,"agent",!0);return}if(tt(u)){T(e,r,n,u,o,i,et(t),c,f,a,"agent");return}if(u==="exec_command_end"){const s=Array.isArray(t.command)?t.command:t.parsed_cmd??t.command,m=t.exit_code??t.exitCode,p=[typeof t.aggregated_output=="string"?t.aggregated_output:"",m!=null?`
6
+ (exit ${String(m)})`:""].join("");_(e,r,n,u,o,i,"command_execution",c,f,a,{command:s},p);return}if(u==="patch_apply_end"){_(e,r,n,u,o,i,"apply_patch",c,f,a,t.changes,{success:t.success,stdout:t.stdout,stderr:t.stderr});return}if(u==="mcp_tool_call_end"){const s=typeof t.invocation=="object"&&t.invocation!==null?t.invocation:null,m=typeof s?.tool=="string"?s.tool:"mcp_tool_call",p={server:s?.server,...typeof s?.arguments=="object"&&s.arguments!==null?s.arguments:{}};_(e,r,n,u,o,i,m,c,f,a,p,t.result);return}if(u==="dynamic_tool_call_request"){const s=typeof t.tool=="string"?t.tool:"dynamic_tool_call";_(e,r,n,u,o,i,s,c,f,a,t.arguments);return}if(u==="dynamic_tool_call_response"){const s=typeof t.tool=="string"?t.tool:"dynamic_tool_call";_(e,r,n,u,o,i,s,c,f,a,t.callId??t.call_id,t.result??t.output);return}if(u==="web_search_end"){const s=typeof t.action=="object"&&t.action!==null?t.action:null;_(e,r,n,u,o,i,"web_search",c,f,a,s??t.query,t.query);return}if(u==="image_generation_end"){const s=typeof t.saved_path=="string"?t.saved_path.trim():"";if(!s)return;T(e,r,n,u,o,i,Q(s),c,f,a);return}u==="view_image_tool_call"&&_(e,r,n,u,o,i,"view_image",c,f,a,t.path??t.image_path??t)}}function M(e=!1){return{sourceSessionKey:"",workDir:"",modelId:null,title:"",skipImport:e}}function B(e){if((typeof e.thread_source=="string"?e.thread_source.trim().toLowerCase():"")==="subagent")return!0;const n=typeof e.source=="object"&&e.source!==null?e.source:null;if(n&&typeof n.subagent=="object"&&n.subagent!==null)return!0;const t=typeof e.parent_thread_id=="string"&&e.parent_thread_id.trim().length>0,o=typeof e.agent_nickname=="string"||typeof e.agent_role=="string"||typeof e.multi_agent_version=="string";return t&&o}function st(e){const r=y.openSync(e,"r");try{const n=[];let t=0,o="";for(;t<1024*1024;){const a=Buffer.alloc(16384),u=y.readSync(r,a,0,a.length,t);if(u<=0)break;const s=a.subarray(0,u);n.push(s),t+=u;const m=Buffer.concat(n),p=m.indexOf(10);if(p>=0){o=m.subarray(0,p).toString("utf8");break}}!o&&n.length>0&&(o=Buffer.concat(n).toString("utf8"));const i=E(o);if(!i||i.type!=="session_meta")return M();const c=typeof i.payload=="object"&&i.payload!==null?i.payload:null;if(!c)return M();if(B(c))return M(!0);const f=typeof c.id=="string"?c.id:"";return{sourceSessionKey:f,workDir:typeof c.cwd=="string"?c.cwd:"",modelId:H(c),title:L(f)??"",skipImport:!1}}finally{y.closeSync(r)}return M()}function H(e){return(typeof e.model=="string"?e.model.trim():"")||null}function ut(e,r){if((typeof e.id=="string"?e.id:typeof e.thread_id=="string"?e.thread_id:typeof e.session_id=="string"?e.session_id:"")!==r)return null;const o=(typeof e.thread_name=="string"?e.thread_name:typeof e.title=="string"?e.title:"").trim();return o?o.slice(0,120):null}function L(e){if(!e)return null;const r=b.join(S.homedir(),".codex","session_index.jsonl");if(!y.existsSync(r))return null;let n=null;return N(r,0,t=>{if(!t.trim())return;const o=E(t);if(!o)return;const i=ut(o,e);i&&(n=i)}),n}function lt(){const e=[b.join(S.homedir(),".codex","sessions"),b.join(S.homedir(),".codex","archived_sessions")],r=[],n=t=>{for(const o of y.readdirSync(t,{withFileTypes:!0})){const i=b.join(t,o.name);o.isDirectory()?n(i):o.isFile()&&o.name.endsWith(".jsonl")&&r.push(i)}};for(const t of e)y.existsSync(t)&&n(t);return[...new Set(r)].sort()}function gt(e,r){const n=[];let{sourceSessionKey:t,workDir:o,modelId:i,title:c,skipImport:f}=st(e);if(f)return{nextOffset:y.statSync(e).size,events:[]};let a=!1;return{nextOffset:N(e,r,(s,m)=>{const p=E(s);if(!p)return;const A=typeof p.type=="string"?p.type:"",l=typeof p.payload=="object"&&p.payload!==null?p.payload:null,j=P(p.timestamp);if(!(!l||!j)){if(A==="session_meta"){if(B(l)){n.length=0,f=!0;return}t=typeof l.id=="string"?l.id:t,o=typeof l.cwd=="string"?l.cwd:o,i=H(l)??i,c||(c=L(t)??"");return}if(!f&&t){if(A==="response_item"){const h=$(l);h?.role==="user"&&h.titleText&&!c&&(c=h.titleText.slice(0,80)),ot(n,e,m,l,t,j,c,i,o);return}if(A==="event_msg"){const h=typeof l.type=="string"?l.type:"";if(K(h)){for(let g=n.length-1;g>=0;g-=1){const d=n[g];if(d?.agentType==="codex"&&d.role==="agent"&&!q(d.payload)){d.terminal=!0,a=!1;break}}return}if(h==="user_message"){const g=w(l);if(g?.titleText&&!c&&(c=g.titleText.slice(0,80)),g){const d=I(n,"user",g.payload,j);d>=0&&n.splice(d,1)}}else if(h==="agent_message"){const g=typeof l.message=="string"?x(l.message):"";if(g&&!C(g)){const d=I(n,"agent",g,j);d>=0&&n.splice(d,1)}}const J=n.length;it(n,e,m,l,t,j,c,i,o),a&&n.length>J&&(n[n.length-1].terminal=!0,a=!1)}}}}),events:n}}export{lt as listCodexRolloutFiles,gt as parseCodexRolloutChunk};
@@ -1,12 +1,8 @@
1
1
  import type { ParsedNativeEvent } from './types.js';
2
+ export { listCodexRolloutFiles, parseCodexRolloutChunk } from './codex-parser.js';
2
3
  export { listOpenCodeSessionFiles, parseOpenCodeSessionFile, parseOpenCodeSessionSnapshot, type OpenCodeSnapshot, } from './opencode-parser.js';
3
- export declare function listCodexRolloutFiles(): string[];
4
4
  export declare function listClaudeTranscriptFiles(): string[];
5
5
  export declare function lookupClaudeTranscriptCwd(sourceSessionKey: string): string | null;
6
- export declare function parseCodexRolloutChunk(filePath: string, startOffset: number): {
7
- nextOffset: number;
8
- events: ParsedNativeEvent[];
9
- };
10
6
  export declare function parseClaudeTranscriptChunk(filePath: string, startOffset: number): {
11
7
  nextOffset: number;
12
8
  events: ParsedNativeEvent[];
@@ -1,8 +1,3 @@
1
- import T from"node:fs";import j from"node:os";import x from"node:path";import{buildApprovalPendingPayload as V,buildUserMessagePayload as W,isSystemControlPayload as A,isToolPayload as F}from"@shennian/wire";import{listOpenCodeSessionFiles as jt,parseOpenCodeSessionFile as At,parseOpenCodeSessionSnapshot as Mt}from"./opencode-parser.js";import{buildImagePayload as X,buildToolPayload as Y,inferMimeType as E,makeCursor as I,makeEventKey as w,normalizeText as h,parseStructuredString as Z,readClaudeEventCwd as N,readJsonlLines as S,readTimestamp as q,safeParse as M,isClaudeSubagentTranscript as D,shouldIgnoreClaudeProjectDir as K,shouldIgnoreClaudeTranscriptPath as O,shouldIgnoreNativeScanPath as R}from"./parser-common.js";function P(e){if(typeof e=="string"){const s=e.trim();return s?{path:s,name:x.basename(s)||"image.png",mimeType:E(s),kind:"image"}:null}if(typeof e!="object"||e===null)return null;const r=e,n=typeof r.path=="string"?r.path:typeof r.file_path=="string"?r.file_path:typeof r.saved_path=="string"?r.saved_path:"";if(!n.trim())return null;const t=typeof r.name=="string"&&r.name.trim()?r.name:x.basename(n)||"image.png",o=typeof r.mimeType=="string"&&r.mimeType.trim()?r.mimeType:E(n);return{path:n,name:t,mimeType:o,kind:"image"}}function U(e){return Array.isArray(e)?e.map(n=>{if(typeof n=="string")return n;if(typeof n=="object"&&n!==null){const t=n;return typeof t.text=="string"?t.text:""}return""}).map(n=>h(n)).filter(Boolean).join(`
1
+ import g from"node:fs";import C from"node:os";import c from"node:path";import{listCodexRolloutFiles as q,parseCodexRolloutChunk as G}from"./codex-parser.js";import{listOpenCodeSessionFiles as Q,parseOpenCodeSessionFile as U,parseOpenCodeSessionSnapshot as V}from"./opencode-parser.js";import{makeCursor as j,makeEventKey as h,normalizeText as k,readClaudeEventCwd as v,readJsonlLines as S,readTimestamp as F,safeParse as T,isClaudeSubagentTranscript as E,shouldIgnoreClaudeProjectDir as I,shouldIgnoreClaudeTranscriptPath as O,shouldIgnoreNativeScanPath as b}from"./parser-common.js";function _(e){const r=C.homedir();return e.startsWith(r)?e.slice(r.length).replace(/^\//,"")||"~":e.replace(/\//g,"-")}function z(){const e=c.join(C.homedir(),".claude","projects");if(!g.existsSync(e))return[];const r=[],o=t=>{for(const n of g.readdirSync(t,{withFileTypes:!0})){const i=c.join(t,n.name);if(n.isDirectory()){if(t===e&&I(n.name))continue;o(i)}else n.isFile()&&n.name.endsWith(".jsonl")&&r.push(i)}};return o(e),r.sort()}function B(e){if(!e)return null;const r=z().find(t=>c.basename(t,".jsonl")===e);if(!r)return null;let o=null;return S(r,0,t=>{if(o||!t.trim())return;const n=T(t);if(!n)return;const i=v(n);i&&(o=i)}),o}function J(e,r){const o=g.statSync(e).size;if(E(e)||O(e))return{nextOffset:o,events:[]};const t=[],n=c.basename(e,".jsonl"),i=_(c.dirname(e).replace(c.join(C.homedir(),".claude","projects")+c.sep,""));if(b(i))return{nextOffset:o,events:[]};let l="";return{nextOffset:S(e,r,(w,p)=>{const s=T(w);if(!s)return;const f=F(s.timestamp),y=typeof s.type=="string"?s.type:"";if(!f||!y)return;const d=v(s);if(!(d&&b(d))){if(y==="user"){const a=typeof s.message=="object"&&s.message!==null?s.message:null,u=typeof a?.content=="string"?k(a.content):"";if(!u)return;l||(l=u.slice(0,80)),t.push({agentType:"claude",sourceMode:"claude_transcript_import",sourceSessionKey:n,sourceEventKey:h(e,p,"user"),cursor:j(e,p),role:"user",ts:f,payload:u,title:l,workDir:d??i})}else if(y==="assistant"){const a=typeof s.message=="object"&&s.message!==null?s.message:null,u=Array.isArray(a?.content)?a.content:[],x=k(u.map(m=>typeof m=="object"&&m!==null&&typeof m.text=="string"?m.text:"").filter(Boolean).join(`
2
2
 
3
- `):""}function z(e){const r=h(e);if(!r)return{text:"",strippedWrapper:!1};const n=r.match(/My request for Codex:\s*([\s\S]*)$/i);return n&&n[1]?{text:tt(n[1]),strippedWrapper:!0}:{text:r,strippedWrapper:!1}}function tt(e){return h(e.replace(/<image>\s*<\/image>/gi,""))}function B(e){const r=h(e);if(!r)return!1;if(A(r)||/^<environment_context>[\s\S]*<\/environment_context>$/i.test(r)&&r.includes("<current_date>")&&r.includes("<timezone>")&&r.includes("<workspace_roots>"))return!0;const n=r.startsWith("# AGENTS.md instructions for ")&&r.includes("<INSTRUCTIONS>")&&r.includes("</INSTRUCTIONS>"),t=r.includes("<environment_context>")&&r.includes("</environment_context>");return n&&t}function $(e){const r=U(e.text_elements),n=Array.isArray(e.input)?U(e.input):"",t=typeof e.message=="string"?z(e.message):{text:"",strippedWrapper:!1},o=t.text,s=r||n||o,u=t.strippedWrapper?"codex_app_context_wrapper":void 0,a=Array.isArray(e.local_images)?e.local_images.map(P).filter(l=>l!=null):[];return!s&&a.length===0||A(s)&&a.length===0||B(s)&&a.length===0?null:a.length>0?{payload:W(s,a),titleText:s,repairHint:u}:{payload:s,titleText:s,repairHint:u}}function et(e){return e==="turn_completed"||e==="turn_complete"||e==="task_complete"}function nt(e){return/approval|permission|confirm|user[_-]?input|input[_-]?required/i.test(e)}function rt(e){const r=typeof e.command=="string"?e.command:Array.isArray(e.command)?e.command.join(" "):"",n=typeof e.prompt=="string"?e.prompt:typeof e.reason=="string"?e.reason:typeof e.message=="string"?e.message:r?`Codex \u8BF7\u6C42\u6267\u884C\u547D\u4EE4\uFF1A${r}`:"Codex \u6B63\u5728\u7B49\u5F85\u7528\u6237\u786E\u8BA4\u540E\u7EE7\u7EED\u3002";return V({title:"\u9700\u8981\u7528\u6237\u786E\u8BA4",content:n,source:"codex",actionHint:"\u5F53\u524D\u795E\u5FF5\u6682\u4E0D\u652F\u6301\u8FDC\u7A0B\u786E\u8BA4\uFF0C\u8BF7\u56DE\u5230\u8FD0\u884C Codex \u7684\u7535\u8111/\u7EC8\u7AEF\u5B8C\u6210\u786E\u8BA4\u3002"})}function H(e,r){return Array.isArray(e)?h(e.map(n=>{if(typeof n=="string")return n;if(typeof n!="object"||n===null)return"";const t=n;return t.type!==r?"":typeof t.text=="string"?t.text:""}).filter(Boolean).join(`
4
-
5
- `)):""}function ot(e){if(!Array.isArray(e))return[];const r=[];for(const n of e){if(typeof n!="object"||n===null)continue;const t=n;if(t.type!=="input_image")continue;const o=typeof t.path=="string"?t.path:typeof t.file_path=="string"?t.file_path:typeof t.saved_path=="string"?t.saved_path:typeof t.image_path=="string"?t.image_path:"";o.trim()&&r.push({path:o,name:x.basename(o)||"image.png",mimeType:E(o),kind:"image"})}return r}function L(e){if(e.type!=="message")return null;const r=e.role==="assistant"?"agent":e.role==="user"?"user":null;if(!r)return null;if(r==="agent"){const s=H(e.content,"output_text");return A(s)?null:s?{role:r,payload:s,titleText:s}:null}const n=z(H(e.content,"input_text")),t=n.text,o=ot(e.content);return!t&&o.length===0||A(t)&&o.length===0||B(t)&&o.length===0?null:{role:r,payload:o.length>0?W(t,o):t,titleText:t,repairHint:n.strippedWrapper?"codex_app_context_wrapper":void 0}}function J(e){if(!e)return"";try{const r=JSON.parse(e);if(typeof r=="object"&&r!==null){const n=r;if(n.type==="user"&&typeof n.content=="string")return h(n.content)}}catch{}return h(e)}function st(e,r,n,t){return e.agentType!=="codex"||e.role!==r||F(e.payload)||Math.abs(e.ts-t)>300*1e3?!1:J(e.payload)===J(n)}function k(e,r,n,t){for(let o=e.length-1;o>=0;o-=1){const s=e[o];if(s){if(st(s,r,n,t))return o;if(s.agentType==="codex"&&Math.abs(s.ts-t)>300*1e3)break}}return-1}function b(e,r,n,t,o,s,u,a,l,c,i="agent",f=!1,m){u&&e.push({agentType:"codex",sourceMode:"codex_rollout_import",sourceSessionKey:o,sourceEventKey:w(r,n,t),cursor:I(r,n),role:i,ts:s,payload:u,title:a,modelId:l,workDir:c,terminal:f,repairHint:m})}function C(e,r,n,t,o,s,u,a,l,c,i,f){b(e,r,n,t,o,s,Y(u,i,f),a,l,c)}function it(e,r,n,t,o,s,u,a,l){const c=typeof t.type=="string"?t.type:"";if(c){if(c==="message"){const i=L(t);if(!i||k(e,i.role,i.payload,s)>=0)return;b(e,r,n,`${c}:${i.role}`,o,s,i.payload,u,a,l,i.role,!1,i.repairHint);return}if(c==="function_call"){const i=typeof t.name=="string"?t.name:"function_call";C(e,r,n,c,o,s,i,u,a,l,Z(t.arguments));return}if(c==="function_call_output"){C(e,r,n,c,o,s,"function_call_output",u,a,l,t.call_id,t.output);return}if(c==="custom_tool_call"){const i=typeof t.name=="string"?t.name:"custom_tool_call",f=t.input!==void 0?{input:t.input}:void 0;C(e,r,n,c,o,s,i,u,a,l,f);return}if(c==="custom_tool_call_output"){const i=typeof t.name=="string"?t.name:"custom_tool_call_output",f=t.output??t.result??t.content;C(e,r,n,c,o,s,i,u,a,l,t.call_id,f);return}if(c==="web_search_call"){const i=typeof t.action=="object"&&t.action!==null?t.action:null;C(e,r,n,c,o,s,"web_search",u,a,l,i??t.query);return}}}function ct(e,r,n,t,o,s,u,a,l){const c=typeof t.type=="string"?t.type:"";if(c){if(c==="user_message"){const i=$(t);if(!i)return;b(e,r,n,c,o,s,i.payload,u,a,l,"user",!1,i.repairHint);return}if(c==="agent_message"){const i=typeof t.message=="string"?h(t.message):"";if(!i||A(i))return;b(e,r,n,c,o,s,i,u,a,l);return}if(c==="turn_aborted"||c==="error"){const i=typeof t.message=="string"?h(t.message):typeof t.error=="string"?h(t.error):"";if(!i)return;b(e,r,n,c,o,s,i,u,a,l,"agent",!0);return}if(nt(c)){b(e,r,n,c,o,s,rt(t),u,a,l,"agent");return}if(c==="exec_command_end"){const i=Array.isArray(t.command)?t.command:t.parsed_cmd??t.command,f=t.exit_code??t.exitCode,m=[typeof t.aggregated_output=="string"?t.aggregated_output:"",f!=null?`
6
- (exit ${String(f)})`:""].join("");C(e,r,n,c,o,s,"command_execution",u,a,l,{command:i},m);return}if(c==="patch_apply_end"){C(e,r,n,c,o,s,"apply_patch",u,a,l,t.changes,{success:t.success,stdout:t.stdout,stderr:t.stderr});return}if(c==="mcp_tool_call_end"){const i=typeof t.invocation=="object"&&t.invocation!==null?t.invocation:null,f=typeof i?.tool=="string"?i.tool:"mcp_tool_call",m={server:i?.server,...typeof i?.arguments=="object"&&i.arguments!==null?i.arguments:{}};C(e,r,n,c,o,s,f,u,a,l,m,t.result);return}if(c==="dynamic_tool_call_request"){const i=typeof t.tool=="string"?t.tool:"dynamic_tool_call";C(e,r,n,c,o,s,i,u,a,l,t.arguments);return}if(c==="dynamic_tool_call_response"){const i=typeof t.tool=="string"?t.tool:"dynamic_tool_call";C(e,r,n,c,o,s,i,u,a,l,t.callId??t.call_id,t.result??t.output);return}if(c==="web_search_end"){const i=typeof t.action=="object"&&t.action!==null?t.action:null;C(e,r,n,c,o,s,"web_search",u,a,l,i??t.query,t.query);return}if(c==="image_generation_end"){const i=typeof t.saved_path=="string"?t.saved_path.trim():"";if(!i)return;b(e,r,n,c,o,s,X(i),u,a,l);return}c==="view_image_tool_call"&&C(e,r,n,c,o,s,"view_image",u,a,l,t.path??t.image_path??t)}}function ut(e){const r=j.homedir();return e.startsWith(r)?e.slice(r.length).replace(/^\//,"")||"~":e.replace(/\//g,"-")}function at(e){const r=T.openSync(e,"r");try{const n=[];let t=0,o="";for(;t<1024*1024;){const l=Buffer.alloc(16384),c=T.readSync(r,l,0,l.length,t);if(c<=0)break;const i=l.subarray(0,c);n.push(i),t+=c;const f=Buffer.concat(n),m=f.indexOf(10);if(m>=0){o=f.subarray(0,m).toString("utf8");break}}!o&&n.length>0&&(o=Buffer.concat(n).toString("utf8"));const s=M(o);if(!s||s.type!=="session_meta")return{sourceSessionKey:"",workDir:"",modelId:null,title:""};const u=typeof s.payload=="object"&&s.payload!==null?s.payload:null;if(!u)return{sourceSessionKey:"",workDir:"",modelId:null,title:""};const a=typeof u.id=="string"?u.id:"";return{sourceSessionKey:a,workDir:typeof u.cwd=="string"?u.cwd:"",modelId:G(u),title:Q(a)??""}}finally{T.closeSync(r)}return{sourceSessionKey:"",workDir:"",modelId:null,title:""}}function G(e){return(typeof e.model=="string"?e.model.trim():"")||null}function lt(e,r){if((typeof e.id=="string"?e.id:typeof e.thread_id=="string"?e.thread_id:typeof e.session_id=="string"?e.session_id:"")!==r)return null;const o=(typeof e.thread_name=="string"?e.thread_name:typeof e.title=="string"?e.title:"").trim();return o?o.slice(0,120):null}function Q(e){if(!e)return null;const r=x.join(j.homedir(),".codex","session_index.jsonl");if(!T.existsSync(r))return null;let n=null;return S(r,0,t=>{if(!t.trim())return;const o=M(t);if(!o)return;const s=lt(o,e);s&&(n=s)}),n}function _t(){const e=[x.join(j.homedir(),".codex","sessions"),x.join(j.homedir(),".codex","archived_sessions")],r=[],n=t=>{for(const o of T.readdirSync(t,{withFileTypes:!0})){const s=x.join(t,o.name);o.isDirectory()?n(s):o.isFile()&&o.name.endsWith(".jsonl")&&r.push(s)}};for(const t of e)T.existsSync(t)&&n(t);return[...new Set(r)].sort()}function ft(){const e=x.join(j.homedir(),".claude","projects");if(!T.existsSync(e))return[];const r=[],n=t=>{for(const o of T.readdirSync(t,{withFileTypes:!0})){const s=x.join(t,o.name);if(o.isDirectory()){if(t===e&&K(o.name))continue;n(s)}else o.isFile()&&o.name.endsWith(".jsonl")&&r.push(s)}};return n(e),r.sort()}function yt(e){if(!e)return null;const r=ft().find(t=>x.basename(t,".jsonl")===e);if(!r)return null;let n=null;return S(r,0,t=>{if(n||!t.trim())return;const o=M(t);if(!o)return;const s=N(o);s&&(n=s)}),n}function ht(e,r){const n=[];let{sourceSessionKey:t,workDir:o,modelId:s,title:u}=at(e),a=!1;return{nextOffset:S(e,r,(c,i)=>{const f=M(c);if(!f)return;const m=typeof f.type=="string"?f.type:"",p=typeof f.payload=="object"&&f.payload!==null?f.payload:null,_=q(f.timestamp);if(!(!p||!_)){if(m==="session_meta"){t=typeof p.id=="string"?p.id:t,o=typeof p.cwd=="string"?p.cwd:o,s=G(p)??s,u||(u=Q(t)??"");return}if(t){if(m==="response_item"){const y=L(p);y?.role==="user"&&y.titleText&&!u&&(u=y.titleText.slice(0,80)),it(n,e,i,p,t,_,u,s,o);return}if(m==="event_msg"){const y=typeof p.type=="string"?p.type:"";if(et(y)){for(let d=n.length-1;d>=0;d-=1){const g=n[d];if(g?.agentType==="codex"&&g.role==="agent"&&!F(g.payload)){g.terminal=!0,a=!1;break}}return}if(y==="user_message"){const d=$(p);if(d?.titleText&&!u&&(u=d.titleText.slice(0,80)),d){const g=k(n,"user",d.payload,_);g>=0&&n.splice(g,1)}}else if(y==="agent_message"){const d=typeof p.message=="string"?h(p.message):"";if(d&&!A(d)){const g=k(n,"agent",d,_);g>=0&&n.splice(g,1)}}const v=n.length;ct(n,e,i,p,t,_,u,s,o),a&&n.length>v&&(n[n.length-1].terminal=!0,a=!1)}}}}),events:n}}function Ct(e,r){const n=T.statSync(e).size;if(D(e)||O(e))return{nextOffset:n,events:[]};const t=[],o=x.basename(e,".jsonl"),s=ut(x.dirname(e).replace(x.join(j.homedir(),".claude","projects")+x.sep,""));if(R(s))return{nextOffset:n,events:[]};let u="";return{nextOffset:S(e,r,(l,c)=>{const i=M(l);if(!i)return;const f=q(i.timestamp),m=typeof i.type=="string"?i.type:"";if(!f||!m)return;const p=N(i);if(!(p&&R(p))){if(m==="user"){const _=typeof i.message=="object"&&i.message!==null?i.message:null,y=typeof _?.content=="string"?h(_.content):"";if(!y)return;u||(u=y.slice(0,80)),t.push({agentType:"claude",sourceMode:"claude_transcript_import",sourceSessionKey:o,sourceEventKey:w(e,c,"user"),cursor:I(e,c),role:"user",ts:f,payload:y,title:u,workDir:p??s})}else if(m==="assistant"){const _=typeof i.message=="object"&&i.message!==null?i.message:null,y=Array.isArray(_?.content)?_.content:[],v=h(y.map(g=>typeof g=="object"&&g!==null&&typeof g.text=="string"?g.text:"").filter(Boolean).join(`
7
-
8
- `));if(!v)return;const d=typeof _?.model=="string"?_.model:null;t.push({agentType:"claude",sourceMode:"claude_transcript_import",sourceSessionKey:o,sourceEventKey:w(e,c,"assistant"),cursor:I(e,c),role:"agent",ts:f,payload:v,title:u,modelId:d,workDir:p??s})}}}),events:t}}export{ft as listClaudeTranscriptFiles,_t as listCodexRolloutFiles,jt as listOpenCodeSessionFiles,yt as lookupClaudeTranscriptCwd,Ct as parseClaudeTranscriptChunk,ht as parseCodexRolloutChunk,At as parseOpenCodeSessionFile,Mt as parseOpenCodeSessionSnapshot};
3
+ `));if(!x)return;const D=typeof a?.model=="string"?a.model:null;t.push({agentType:"claude",sourceMode:"claude_transcript_import",sourceSessionKey:n,sourceEventKey:h(e,p,"assistant"),cursor:j(e,p),role:"agent",ts:f,payload:x,title:l,modelId:D,workDir:d??i})}}}),events:t}}export{z as listClaudeTranscriptFiles,q as listCodexRolloutFiles,Q as listOpenCodeSessionFiles,B as lookupClaudeTranscriptCwd,J as parseClaudeTranscriptChunk,G as parseCodexRolloutChunk,U as parseOpenCodeSessionFile,V as parseOpenCodeSessionSnapshot};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shennian",
3
- "version": "0.2.135",
3
+ "version": "0.2.137",
4
4
  "description": "Shennian — AI Agent Control Plane CLI",
5
5
  "type": "module",
6
6
  "bin": {