@truesayer/node 0.1.1 → 0.1.2

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.
Files changed (2) hide show
  1. package/dist/node.js +28 -28
  2. package/package.json +1 -1
package/dist/node.js CHANGED
@@ -1,41 +1,41 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var sr=Object.create;var Ke=Object.defineProperty;var ir=Object.getOwnPropertyDescriptor;var ar=Object.getOwnPropertyNames;var dr=Object.getPrototypeOf,cr=Object.prototype.hasOwnProperty;var ur=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of ar(t))!cr.call(e,o)&&o!==r&&Ke(e,o,{get:()=>t[o],enumerable:!(n=ir(t,o))||n.enumerable});return e};var X=(e,t,r)=>(r=e!=null?sr(dr(e)):{},ur(t||!e||!e.__esModule?Ke(r,"default",{value:e,enumerable:!0}):r,e));var tr=require("fs"),rr=require("path");var ae=X(require("os")),x=require("fs"),M=require("path");var Ye=require("crypto"),F=require("fs"),q=X(require("path")),Xe=X(require("simple-git")),lr=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,ce=new Map,pr=["PATH","HOME","LANG","LC_ALL","TMPDIR","TEMP","TMP","SSH_AUTH_SOCK","GIT_SSH","GIT_SSH_COMMAND","GIT_EXEC_PATH","GIT_CONFIG_GLOBAL","GIT_CONFIG_SYSTEM","SystemRoot","USERPROFILE"];function mr(e){let t={};for(let n of pr){let o=process.env[n];o!==void 0&&(t[n]=o)}let r=q.default.resolve(e);return{...t,GIT_TERMINAL_PROMPT:"0",GIT_CONFIG_COUNT:"1",GIT_CONFIG_KEY_0:"safe.directory",GIT_CONFIG_VALUE_0:r,GIT_AUTHOR_NAME:process.env.TRUESAYER_GIT_AUTHOR_NAME||process.env.GIT_AUTHOR_NAME||"Truesayer",GIT_AUTHOR_EMAIL:process.env.TRUESAYER_GIT_AUTHOR_EMAIL||process.env.GIT_AUTHOR_EMAIL||"truesayer@example.invalid",GIT_COMMITTER_NAME:process.env.TRUESAYER_GIT_COMMITTER_NAME||process.env.GIT_COMMITTER_NAME||"Truesayer",GIT_COMMITTER_EMAIL:process.env.TRUESAYER_GIT_COMMITTER_EMAIL||process.env.GIT_COMMITTER_EMAIL||"truesayer@example.invalid"}}function fr(e){return(0,Xe.default)(e,{trimmed:!0,unsafe:{allowUnsafeConfigEnvCount:!0}}).env(mr(e))}async function I(e,t){return(await fr(t).raw(e)).trim()}async function Se(e){return I(["rev-parse","--show-toplevel"],e)}function gr(e){return`agent/work/${lr.test(e)?e:`action-${e.replace(/[^A-Za-z0-9_-]/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"")||"unknown"}`}`}async function Ze(e,t){let r=ce.get(e)??Promise.resolve(),n=()=>{},o=r.catch(()=>{}).then(()=>new Promise(s=>{n=s}));ce.set(e,o),await r.catch(()=>{});try{return await t()}finally{n(),ce.get(e)===o&&ce.delete(e)}}async function hr(e,t){try{return await I(["rev-parse","--verify",`refs/heads/${e}`],t),!0}catch{return!1}}async function Ie(e){try{return await I(["rev-parse","--is-inside-work-tree"],e)==="true"}catch{return!1}}async function vr(e){try{return await I(["rev-parse","--verify","HEAD"],e),!0}catch{return!1}}async function yr(e){if(await vr(e))return;if((await I(["status","--porcelain"],e)).trim()){await I(["add","-A"],e),await I(["commit","-m","Initial workspace snapshot","--no-gpg-sign"],e);return}await I(["commit","--allow-empty","-m","Initial workspace snapshot","--no-gpg-sign"],e)}async function le(e){let t=q.default.resolve(e.path),r=e.baseRef?.trim()||"main";(0,F.mkdirSync)(t,{recursive:!0});let n=!1;await Ie(t)||(await I(["init","-b",r],t),n=!0);let o=await Se(t);await yr(o);try{await I(["rev-parse","--verify",r],o)}catch{throw new Error(`baseRef not found: ${r}`)}return{path:t,baseRef:r,initialized:n,empty:!1,repoRoot:o}}function kr(e){return e instanceof Error?e.message:String(e)}async function ze(e,t,r){try{await I(e,r);return}catch(n){if(!kr(n).includes("already exists")||!(0,F.existsSync)(t))throw n;if(await Ie(t))return;(0,F.rmSync)(t,{recursive:!0,force:!0}),await I(e,r)}}async function Qe(e){let t=gr(e.actionId),r=await Se(e.repoPath),n=q.default.resolve(e.worktreePath);return Ze(r,async()=>{(0,F.existsSync)(n)&&!await Ie(n)&&(0,F.rmSync)(n,{recursive:!0,force:!0}),(0,F.mkdirSync)(q.default.dirname(n),{recursive:!0}),(0,F.existsSync)(n)||(await hr(t,r)?await ze(["worktree","add",n,t],n,r):await ze(["worktree","add","-b",t,n,e.baseBranch],n,r));let o=await I(["merge-base",e.baseBranch,t],n);return{branch:t,path:n,baseSha:o,baseRef:e.baseBranch}})}async function Pe(e){return I(["rev-parse","HEAD"],e)}function ue(e){return(0,Ye.createHash)("sha256").update(e).digest("hex")}function pe(e){return e.split(`
3
- `).map(t=>t.trimEnd()).filter(Boolean)}async function wr(e){return pe(await I(["diff","--cached","--name-only"],e)).length>0}async function br(e){try{return await I(["symbolic-ref","--short","HEAD"],e)}catch{return I(["rev-parse","HEAD"],e)}}async function Rr(e,t){return I(["rev-parse","--verify",e],t)}function _r(e,t){return e===t||`refs/heads/${e}`===t||e===`refs/heads/${t}`}async function me(e,t){let r=["ls-files","--others","--exclude-standard"];return t&&r.push("--",t),pe(await I(r,e))}function Ae(e,t){if(q.default.isAbsolute(t))throw new Error(`Absolute git file paths are not allowed: ${t}`);let r=q.default.resolve(e),n=q.default.resolve(r,t),o=q.default.relative(r,n);if(!(o&&o!==".."&&!o.startsWith(`..${q.default.sep}`)&&!q.default.isAbsolute(o)))throw new Error(`Unsafe git file path outside worktree: ${t}`);return n}function et(e){if(e.includes(0))return null;let t=e.toString("utf8");return t.length===0?0:t.endsWith(`
4
- `)?t.slice(0,-1).split(/\r\n|\r|\n/).length:t.split(/\r\n|\r|\n/).length}function Er(e,t){let r=et(t);if(r===null)return[`diff --git a/${e} b/${e}`,"new file mode 100644","Binary files /dev/null and b/"+e+" differ"].join(`
2
+ "use strict";var or=Object.create;var Ke=Object.defineProperty;var sr=Object.getOwnPropertyDescriptor;var ir=Object.getOwnPropertyNames;var ar=Object.getPrototypeOf,dr=Object.prototype.hasOwnProperty;var cr=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of ir(t))!dr.call(e,o)&&o!==r&&Ke(e,o,{get:()=>t[o],enumerable:!(n=sr(t,o))||n.enumerable});return e};var V=(e,t,r)=>(r=e!=null?or(ar(e)):{},cr(t||!e||!e.__esModule?Ke(r,"default",{value:e,enumerable:!0}):r,e));var er=require("fs"),tr=require("path");var ae=V(require("os")),x=require("fs"),M=require("path");var Ye=require("crypto"),F=require("fs"),q=V(require("path")),Xe=V(require("simple-git")),ur=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,ce=new Map,lr=["PATH","HOME","LANG","LC_ALL","TMPDIR","TEMP","TMP","SSH_AUTH_SOCK","GIT_SSH","GIT_SSH_COMMAND","GIT_EXEC_PATH","GIT_CONFIG_GLOBAL","GIT_CONFIG_SYSTEM","SystemRoot","USERPROFILE"];function pr(e){let t={};for(let n of lr){let o=process.env[n];o!==void 0&&(t[n]=o)}let r=q.default.resolve(e);return{...t,GIT_TERMINAL_PROMPT:"0",GIT_CONFIG_COUNT:"1",GIT_CONFIG_KEY_0:"safe.directory",GIT_CONFIG_VALUE_0:r,GIT_AUTHOR_NAME:process.env.TRUESAYER_GIT_AUTHOR_NAME||process.env.GIT_AUTHOR_NAME||"Truesayer",GIT_AUTHOR_EMAIL:process.env.TRUESAYER_GIT_AUTHOR_EMAIL||process.env.GIT_AUTHOR_EMAIL||"truesayer@example.invalid",GIT_COMMITTER_NAME:process.env.TRUESAYER_GIT_COMMITTER_NAME||process.env.GIT_COMMITTER_NAME||"Truesayer",GIT_COMMITTER_EMAIL:process.env.TRUESAYER_GIT_COMMITTER_EMAIL||process.env.GIT_COMMITTER_EMAIL||"truesayer@example.invalid"}}function mr(e){return(0,Xe.default)(e,{trimmed:!0,unsafe:{allowUnsafeConfigEnvCount:!0}}).env(pr(e))}async function I(e,t){return(await mr(t).raw(e)).trim()}async function Ne(e){return I(["rev-parse","--show-toplevel"],e)}function fr(e){return`agent/work/${ur.test(e)?e:`action-${e.replace(/[^A-Za-z0-9_-]/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"")||"unknown"}`}`}async function Ze(e,t){let r=ce.get(e)??Promise.resolve(),n=()=>{},o=r.catch(()=>{}).then(()=>new Promise(s=>{n=s}));ce.set(e,o),await r.catch(()=>{});try{return await t()}finally{n(),ce.get(e)===o&&ce.delete(e)}}async function gr(e,t){try{return await I(["rev-parse","--verify",`refs/heads/${e}`],t),!0}catch{return!1}}async function Se(e){try{return await I(["rev-parse","--is-inside-work-tree"],e)==="true"}catch{return!1}}async function hr(e){try{return await I(["rev-parse","--verify","HEAD"],e),!0}catch{return!1}}async function vr(e){if(await hr(e))return;if((await I(["status","--porcelain"],e)).trim()){await I(["add","-A"],e),await I(["commit","-m","Initial workspace snapshot","--no-gpg-sign"],e);return}await I(["commit","--allow-empty","-m","Initial workspace snapshot","--no-gpg-sign"],e)}async function Ie(e){let t=q.default.resolve(e.path),r=e.baseRef?.trim()||"main";(0,F.mkdirSync)(t,{recursive:!0});let n=!1;await Se(t)||(await I(["init","-b",r],t),n=!0);let o=await Ne(t);await vr(o);try{await I(["rev-parse","--verify",r],o)}catch{throw new Error(`baseRef not found: ${r}`)}return{path:t,baseRef:r,initialized:n,empty:!1,repoRoot:o}}function yr(e){return e instanceof Error?e.message:String(e)}async function ze(e,t,r){try{await I(e,r);return}catch(n){if(!yr(n).includes("already exists")||!(0,F.existsSync)(t))throw n;if(await Se(t))return;(0,F.rmSync)(t,{recursive:!0,force:!0}),await I(e,r)}}async function Qe(e){let t=fr(e.actionId),r=await Ne(e.repoPath),n=q.default.resolve(e.worktreePath);return Ze(r,async()=>{(0,F.existsSync)(n)&&!await Se(n)&&(0,F.rmSync)(n,{recursive:!0,force:!0}),(0,F.mkdirSync)(q.default.dirname(n),{recursive:!0}),(0,F.existsSync)(n)||(await gr(t,r)?await ze(["worktree","add",n,t],n,r):await ze(["worktree","add","-b",t,n,e.baseBranch],n,r));let o=await I(["merge-base",e.baseBranch,t],n);return{branch:t,path:n,baseSha:o,baseRef:e.baseBranch}})}async function Pe(e){return I(["rev-parse","HEAD"],e)}function ue(e){return(0,Ye.createHash)("sha256").update(e).digest("hex")}function le(e){return e.split(`
3
+ `).map(t=>t.trimEnd()).filter(Boolean)}async function kr(e){return le(await I(["diff","--cached","--name-only"],e)).length>0}async function wr(e){try{return await I(["symbolic-ref","--short","HEAD"],e)}catch{return I(["rev-parse","HEAD"],e)}}async function br(e,t){return I(["rev-parse","--verify",e],t)}function Rr(e,t){return e===t||`refs/heads/${e}`===t||e===`refs/heads/${t}`}async function pe(e,t){let r=["ls-files","--others","--exclude-standard"];return t&&r.push("--",t),le(await I(r,e))}function Ae(e,t){if(q.default.isAbsolute(t))throw new Error(`Absolute git file paths are not allowed: ${t}`);let r=q.default.resolve(e),n=q.default.resolve(r,t),o=q.default.relative(r,n);if(!(o&&o!==".."&&!o.startsWith(`..${q.default.sep}`)&&!q.default.isAbsolute(o)))throw new Error(`Unsafe git file path outside worktree: ${t}`);return n}function et(e){if(e.includes(0))return null;let t=e.toString("utf8");return t.length===0?0:t.endsWith(`
4
+ `)?t.slice(0,-1).split(/\r\n|\r|\n/).length:t.split(/\r\n|\r|\n/).length}function _r(e,t){let r=et(t);if(r===null)return[`diff --git a/${e} b/${e}`,"new file mode 100644","Binary files /dev/null and b/"+e+" differ"].join(`
5
5
  `);let n=t.toString("utf8"),o=n.length===0?[]:n.replace(/\n$/,"").split(/\r\n|\r|\n/);return[`diff --git a/${e} b/${e}`,"new file mode 100644","--- /dev/null",`+++ b/${e}`,`@@ -0,0 +1,${r} @@`,...o.map(s=>`+${s}`)].join(`
6
- `)}async function Tr(e,t){let r=pe(await I(["diff","--name-status",e],t)),n=new Set(r.map(s=>s.split(" ").at(-1)??"")),o=(await me(t)).filter(s=>!n.has(s)).map(s=>`A ${s}`);return[...r,...o].join(`
7
- `)}async function Nr(e,t){let r=pe(await I(["diff","--numstat",e],t)),n=new Set(r.map(s=>s.split(" ").slice(2).join(" ")).filter(Boolean)),o=await Promise.all((await me(t)).filter(s=>!n.has(s)).map(s=>{let a=(0,F.readFileSync)(Ae(t,s));return`${et(a)??"-"} 0 ${s}`}));return[...r,...o].join(`
8
- `)}async function Sr(e,t,r){return new Set(await me(t,r)).has(r)?Er(r,(0,F.readFileSync)(Ae(t,r))):I(["diff",e,"--",r],t)}function Ir(e){return e.replace(/^"(.*)"$/,"$1").replace(/^a\//,"").replace(/^b\//,"")}function Pr(e){let t=/^diff --git a\/(.+?) b\/(.+)$/.exec(e.trim());return t?Ir(t[2]??t[1]??""):null}function Ar(e){let t=new Map,r=null,n=[],o=()=>{if(!r)return;let s=n.join(`
6
+ `)}async function Er(e,t){let r=le(await I(["diff","--name-status",e],t)),n=new Set(r.map(s=>s.split(" ").at(-1)??"")),o=(await pe(t)).filter(s=>!n.has(s)).map(s=>`A ${s}`);return[...r,...o].join(`
7
+ `)}async function Tr(e,t){let r=le(await I(["diff","--numstat",e],t)),n=new Set(r.map(s=>s.split(" ").slice(2).join(" ")).filter(Boolean)),o=await Promise.all((await pe(t)).filter(s=>!n.has(s)).map(s=>{let a=(0,F.readFileSync)(Ae(t,s));return`${et(a)??"-"} 0 ${s}`}));return[...r,...o].join(`
8
+ `)}async function Nr(e,t,r){return new Set(await pe(t,r)).has(r)?_r(r,(0,F.readFileSync)(Ae(t,r))):I(["diff",e,"--",r],t)}function Sr(e){return e.replace(/^"(.*)"$/,"$1").replace(/^a\//,"").replace(/^b\//,"")}function Ir(e){let t=/^diff --git a\/(.+?) b\/(.+)$/.exec(e.trim());return t?Sr(t[2]??t[1]??""):null}function Pr(e){let t=new Map,r=null,n=[],o=()=>{if(!r)return;let s=n.join(`
9
9
  `);t.set(r,s.endsWith(`
10
10
  `)?s:`${s}
11
11
  `)};for(let s of e.split(`
12
- `)){let a=Pr(s);if(a){o(),r=a,n=[s];continue}r&&n.push(s)}return o(),t}function Ve(e){let t=Number(e);return Number.isFinite(t)?t:0}function xr(e){let t=e.trim();if(!t.includes(" => "))return t;let r=/^(.*)\{.* => (.*)\}(.*)$/.exec(t);return r?`${r[1]}${r[2]}${r[3]}`:t.slice(t.lastIndexOf(" => ")+4).trim()}function Cr(e){let t=new Map;for(let r of e.split(`
13
- `).filter(Boolean)){let[n,o,...s]=r.split(" "),a=xr(s.join(" "));a&&t.set(a,{additions:Ve(n),deletions:Ve(o)})}return t}function Mr(e){let[t,...r]=e.split(" "),n=t.charAt(0),o=n==="R"||n==="C"?r.at(-1)?.trim():r.join(" ").trim();return o?{path:o,status:n==="A"?"added":n==="D"?"deleted":n==="R"?"renamed":"modified"}:null}function Dr(e,t){let r=Cr(t);return e.split(`
14
- `).filter(Boolean).map(Mr).filter(n=>n!==null).map(n=>({...n,additions:r.get(n.path)?.additions??0,deletions:r.get(n.path)?.deletions??0}))}function Or(e,t){return ue((0,F.readFileSync)(Ae(e,t)))}function Ur(e,t){if(t.size===0)return ue(e);let r=Array.from(t.entries()).sort(([n],[o])=>n.localeCompare(o)).map(([n,o])=>`${n}\0${o}`).join(`
15
- `);return ue(`${e}\0untracked-content\0${r}`)}function Lr(e){return Dr(e.fileListRaw,e.numstatRaw).map(t=>{let r=e.diffByFile.get(t.path)??"",n=e.untrackedContentHashes.get(t.path);return{path:t.path,status:t.status,additions:t.additions,deletions:t.deletions,patchHash:ue(n?`${r}\0untracked-content\0${n}`:r),untracked:e.untracked.has(t.path)}})}async function Z(e,t="main"){let r=await Se(e),n=await br(r),o=t.trim()||"main",s=_r(n,o)?await I(["rev-parse","HEAD"],r):await Rr(o,r),[a,i,d,p,v]=await Promise.all([Tr(s,r),Nr(s,r),I(["diff","--no-textconv","--no-ext-diff",s],r),me(r),wr(r)]),l=await Promise.all(p.map(b=>Sr(s,r,b))),f=new Map(p.map(b=>[b,Or(r,b)])),y=[d,...l].filter(Boolean).join(`
16
- `),c=y&&!y.endsWith(`
12
+ `)){let a=Ir(s);if(a){o(),r=a,n=[s];continue}r&&n.push(s)}return o(),t}function Ve(e){let t=Number(e);return Number.isFinite(t)?t:0}function Ar(e){let t=e.trim();if(!t.includes(" => "))return t;let r=/^(.*)\{.* => (.*)\}(.*)$/.exec(t);return r?`${r[1]}${r[2]}${r[3]}`:t.slice(t.lastIndexOf(" => ")+4).trim()}function xr(e){let t=new Map;for(let r of e.split(`
13
+ `).filter(Boolean)){let[n,o,...s]=r.split(" "),a=Ar(s.join(" "));a&&t.set(a,{additions:Ve(n),deletions:Ve(o)})}return t}function Cr(e){let[t,...r]=e.split(" "),n=t.charAt(0),o=n==="R"||n==="C"?r.at(-1)?.trim():r.join(" ").trim();return o?{path:o,status:n==="A"?"added":n==="D"?"deleted":n==="R"?"renamed":"modified"}:null}function Mr(e,t){let r=xr(t);return e.split(`
14
+ `).filter(Boolean).map(Cr).filter(n=>n!==null).map(n=>({...n,additions:r.get(n.path)?.additions??0,deletions:r.get(n.path)?.deletions??0}))}function Dr(e,t){return ue((0,F.readFileSync)(Ae(e,t)))}function Or(e,t){if(t.size===0)return ue(e);let r=Array.from(t.entries()).sort(([n],[o])=>n.localeCompare(o)).map(([n,o])=>`${n}\0${o}`).join(`
15
+ `);return ue(`${e}\0untracked-content\0${r}`)}function Ur(e){return Mr(e.fileListRaw,e.numstatRaw).map(t=>{let r=e.diffByFile.get(t.path)??"",n=e.untrackedContentHashes.get(t.path);return{path:t.path,status:t.status,additions:t.additions,deletions:t.deletions,patchHash:ue(n?`${r}\0untracked-content\0${n}`:r),untracked:e.untracked.has(t.path)}})}async function Y(e,t="main"){let r=await Ne(e),n=await wr(r),o=t.trim()||"main",s=Rr(n,o)?await I(["rev-parse","HEAD"],r):await br(o,r),[a,i,c,m,v]=await Promise.all([Er(s,r),Tr(s,r),I(["diff","--no-textconv","--no-ext-diff",s],r),pe(r),kr(r)]),l=await Promise.all(m.map(b=>Nr(s,r,b))),f=new Map(m.map(b=>[b,Dr(r,b)])),y=[c,...l].filter(Boolean).join(`
16
+ `),d=y&&!y.endsWith(`
17
17
  `)?`${y}
18
- `:y,k=Ar(c);return{repoRoot:r,baseSha:s,baseRef:o,currentRef:n,diff:c,diffHash:Ur(c,f),hasStagedChanges:v,files:Lr({fileListRaw:a,numstatRaw:i,diffByFile:k,untracked:new Set(p),untrackedContentHashes:f})}}function Fr(e,t,r){let n=e.files.find(o=>o.path===t);if(!n)throw new Error("file is not in current git diff");if(r&&n.patchHash!==r)throw new Error("git diff changed; refresh before restoring");return n}async function tt(e){let t=await Z(e.worktreePath,e.baseRef??void 0);if(t.baseSha!==e.baseSha)throw new Error("git base changed; refresh before restoring");if(t.hasStagedChanges)throw new Error("staged changes are not supported");let r=e.filePath?[Fr(t,e.filePath,e.expectedPatchHash)]:t.files;if(!e.filePath&&e.expectedDiffHash&&t.diffHash!==e.expectedDiffHash)throw new Error("git diff changed; refresh before restoring");let n=r.filter(a=>!a.untracked).map(a=>a.path),o=r.filter(a=>a.untracked).map(a=>a.path),s=t.repoRoot;return await Ze(s,async()=>{n.length>0&&await I(["restore",`--source=${e.baseSha}`,"--worktree","--",...n],s),o.length>0&&await I(["clean","-f","--",...o],s)}),Z(s,e.baseRef??void 0)}var fe=require("fs"),rt=require("os"),O=require("path");function V(){return process.env.TRUESAYER_NODE_HOME?.trim()||(0,O.join)((0,rt.homedir)(),".truesayer-node")}function ge(e){return(0,O.join)(e?.trim()||V(),"provider.json")}function J(e){return e.replace(/[^a-zA-Z0-9_-]/g,"_").slice(0,120)||"unknown"}function nt(e){return(0,fe.mkdirSync)(e,{recursive:!0,mode:448}),(0,fe.chmodSync)(e,448),e}function Hr(e){return{HOME:e,CLAUDE_CONFIG_DIR:(0,O.join)(e,".claude"),CODEX_HOME:(0,O.join)(e,".codex")}}function xe(e){let t=e.truesayerNodeHome?.trim()||V(),r=J(e.agentId),n=(0,O.join)(t,"agents",r),o=(0,O.join)(t,"runtime-home"),s=(0,O.join)(n,"space"),a=(0,O.join)(s,"profile");for(let i of[o,(0,O.join)(o,".claude"),(0,O.join)(o,".codex"),s,a])nt(i);return{agentRoot:n,providerHome:o,spaceRoot:s,profileDir:a,providerEnv:Hr(o)}}function ot(e){let t=e.truesayerNodeHome?.trim()||V(),r=J(e.workspaceId),n=J(e.agentSessionId),o=J(e.agentRunId),s=J(e.repoAlias),a=xe({truesayerNodeHome:t,workspaceId:e.workspaceId,agentId:e.agentId}),{agentRoot:i,providerHome:d,spaceRoot:p,profileDir:v}=a,l=(0,O.join)(t,"workspace",r),f=(0,O.join)(p,"context",n),y=(0,O.join)(p,"agent-run",o),c=(0,O.join)(l,"worktree",s,o);for(let k of[l,f,y,c])nt(k);return{agentRoot:i,workspaceRoot:l,providerHome:d,spaceRoot:p,profileDir:v,contextDir:f,agentRunDir:y,worktreeDir:c,fileToolRoot:c,providerEnv:a.providerEnv}}function st(e){let t=e.truesayerNodeHome?.trim()||V(),r=J(e.workspaceId),n=J(e.channelId);return(0,O.join)(t,"workspace",r,"channels",n,"space")}var C=require("fs"),G=require("path");function $r(e){return e.replace(/[^a-zA-Z0-9_-]/g,"_").slice(0,120)||"unknown"}function Ce(e){(0,C.mkdirSync)(e,{recursive:!0,mode:448}),(0,C.chmodSync)(e,448)}function qr(e){if(!(0,C.existsSync)(e))return{};try{let t=JSON.parse((0,C.readFileSync)(e,"utf8"));return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}catch{return{}}}function it(e){return typeof e=="string"&&e.trim()?e.trim():""}function jr(e){return typeof e=="number"&&Number.isFinite(e)?Math.trunc(e):0}var Q=class{constructor(t){this.root=(0,G.join)(t?.trim()||V(),"provider-sessions"),Ce(this.root)}sessionDir(t){return(0,G.join)(this.root,$r(t))}eventsPath(t){return(0,G.join)(this.sessionDir(t),"events.jsonl")}statePath(t){return(0,G.join)(this.sessionDir(t),"state.json")}readState(t){let r=qr(this.statePath(t));return{providerSessionId:t,agentRunId:it(r.agentRunId),providerName:it(r.providerName),ackLine:Math.max(0,jr(r.ackLine))}}writeState(t){let r=this.statePath(t.providerSessionId);Ce((0,G.dirname)(r)),(0,C.writeFileSync)(r,`${JSON.stringify(t,null,2)}
18
+ `:y,k=Pr(d);return{repoRoot:r,baseSha:s,baseRef:o,currentRef:n,diff:d,diffHash:Or(d,f),hasStagedChanges:v,files:Ur({fileListRaw:a,numstatRaw:i,diffByFile:k,untracked:new Set(m),untrackedContentHashes:f})}}function Lr(e,t,r){let n=e.files.find(o=>o.path===t);if(!n)throw new Error("file is not in current git diff");if(r&&n.patchHash!==r)throw new Error("git diff changed; refresh before restoring");return n}async function tt(e){let t=await Y(e.worktreePath,e.baseRef??void 0);if(t.baseSha!==e.baseSha)throw new Error("git base changed; refresh before restoring");if(t.hasStagedChanges)throw new Error("staged changes are not supported");let r=e.filePath?[Lr(t,e.filePath,e.expectedPatchHash)]:t.files;if(!e.filePath&&e.expectedDiffHash&&t.diffHash!==e.expectedDiffHash)throw new Error("git diff changed; refresh before restoring");let n=r.filter(a=>!a.untracked).map(a=>a.path),o=r.filter(a=>a.untracked).map(a=>a.path),s=t.repoRoot;return await Ze(s,async()=>{n.length>0&&await I(["restore",`--source=${e.baseSha}`,"--worktree","--",...n],s),o.length>0&&await I(["clean","-f","--",...o],s)}),Y(s,e.baseRef??void 0)}var me=require("fs"),rt=require("os"),U=require("path");function Z(){return process.env.TRUESAYER_NODE_HOME?.trim()||(0,U.join)((0,rt.homedir)(),".truesayer-node")}function fe(e){return(0,U.join)(e?.trim()||Z(),"provider.json")}function X(e){return e.replace(/[^a-zA-Z0-9_-]/g,"_").slice(0,120)||"unknown"}function nt(e){return(0,me.mkdirSync)(e,{recursive:!0,mode:448}),(0,me.chmodSync)(e,448),e}function Fr(e){return{HOME:e,CLAUDE_CONFIG_DIR:(0,U.join)(e,".claude"),CODEX_HOME:(0,U.join)(e,".codex")}}function xe(e){let t=e.truesayerNodeHome?.trim()||Z(),r=X(e.agentId),n=(0,U.join)(t,"agents",r),o=(0,U.join)(t,"runtime-home"),s=(0,U.join)(n,"space"),a=(0,U.join)(s,"profile");for(let i of[o,(0,U.join)(o,".claude"),(0,U.join)(o,".codex"),s,a])nt(i);return{agentRoot:n,providerHome:o,spaceRoot:s,profileDir:a,providerEnv:Fr(o)}}function ot(e){let t=e.truesayerNodeHome?.trim()||Z(),r=X(e.workspaceId),n=X(e.agentSessionId),o=X(e.agentRunId),s=X(e.repoAlias),a=xe({truesayerNodeHome:t,workspaceId:e.workspaceId,agentId:e.agentId}),{agentRoot:i,providerHome:c,spaceRoot:m,profileDir:v}=a,l=(0,U.join)(t,"workspace",r),f=(0,U.join)(m,"context",n),y=(0,U.join)(m,"agent-run",o),d=(0,U.join)(l,"worktree",s,o);for(let k of[l,f,y,d])nt(k);return{agentRoot:i,workspaceRoot:l,providerHome:c,spaceRoot:m,profileDir:v,contextDir:f,agentRunDir:y,worktreeDir:d,fileToolRoot:d,providerEnv:a.providerEnv}}var C=require("fs"),G=require("path");function Hr(e){return e.replace(/[^a-zA-Z0-9_-]/g,"_").slice(0,120)||"unknown"}function Ce(e){(0,C.mkdirSync)(e,{recursive:!0,mode:448}),(0,C.chmodSync)(e,448)}function $r(e){if(!(0,C.existsSync)(e))return{};try{let t=JSON.parse((0,C.readFileSync)(e,"utf8"));return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}catch{return{}}}function st(e){return typeof e=="string"&&e.trim()?e.trim():""}function qr(e){return typeof e=="number"&&Number.isFinite(e)?Math.trunc(e):0}var Q=class{constructor(t){this.root=(0,G.join)(t?.trim()||Z(),"provider-sessions"),Ce(this.root)}sessionDir(t){return(0,G.join)(this.root,Hr(t))}eventsPath(t){return(0,G.join)(this.sessionDir(t),"events.jsonl")}statePath(t){return(0,G.join)(this.sessionDir(t),"state.json")}readState(t){let r=$r(this.statePath(t));return{providerSessionId:t,agentRunId:st(r.agentRunId),providerName:st(r.providerName),ackLine:Math.max(0,qr(r.ackLine))}}writeState(t){let r=this.statePath(t.providerSessionId);Ce((0,G.dirname)(r)),(0,C.writeFileSync)(r,`${JSON.stringify(t,null,2)}
19
19
  `,{mode:384}),(0,C.chmodSync)(r,384)}append(t){let r=this.readState(t.providerSessionId),n=this.eventsPath(t.providerSessionId);Ce((0,G.dirname)(n));let o=this.readEvents(t.providerSessionId).length+1;return(0,C.appendFileSync)(n,`${JSON.stringify(t.raw)}
20
20
  `,{mode:384}),(0,C.chmodSync)(n,384),this.writeState({providerSessionId:t.providerSessionId,agentRunId:t.agentRunId||r.agentRunId,providerName:t.providerName||r.providerName,ackLine:r.ackLine}),{line:o,raw:t.raw}}markAck(t,r){if(!t||!Number.isFinite(r)||r<=0)return;let n=this.readState(t);this.writeState({...n,ackLine:Math.max(n.ackLine,Math.trunc(r))})}readEvents(t){let r=this.eventsPath(t);return(0,C.existsSync)(r)?(0,C.readFileSync)(r,"utf8").split(`
21
- `).filter(n=>n.trim().length>0).map((n,o)=>{try{return{line:o+1,raw:JSON.parse(n)}}catch{return{line:o+1,raw:{type:"node.raw_parse_failed"}}}}):[]}unackedBatches(t=100){return(0,C.existsSync)(this.root)?(0,C.readdirSync)(this.root,{withFileTypes:!0}).filter(r=>r.isDirectory()).flatMap(r=>{let n=this.readState(r.name);if(!n.agentRunId||!n.providerSessionId)return[];let o=this.readEvents(n.providerSessionId).filter(s=>s.line>n.ackLine).slice(0,t);return o.length>0?[{...n,events:o}]:[]}):[]}};var ke=require("fs/promises"),ut=require("os"),lt=require("path"),Oe=require("@anthropic-ai/claude-agent-sdk");var at=X(require("os")),ee=require("fs"),D=require("@anthropic-ai/claude-agent-sdk"),u=require("zod/v4"),Wr=16*1024,Gr=12e3;function Br(e){return{content:[{type:"text",text:JSON.stringify(e??{})}]}}var Me=u.z.object({id:u.z.string().describe("Stable slug for this task item, such as implement-todo-app."),label:u.z.string().trim().min(1).describe('Descriptive task title, such as "\u5B9E\u73B0\u5168\u6808 Todo app"; do not use only "1", "step 1", or "phase 1".'),ownerAgentId:u.z.string().describe("Target Truesayer teammate id from list_channel_agents or resolve_channel_agent. Do not put responsibilities, roles, names, or mention text here."),status:u.z.enum(["todo","active","done","blocked"]).optional(),estMinutes:u.z.number().optional(),dependsOn:u.z.array(u.z.string()).optional()}).passthrough(),Jr=u.z.object({creationCheckId:u.z.string().uuid(),name:u.z.string().optional(),description:u.z.string().optional(),providerName:u.z.string().optional(),providerId:u.z.string().optional(),modelId:u.z.string().optional(),selectedModel:u.z.string().optional(),reasoningEffort:u.z.enum(["default","none","minimal","low","medium","high","xhigh","max"]).optional(),thinkingMode:u.z.enum(["default","disabled","adaptive"]).optional(),serviceTier:u.z.enum(["default","fast","flex"]).optional(),responsibility:u.z.string().optional()}).passthrough();function Kr(e){if(!e.startsWith("/tmp/")&&!e.startsWith(`${at.default.tmpdir()}/`))return!1;try{let t=(0,ee.statSync)(e);return t.isFile()&&t.size>0}catch{return!1}}function zr(e){try{let t=(0,ee.statSync)(e),r=Math.max(0,t.size-Wr);return(0,ee.readFileSync)(e).subarray(r).toString("utf8").replace(/\0/g,"").trim().slice(-Gr)}catch{return""}}function Vr(e){if(typeof e.logTail=="string"&&e.logTail.trim())return e;let t=typeof e.logPath=="string"?e.logPath.trim():"";if(!t||!Kr(t))return e;let r=zr(t);return r?{...e,logTail:r}:e}function De(e,t){let r=async(o,s)=>{let a=o==="record_background_service"?Vr(s):s;return Br(await t({agentRunId:e,toolName:o,args:a}))};return[(0,D.tool)("reply_to_channel",'Publish the final visible message or meaningful stage update in the current Truesayer channel. Use intent="update" only for a meaningful stage synchronization that a human should see; use intent="final" for the run-ending report after all required work, validation, delegation, background-service recording, and blocker checks are complete. Do not use it for acknowledgements, "I will check" notes, or low-value chatter. After calling it, do not call more tools; after a final reply succeeds, finish the turn.',{body:u.z.string(),intent:u.z.enum(["update","final"]).optional(),attachmentIds:u.z.array(u.z.string()).optional(),messageId:u.z.string().optional()},async o=>r("reply_to_channel",o),{alwaysLoad:!0}),(0,D.tool)("create_agent","Create an active Truesayer teammate profile and bind it to a Node runtime provider/model. This is a protected action that blocks for human approval. It does not add the new teammate to the current channel; channel membership must be granted by the frontend, an admin API, setup seed, or an explicit Server policy.",{creationCheckId:u.z.string().uuid(),name:u.z.string(),description:u.z.string(),providerId:u.z.string().optional(),providerName:u.z.string().optional(),modelId:u.z.string().optional(),selectedModel:u.z.string().optional(),reasoningEffort:u.z.enum(["default","none","minimal","low","medium","high","xhigh","max"]).optional(),thinkingMode:u.z.enum(["default","disabled","adaptive"]).optional(),serviceTier:u.z.enum(["default","fast","flex"]).optional(),systemPrompt:u.z.string().optional(),soul:u.z.string().optional(),tone:u.z.number().optional()},async o=>r("create_agent",o),{alwaysLoad:!0}),(0,D.tool)("create_agents","Create multiple active Truesayer teammate profiles in one protected action. This blocks for human approval before the Server creates the profiles. Each agents[] item must include a stable creationCheckId UUIDv7; reuse the same creationCheckId when retrying the same logical agent creation request. It does not add the new teammates to the current channel; channel membership must be granted by the frontend, an admin API, setup seed, or an explicit Server policy.",{summary:u.z.string().describe("Human-readable summary shown on the approval activity card."),agents:u.z.array(Jr.extend({name:u.z.string(),description:u.z.string()})).min(1)},async o=>r("create_agents",o),{alwaysLoad:!0}),(0,D.tool)("request_add_agents_to_channel","Request human approval to add existing Truesayer agent teammates to the current channel. Use this after create_agents returns agentIds and list_channel_agents shows those agents are not_bound. The Server blocks until a human approves, then grants channel membership and active channel agent instances for the listed agentIds.",{summary:u.z.string().describe("Human-readable summary shown on the approval activity card."),agentIds:u.z.array(u.z.string()).min(1).describe("Existing Truesayer agent ids to add to the current channel. Use ids returned by create_agents or list_channel_agents; do not use names.")},async o=>r("request_add_agents_to_channel",o),{alwaysLoad:!0}),(0,D.tool)("request_change_channel_workdir","Request human approval to change the current channel code directory. Use this when the current channel should run agents against a different local Git repository path. The Server blocks until a human approves, asks the connected Node to prepare that path, and only then updates the channel.",{summary:u.z.string().describe("Human-readable summary shown on the approval activity card."),path:u.z.string().trim().min(1).describe("Absolute or Node-local path to the Git repository or directory to initialize as the current channel code space."),baseRef:u.z.string().trim().optional().describe("Git base ref for agent worktrees; defaults to main.")},async o=>r("request_change_channel_workdir",o),{alwaysLoad:!0}),(0,D.tool)("message_agent",'Send a work request or update to another Truesayer agent. This is only for immediately runnable work. If the message continues or refers to a structured task-card item, include planItemId so the Server can reuse the existing handoff instead of creating duplicate work. Do not use it to pre-send future or dependency-blocked work such as "audit after implementation"; represent that as blocked items in delegate_plan instead. Use this to delegate execution instead of visibly @mentioning that agent. After a successful delegation, end the current run. Truesayer may wake the current agent with downstream results and evidence; decide the next step yourself.',{toAgentId:u.z.string(),body:u.z.string(),refTaskId:u.z.string().optional(),planItemId:u.z.string().optional()},async o=>r("message_agent",o),{alwaysLoad:!0}),(0,D.tool)("resolve_channel_agent","Resolve an agent name, mention, or id to a unique teammate in the current Truesayer channel. This is read-only and returns blockers for not_found, not_bound, or ambiguous matches.",{query:u.z.string()},async o=>r("resolve_channel_agent",o),{alwaysLoad:!0}),(0,D.tool)("list_channel_agents","List all Truesayer agents in this workspace and mark whether each one can access the current Truesayer channel. Use this before delegate_plan or message_agent when agent ids or channel access may have changed.",{},async o=>r("list_channel_agents",o),{alwaysLoad:!0}),(0,D.tool)("delegate_plan","Create a channel task card and delegate active items to specific Truesayer agents. Active items are immediately sent to their owner agents as executable work when this tool succeeds. Do not call message_agent to notify the same owner about the same active item. Each item label must describe the actual assigned work in enough detail for the owner to execute it, not only an ordinal. Use blocked items for future or dependency-blocked work, and only make an item active when it should run now. Put all instructions for that phase in the item label/status/dependencies before calling this tool. Do not create plan items owned by yourself or the current agent; coordinator-owned follow-up work such as final review, deciding whether to continue, summary, or reply must stay outside the task card. Do not render coordinator-owned follow-up work as task table rows in visible replies. Use a short sentence instead. Call list_channel_agents first when you need current agent ids or channel access. When the user asks to assign, delegate, create task cards, or start a phase, use this before Bash/Edit/Read unless the user asked you to implement the work yourself. After successful delegation, end the current run. Truesayer may wake the current agent with downstream results and evidence; decide the next step yourself, such as verify, delegate more work, update the plan, report a blocker, or reply to the channel.",{items:u.z.array(Me),replace:u.z.boolean().optional()},async o=>r("delegate_plan",o),{alwaysLoad:!0}),(0,D.tool)("emit_plan","Create or update the visible channel task card for this agent run. Each item label must describe the actual work, not only an ordinal. Do not create plan items owned by yourself or the current agent; coordinator-owned follow-up work such as final review, deciding whether to continue, summary, or reply must stay outside the task card. Do not render coordinator-owned follow-up work as task table rows in visible replies. Use a short sentence instead. Existing unfinished downstream items are preserved unless replace is true. Use delegate_plan instead when active items should be assigned to other agents. Call list_channel_agents first when ownerAgentId values need current agent ids or channel access.",{items:u.z.array(Me),replace:u.z.boolean().optional()},async o=>r("emit_plan",o),{alwaysLoad:!0}),(0,D.tool)("advance_plan",'Create or advance the Server-owned execution plan. Use this after planning to let Truesayer decide the next runnable task. Items may include executionKind="self" or "agent" and scheduleKind="blocking" or "parallel". For blocking agent work, the Server queues the teammate run and marks the current agent session as waiting until the child task completes. If this returns self_task, execute only that returned task and later call update_task. If this returns waiting or dispatched, do not also message the same teammate.',{items:u.z.array(Me).optional()},async o=>r("advance_plan",o),{alwaysLoad:!0}),(0,D.tool)("update_plan_item","Update one item on the current canonical task card. Do not provide or guess a root task id; the Truesayer Server chooses the writable plan from this agent run context.",{itemId:u.z.string(),status:u.z.enum(["todo","active","done","blocked"])},async o=>r("update_plan_item",o),{alwaysLoad:!0}),(0,D.tool)("update_task","Mark the Server-assigned plan task for this agent run as done, blocked, or cancelled. Use this before a final reply when advance_plan or a delegated plan task assigned concrete work to this run. The Server rejects updates for tasks not assigned to this agent run.",{taskId:u.z.string(),status:u.z.enum(["done","blocked","cancelled"]),summary:u.z.string().optional(),evidence:u.z.record(u.z.string(),u.z.unknown()).optional()},async o=>r("update_task",o),{alwaysLoad:!0}),(0,D.tool)("record_background_service","Record a visible background service started for human inspection. Use this after starting a keep-alive dev/server process in the background and after a bounded health check succeeds. Include PID, port, URL, and log path so Activity can show a visible background service row. This records observability only; it does not start, stop, or clean up the process.",{label:u.z.string().optional(),pid:u.z.number().optional(),port:u.z.number().optional(),url:u.z.string().optional(),healthUrl:u.z.string().optional(),logPath:u.z.string().optional(),cwd:u.z.string().optional()},async o=>r("record_background_service",o),{alwaysLoad:!0})]}function dt(e,t){return(0,D.createSdkMcpServer)({name:"truesayer-platform",version:"0.1.0",tools:De(e,t),alwaysLoad:!0})}var he=["Truesayer platform tools are available as local tools. They send JSON-RPC requests from the Node process to the Truesayer Server over the existing WebSocket.",'reply_to_channel publishes a human-facing channel message. It has intent="update" for a meaningful stage synchronization and intent="final" for the run-ending report.','Use reply_to_channel intent="update" sparingly, only when the human should see a concrete stage result, blocker, approval context, or coordination state. Do not use it for acknowledgements, "I will check" notes, or low-value chatter.','Before reply_to_channel intent="final", finish all required tool work: verification, git/status checks, service health checks, record_background_service when needed, delegation, and blocker analysis. After a final reply succeeds, do not call more tools, do not continue verification, and finish the turn.',"Visible mentions in channel messages must use the canonical token <@teamMemberId>. Plain @name text is display-only and does not route work. Use list_channel_agents or resolve_channel_agent to get exact teammate ids before mentioning another teammate.","Use create_agents to create long-lived teammates that do not yet exist. Put what the teammate does in description, not role. Every agents[] item must include a stable creationCheckId UUIDv7; reuse it when retrying the same logical agent creation. create_agents blocks for human approval before the Server creates the profiles, and returns agentId plus mentionName values to use in message_agent and task card ownerAgentId.","Use create_agent only when creating exactly one teammate. It is also protected and blocks for human approval.","create_agent and create_agents do not add new teammates to the current channel. After creating teammates for current-channel collaboration, call request_add_agents_to_channel with the returned agentIds. It blocks for human approval before the Server grants channel access.","Use request_change_channel_workdir when you need to change the current channel code directory. It is protected and blocks for human approval before the Server stores the new channel path.","Use list_channel_agents to get the realtime list of all Truesayer agents in this workspace and whether each can access the current channel. Use it before delegate_plan or message_agent when IDs, names, or channel membership may have changed.","Use resolve_channel_agent to turn a teammate name or @mention in the current channel into the agentId required by message_agent and task card ownerAgentId. If it returns not_bound, ambiguous, or not_found, report that blocker instead of guessing an id.","message_agent is only for immediately runnable work. If continuing a structured task-card item, include planItemId. The recipient may start as soon as the tool succeeds, so do not use message_agent to pre-send future, conditional, or dependency-blocked work.","Use advance_plan as the preferred execution entrypoint for structured plans. It lets the Server choose runnable self tasks, blocking teammate handoffs, or parallel teammate handoffs from the plan state.","Use delegate_plan or emit_plan for legacy visible channel task cards, and update_plan_item to update legacy item status. Task item labels must be descriptive enough for the assigned agent to execute from the item alone.","Use update_task before final reply when the Server assigned a concrete plan task to this run. update_task changes machine state; reply_to_channel is the human-facing stage or final message.","delegate_plan active items with valid ownerAgentId values are already sent to their owner agents as executable work when the tool succeeds. Do not follow delegate_plan with message_agent for the same active item; put the full task instructions into the active plan item before delegating.","Future or dependency-blocked work must be represented as blocked task card items with delegate_plan or emit_plan. Do not send those items through message_agent until they are actually runnable.","Do not create plan items owned by yourself or the current agent. Coordinator-owned follow-up work such as final review, deciding whether to continue, summary, or reply is not a task-card item. After delegated work finishes, Truesayer may wake the current agent with downstream results and evidence, and you decide the next step yourself: verify, delegate more work, update the plan, report a blocker, or reply to the channel.","If a prompt asks you to create a collaboration team, call create_agents once with the whole team so the human sees one approval card. After it succeeds, call request_add_agents_to_channel once with the created agentIds when those teammates need to work in the current channel. If either tool is rejected or blocked, report that blocker instead of retrying.","If a prompt asks you to assign, delegate, create task cards, update a plan, or start a phased handoff with existing teammates, your first tool call must be delegate_plan or message_agent in the legacy flow, or advance_plan in the Server-owned plan execution flow, before any file, git, shell, package-manager, or code-edit tool.","A coordinating agent must not do another agent's assigned implementation, audit, or optimization work itself. Create the task card or agent message, then end the current run. Truesayer may wake the current agent with a continuation when downstream work reports back.","Never send message_agent to yourself as an availability test. If no suitable teammate exists, call create_agent first; if provider capability is missing, reply with the blocker.","Only use message_agent after delegate_plan for genuinely new follow-up communication, not as a notification that the delegated active item exists.","Do not use provider-native Agent, Task, TodoRead, or TodoWrite for product coordination. Truesayer task cards, plan updates, and teammate handoffs must go through Truesayer platform tools so the Server can audit every agent run.","If the provider UI prefixes Truesayer tools as MCP tools, select the matching tool whose name ends with create_agents, create_agent, request_add_agents_to_channel, request_change_channel_workdir, resolve_channel_agent, reply_to_channel, message_agent, delegate_plan, emit_plan, advance_plan, update_task, update_plan_item, or record_background_service.","Long-running or continuously-running service/watch commands, such as dev servers, file watchers, npm start, npm run start, npm run dev, vite, next dev, nodemon, tsx --watch, tail -f, database servers, or queue workers, must not be run as foreground blocking commands. Start them in the background, redirect logs to a file, record the PID, and run a bounded health check with timeout. Stop or clean up the process when validation is complete unless the task explicitly asks to keep the service available for human inspection; in that case keep it running and call record_background_service with PID, port, URL, and log path. Finite commands such as install, build, test, lint, migration, and one-shot scripts should run in the foreground and must return an exit code.","Do not try to access the Truesayer Server database, provider secrets, or Server-only environment variables from Node."].join(`
22
- `);function ve(e){let t=Object.entries(e??{});return t.length===0?"":["Available Node runtime providers for create_agent/create_agents runtime selection:",...t.map(([r,n])=>`- ${r} (${n.kind}): ${n.models.join(", ")}`)].join(`
23
- `)}var Yr=["PATH","HOME","USER","LOGNAME","SHELL","TMPDIR","TEMP","TMP","LOCALAPPDATA","APPDATA","XDG_CONFIG_HOME","XDG_CACHE_HOME","XDG_DATA_HOME","CLAUDE_CONFIG_DIR","CODEX_HOME","SSL_CERT_FILE","SSL_CERT_DIR","NODE_EXTRA_CA_CERTS","LANG","LC_ALL","TERM","SystemRoot","ComSpec","PATHEXT","WINDIR","TRUESAYER_CODEX_BIN","TRUESAYER_CODEX_REQUEST_TIMEOUT_MS","CODEX_CAPTURE_PATH","FAKE_CODEX_CAPTURE_PATH"];function Xr(e=process.env){let t={};for(let r of Yr){let n=e[r];typeof n=="string"&&n.length>0&&(t[r]=n)}return t}function te(e={}){return{...Xr(),...e}}function ye(){return te()}var Zr=["Agent","Task","TodoRead","TodoWrite"];async function*Qr(){}function en(e){return Array.from(new Set(e.map(t=>t.trim()).filter(Boolean)))}function tn(e){return en((e??[]).map(t=>t.value))}function rn(e,t,r,n){let o;return new Promise((s,a)=>{o=setTimeout(()=>{r(),a(new Error(n))},t),o.unref?.(),e.then(i=>{o&&clearTimeout(o),s(i)},i=>{o&&clearTimeout(o),a(i)})})}async function pt(e={}){let t=e.cwd??await(0,ke.mkdtemp)((0,lt.join)((0,ut.tmpdir)(),"truesayer-claude-model-probe-")),r=!e.cwd,n=new AbortController,o=(0,Oe.query)({prompt:Qr(),options:{cwd:t,env:ye(),abortController:n,maxTurns:1}});try{let s=await rn(o.initializationResult(),e.timeoutMs??3e4,()=>n.abort(),"Claude Code model discovery timed out");return tn(s.models)}finally{o.close(),r&&await(0,ke.rm)(t,{recursive:!0,force:!0})}}function nn(e,t,r){let n=[e?.trim(),t?he:"",t?ve(r):""].filter(Boolean).join(`
21
+ `).filter(n=>n.trim().length>0).map((n,o)=>{try{return{line:o+1,raw:JSON.parse(n)}}catch{return{line:o+1,raw:{type:"node.raw_parse_failed"}}}}):[]}unackedBatches(t=100){return(0,C.existsSync)(this.root)?(0,C.readdirSync)(this.root,{withFileTypes:!0}).filter(r=>r.isDirectory()).flatMap(r=>{let n=this.readState(r.name);if(!n.agentRunId||!n.providerSessionId)return[];let o=this.readEvents(n.providerSessionId).filter(s=>s.line>n.ackLine).slice(0,t);return o.length>0?[{...n,events:o}]:[]}):[]}};var ye=require("fs/promises"),ct=require("os"),ut=require("path"),Oe=require("@anthropic-ai/claude-agent-sdk");var it=V(require("os")),ee=require("fs"),D=require("@anthropic-ai/claude-agent-sdk"),u=require("zod/v4"),jr=16*1024,Wr=12e3;function Gr(e){return{content:[{type:"text",text:JSON.stringify(e??{})}]}}var Me=u.z.object({id:u.z.string().describe("Stable slug for this task item, such as implement-todo-app."),label:u.z.string().trim().min(1).describe('Descriptive task title, such as "\u5B9E\u73B0\u5168\u6808 Todo app"; do not use only "1", "step 1", or "phase 1".'),ownerAgentId:u.z.string().describe("Target Truesayer teammate id from list_channel_agents or resolve_channel_agent. Do not put responsibilities, roles, names, or mention text here."),status:u.z.enum(["todo","active","done","blocked"]).optional(),estMinutes:u.z.number().optional(),dependsOn:u.z.array(u.z.string()).optional()}).passthrough(),Br=u.z.object({creationCheckId:u.z.string().uuid(),name:u.z.string().optional(),description:u.z.string().optional(),providerName:u.z.string().optional(),providerId:u.z.string().optional(),modelId:u.z.string().optional(),selectedModel:u.z.string().optional(),reasoningEffort:u.z.enum(["default","none","minimal","low","medium","high","xhigh","max"]).optional(),thinkingMode:u.z.enum(["default","disabled","adaptive"]).optional(),serviceTier:u.z.enum(["default","fast","flex"]).optional(),responsibility:u.z.string().optional()}).passthrough();function Jr(e){if(!e.startsWith("/tmp/")&&!e.startsWith(`${it.default.tmpdir()}/`))return!1;try{let t=(0,ee.statSync)(e);return t.isFile()&&t.size>0}catch{return!1}}function Kr(e){try{let t=(0,ee.statSync)(e),r=Math.max(0,t.size-jr);return(0,ee.readFileSync)(e).subarray(r).toString("utf8").replace(/\0/g,"").trim().slice(-Wr)}catch{return""}}function zr(e){if(typeof e.logTail=="string"&&e.logTail.trim())return e;let t=typeof e.logPath=="string"?e.logPath.trim():"";if(!t||!Jr(t))return e;let r=Kr(t);return r?{...e,logTail:r}:e}function De(e,t){let r=async(o,s)=>{let a=o==="record_background_service"?zr(s):s;return Gr(await t({agentRunId:e,toolName:o,args:a}))};return[(0,D.tool)("reply_to_channel",'Publish the final visible message or meaningful stage update in the current Truesayer channel. Use intent="update" only for a meaningful stage synchronization that a human should see; use intent="final" for the run-ending report after all required work, validation, delegation, background-service recording, and blocker checks are complete. Do not use it for acknowledgements, "I will check" notes, or low-value chatter. After calling it, do not call more tools; after a final reply succeeds, finish the turn.',{body:u.z.string(),intent:u.z.enum(["update","final"]).optional(),attachmentIds:u.z.array(u.z.string()).optional(),messageId:u.z.string().optional()},async o=>r("reply_to_channel",o),{alwaysLoad:!0}),(0,D.tool)("create_agent","Create an active Truesayer teammate profile and bind it to a Node runtime provider/model. This is a protected action that blocks for human approval. It does not add the new teammate to the current channel; channel membership must be granted by the frontend, an admin API, setup seed, or an explicit Server policy.",{creationCheckId:u.z.string().uuid(),name:u.z.string(),description:u.z.string(),providerId:u.z.string().optional(),providerName:u.z.string().optional(),modelId:u.z.string().optional(),selectedModel:u.z.string().optional(),reasoningEffort:u.z.enum(["default","none","minimal","low","medium","high","xhigh","max"]).optional(),thinkingMode:u.z.enum(["default","disabled","adaptive"]).optional(),serviceTier:u.z.enum(["default","fast","flex"]).optional(),systemPrompt:u.z.string().optional(),soul:u.z.string().optional(),tone:u.z.number().optional()},async o=>r("create_agent",o),{alwaysLoad:!0}),(0,D.tool)("create_agents","Create multiple active Truesayer teammate profiles in one protected action. This blocks for human approval before the Server creates the profiles. Each agents[] item must include a stable creationCheckId UUIDv7; reuse the same creationCheckId when retrying the same logical agent creation request. It does not add the new teammates to the current channel; channel membership must be granted by the frontend, an admin API, setup seed, or an explicit Server policy.",{summary:u.z.string().describe("Human-readable summary shown on the approval activity card."),agents:u.z.array(Br.extend({name:u.z.string(),description:u.z.string()})).min(1)},async o=>r("create_agents",o),{alwaysLoad:!0}),(0,D.tool)("request_add_agents_to_channel","Request human approval to add existing Truesayer agent teammates to the current channel. Use this after create_agents returns agentIds and list_channel_agents shows those agents are not_bound. The Server blocks until a human approves, then grants channel membership and active channel agent instances for the listed agentIds.",{summary:u.z.string().describe("Human-readable summary shown on the approval activity card."),agentIds:u.z.array(u.z.string()).min(1).describe("Existing Truesayer agent ids to add to the current channel. Use ids returned by create_agents or list_channel_agents; do not use names.")},async o=>r("request_add_agents_to_channel",o),{alwaysLoad:!0}),(0,D.tool)("request_change_channel_workdir","Request human approval to change the current channel code directory. Use this when the current channel should run agents against a different local Git repository path. The Server blocks until a human approves, asks the connected Node to prepare that path, and only then updates the channel.",{summary:u.z.string().describe("Human-readable summary shown on the approval activity card."),path:u.z.string().trim().min(1).describe("Absolute or Node-local path to the Git repository or directory to initialize as the current channel code space."),baseRef:u.z.string().trim().optional().describe("Git base ref for agent worktrees; defaults to main.")},async o=>r("request_change_channel_workdir",o),{alwaysLoad:!0}),(0,D.tool)("message_agent",'Send a work request or update to another Truesayer agent. This is only for immediately runnable work. If the message continues or refers to a structured task-card item, include planItemId so the Server can reuse the existing handoff instead of creating duplicate work. Do not use it to pre-send future or dependency-blocked work such as "audit after implementation"; represent that as blocked items in delegate_plan instead. Use this to delegate execution instead of visibly @mentioning that agent. After a successful delegation, end the current run. Truesayer may wake the current agent with downstream results and evidence; decide the next step yourself.',{toAgentId:u.z.string(),body:u.z.string(),refTaskId:u.z.string().optional(),planItemId:u.z.string().optional()},async o=>r("message_agent",o),{alwaysLoad:!0}),(0,D.tool)("resolve_channel_agent","Resolve an agent name, mention, or id to a unique teammate in the current Truesayer channel. This is read-only and returns blockers for not_found, not_bound, or ambiguous matches.",{query:u.z.string()},async o=>r("resolve_channel_agent",o),{alwaysLoad:!0}),(0,D.tool)("list_channel_agents","List all Truesayer agents in this workspace and mark whether each one can access the current Truesayer channel. Use this before delegate_plan or message_agent when agent ids or channel access may have changed.",{},async o=>r("list_channel_agents",o),{alwaysLoad:!0}),(0,D.tool)("delegate_plan","Create a channel task card and delegate active items to specific Truesayer agents. Active items are immediately sent to their owner agents as executable work when this tool succeeds. Do not call message_agent to notify the same owner about the same active item. Each item label must describe the actual assigned work in enough detail for the owner to execute it, not only an ordinal. Use blocked items for future or dependency-blocked work, and only make an item active when it should run now. Put all instructions for that phase in the item label/status/dependencies before calling this tool. Do not create plan items owned by yourself or the current agent; coordinator-owned follow-up work such as final review, deciding whether to continue, summary, or reply must stay outside the task card. Do not render coordinator-owned follow-up work as task table rows in visible replies. Use a short sentence instead. Call list_channel_agents first when you need current agent ids or channel access. When the user asks to assign, delegate, create task cards, or start a phase, use this before Bash/Edit/Read unless the user asked you to implement the work yourself. After successful delegation, end the current run. Truesayer may wake the current agent with downstream results and evidence; decide the next step yourself, such as verify, delegate more work, update the plan, report a blocker, or reply to the channel.",{items:u.z.array(Me),replace:u.z.boolean().optional()},async o=>r("delegate_plan",o),{alwaysLoad:!0}),(0,D.tool)("emit_plan","Create or update the visible channel task card for this agent run. Each item label must describe the actual work, not only an ordinal. Do not create plan items owned by yourself or the current agent; coordinator-owned follow-up work such as final review, deciding whether to continue, summary, or reply must stay outside the task card. Do not render coordinator-owned follow-up work as task table rows in visible replies. Use a short sentence instead. Existing unfinished downstream items are preserved unless replace is true. Use delegate_plan instead when active items should be assigned to other agents. Call list_channel_agents first when ownerAgentId values need current agent ids or channel access.",{items:u.z.array(Me),replace:u.z.boolean().optional()},async o=>r("emit_plan",o),{alwaysLoad:!0}),(0,D.tool)("advance_plan",'Create or advance the Server-owned execution plan. Use this after planning to let Truesayer decide the next runnable task. Items may include executionKind="self" or "agent" and scheduleKind="blocking" or "parallel". For blocking agent work, the Server queues the teammate run and marks the current agent session as waiting until the child task completes. If this returns self_task, execute only that returned task and later call update_task. If this returns waiting or dispatched, do not also message the same teammate.',{items:u.z.array(Me).optional()},async o=>r("advance_plan",o),{alwaysLoad:!0}),(0,D.tool)("update_plan_item","Update one item on the current canonical task card. Do not provide or guess a root task id; the Truesayer Server chooses the writable plan from this agent run context.",{itemId:u.z.string(),status:u.z.enum(["todo","active","done","blocked"])},async o=>r("update_plan_item",o),{alwaysLoad:!0}),(0,D.tool)("update_task","Mark the Server-assigned plan task for this agent run as done, blocked, or cancelled. Use this before a final reply when advance_plan or a delegated plan task assigned concrete work to this run. The Server rejects updates for tasks not assigned to this agent run.",{taskId:u.z.string(),status:u.z.enum(["done","blocked","cancelled"]),summary:u.z.string().optional(),evidence:u.z.record(u.z.string(),u.z.unknown()).optional()},async o=>r("update_task",o),{alwaysLoad:!0}),(0,D.tool)("record_background_service","Record a visible background service started for human inspection. Use this after starting a keep-alive dev/server process in the background and after a bounded health check succeeds. Include PID, port, URL, and log path so Activity can show a visible background service row. This records observability only; it does not start, stop, or clean up the process.",{label:u.z.string().optional(),pid:u.z.number().optional(),port:u.z.number().optional(),url:u.z.string().optional(),healthUrl:u.z.string().optional(),logPath:u.z.string().optional(),cwd:u.z.string().optional()},async o=>r("record_background_service",o),{alwaysLoad:!0})]}function at(e,t){return(0,D.createSdkMcpServer)({name:"truesayer-platform",version:"0.1.0",tools:De(e,t),alwaysLoad:!0})}var ge=["Truesayer platform tools are available as local tools. They send JSON-RPC requests from the Node process to the Truesayer Server over the existing WebSocket.",'reply_to_channel publishes a human-facing channel message. It has intent="update" for a meaningful stage synchronization and intent="final" for the run-ending report.','Use reply_to_channel intent="update" sparingly, only when the human should see a concrete stage result, blocker, approval context, or coordination state. Do not use it for acknowledgements, "I will check" notes, or low-value chatter.','Before reply_to_channel intent="final", finish all required tool work: verification, git/status checks, service health checks, record_background_service when needed, delegation, and blocker analysis. After a final reply succeeds, do not call more tools, do not continue verification, and finish the turn.',"Visible mentions in channel messages must use the canonical token <@teamMemberId>. Plain @name text is display-only and does not route work. Use list_channel_agents or resolve_channel_agent to get exact teammate ids before mentioning another teammate.","Use create_agents to create long-lived teammates that do not yet exist. Put what the teammate does in description, not role. Every agents[] item must include a stable creationCheckId UUIDv7; reuse it when retrying the same logical agent creation. create_agents blocks for human approval before the Server creates the profiles, and returns agentId plus mentionName values to use in message_agent and task card ownerAgentId.","Use create_agent only when creating exactly one teammate. It is also protected and blocks for human approval.","create_agent and create_agents do not add new teammates to the current channel. After creating teammates for current-channel collaboration, call request_add_agents_to_channel with the returned agentIds. It blocks for human approval before the Server grants channel access.","Use request_change_channel_workdir when you need to change the current channel code directory. It is protected and blocks for human approval before the Server stores the new channel path.","Use list_channel_agents to get the realtime list of all Truesayer agents in this workspace and whether each can access the current channel. Use it before delegate_plan or message_agent when IDs, names, or channel membership may have changed.","Use resolve_channel_agent to turn a teammate name or @mention in the current channel into the agentId required by message_agent and task card ownerAgentId. If it returns not_bound, ambiguous, or not_found, report that blocker instead of guessing an id.","message_agent is only for immediately runnable work. If continuing a structured task-card item, include planItemId. The recipient may start as soon as the tool succeeds, so do not use message_agent to pre-send future, conditional, or dependency-blocked work.","Use advance_plan as the preferred execution entrypoint for structured plans. It lets the Server choose runnable self tasks, blocking teammate handoffs, or parallel teammate handoffs from the plan state.","Use delegate_plan or emit_plan for legacy visible channel task cards, and update_plan_item to update legacy item status. Task item labels must be descriptive enough for the assigned agent to execute from the item alone.","Use update_task before final reply when the Server assigned a concrete plan task to this run. update_task changes machine state; reply_to_channel is the human-facing stage or final message.","delegate_plan active items with valid ownerAgentId values are already sent to their owner agents as executable work when the tool succeeds. Do not follow delegate_plan with message_agent for the same active item; put the full task instructions into the active plan item before delegating.","Future or dependency-blocked work must be represented as blocked task card items with delegate_plan or emit_plan. Do not send those items through message_agent until they are actually runnable.","Do not create plan items owned by yourself or the current agent. Coordinator-owned follow-up work such as final review, deciding whether to continue, summary, or reply is not a task-card item. After delegated work finishes, Truesayer may wake the current agent with downstream results and evidence, and you decide the next step yourself: verify, delegate more work, update the plan, report a blocker, or reply to the channel.","If a prompt asks you to create a collaboration team, call create_agents once with the whole team so the human sees one approval card. After it succeeds, call request_add_agents_to_channel once with the created agentIds when those teammates need to work in the current channel. If either tool is rejected or blocked, report that blocker instead of retrying.","If a prompt asks you to assign, delegate, create task cards, update a plan, or start a phased handoff with existing teammates, your first tool call must be delegate_plan or message_agent in the legacy flow, or advance_plan in the Server-owned plan execution flow, before any file, git, shell, package-manager, or code-edit tool.","A coordinating agent must not do another agent's assigned implementation, audit, or optimization work itself. Create the task card or agent message, then end the current run. Truesayer may wake the current agent with a continuation when downstream work reports back.","Never send message_agent to yourself as an availability test. If no suitable teammate exists, call create_agent first; if provider capability is missing, reply with the blocker.","Only use message_agent after delegate_plan for genuinely new follow-up communication, not as a notification that the delegated active item exists.","Do not use provider-native Agent, Task, TodoRead, or TodoWrite for product coordination. Truesayer task cards, plan updates, and teammate handoffs must go through Truesayer platform tools so the Server can audit every agent run.","If the provider UI prefixes Truesayer tools as MCP tools, select the matching tool whose name ends with create_agents, create_agent, request_add_agents_to_channel, request_change_channel_workdir, resolve_channel_agent, reply_to_channel, message_agent, delegate_plan, emit_plan, advance_plan, update_task, update_plan_item, or record_background_service.","Long-running or continuously-running service/watch commands, such as dev servers, file watchers, npm start, npm run start, npm run dev, vite, next dev, nodemon, tsx --watch, tail -f, database servers, or queue workers, must not be run as foreground blocking commands. Start them in the background, redirect logs to a file, record the PID, and run a bounded health check with timeout. Stop or clean up the process when validation is complete unless the task explicitly asks to keep the service available for human inspection; in that case keep it running and call record_background_service with PID, port, URL, and log path. Finite commands such as install, build, test, lint, migration, and one-shot scripts should run in the foreground and must return an exit code.","Do not try to access the Truesayer Server database, provider secrets, or Server-only environment variables from Node."].join(`
22
+ `);function he(e){let t=Object.entries(e??{});return t.length===0?"":["Available Node runtime providers for create_agent/create_agents runtime selection:",...t.map(([r,n])=>`- ${r} (${n.kind}): ${n.models.join(", ")}`)].join(`
23
+ `)}var Vr=["PATH","HOME","USER","LOGNAME","SHELL","TMPDIR","TEMP","TMP","LOCALAPPDATA","APPDATA","XDG_CONFIG_HOME","XDG_CACHE_HOME","XDG_DATA_HOME","CLAUDE_CONFIG_DIR","CODEX_HOME","SSL_CERT_FILE","SSL_CERT_DIR","NODE_EXTRA_CA_CERTS","LANG","LC_ALL","TERM","SystemRoot","ComSpec","PATHEXT","WINDIR","TRUESAYER_CODEX_BIN","TRUESAYER_CODEX_REQUEST_TIMEOUT_MS","CODEX_CAPTURE_PATH","FAKE_CODEX_CAPTURE_PATH"];function Yr(e=process.env){let t={};for(let r of Vr){let n=e[r];typeof n=="string"&&n.length>0&&(t[r]=n)}return t}function te(e={}){return{...Yr(),...e}}function ve(){return te()}var Xr=["Agent","Task","TodoRead","TodoWrite"];async function*Zr(){}function Qr(e){return Array.from(new Set(e.map(t=>t.trim()).filter(Boolean)))}function en(e){return Qr((e??[]).map(t=>t.value))}function tn(e,t,r,n){let o;return new Promise((s,a)=>{o=setTimeout(()=>{r(),a(new Error(n))},t),o.unref?.(),e.then(i=>{o&&clearTimeout(o),s(i)},i=>{o&&clearTimeout(o),a(i)})})}async function lt(e={}){let t=e.cwd??await(0,ye.mkdtemp)((0,ut.join)((0,ct.tmpdir)(),"truesayer-claude-model-probe-")),r=!e.cwd,n=new AbortController,o=(0,Oe.query)({prompt:Zr(),options:{cwd:t,env:ve(),abortController:n,maxTurns:1}});try{let s=await tn(o.initializationResult(),e.timeoutMs??3e4,()=>n.abort(),"Claude Code model discovery timed out");return en(s.models)}finally{o.close(),r&&await(0,ye.rm)(t,{recursive:!0,force:!0})}}function rn(e,t,r){let n=[e?.trim(),t?ge:"",t?he(r):""].filter(Boolean).join(`
24
24
 
25
- `);return n?{type:"preset",preset:"claude_code",append:n}:void 0}function L(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}function on(e){return typeof e=="string"&&e.trim()?e.trim():""}function sn(e){return typeof e=="string"?e.trim():Array.isArray(e)?e.filter(r=>typeof r=="string"&&r.trim().length>0).map(r=>r.trim()).join(" "):""}function mt(...e){for(let t of e){let r=sn(t);if(r)return r}return""}function K(...e){for(let t of e){let r=on(t);if(r)return r}return""}function ft(e,t=""){let r=e.toLowerCase(),n=t.toLowerCase();return["read","grep","glob","ls"].includes(r)?"read":["write","edit","multiedit"].includes(r)?"write":r==="update"?"update":r==="bash"||r==="exec"||r==="exec_command"||r==="codex_command"?/(^|[;&|]\s*)apply_patch\b/.test(n)?"write":/^\s*(sed\s+-n\b|cat\b|head\b|tail\b|nl\b|find\b|ls\b|rg\b|grep\b|pwd\b)/.test(n)?"read":"exec":r.startsWith("mcp__truesayer__")?"platform_tool":"exec"}function gt(e){return e==="read"?"read":e==="write"?"write":e==="update"?"update":e==="platform_tool"?"platform_tool":"exec"}function an(e){return L(e)}function dn(e,t){let r=K(e.name);if(!r)return null;let n=an(e.input),o=mt(n.command,n.cmd,n.commandLine),s=K(n.file_path,n.path,n.filePath),a=ft(r,o),i=K(e.id);return i&&t?.set(i,{rawToolName:r,command:o,path:s,operation:a}),{type:"agent_run.tool.started",payload:{provider:"claude",toolName:gt(a),toolCallId:i,...o?{command:o}:{},...s?{path:s}:{},operation:a}}}function cn(e,t){let n=(Array.isArray(L(e.message).content)?L(e.message).content:[]).map(L).find(f=>f.type==="tool_result");if(!n)return null;let o=L(e.toolUseResult),s=L(o.file),a=K(n.tool_use_id,n.toolUseId),i=t?.get(a)??{},d=K(s.filePath,s.file_path,o.filePath,o.file_path,i.path),p=mt(o.command,o.cmd,i.command),v=K(i.operation)||(d?"read":ft(p?"Bash":"tool",p)),l=d&&typeof s.numLines=="number"?`${s.numLines} lines`:K(o.stdout,o.output,n.content);return{type:"agent_run.tool.completed",payload:{provider:"claude",toolName:gt(v),toolCallId:a,...p?{command:p}:{},...d?{path:d}:{},operation:v,...l?{output:l}:{}}}}function un(e,t=new Map){let r=L(e),n=L(r.message),o=Array.isArray(n.content)?n.content:[],s=[];for(let i of o.map(L))if(i.type==="tool_use"){let d=dn(i,t);d&&s.push(d)}let a=cn(r,t);return a&&s.push(a),s}function ln(e){if(e.type==="result"){let t=e.result;return typeof t=="string"?t:null}return null}function re(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function ct(...e){for(let t of e){let r=re(t);if(r!==void 0)return Math.max(0,Math.trunc(r))}}function pn(e){let t=L(e),r=L(t.usage),n=L(t.tokenUsage),o=L(t.token_usage),s=L(t.tokens),a=L(t.usageSummary);return{inputTokens:ct(r.input_tokens,r.inputTokens,r.prompt_tokens,r.promptTokens,n.input_tokens,n.inputTokens,n.prompt_tokens,n.promptTokens,o.input_tokens,o.inputTokens,o.prompt_tokens,o.promptTokens,s.input_tokens,s.inputTokens,s.prompt_tokens,s.promptTokens,a.input_tokens,a.inputTokens,t.input_tokens,t.inputTokens,t.total_input_tokens,t.prompt_tokens,t.promptTokens),outputTokens:ct(r.output_tokens,r.outputTokens,r.completion_tokens,r.completionTokens,n.output_tokens,n.outputTokens,n.completion_tokens,n.completionTokens,o.output_tokens,o.outputTokens,o.completion_tokens,o.completionTokens,s.output_tokens,s.outputTokens,s.completion_tokens,s.completionTokens,a.output_tokens,a.outputTokens,t.output_tokens,t.outputTokens,t.total_output_tokens,t.completion_tokens,t.completionTokens),costUsd:re(t.total_cost_usd)??re(t.cost_usd)??re(r.total_cost_usd)??re(r.cost_usd)}}function mn(e){return e.type!=="result"?{}:pn(e)}async function fn(e,t){let r=typeof e=="string"?e:e.agentRunId,n=typeof e=="string"?void 0:e.emitRawEvent,o="",s={},a=2,i=[],d=new Map;try{for await(let p of t){await n?.(p);for(let v of un(p,d))i.push({eventId:`${r}:claude:${a}`,eventSeq:a,type:v.type,payload:v.payload}),a+=1;o=ln(p)??o,s={...s,...mn(p)}}return{output:o.trim()||"Agent run completed",...s,events:i}}catch(p){let v=p instanceof Error?p:new Error(String(p));throw v.events=i,v.emittedEventIds=new Set,v}finally{t.close()}}async function ht(e){if(e.provider.kind!=="claude-code"&&e.provider.kind!=="claude-compatible")throw new Error(`unsupported node provider kind: ${e.provider.kind}`);let t=new AbortController,r=e.invokeTool?{truesayer:dt(e.agentRunId,e.invokeTool)}:void 0,n=(0,Oe.query)({prompt:e.prompt,options:{...gn(e.providerSessionId)?{sessionId:e.providerSessionId}:{},cwd:e.cwd,env:e.env,model:e.selectedModel,systemPrompt:nn(e.systemPrompt,!!e.invokeTool,e.availableProviders),mcpServers:r,maxTurns:e.maxTurns??80,permissionMode:"bypassPermissions",allowDangerouslySkipPermissions:!0,disallowedTools:[...Zr],abortController:t}});return fn(e,n)}function gn(e){return/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(e)}var Y=require("fs"),bt=require("child_process"),Rt=require("readline"),_t=require("module"),oe=require("path"),Fe=require("zod/v4");function vt(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}function yt(e){return typeof e=="string"?e.trim():""}function hn(e){let t=vt(e),r=yt(t.type);return r==="add"||r==="delete"?{type:r}:r==="update"?{type:r,move_path:typeof t.move_path=="string"?t.move_path:null}:null}function vn(e){let t=vt(e),r=yt(t.path),n=hn(t.kind);return!r||!n?null:{path:r,kind:n,diff:typeof t.diff=="string"?t.diff:""}}function Ue(e){return Array.isArray(e)?e.map(vn).filter(t=>t!==null).map(t=>{let r=yn(t.kind);return{path:r==="renamed"&&t.kind.type==="update"&&t.kind.move_path?t.kind.move_path:t.path,status:r,...t.diff?{diff:t.diff}:{}}}):[]}function yn(e){return e.type==="add"?"added":e.type==="delete"?"deleted":e.move_path?"renamed":"modified"}var He=6e4,Et=1,kn=(0,_t.createRequire)(__filename);function wn(){let e=kn.resolve("@openai/codex/package.json");return(0,oe.join)((0,oe.dirname)(e),"bin","codex.js")}function N(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}function S(e){return typeof e=="string"&&e.trim()?e.trim():""}function $e(e){return typeof e=="string"?e:""}function P(...e){for(let t of e){let r=S(t);if(r)return r}return""}function Le(...e){for(let t of e)if(typeof t=="number"&&Number.isFinite(t))return t}function bn(e){return typeof e=="string"?e.trim():Array.isArray(e)?e.filter(r=>typeof r=="string"&&r.trim().length>0).map(r=>r.trim()).join(" "):""}function Rn(...e){for(let t of e){let r=bn(t);if(r)return r}return""}function _n(e){return e.some(t=>["read","search","listFiles"].includes(P(t.type)))?"read":"exec"}function kt(e){return e==="read"?"read":e==="write"?"write":e==="update"?"update":e==="platform_tool"?"platform_tool":"exec"}function En(e){return Array.isArray(e)?e.map(N).filter(t=>P(t.type)):[]}function Tn(e){return Array.from(new Set(e.map(t=>P(t.path)).filter(Boolean)))}function Nn(e){return e.some(t=>t.status!=="added")?"update":"write"}function Sn(e){let t=P(e.tool);if(e.type!=="mcpToolCall")return t;let r=P(e.server);return r&&t?`${r}.${t}`:t}function In(e){let t=e.method,r=e.params??{},n=N(r.item),o=S(n.type),s=t==="item/completed"?"agent_run.tool.completed":"agent_run.tool.started";if(t!=="item/started"&&t!=="item/completed")return null;if(o==="commandExecution"){let a=Rn(n.command),i=En(n.commandActions),d=_n(i),p=Tn(i),v=P(n.status),l=P(n.aggregatedOutput),f=Le(n.exitCode),y=Le(n.durationMs);return{type:s,payload:{provider:"codex",toolName:kt(d),toolCallId:P(n.id),...a?{command:a}:{},...P(n.cwd)?{cwd:P(n.cwd)}:{},...p[0]?{path:p[0]}:{},...p.length>0?{paths:p}:{},operation:d,...v?{status:v}:{},...f===void 0?{}:{exitCode:f},...l?{output:l}:{},...y===void 0?{}:{durationMs:y},...i.length>0?{commandActions:i}:{}}}}if(o==="fileChange"){let a=Ue(n.changes);if(a.length===0)return null;let i=a.map(v=>v.path),d=Nn(a),p=P(n.status);return{type:s,payload:{provider:"codex",toolName:kt(d),toolCallId:P(n.id),command:"fileChange",path:i[0],paths:i,operation:d,...p?{status:p}:{},fileChanges:a,...a[0]?.diff?{diff:a[0].diff}:{}}}}if(o==="dynamicToolCall"||o==="mcpToolCall"){let a=Sn(n),i=Le(n.durationMs);return{type:s,payload:{provider:"codex",toolName:"platform_tool",toolCallId:P(n.id),platformToolName:a,...n.arguments===void 0?{}:{arguments:n.arguments},operation:"platform_tool",...P(n.status)?{status:P(n.status)}:{},...typeof n.success=="boolean"?{success:n.success}:{},...n.contentItems===void 0||n.contentItems===null?{}:{contentItems:n.contentItems},...n.result===void 0||n.result===null?{}:{result:n.result},...n.error===void 0||n.error===null?{}:{error:n.error},...i===void 0?{}:{durationMs:i}}}}return null}function Pn(e){if(e.method!=="item/fileChange/patchUpdated")return null;let t=e.params??{},r=Ue(t.changes);if(r.length===0)return null;let n=r.map(o=>o.path);return{type:"agent_run.provider_event",payload:{provider:"codex",method:e.method,...P(t.itemId)?{itemId:P(t.itemId)}:{},paths:n,changes:r,...P(t.threadId)?{threadId:P(t.threadId)}:{},...P(t.turnId)?{turnId:P(t.turnId)}:{}}}}function An(e){let t=e.params??{};if(e.method==="item/completed"){let r=N(t.item);if(r.type==="agentMessage"){let n=S(r.text);return n?{type:"agent_run.message.completed",payload:{provider:"codex",text:n,...S(r.phase)?{phase:S(r.phase)}:{}}}:null}}return e.method==="error"?{type:"agent_run.provider_event",payload:{provider:"codex",method:e.method,params:t}}:e.method==="turn/diff/updated"?{type:"agent_run.provider_event",payload:{provider:"codex",method:e.method,...P(t.threadId)?{threadId:P(t.threadId)}:{},...P(t.turnId)?{turnId:P(t.turnId)}:{},...$e(t.diff)?{diff:$e(t.diff)}:{}}}:null}function xn(e){return In(e)??Pn(e)??An(e)}function Tt(e){if(e.method!=="error")return null;let t=e.params??{};if(t.willRetry===!0)return null;let r=N(t.error),n=N(r.codexErrorInfo),o=S(t.codexErrorInfo)||S(r.codexErrorInfo)||Object.keys(n)[0]||S(t.code)||S(t.errorCode)||S(r.code),s=S(t.message)||S(r.message)||S(t.error)||"Codex app-server provider error";return new Error(`Codex app-server error${o?` ${o}`:""}: ${s}`)}function Cn(e){if(e.method!=="turn/completed")return null;let t=e.params??{},r=N(t.turn),n=S(r.status);if(n!=="failed"&&n!=="interrupted")return null;let o=N(r.error),s=P(o.message,r.error,r.lastError,t.error,n==="interrupted"?"Codex turn interrupted":"Codex turn failed");return new Error(s)}function Mn(e){let t=e.TRUESAYER_CODEX_REQUEST_TIMEOUT_MS?.trim();if(!t)return He;let r=Number(t);return Number.isFinite(r)&&r>0?Math.trunc(r):He}function Dn(e){if(e.exitCode!==null||e.killed)return;let t=e.pid;if(t&&process.platform!=="win32")try{process.kill(-t,"SIGTERM");return}catch{}e.kill("SIGTERM")}function Nt(e){let t=e.env.TRUESAYER_CODEX_BIN||wn(),r=(0,bt.spawn)(process.execPath,[t,"app-server","--listen","stdio://",...e.args??[]],{cwd:e.cwd,env:e.env,stdio:["pipe","pipe","pipe"],detached:e.detached===!0}),n=new Map,o=[],s=e.requestTimeoutMs??He,a=1,i=!1;function d(){return o.join("").slice(-1e3).trim()}function p(f,y){return new Error(`Codex app-server request timed out after ${s}ms (method ${y.method}, requestId ${f}, stderr: ${d()||"no stderr"})`)}function v(f,y){for(let[c,k]of n)n.delete(c),k.timeout&&clearTimeout(k.timeout),e.onRequestEvent?.("failed",{method:k.method,requestId:c,elapsedMs:Date.now()-k.startedAt,reason:y,error:f.message}),k.reject(f)}let l=(0,Rt.createInterface)({input:r.stdout});return l.on("line",f=>{let y=f.trim();if(!y)return;let c;try{c=JSON.parse(y)}catch{return}let k=N(c),b=k.id;if((typeof b=="number"||typeof b=="string")&&n.has(b)){let w=n.get(b);n.delete(b),w?.timeout&&clearTimeout(w.timeout);let m=k;m.error?(e.onRequestEvent?.("failed",{method:w?.method??"unknown",requestId:b,elapsedMs:w?Date.now()-w.startedAt:void 0,reason:"error",error:m.error.message??"Codex app-server request failed"}),w?.reject(new Error(m.error.message??"Codex app-server request failed"))):(e.onRequestEvent?.("completed",{method:w?.method??"unknown",requestId:b,elapsedMs:w?Date.now()-w.startedAt:void 0}),w?.resolve(m.result));return}let R=S(k.method);if(R){if((typeof b=="number"||typeof b=="string")&&e.onServerRequest){e.onServerRequest({id:b,method:R,params:N(k.params)}).then(A=>{r.stdin.write(`${JSON.stringify({id:b,result:A})}
25
+ `);return n?{type:"preset",preset:"claude_code",append:n}:void 0}function L(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}function nn(e){return typeof e=="string"&&e.trim()?e.trim():""}function on(e){return typeof e=="string"?e.trim():Array.isArray(e)?e.filter(r=>typeof r=="string"&&r.trim().length>0).map(r=>r.trim()).join(" "):""}function pt(...e){for(let t of e){let r=on(t);if(r)return r}return""}function J(...e){for(let t of e){let r=nn(t);if(r)return r}return""}function mt(e,t=""){let r=e.toLowerCase(),n=t.toLowerCase();return["read","grep","glob","ls"].includes(r)?"read":["write","edit","multiedit"].includes(r)?"write":r==="update"?"update":r==="bash"||r==="exec"||r==="exec_command"||r==="codex_command"?/(^|[;&|]\s*)apply_patch\b/.test(n)?"write":/^\s*(sed\s+-n\b|cat\b|head\b|tail\b|nl\b|find\b|ls\b|rg\b|grep\b|pwd\b)/.test(n)?"read":"exec":r.startsWith("mcp__truesayer__")?"platform_tool":"exec"}function ft(e){return e==="read"?"read":e==="write"?"write":e==="update"?"update":e==="platform_tool"?"platform_tool":"exec"}function sn(e){return L(e)}function an(e,t){let r=J(e.name);if(!r)return null;let n=sn(e.input),o=pt(n.command,n.cmd,n.commandLine),s=J(n.file_path,n.path,n.filePath),a=mt(r,o),i=J(e.id);return i&&t?.set(i,{rawToolName:r,command:o,path:s,operation:a}),{type:"agent_run.tool.started",payload:{provider:"claude",toolName:ft(a),toolCallId:i,...o?{command:o}:{},...s?{path:s}:{},operation:a}}}function dn(e,t){let n=(Array.isArray(L(e.message).content)?L(e.message).content:[]).map(L).find(f=>f.type==="tool_result");if(!n)return null;let o=L(e.toolUseResult),s=L(o.file),a=J(n.tool_use_id,n.toolUseId),i=t?.get(a)??{},c=J(s.filePath,s.file_path,o.filePath,o.file_path,i.path),m=pt(o.command,o.cmd,i.command),v=J(i.operation)||(c?"read":mt(m?"Bash":"tool",m)),l=c&&typeof s.numLines=="number"?`${s.numLines} lines`:J(o.stdout,o.output,n.content);return{type:"agent_run.tool.completed",payload:{provider:"claude",toolName:ft(v),toolCallId:a,...m?{command:m}:{},...c?{path:c}:{},operation:v,...l?{output:l}:{}}}}function cn(e,t=new Map){let r=L(e),n=L(r.message),o=Array.isArray(n.content)?n.content:[],s=[];for(let i of o.map(L))if(i.type==="tool_use"){let c=an(i,t);c&&s.push(c)}let a=dn(r,t);return a&&s.push(a),s}function un(e){if(e.type==="result"){let t=e.result;return typeof t=="string"?t:null}return null}function re(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function dt(...e){for(let t of e){let r=re(t);if(r!==void 0)return Math.max(0,Math.trunc(r))}}function ln(e){let t=L(e),r=L(t.usage),n=L(t.tokenUsage),o=L(t.token_usage),s=L(t.tokens),a=L(t.usageSummary);return{inputTokens:dt(r.input_tokens,r.inputTokens,r.prompt_tokens,r.promptTokens,n.input_tokens,n.inputTokens,n.prompt_tokens,n.promptTokens,o.input_tokens,o.inputTokens,o.prompt_tokens,o.promptTokens,s.input_tokens,s.inputTokens,s.prompt_tokens,s.promptTokens,a.input_tokens,a.inputTokens,t.input_tokens,t.inputTokens,t.total_input_tokens,t.prompt_tokens,t.promptTokens),outputTokens:dt(r.output_tokens,r.outputTokens,r.completion_tokens,r.completionTokens,n.output_tokens,n.outputTokens,n.completion_tokens,n.completionTokens,o.output_tokens,o.outputTokens,o.completion_tokens,o.completionTokens,s.output_tokens,s.outputTokens,s.completion_tokens,s.completionTokens,a.output_tokens,a.outputTokens,t.output_tokens,t.outputTokens,t.total_output_tokens,t.completion_tokens,t.completionTokens),costUsd:re(t.total_cost_usd)??re(t.cost_usd)??re(r.total_cost_usd)??re(r.cost_usd)}}function pn(e){return e.type!=="result"?{}:ln(e)}async function mn(e,t){let r=typeof e=="string"?e:e.agentRunId,n=typeof e=="string"?void 0:e.emitRawEvent,o="",s={},a=2,i=[],c=new Map;try{for await(let m of t){await n?.(m);for(let v of cn(m,c))i.push({eventId:`${r}:claude:${a}`,eventSeq:a,type:v.type,payload:v.payload}),a+=1;o=un(m)??o,s={...s,...pn(m)}}return{output:o.trim()||"Agent run completed",...s,events:i}}catch(m){let v=m instanceof Error?m:new Error(String(m));throw v.events=i,v.emittedEventIds=new Set,v}finally{t.close()}}async function gt(e){if(e.provider.kind!=="claude-code"&&e.provider.kind!=="claude-compatible")throw new Error(`unsupported node provider kind: ${e.provider.kind}`);let t=new AbortController,r=e.invokeTool?{truesayer:at(e.agentRunId,e.invokeTool)}:void 0,n=(0,Oe.query)({prompt:e.prompt,options:{...fn(e.providerSessionId)?{sessionId:e.providerSessionId}:{},cwd:e.cwd,env:e.env,model:e.selectedModel,systemPrompt:rn(e.systemPrompt,!!e.invokeTool,e.availableProviders),mcpServers:r,maxTurns:e.maxTurns??80,permissionMode:"bypassPermissions",allowDangerouslySkipPermissions:!0,disallowedTools:[...Xr],abortController:t}});return mn(e,n)}function fn(e){return/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(e)}var z=require("fs"),wt=require("child_process"),bt=require("readline"),Rt=require("module"),oe=require("path"),Fe=require("zod/v4");function ht(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}function vt(e){return typeof e=="string"?e.trim():""}function gn(e){let t=ht(e),r=vt(t.type);return r==="add"||r==="delete"?{type:r}:r==="update"?{type:r,move_path:typeof t.move_path=="string"?t.move_path:null}:null}function hn(e){let t=ht(e),r=vt(t.path),n=gn(t.kind);return!r||!n?null:{path:r,kind:n,diff:typeof t.diff=="string"?t.diff:""}}function Ue(e){return Array.isArray(e)?e.map(hn).filter(t=>t!==null).map(t=>{let r=vn(t.kind);return{path:r==="renamed"&&t.kind.type==="update"&&t.kind.move_path?t.kind.move_path:t.path,status:r,...t.diff?{diff:t.diff}:{}}}):[]}function vn(e){return e.type==="add"?"added":e.type==="delete"?"deleted":e.move_path?"renamed":"modified"}var He=6e4,_t=1,yn=(0,Rt.createRequire)(__filename);function kn(){let e=yn.resolve("@openai/codex/package.json");return(0,oe.join)((0,oe.dirname)(e),"bin","codex.js")}function N(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}function S(e){return typeof e=="string"&&e.trim()?e.trim():""}function $e(e){return typeof e=="string"?e:""}function P(...e){for(let t of e){let r=S(t);if(r)return r}return""}function Le(...e){for(let t of e)if(typeof t=="number"&&Number.isFinite(t))return t}function wn(e){return typeof e=="string"?e.trim():Array.isArray(e)?e.filter(r=>typeof r=="string"&&r.trim().length>0).map(r=>r.trim()).join(" "):""}function bn(...e){for(let t of e){let r=wn(t);if(r)return r}return""}function Rn(e){return e.some(t=>["read","search","listFiles"].includes(P(t.type)))?"read":"exec"}function yt(e){return e==="read"?"read":e==="write"?"write":e==="update"?"update":e==="platform_tool"?"platform_tool":"exec"}function _n(e){return Array.isArray(e)?e.map(N).filter(t=>P(t.type)):[]}function En(e){return Array.from(new Set(e.map(t=>P(t.path)).filter(Boolean)))}function Tn(e){return e.some(t=>t.status!=="added")?"update":"write"}function Nn(e){let t=P(e.tool);if(e.type!=="mcpToolCall")return t;let r=P(e.server);return r&&t?`${r}.${t}`:t}function Sn(e){let t=e.method,r=e.params??{},n=N(r.item),o=S(n.type),s=t==="item/completed"?"agent_run.tool.completed":"agent_run.tool.started";if(t!=="item/started"&&t!=="item/completed")return null;if(o==="commandExecution"){let a=bn(n.command),i=_n(n.commandActions),c=Rn(i),m=En(i),v=P(n.status),l=P(n.aggregatedOutput),f=Le(n.exitCode),y=Le(n.durationMs);return{type:s,payload:{provider:"codex",toolName:yt(c),toolCallId:P(n.id),...a?{command:a}:{},...P(n.cwd)?{cwd:P(n.cwd)}:{},...m[0]?{path:m[0]}:{},...m.length>0?{paths:m}:{},operation:c,...v?{status:v}:{},...f===void 0?{}:{exitCode:f},...l?{output:l}:{},...y===void 0?{}:{durationMs:y},...i.length>0?{commandActions:i}:{}}}}if(o==="fileChange"){let a=Ue(n.changes);if(a.length===0)return null;let i=a.map(v=>v.path),c=Tn(a),m=P(n.status);return{type:s,payload:{provider:"codex",toolName:yt(c),toolCallId:P(n.id),command:"fileChange",path:i[0],paths:i,operation:c,...m?{status:m}:{},fileChanges:a,...a[0]?.diff?{diff:a[0].diff}:{}}}}if(o==="dynamicToolCall"||o==="mcpToolCall"){let a=Nn(n),i=Le(n.durationMs);return{type:s,payload:{provider:"codex",toolName:"platform_tool",toolCallId:P(n.id),platformToolName:a,...n.arguments===void 0?{}:{arguments:n.arguments},operation:"platform_tool",...P(n.status)?{status:P(n.status)}:{},...typeof n.success=="boolean"?{success:n.success}:{},...n.contentItems===void 0||n.contentItems===null?{}:{contentItems:n.contentItems},...n.result===void 0||n.result===null?{}:{result:n.result},...n.error===void 0||n.error===null?{}:{error:n.error},...i===void 0?{}:{durationMs:i}}}}return null}function In(e){if(e.method!=="item/fileChange/patchUpdated")return null;let t=e.params??{},r=Ue(t.changes);if(r.length===0)return null;let n=r.map(o=>o.path);return{type:"agent_run.provider_event",payload:{provider:"codex",method:e.method,...P(t.itemId)?{itemId:P(t.itemId)}:{},paths:n,changes:r,...P(t.threadId)?{threadId:P(t.threadId)}:{},...P(t.turnId)?{turnId:P(t.turnId)}:{}}}}function Pn(e){let t=e.params??{};if(e.method==="item/completed"){let r=N(t.item);if(r.type==="agentMessage"){let n=S(r.text);return n?{type:"agent_run.message.completed",payload:{provider:"codex",text:n,...S(r.phase)?{phase:S(r.phase)}:{}}}:null}}return e.method==="error"?{type:"agent_run.provider_event",payload:{provider:"codex",method:e.method,params:t}}:e.method==="turn/diff/updated"?{type:"agent_run.provider_event",payload:{provider:"codex",method:e.method,...P(t.threadId)?{threadId:P(t.threadId)}:{},...P(t.turnId)?{turnId:P(t.turnId)}:{},...$e(t.diff)?{diff:$e(t.diff)}:{}}}:null}function An(e){return Sn(e)??In(e)??Pn(e)}function Et(e){if(e.method!=="error")return null;let t=e.params??{};if(t.willRetry===!0)return null;let r=N(t.error),n=N(r.codexErrorInfo),o=S(t.codexErrorInfo)||S(r.codexErrorInfo)||Object.keys(n)[0]||S(t.code)||S(t.errorCode)||S(r.code),s=S(t.message)||S(r.message)||S(t.error)||"Codex app-server provider error";return new Error(`Codex app-server error${o?` ${o}`:""}: ${s}`)}function xn(e){if(e.method!=="turn/completed")return null;let t=e.params??{},r=N(t.turn),n=S(r.status);if(n!=="failed"&&n!=="interrupted")return null;let o=N(r.error),s=P(o.message,r.error,r.lastError,t.error,n==="interrupted"?"Codex turn interrupted":"Codex turn failed");return new Error(s)}function Cn(e){let t=e.TRUESAYER_CODEX_REQUEST_TIMEOUT_MS?.trim();if(!t)return He;let r=Number(t);return Number.isFinite(r)&&r>0?Math.trunc(r):He}function Mn(e){if(e.exitCode!==null||e.killed)return;let t=e.pid;if(t&&process.platform!=="win32")try{process.kill(-t,"SIGTERM");return}catch{}e.kill("SIGTERM")}function Tt(e){let t=e.env.TRUESAYER_CODEX_BIN||kn(),r=(0,wt.spawn)(process.execPath,[t,"app-server","--listen","stdio://",...e.args??[]],{cwd:e.cwd,env:e.env,stdio:["pipe","pipe","pipe"],detached:e.detached===!0}),n=new Map,o=[],s=e.requestTimeoutMs??He,a=1,i=!1;function c(){return o.join("").slice(-1e3).trim()}function m(f,y){return new Error(`Codex app-server request timed out after ${s}ms (method ${y.method}, requestId ${f}, stderr: ${c()||"no stderr"})`)}function v(f,y){for(let[d,k]of n)n.delete(d),k.timeout&&clearTimeout(k.timeout),e.onRequestEvent?.("failed",{method:k.method,requestId:d,elapsedMs:Date.now()-k.startedAt,reason:y,error:f.message}),k.reject(f)}let l=(0,bt.createInterface)({input:r.stdout});return l.on("line",f=>{let y=f.trim();if(!y)return;let d;try{d=JSON.parse(y)}catch{return}let k=N(d),b=k.id;if((typeof b=="number"||typeof b=="string")&&n.has(b)){let w=n.get(b);n.delete(b),w?.timeout&&clearTimeout(w.timeout);let p=k;p.error?(e.onRequestEvent?.("failed",{method:w?.method??"unknown",requestId:b,elapsedMs:w?Date.now()-w.startedAt:void 0,reason:"error",error:p.error.message??"Codex app-server request failed"}),w?.reject(new Error(p.error.message??"Codex app-server request failed"))):(e.onRequestEvent?.("completed",{method:w?.method??"unknown",requestId:b,elapsedMs:w?Date.now()-w.startedAt:void 0}),w?.resolve(p.result));return}let R=S(k.method);if(R){if((typeof b=="number"||typeof b=="string")&&e.onServerRequest){e.onServerRequest({id:b,method:R,params:N(k.params)}).then(A=>{r.stdin.write(`${JSON.stringify({id:b,result:A})}
26
26
  `)}).catch(A=>{r.stdin.write(`${JSON.stringify({id:b,error:{code:-32603,message:A instanceof Error?A.message:String(A)}})}
27
- `)});return}let m={method:R,params:N(k.params)};e.onNotification?.(m);let g=Tt(m);g&&v(g,"provider_error")}}),r.stderr.on("data",f=>{o.push(f.toString("utf8")),o.length>25&&o.shift()}),r.on("exit",(f,y)=>{if(i)return;let c=`Codex app-server exited (code ${f??"null"}, signal ${y??"null"}): ${d()||"no stderr"}`,k=new Error(c);v(k,"app_server_exit"),e.onExit?.(k)}),{stderrTail:d,request(f,y){let c=a;a+=1,e.onRequestEvent?.("started",{method:f,requestId:c});let k=new Promise((b,R)=>{let w={method:f,startedAt:Date.now(),resolve:b,reject:R},m=setTimeout(()=>{if(!n.delete(c))return;let g=p(c,w);e.onRequestEvent?.("failed",{method:f,requestId:c,elapsedMs:Date.now()-w.startedAt,reason:"timeout"}),R(g)},s);typeof m.unref=="function"&&m.unref(),w.timeout=m,n.set(c,w)});return r.stdin.write(`${JSON.stringify({id:c,method:f,params:y})}
27
+ `)});return}let p={method:R,params:N(k.params)};e.onNotification?.(p);let g=Et(p);g&&v(g,"provider_error")}}),r.stderr.on("data",f=>{o.push(f.toString("utf8")),o.length>25&&o.shift()}),r.on("exit",(f,y)=>{if(i)return;let d=`Codex app-server exited (code ${f??"null"}, signal ${y??"null"}): ${c()||"no stderr"}`,k=new Error(d);v(k,"app_server_exit"),e.onExit?.(k)}),{stderrTail:c,request(f,y){let d=a;a+=1,e.onRequestEvent?.("started",{method:f,requestId:d});let k=new Promise((b,R)=>{let w={method:f,startedAt:Date.now(),resolve:b,reject:R},p=setTimeout(()=>{if(!n.delete(d))return;let g=m(d,w);e.onRequestEvent?.("failed",{method:f,requestId:d,elapsedMs:Date.now()-w.startedAt,reason:"timeout"}),R(g)},s);typeof p.unref=="function"&&p.unref(),w.timeout=p,n.set(d,w)});return r.stdin.write(`${JSON.stringify({id:d,method:f,params:y})}
28
28
  `),k},notify(f,y){r.stdin.write(`${JSON.stringify({method:f,...y===void 0?{}:{params:y}})}
29
- `)},close(){i=!0,l.close(),Dn(r)}}}function On(e){let t=N(e).data;if(!Array.isArray(t))return[];let r=t.flatMap(n=>{let o=N(n),s=S(o.model)||S(o.id);return s?[s]:[]});return Array.from(new Set(r.map(n=>n.trim()).filter(Boolean)))}async function St(e={}){let t=Nt({env:e.env??te(),detached:process.platform!=="win32",requestTimeoutMs:e.timeoutMs??3e4});try{return await t.request("initialize",{clientInfo:{name:"truesayer",title:"Truesayer",version:"0.1.0"},capabilities:{experimentalApi:!0,optOutNotificationMethods:[]}}),t.notify("initialized"),On(await t.request("model/list",{includeHidden:!1,limit:100}))}finally{t.close()}}function It(e){return e?(0,oe.join)(e,"codex-app-server-session.json"):void 0}function Un(e){let t=It(e);if(!t||!(0,Y.existsSync)(t))return{};try{let r=JSON.parse((0,Y.readFileSync)(t,"utf8")),n=N(r),o=S(n.threadId),s=n.platformToolsVersion;return{threadId:o||void 0,platformToolsVersion:typeof s=="number"&&Number.isFinite(s)?s:void 0}}catch{return{}}}function Ln(e,t,r){let n=It(e);n&&(0,Y.writeFileSync)(n,`${JSON.stringify({threadId:t,...r?{platformToolsVersion:Et}:{}})}
30
- `,{mode:384})}var Fn=["Long-running or continuously-running service/watch commands, such as dev servers, file watchers, npm start, npm run start, npm run dev, vite, next dev, nodemon, tsx --watch, tail -f, database servers, or queue workers, must not be run as foreground blocking commands. Start them in the background, redirect logs to a file, record the PID, and run a bounded health check with timeout. Stop or clean up the process when validation is complete unless the task explicitly asks to keep the service available for human inspection; in that case keep it running in the background and report PID, port, URL, and log path. Finite commands such as install, build, test, lint, migration, and one-shot scripts should run in the foreground and must return an exit code.","Do not try to access the Truesayer Server database, provider secrets, or Server-only environment variables from Node.","All file creation and manual file edits MUST use apply_patch or Codex native fileChange. This overrides any base instruction that allows shell redirection, here-docs, cat, tee, scripts, or generated-file exceptions. Do not create or edit files with cat, tee, heredoc, sed -i, perl -pi, python/node scripts, or shell redirection, even for generated files like package.json or temporary scratch files under /tmp."].join(`
31
- `);function Hn(e){return["Truesayer runtime instructions:",[e.systemPrompt?.trim(),e.invokeTool?he:"",e.invokeTool?ve(e.availableProviders):"",Fn].filter(Boolean).join(`
29
+ `)},close(){i=!0,l.close(),Mn(r)}}}function Dn(e){let t=N(e).data;if(!Array.isArray(t))return[];let r=t.flatMap(n=>{let o=N(n),s=S(o.model)||S(o.id);return s?[s]:[]});return Array.from(new Set(r.map(n=>n.trim()).filter(Boolean)))}async function Nt(e={}){let t=Tt({env:e.env??te(),detached:process.platform!=="win32",requestTimeoutMs:e.timeoutMs??3e4});try{return await t.request("initialize",{clientInfo:{name:"truesayer",title:"Truesayer",version:"0.1.0"},capabilities:{experimentalApi:!0,optOutNotificationMethods:[]}}),t.notify("initialized"),Dn(await t.request("model/list",{includeHidden:!1,limit:100}))}finally{t.close()}}function St(e){return e?(0,oe.join)(e,"codex-app-server-session.json"):void 0}function On(e){let t=St(e);if(!t||!(0,z.existsSync)(t))return{};try{let r=JSON.parse((0,z.readFileSync)(t,"utf8")),n=N(r),o=S(n.threadId),s=n.platformToolsVersion;return{threadId:o||void 0,platformToolsVersion:typeof s=="number"&&Number.isFinite(s)?s:void 0}}catch{return{}}}function Un(e,t,r){let n=St(e);n&&(0,z.writeFileSync)(n,`${JSON.stringify({threadId:t,...r?{platformToolsVersion:_t}:{}})}
30
+ `,{mode:384})}var Ln=["Long-running or continuously-running service/watch commands, such as dev servers, file watchers, npm start, npm run start, npm run dev, vite, next dev, nodemon, tsx --watch, tail -f, database servers, or queue workers, must not be run as foreground blocking commands. Start them in the background, redirect logs to a file, record the PID, and run a bounded health check with timeout. Stop or clean up the process when validation is complete unless the task explicitly asks to keep the service available for human inspection; in that case keep it running in the background and report PID, port, URL, and log path. Finite commands such as install, build, test, lint, migration, and one-shot scripts should run in the foreground and must return an exit code.","Do not try to access the Truesayer Server database, provider secrets, or Server-only environment variables from Node.","All file creation and manual file edits MUST use apply_patch or Codex native fileChange. This overrides any base instruction that allows shell redirection, here-docs, cat, tee, scripts, or generated-file exceptions. Do not create or edit files with cat, tee, heredoc, sed -i, perl -pi, python/node scripts, or shell redirection, even for generated files like package.json or temporary scratch files under /tmp."].join(`
31
+ `);function Fn(e){return["Truesayer runtime instructions:",[e.systemPrompt?.trim(),e.invokeTool?ge:"",e.invokeTool?he(e.availableProviders):"",Ln].filter(Boolean).join(`
32
32
 
33
33
  `)].join(`
34
- `)}function $n(e){return e.prompt}function we(e){return JSON.stringify(e)}function qn(e){return/^[A-Za-z0-9_-]+$/.test(e)?e:we(e)}function jn(e){if(e.provider.source!=="provider-file"||e.provider.kind!=="codex"&&e.provider.kind!=="openai-compatible")return[];let t=e.provider.baseUrl?.trim()||e.env.OPENAI_BASE_URL?.trim();if(!t)return[];let r=e.providerName.trim();if(!r)return[];let n=[`name=${we(e.provider.displayName||r)}`,`base_url=${we(t)}`,'wire_api="responses"','env_key="OPENAI_API_KEY"',"requires_openai_auth=false","supports_websockets=false"].join(",");return["-c",`model_provider=${we(r)}`,"-c",`model_providers.${qn(r)}={${n}}`]}function Wn(e){return e===void 0?null:e}function Gn(e){return e&&typeof e=="object"&&!Array.isArray(e)?Fe.z.toJSONSchema(Fe.z.object(e)):{type:"object",properties:{},additionalProperties:!0}}function Bn(e){if(!e.invokeTool)return null;let t=De(e.agentRunId,e.invokeTool),r=new Map;return{dynamicTools:t.map(o=>{let s=o.handler;return r.set(o.name,async a=>s(a)),{namespace:"truesayer",name:o.name,description:o.description,inputSchema:Wn(Gn(o.inputSchema)),deferLoading:!1}}),handlers:r}}function Jn(e){let t=N(e).content;if(Array.isArray(t)){let r=t.map(N).map(n=>$e(n.text)).filter(Boolean).join(`
35
- `);if(r)return r}return JSON.stringify(e??{})}async function Kn(e,t){if(e.method!=="item/tool/call")throw new Error(`Unsupported Codex app-server request: ${e.method}`);if(!t)return{contentItems:[{type:"inputText",text:"Truesayer platform tools are not available for this run."}],success:!1};let r=S(e.params?.tool),n=t.handlers.get(r);if(!n)return{contentItems:[{type:"inputText",text:`Unknown Truesayer platform tool: ${r||"(missing)"}`}],success:!1};try{let o=N(e.params?.arguments),s=await n(o);return{contentItems:[{type:"inputText",text:Jn(s)}],success:!0}}catch(o){return{contentItems:[{type:"inputText",text:o instanceof Error?o.message:String(o)}],success:!1}}}function zn(e){let t=N(e),r=N(t.last),n=N(t.total);return{inputTokens:be(r.input_tokens,r.inputTokens,r.prompt_tokens,r.promptTokens,n.input_tokens,n.inputTokens,n.prompt_tokens,n.promptTokens,t.input_tokens,t.inputTokens,t.prompt_tokens,t.promptTokens),outputTokens:be(r.output_tokens,r.outputTokens,r.completion_tokens,r.completionTokens,n.output_tokens,n.outputTokens,n.completion_tokens,n.completionTokens,t.output_tokens,t.outputTokens,t.completion_tokens,t.completionTokens)}}function ne(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function be(...e){for(let t of e){let r=ne(t);if(r!==void 0)return Math.max(0,Math.trunc(r))}}function Vn(e){let t=N(e),r=N(t.usage),n=N(t.tokenUsage),o=N(t.token_usage),s=N(t.tokens),a=N(t.usageSummary);return{inputTokens:be(r.input_tokens,r.inputTokens,r.prompt_tokens,r.promptTokens,n.input_tokens,n.inputTokens,n.prompt_tokens,n.promptTokens,o.input_tokens,o.inputTokens,o.prompt_tokens,o.promptTokens,s.input_tokens,s.inputTokens,s.prompt_tokens,s.promptTokens,a.input_tokens,a.inputTokens,t.input_tokens,t.inputTokens,t.total_input_tokens,t.prompt_tokens,t.promptTokens),outputTokens:be(r.output_tokens,r.outputTokens,r.completion_tokens,r.completionTokens,n.output_tokens,n.outputTokens,n.completion_tokens,n.completionTokens,o.output_tokens,o.outputTokens,o.completion_tokens,o.completionTokens,s.output_tokens,s.outputTokens,s.completion_tokens,s.completionTokens,a.output_tokens,a.outputTokens,t.output_tokens,t.outputTokens,t.total_output_tokens,t.completion_tokens,t.completionTokens),costUsd:ne(t.total_cost_usd)??ne(t.cost_usd)??ne(r.total_cost_usd)??ne(r.cost_usd)}}function wt(...e){let t={};for(let r of e)r&&(r.inputTokens!==void 0&&(t.inputTokens=r.inputTokens),r.outputTokens!==void 0&&(t.outputTokens=r.outputTokens),"costUsd"in r&&r.costUsd!==void 0&&(t.costUsd=r.costUsd));return t}function Yn(e,t){let r=[],n=new Set,o=new Map,s=new Map,a=new Map,i=new Map,d=2,p="",v=null,l=null;function f(m){r.push(m),!n.has(m.eventId)&&(n.add(m.eventId),e.emitEvent?.(m))}function y(m,g){f({eventId:`${e.agentRunId}:codex:${d}`,eventSeq:d,type:`agent_run.provider_request.${m}`,payload:{provider:"codex",...g}}),d+=1}function c(m){let g=xn(m);g&&(f({eventId:`${e.agentRunId}:codex:${d}`,eventSeq:d,type:g.type,payload:g.payload}),d+=1)}function k(m,g={}){let T={output:p.trim()||"Codex run completed",...g.inputTokens===void 0?{}:{inputTokens:g.inputTokens},...g.outputTokens===void 0?{}:{outputTokens:g.outputTokens}};a.set(m,T);let _=i.get(m)??[];i.delete(m);for(let E of _)E.resolve(T)}function b(m){for(let g of i.values())for(let A of g)A.reject(m);i.clear()}function R(m){e.emitRawEvent?.(m);let g=m.params??{},A=Tt(m),T=Cn(m);if(m.method==="item/agentMessage/delta"){let E=S(g.itemId),U=S(g.delta);if(E&&U){let j=`${o.get(E)??""}${U}`;o.set(E,j),p=j}}if(m.method==="item/completed"){let E=N(g.item);if(E.type==="agentMessage"){let U=S(E.text);U&&(p=U)}}if(m.method==="turn/completed"){let E=N(g.turn),U=S(E.id),j=S(E.status);U&&j==="completed"&&k(U,wt(s.get(U),Vn(E)))}if(m.method==="thread/tokenUsage/updated"){let E=S(g.turnId);E&&s.set(E,wt(s.get(E),zn(g.tokenUsage)))}c(m);let _=A??T;_&&(v=_,b(_))}let w=Nt({cwd:e.cwd,env:e.env,args:jn(e),requestTimeoutMs:Mn(e.env),onNotification:R,onServerRequest:m=>Kn(m,t),onRequestEvent:y,onExit(m){l=m,b(m)}});return{events:r,emittedEventIds:n,stderrTail:w.stderrTail,request:w.request,notify:w.notify,close:w.close,waitForTurnCompleted(m){let g=a.get(m);return g!==void 0?Promise.resolve(g):v?Promise.reject(v):l?Promise.reject(l):(y("started",{method:"turn/completed",turnId:m}),new Promise((A,T)=>{let _={resolve:A,reject:T},E=i.get(m)??[];E.push(_),i.set(m,E)}))}}}function Xn(e){let t=S(N(N(e).thread).id);if(!t)throw new Error("Codex app-server did not return a thread id");return t}function Zn(e){let t=S(N(N(e).turn).id);if(!t)throw new Error("Codex app-server did not return a turn id");return t}async function Pt(e){if(e.provider.kind!=="codex"&&e.provider.kind!=="openai-compatible")throw new Error(`unsupported node provider kind: ${e.provider.kind}`);let t=Bn(e),r=Yn(e,t),n=e.provider.source==="provider-file"?e.providerName:void 0,o={...e.reasoningEffort&&e.reasoningEffort!=="default"?{reasoningEffort:e.reasoningEffort}:{},...e.serviceTier&&e.serviceTier!=="default"?{serviceTier:e.serviceTier}:{}},s=Hn(e),a=()=>{};try{if(e.abortSignal?.aborted)throw new Error("Interrupted by user");await r.request("initialize",{clientInfo:{name:"truesayer-node",title:"Truesayer Node",version:"0.1.0"},capabilities:{experimentalApi:!0,optOutNotificationMethods:[]}}),r.notify("initialized");let i=Un(e.sessionStateDir),d=i.threadId;if(t&&i.platformToolsVersion!==Et&&(d=void 0),d)await r.request("thread/resume",{threadId:d,model:e.selectedModel,...n?{modelProvider:n}:{},cwd:e.cwd,approvalPolicy:"never",sandbox:"danger-full-access",experimentalRawEvents:!1,excludeTurns:!0,persistExtendedHistory:!0,developerInstructions:s,...t?{dynamicTools:t.dynamicTools}:{},...o});else{let y=await r.request("thread/start",{model:e.selectedModel,...n?{modelProvider:n}:{},cwd:e.cwd,approvalPolicy:"never",sandbox:"danger-full-access",experimentalRawEvents:!1,persistExtendedHistory:!0,developerInstructions:s,...t?{dynamicTools:t.dynamicTools}:{},...o});d=Xn(y),Ln(e.sessionStateDir,d,t)}let p=await r.request("turn/start",{threadId:d,input:[{type:"text",text:$n(e),text_elements:[]}],cwd:e.cwd,approvalPolicy:"never",model:e.selectedModel,...o}),v=Zn(p),l=e.abortSignal?new Promise((y,c)=>{let k=()=>{r.request("turn/interrupt",{threadId:d,turnId:v}).catch(()=>{}),c(new Error("Interrupted by user"))};e.abortSignal?.addEventListener("abort",k,{once:!0}),a=()=>e.abortSignal?.removeEventListener("abort",k)}):null,f=await(l?Promise.race([r.waitForTurnCompleted(v),l]):r.waitForTurnCompleted(v));return{output:f.output.trim()||"Codex run completed",...f.inputTokens===void 0?{}:{inputTokens:f.inputTokens},...f.outputTokens===void 0?{}:{outputTokens:f.outputTokens},events:r.events,emittedEventIds:r.emittedEventIds}}catch(i){throw i instanceof Error&&(i.events=r.events,i.emittedEventIds=r.emittedEventIds),i}finally{a(),r.close()}}function Re(e){return Array.from(new Set(e.map(t=>t.trim()).filter(Boolean)))}function qe(e){return typeof e=="object"&&e!==null?e:void 0}function At(e){return typeof e=="string"&&e.trim()?e.trim():void 0}function Qn(e){return e.replace(/\/+$/,"")}function xt(e,t){let r=Qn(e);return t==="v1/models"&&/\/v1$/i.test(r)?`${r}/models`:`${r}/${t}`}function eo(e){if(!e.baseUrl?.trim()||!e.apiKey?.trim())return[];let t=e.kind.toLowerCase(),r=e.baseUrl.trim(),n=[];return(t.includes("claude")||t.includes("anthropic"))&&n.push({url:xt(r,"v1/models"),auth:"anthropic"}),(t.includes("openai")||t==="codex")&&n.push({url:xt(r,"models"),auth:"bearer"}),n.filter((o,s,a)=>a.findIndex(i=>i.url===o.url)===s)}function to(e){let t=qe(e);return At(t?.id)??At(t?.model)}function ro(e){let t=qe(e)?.data;if(!Array.isArray(t))return[];let r=t.flatMap(s=>{let a=to(s);if(!a)return[];let i=qe(s),d=typeof i?.created=="number"?i.created:typeof i?.created_at=="number"?i.created_at:void 0;return[{id:a,created:d}]}),o=r.some(s=>s.created!==void 0)?[...r].sort((s,a)=>(a.created??Number.NEGATIVE_INFINITY)-(s.created??Number.NEGATIVE_INFINITY)):r;return Re(o.map(s=>s.id))}async function no(e,t){let r={accept:"application/json"};e.auth==="anthropic"?(r["x-api-key"]=t,r["anthropic-version"]="2023-06-01"):r.authorization=`Bearer ${t}`;let n=await fetch(e.url,{method:"GET",headers:r});if(!n.ok)throw new Error(`HTTP ${n.status}`);let o=ro(await n.json().catch(()=>null));if(o.length===0)throw new Error("response did not contain model ids");return o}async function je(e,t){let r=t.apiKey?.trim();if(!r)throw new Error(`provider ${e} cannot discover models without an API key`);let n=eo(t);if(n.length===0)throw new Error(`provider ${e} cannot discover models without a supported baseUrl`);let o=[];for(let s of n)try{return await no(s,r)}catch(a){o.push(`${s.url}: ${a instanceof Error?a.message:String(a)}`)}throw new Error(`provider ${e} model discovery failed: ${o.join("; ")}`)}async function Ct(e,t){if(t.source==="provider-file"&&t.models?.length)return Re(t.models);if(t.source==="provider-file")try{return await je(e,t)}catch(r){return console.warn(`[node] provider ${e} model discovery unavailable:`,r instanceof Error?r.message:String(r)),[]}if(t.source!=="native")return[];try{if(e==="local-claude-code"&&t.kind==="claude-code")return await pt();if(e==="local-codex"&&t.kind==="codex")return await St()}catch(r){console.warn(`[node] provider ${e} unavailable:`,r instanceof Error?r.message:String(r))}return[]}var qt=X(require("ws")),oo=15e3;function so(e){let t=e.emittedEventIds??new Set;return(e.events??[]).filter(r=>!t.has(r.eventId))}var Mt={"local-claude-code":{kind:"claude-code",displayName:"Local Claude Code",source:"native"},"local-codex":{kind:"codex",displayName:"Local Codex",source:"native"}};function io(e){return e.split(/[-_\s]+/).filter(Boolean).map(t=>`${t[0]?.toUpperCase()??""}${t.slice(1)}`).join(" ")}function ao(e){if(!e?.trim()||!(0,x.existsSync)(e))return{};co(e);let t;try{t=JSON.parse((0,x.readFileSync)(e,"utf8"))}catch{throw new Error(`provider file is not valid JSON: ${e}`)}let r=t&&typeof t=="object"&&!Array.isArray(t)&&t.providers&&typeof t.providers=="object"&&!Array.isArray(t.providers)?t.providers:{},n={};for(let[o,s]of Object.entries(r)){let a=o.trim();if(!a||!s||typeof s!="object"||Array.isArray(s))continue;let i=s,d=typeof i.kind=="string"&&i.kind.trim()?i.kind.trim():"openai-compatible",p=typeof i.displayName=="string"&&i.displayName.trim()?i.displayName.trim():io(a),v=Array.isArray(i.models)?Array.from(new Set(i.models.filter(b=>typeof b=="string"&&b.trim().length>0).map(b=>b.trim()))):void 0,l=typeof i.apiKey=="string"&&i.apiKey.trim()?i.apiKey.trim():void 0,f=typeof i.baseUrl=="string"&&i.baseUrl.trim()?i.baseUrl.trim():void 0,y=typeof i.ANTHROPIC_DEFAULT_HAIKU_MODEL=="string"&&i.ANTHROPIC_DEFAULT_HAIKU_MODEL.trim()?i.ANTHROPIC_DEFAULT_HAIKU_MODEL.trim():void 0,c=typeof i.ANTHROPIC_DEFAULT_SONNET_MODEL=="string"&&i.ANTHROPIC_DEFAULT_SONNET_MODEL.trim()?i.ANTHROPIC_DEFAULT_SONNET_MODEL.trim():void 0,k=typeof i.ANTHROPIC_DEFAULT_OPUS_MODEL=="string"&&i.ANTHROPIC_DEFAULT_OPUS_MODEL.trim()?i.ANTHROPIC_DEFAULT_OPUS_MODEL.trim():void 0;n[a]={kind:d,displayName:p,source:"provider-file",...Dt(d,v)?.length?{models:Dt(d,v)}:{},...l?{apiKey:l}:{},...f?{baseUrl:f}:{},...y?{anthropicDefaultHaikuModel:y}:{},...c?{anthropicDefaultSonnetModel:c}:{},...k?{anthropicDefaultOpusModel:k}:{}}}return n}function co(e){if(process.platform!=="win32")try{((0,x.statSync)(e).mode&63)!==0&&console.warn(`[node] provider file permissions are too broad; run chmod 600 ${e}`)}catch{return}}function jt(e){process.platform!=="win32"&&(0,x.chmodSync)(e,384)}function uo(e){return(0,x.mkdirSync)((0,M.dirname)(e),{recursive:!0,mode:448}),(0,x.existsSync)(e)||(0,x.writeFileSync)(e,`${JSON.stringify({providers:{}},null,2)}
36
- `,{mode:384}),jt(e),Ge(e),e}function Dt(e,t){if(!t?.length)return;if(!e.toLowerCase().includes("claude"))return t;let r=t.filter(n=>!["haiku","sonnet","opus"].includes(n.trim().toLowerCase()));return r.length>0?r:void 0}function se(e){if(!e)return;let t=e.trim();if(t)return t.length>8?`${t.slice(0,4)}***${t.slice(-4)}`:`${t.slice(0,4)}***`}function Ee(e){let t=ao(e);for(let r of Object.keys(t))if(Mt[r])throw new Error(`duplicate provider name: ${r}`);return{...Mt,...t}}async function lo(e={}){let t=Ee(e.providerFile),r={},n=e.probeProviderModels??Ct,o=await Promise.all(Object.entries(t).map(async([s,a])=>[s,await n(s,a,{})]));for(let[s,a]of o){let i=t[s];i&&a.length!==0&&(r[s]={kind:i.kind,displayName:i.displayName,source:i.source,models:a,modelsDiscoveredBy:i.source==="provider-file"?i.models?.length?"provider-file":"api-probe":"sdk-probe",...i.source==="provider-file"&&i.baseUrl?{baseUrl:i.baseUrl}:{},...i.source==="provider-file"&&se(i.apiKey)?{apiKeyPreview:se(i.apiKey)}:{},...i.source==="provider-file"?{configEditable:!0}:{},...i.source==="provider-file"&&i.anthropicDefaultHaikuModel?{anthropicDefaultHaikuModel:i.anthropicDefaultHaikuModel}:{},...i.source==="provider-file"&&i.anthropicDefaultSonnetModel?{anthropicDefaultSonnetModel:i.anthropicDefaultSonnetModel}:{},...i.source==="provider-file"&&i.anthropicDefaultOpusModel?{anthropicDefaultOpusModel:i.anthropicDefaultOpusModel}:{}})}return r}function po(e){return Object.fromEntries(Object.entries(e).map(([t,r])=>[t,{kind:r.kind,displayName:r.displayName,source:r.source,models:r.models,modelsDiscoveredBy:r.modelsDiscoveredBy}]))}function mo(e,t){return{type:"node.hello",payload:{nodeName:e.nodeName,nodeVersion:e.nodeVersion,platform:{os:process.platform,arch:process.arch,hostname:ae.default.hostname()},capabilities:{providers:po(t),supportsWorktrees:!0,browserE2E:(e.probeBrowserE2E??go)()}}}}var fo={"libnss3.so":["/usr/lib/x86_64-linux-gnu/libnss3.so","/usr/lib/aarch64-linux-gnu/libnss3.so","/usr/lib64/libnss3.so"],"libatk-bridge-2.0.so.0":["/usr/lib/x86_64-linux-gnu/libatk-bridge-2.0.so.0","/usr/lib/aarch64-linux-gnu/libatk-bridge-2.0.so.0","/usr/lib64/libatk-bridge-2.0.so.0"],"libcups.so.2":["/usr/lib/x86_64-linux-gnu/libcups.so.2","/usr/lib/aarch64-linux-gnu/libcups.so.2","/usr/lib64/libcups.so.2"],"libxkbcommon.so.0":["/usr/lib/x86_64-linux-gnu/libxkbcommon.so.0","/usr/lib/aarch64-linux-gnu/libxkbcommon.so.0","/usr/lib64/libxkbcommon.so.0"],"libgbm.so.1":["/usr/lib/x86_64-linux-gnu/libgbm.so.1","/usr/lib/aarch64-linux-gnu/libgbm.so.1","/usr/lib64/libgbm.so.1"],"libasound.so.2":["/usr/lib/x86_64-linux-gnu/libasound.so.2","/usr/lib/aarch64-linux-gnu/libasound.so.2","/usr/lib64/libasound.so.2"]};function go(){let e=process.env.TRUESAYER_NODE_BROWSER_E2E?.trim().toLowerCase();if(e==="available"||e==="unavailable"||e==="unknown")return{status:e,diagnostics:["set by TRUESAYER_NODE_BROWSER_E2E"]};if(process.platform!=="linux")return{status:"unknown",diagnostics:["automatic browser dependency detection only supports linux"]};let t=Object.entries(fo).filter(([,r])=>!r.some(n=>(0,x.existsSync)(n))).map(([r])=>r);return t.length>0?{status:"unavailable",diagnostics:t.map(r=>`missing ${r}`)}:{status:"unknown",diagnostics:["linux chromium libraries found; browser binary availability not verified"]}}function $(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}function h(e){return typeof e=="string"&&e.trim()?e.trim():""}function ho(e){return te(e)}function vo(e,t){let r=e;if(!r?.trim())return{};let n=Ee(r)[t];if(!n||n.source!=="provider-file")return{};let o={};return n.kind==="codex"||n.kind==="openai-compatible"?(n.apiKey&&(o.OPENAI_API_KEY=n.apiKey),n.baseUrl&&(o.OPENAI_BASE_URL=n.baseUrl),o):(n.apiKey&&(o.ANTHROPIC_API_KEY=n.apiKey),n.baseUrl&&(o.ANTHROPIC_BASE_URL=n.baseUrl),n.anthropicDefaultOpusModel&&(o.ANTHROPIC_DEFAULT_OPUS_MODEL=n.anthropicDefaultOpusModel,o.ANTHROPIC_DEFAULT_SONNET_MODEL=n.anthropicDefaultSonnetModel||n.anthropicDefaultOpusModel,o.ANTHROPIC_DEFAULT_HAIKU_MODEL=n.anthropicDefaultHaikuModel||n.anthropicDefaultOpusModel),o)}function yo(e){let t=$(e),r=t.id;return t.jsonrpc==="2.0"&&(typeof r=="string"||typeof r=="number"||r===null)&&("result"in t||"error"in t)}function ko(e){let t=$(e),r=t.id;return t.jsonrpc==="2.0"&&(typeof r=="string"||typeof r=="number"||r===null)&&typeof t.method=="string"&&t.method.trim().length>0}function wo(e,t){return JSON.stringify({jsonrpc:"2.0",id:e,result:t})}function bo(e,t){return JSON.stringify({jsonrpc:"2.0",id:e,error:{code:-32e3,message:t}})}function Ro(e){let t=0,r=new Map;return{invokeTool(n){if(e.readyState!==1)throw new Error("node websocket is not open");let o=`tool:${++t}`,s={jsonrpc:"2.0",id:o,method:"tool.invoke",params:{...n,toolCallId:n.toolCallId??o}},a=new Promise((i,d)=>{r.set(o,{resolve:i,reject:d})});try{e.send(JSON.stringify(s))}catch(i){throw r.delete(o),i}return a},handleJsonRpcMessage(n){if(!yo(n)||n.id===null)return!1;let o=r.get(n.id);if(!o)return!1;if(r.delete(n.id),"error"in n&&n.error){let s=typeof n.error.message=="string"?n.error.message:"JSON-RPC tool call failed";return o.reject(new Error(s)),!0}return o.resolve(n.result),!0},rejectPending(n){for(let o of r.values())o.reject(n);r.clear()}}}function _o(e){let t=$(e.runtimeSelection),r=h(t.providerName)||h(t.providerId),n=h(t.selectedModel)||h(t.modelId);if(!r||!n)throw new Error("agent.provision requires providerName and selectedModel");return{providerName:r,selectedModel:n}}var ie=new Map;function Wt(e){let t=$(e),r=h(t.path);return r?{path:r,baseRef:h(t.baseRef)||null}:null}function Te(e){let t=Wt(e.workspaceCodeRepository);if(!t)throw new Error("workspaceCodeRepository.path is required");return t}function Ot(e){return(0,M.resolve)(e?.trim()||process.env.TRUESAYER_NODE_HOME||ae.default.homedir())}function Eo(e,t){let r=e.trim();return r?r==="~"?ae.default.homedir():r.startsWith("~/")?(0,M.resolve)(ae.default.homedir(),r.slice(2)):(0,M.isAbsolute)(r)?(0,M.resolve)(r):(0,M.resolve)(Ot(t),r):Ot(t)}function Ut(e){try{return(0,x.statSync)(e).isDirectory()}catch{return!1}}function To(e){try{return(0,x.statSync)((0,M.join)(e,".git")).isDirectory()||(0,x.statSync)((0,M.join)(e,".git")).isFile()}catch{return!1}}function No(e,t){let r=h(e.path),n=typeof e.limit=="number"&&Number.isFinite(e.limit)?Math.trunc(e.limit):50,o=Math.min(Math.max(n,1),100),s=Eo(r,t),a=/[\\/]$/.test(r),i=Ut(s)||a?s:(0,M.dirname)(s),d=Ut(s)||a?"":(0,M.basename)(s).toLowerCase(),p=[],v=null;try{p=(0,x.readdirSync)(i,{withFileTypes:!0}).filter(l=>l.isDirectory()&&l.name.toLowerCase().startsWith(d)).sort((l,f)=>l.name.localeCompare(f.name)).slice(0,o).map(l=>{let f=(0,M.join)(i,l.name);return{name:l.name,path:f,isDirectory:!0,isGitRepository:To(f)}})}catch(l){v=l instanceof Error?l.message:String(l)}return{path:r,basePath:i,parentPath:(0,M.dirname)(i)===i?null:(0,M.dirname)(i),entries:p,error:v}}function Gt(e){let t=e.files.reduce((n,o)=>n+o.additions,0),r=e.files.reduce((n,o)=>n+o.deletions,0);return{repoRoot:e.repoRoot,baseSha:e.baseSha,baseRef:e.baseRef,currentRef:e.currentRef,diff:e.diff,diffHash:e.diffHash,hasStagedChanges:e.hasStagedChanges,files:e.files,totalAdditions:t,totalDeletions:r,updatedAt:new Date().toISOString()}}async function So(e){let t=Te(e);return Gt(await Z(t.path,t.baseRef??void 0))}async function Io(e){let t=Te(e),r=h(e.baseSha);if(!r)throw new Error("baseSha is required");let n=h(e.scope);if(n!=="file"&&n!=="all")throw new Error("scope must be file or all");let o=n==="file"?h(e.filePath):void 0;if(n==="file"&&!o)throw new Error("filePath is required");return Gt(await tt({worktreePath:t.path,baseSha:r,baseRef:t.baseRef,expectedDiffHash:h(e.diffHash)||void 0,filePath:o,expectedPatchHash:h(e.patchHash)||void 0}))}function Po(e){let t=!1,r=null,n=new Set,o=()=>{if(r=null,t){n.clear();return}let i=Array.from(n).sort();n.clear(),e.emitMessage?.({type:"repo.changed",payload:{watchId:e.watchId,workspaceCodeRepository:{path:e.repositoryPath},channelId:e.channelId,changedPaths:i,changedAt:new Date().toISOString()}})},s=(i,d)=>{t||(d&&n.add(String(d)),!r&&(r=setTimeout(o,750),typeof r.unref=="function"&&r.unref()))},a;try{a=(0,x.watch)(e.repositoryPath,{recursive:!0},s)}catch{a=(0,x.watch)(e.repositoryPath,s)}return{close(){t=!0,r&&(clearTimeout(r),r=null),n.clear(),a.close()}}}function Ao(e){let t=h(e.params.watchId)||"default",r=Te(e.params),n=h(e.params.channelId);if(!n)throw new Error("channelId is required");return ie.get(t)?.close(),ie.delete(t),ie.set(t,Po({watchId:t,repositoryPath:r.path,channelId:n,emitMessage:e.emitMessage})),{ok:!0,watchId:t,workspaceCodeRepository:r,channelId:n}}function xo(e){let t=h(e.watchId)||"default";return ie.get(t)?.close(),ie.delete(t),{ok:!0,watchId:t}}async function Co(e){let t=$(e.request.params);if(e.request.method==="provider.updateConfig")return Do({providerFile:e.providerFile,providers:e.providers,params:$(e.request.params)});if(e.request.method==="provider.discoverModels")return Mo({providerFile:e.providerFile,providers:e.providers,params:$(e.request.params)});if(e.request.method==="repo.snapshot")return So(t);if(e.request.method==="repo.restore")return Io(t);if(e.request.method==="channel_code_repository.prepare"){let d=Te(t);return le({path:d.path,baseRef:d.baseRef})}if(e.request.method==="channel_code_repository.prepare_default_space"){let d=h(t.workspaceId),p=h(t.channelId);if(!d||!p)throw new Error("channel_code_repository.prepare_default_space requires workspaceId and channelId");return le({path:st({truesayerNodeHome:e.truesayerNodeHome,workspaceId:d,channelId:p}),baseRef:h(t.baseRef)||"main"})}if(e.request.method==="channel_code_repository.path_suggestions")return No(t,e.truesayerNodeHome);if(e.request.method==="repo.watch")return Ao({params:t,emitMessage:e.emitMessage});if(e.request.method==="repo.unwatch")return xo(t);if(e.request.method!=="agent.provision")throw new Error(`unsupported node request method: ${e.request.method}`);let r=h(t.workspaceId),n=h(t.agentId);if(!r||!n)throw new Error("agent.provision requires workspaceId and agentId");let{providerName:o,selectedModel:s}=_o(t),a=e.providers[o];if(!a||!a.models.includes(s))throw new Error(`provider/model is not available on this node: ${o}/${s}`);let i=xe({truesayerNodeHome:e.truesayerNodeHome,workspaceId:r,agentId:n});return{ok:!0,agentId:n,providerName:o,selectedModel:s,providerHome:i.providerHome,agentRoot:i.agentRoot,spaceRoot:i.spaceRoot,profileDir:i.profileDir,providerHomeExposedToFileTools:!1}}function Bt(e,t){(0,x.writeFileSync)(e,`${JSON.stringify(t,null,2)}
37
- `,{mode:384}),jt(e)}async function Mo(e){let t=h(e.params.providerName)||h(e.params.providerId);if(!t)throw new Error("provider.discoverModels requires providerName");let r=e.providers[t];if(!r)throw new Error(`provider is not available on this node: ${t}`);if(r.source!=="provider-file")throw new Error(`provider model discovery is not editable on this node: ${t}`);if(!e.providerFile?.trim())throw new Error("provider.discoverModels requires provider file");let o=Ee(e.providerFile)[t];if(!o||o.source!=="provider-file")throw new Error(`provider not found in provider file: ${t}`);let s=await je(t,o),a=Ge(e.providerFile),i=a.providers,d=i[t];if(!d||typeof d!="object"||Array.isArray(d))throw new Error(`provider not found in provider file: ${t}`);return i[t]={...d,models:s},Bt(e.providerFile,a),e.providers[t]={...r,models:s,modelsDiscoveredBy:"api-probe"},{ok:!0,providerName:t,models:s,source:"api-probe"}}function Ge(e){let t;try{t=JSON.parse((0,x.readFileSync)(e,"utf8"))}catch{throw new Error(`provider file is not valid JSON: ${e}`)}if(!t||typeof t!="object"||Array.isArray(t))throw new Error("provider file must be a JSON object");let r=t;if(!r.providers||typeof r.providers!="object"||Array.isArray(r.providers))throw new Error("provider file must contain a providers object");return r}function Do(e){let t=h(e.params.providerName)||h(e.params.providerId);if(!t)throw new Error("provider.updateConfig requires providerName");let r=e.providers[t];if(r&&(r.source!=="provider-file"||r.configEditable!==!0))throw new Error(`provider is not editable on this node: ${t}`);if(!e.providerFile?.trim())throw new Error("provider.updateConfig requires provider file");let n=Object.prototype.hasOwnProperty.call(e.params,"baseUrl"),o=Object.prototype.hasOwnProperty.call(e.params,"apiKey"),s=Object.prototype.hasOwnProperty.call(e.params,"kind"),a=Object.prototype.hasOwnProperty.call(e.params,"models"),i=Object.prototype.hasOwnProperty.call(e.params,"defaultModel"),d=Object.prototype.hasOwnProperty.call(e.params,"anthropicDefaultOpusModel"),p=Object.prototype.hasOwnProperty.call(e.params,"anthropicDefaultSonnetModel"),v=Object.prototype.hasOwnProperty.call(e.params,"anthropicDefaultHaikuModel");if(!s&&!n&&!o&&!a&&!i&&!d&&!p&&!v)throw new Error("provider.updateConfig requires at least one provider config field");let l=Ge(e.providerFile),f=l.providers,y=f[t];if(y&&(typeof y!="object"||Array.isArray(y)))throw new Error(`provider not found in provider file: ${t}`);if(!r&&!s)throw new Error("provider.updateConfig requires kind when creating a provider");let c=y?{...y}:{kind:h(e.params.kind),displayName:h(e.params.displayName)||t};if(s){let R=h(e.params.kind);if(!["claude-compatible","openai-compatible"].includes(R))throw new Error("unsupported provider kind");c.kind=R}if(n){let R=h(e.params.baseUrl);if(!R)throw new Error("baseUrl cannot be empty");c.baseUrl=R}if(o){let R=h(e.params.apiKey);if(!R)throw new Error("apiKey cannot be empty");c.apiKey=R}if(a){let R=Re(Array.isArray(e.params.models)?e.params.models.filter(w=>typeof w=="string"):[]);if(R.length===0)throw new Error("models cannot be empty");c.models=R}if(i){let R=h(e.params.defaultModel);R?c.defaultModel=R:delete c.defaultModel}if(d){let R=h(e.params.anthropicDefaultOpusModel);if(!R)throw new Error("anthropicDefaultOpusModel cannot be empty");c.ANTHROPIC_DEFAULT_OPUS_MODEL=R}if(p){let R=h(e.params.anthropicDefaultSonnetModel);R?c.ANTHROPIC_DEFAULT_SONNET_MODEL=R:delete c.ANTHROPIC_DEFAULT_SONNET_MODEL}if(v){let R=h(e.params.anthropicDefaultHaikuModel);R?c.ANTHROPIC_DEFAULT_HAIKU_MODEL=R:delete c.ANTHROPIC_DEFAULT_HAIKU_MODEL}f[t]=c,Bt(e.providerFile,l);let k=typeof c.kind=="string"?c.kind:r?.kind??"openai-compatible",b=Array.isArray(c.models)?c.models.filter(R=>typeof R=="string"):r?.models??[];return e.providers[t]={kind:k,displayName:typeof c.displayName=="string"?c.displayName:r?.displayName??t,source:"provider-file",models:b,modelsDiscoveredBy:r?.modelsDiscoveredBy??(b.length>0?"provider-file":"api-probe"),...typeof c.baseUrl=="string"?{baseUrl:c.baseUrl}:{},configEditable:!0,...se(typeof c.apiKey=="string"?c.apiKey:void 0)?{apiKeyPreview:se(typeof c.apiKey=="string"?c.apiKey:void 0)}:{},...typeof c.defaultModel=="string"?{defaultModel:c.defaultModel}:{},...typeof c.ANTHROPIC_DEFAULT_OPUS_MODEL=="string"?{anthropicDefaultOpusModel:c.ANTHROPIC_DEFAULT_OPUS_MODEL}:{},...typeof c.ANTHROPIC_DEFAULT_SONNET_MODEL=="string"?{anthropicDefaultSonnetModel:c.ANTHROPIC_DEFAULT_SONNET_MODEL}:{},...typeof c.ANTHROPIC_DEFAULT_HAIKU_MODEL=="string"?{anthropicDefaultHaikuModel:c.ANTHROPIC_DEFAULT_HAIKU_MODEL}:{}},{ok:!0,providerName:t,...s?{kind:k}:{},apiKeyPreview:se(typeof c.apiKey=="string"?c.apiKey:void 0)??null,...a?{models:Array.isArray(c.models)?c.models:[]}:{},...i?{defaultModel:typeof c.defaultModel=="string"?c.defaultModel:null}:{},...v?{anthropicDefaultHaikuModel:typeof c.ANTHROPIC_DEFAULT_HAIKU_MODEL=="string"?c.ANTHROPIC_DEFAULT_HAIKU_MODEL:null}:{},...p?{anthropicDefaultSonnetModel:typeof c.ANTHROPIC_DEFAULT_SONNET_MODEL=="string"?c.ANTHROPIC_DEFAULT_SONNET_MODEL:null}:{},...d?{anthropicDefaultOpusModel:typeof c.ANTHROPIC_DEFAULT_OPUS_MODEL=="string"?c.ANTHROPIC_DEFAULT_OPUS_MODEL:null}:{},needsRestart:!0}}var Oo=/api[-_]?key|secret|token|password|authorization|base[-_]?url|api[-_]?url/i,Uo=/(api[-_]?key|secret|token|password|authorization)\s*[:=]\s*([^\s,;]+)/gi;function _e(e,t=0){if(t>6)return"[redacted:depth]";if(Array.isArray(e))return e.map(n=>_e(n,t+1));if(!e||typeof e!="object")return typeof e=="string"&&e.length>1e3?`${e.slice(0,1e3)}...`:e;let r={};for(let[n,o]of Object.entries(e))r[n]=Oo.test(n)?"[redacted]":_e(o,t+1);return r}function Lo(e){return(e instanceof Error?e.message:String(e)).replace(Uo,"$1=[redacted]").replace(/Bearer\s+[A-Za-z0-9._~+/=-]+/gi,"Bearer [redacted]").slice(0,1e3)}function Fo(e){if(["opus","sonnet","haiku"].includes(e.selectedModel))return e.selectedModel;let t=e.providerFile?.trim()?Ee(e.providerFile)[e.providerName]:void 0,r=e.provider.anthropicDefaultOpusModel??t?.anthropicDefaultOpusModel,n=e.provider.anthropicDefaultSonnetModel??t?.anthropicDefaultSonnetModel,o=e.provider.anthropicDefaultHaikuModel??t?.anthropicDefaultHaikuModel;return e.selectedModel===n?"sonnet":e.selectedModel===o?"haiku":e.selectedModel===r||r?"opus":e.selectedModel}function Ho(e){return e.provider.kind==="claude-code"||e.provider.kind==="claude-compatible"?Fo(e):e.selectedModel}function Lt(e){return e==="default"||e==="none"||e==="minimal"||e==="low"||e==="medium"||e==="high"||e==="xhigh"||e==="max"?e:void 0}function Ft(e){return e==="default"||e==="disabled"||e==="adaptive"?e:void 0}function Ht(e){return e==="default"||e==="fast"||e==="flex"?e:void 0}function $o(e){let t=$(e);if(t.type!=="agent_run.assigned")return null;let r=h(t.agentRunId),n=$(t.payload),o=$(n.runtimeSelection),s=h(n.workspaceId),a=h(n.agentId),i=h(n.agentSessionId),d=h(n.providerSessionId)||i,p=h(n.prompt),v=h(o.providerName),l=h(o.selectedModel);return!r||!s||!a||!i||!p||!v||!l?null:{type:"agent_run.assigned",agentRunId:r,payload:{workspaceId:s,agentId:a,agentSessionId:i,providerSessionId:d,channelId:h(n.channelId)||null,systemPrompt:h(n.systemPrompt)||null,prompt:p,repoAlias:h(n.repoAlias)||"default",workspaceCodeRepository:Wt(n.workspaceCodeRepository),runtimeSelection:{providerName:v,selectedModel:l,...Lt(o.reasoningEffort)?{reasoningEffort:Lt(o.reasoningEffort)}:{},...Ft(o.thinkingMode)?{thinkingMode:Ft(o.thinkingMode)}:{},...Ht(o.serviceTier)?{serviceTier:Ht(o.serviceTier)}:{}}}}}function qo(e){switch(e.kind){case"claude-code":case"claude-compatible":return ht;case"codex":case"openai-compatible":return Pt;default:return async()=>{throw new Error(`unsupported node provider kind: ${e.kind}`)}}}function jo(e){return{type:"agent_run.rejected",agentRunId:e.agentRunId,payload:{reason:"capability_mismatch",providerName:e.payload.runtimeSelection.providerName,selectedModel:e.payload.runtimeSelection.selectedModel}}}function Wo(e){return["<truesayer_workspace_context>",`Current channel worktree root: ${e.cwd}`,e.worktreePath?`Node-managed worktree path: ${e.worktreePath}`:null,e.workspaceCodeRepository?.path?`Workspace code repository: ${e.workspaceCodeRepository.path}`:null,"Treat the current channel as the active repository workspace. Unless the user explicitly says otherwise, repository modifications may span the whole worktree.","</truesayer_workspace_context>","",e.prompt].filter(r=>!!r).join(`
38
- `)}async function Go(e){let t=h(e.worktreePath);if(!t)return null;let r=h(e.baseSha);if(!r&&!h(e.branch))return null;try{let[n,o]=await Promise.all([Pe(t),Z(t,h(e.baseRef)||void 0).catch(()=>null)]);return{...e,headSha:n,dirty:o?o.files.length>0||o.hasStagedChanges:void 0,hasCommitsSinceBase:!!(r&&n&&r!==n)}}catch{return{...e,refreshFailed:!0}}}async function Bo(e){let{providerName:t,selectedModel:r}=e.message.payload.runtimeSelection,n=e.message.payload.providerSessionId||e.message.payload.agentSessionId,o=new Q(e.truesayerNodeHome),s=e.providers[t];if(!s||!s.models.includes(r)){let T=jo(e.message);return await e.emitMessage?.(T),{messages:[T]}}let a=ot({truesayerNodeHome:e.truesayerNodeHome,workspaceId:e.message.payload.workspaceId,agentId:e.message.payload.agentId,agentSessionId:e.message.payload.agentSessionId,agentRunId:e.message.agentRunId,repoAlias:e.message.payload.repoAlias||"default"}),i=a.worktreeDir,d={cwd:i};if(e.message.payload.workspaceCodeRepository){let T=e.message.payload.workspaceCodeRepository,_=await le({path:T.path,baseRef:T.baseRef||"main"}),E=await Qe({actionId:e.message.agentRunId,baseBranch:_.baseRef,repoPath:_.repoRoot,worktreePath:a.worktreeDir});i=E.path,d.cwd=i,d.workspaceCodeRepository={path:_.path,baseRef:_.baseRef},d.worktreePath=E.path,d.branch=E.branch,d.baseSha=E.baseSha,d.baseRef=E.baseRef,d.headSha=await Pe(E.path)}else d.worktreePath=a.worktreeDir;let p=Wo({prompt:e.message.payload.prompt,cwd:i,workspaceCodeRepository:e.message.payload.workspaceCodeRepository,worktreePath:h(d.worktreePath)}),v=[],l=async T=>{v.push(T),await e.emitMessage?.(T)},f=async T=>{let _=o.append({providerSessionId:n,agentRunId:e.message.agentRunId,providerName:t,raw:T});await l({type:"agent_run.event_batch",agentRunId:e.message.agentRunId,payload:{providerSessionId:n,providerName:t,rawEvents:[_]}})},y=1,c=0,k=!1,b=null,R=new Promise(T=>{b=T}),w=new AbortController,m=()=>{w.abort(e.abortSignal?.reason??new Error("Interrupted by user"))};e.abortSignal&&(e.abortSignal.aborted?m():e.abortSignal.addEventListener("abort",m,{once:!0}));let g=async(T,_)=>{y+=1,await l({type:"agent_run.event_batch",agentRunId:e.message.agentRunId,payload:{events:[{eventId:`${e.message.agentRunId}:event:${y}`,eventSeq:y,type:T,payload:_}]}})},A=e.invokeTool?async T=>{c+=1;let _=T.toolCallId||`${e.message.agentRunId}:tool:${c}`;await g("agent_run.tool.started",{toolCallId:_,toolName:T.toolName,status:"started",args:_e(T.args)});try{let E=await e.invokeTool({...T,toolCallId:_});await g("agent_run.tool.completed",{toolCallId:_,toolName:T.toolName,status:"completed",result:_e(E)});let U=$(T.args);if(T.toolName==="reply_to_channel"&&U.intent==="final"&&!k){k=!0;let j=h(U.body)||"Final reply delivered";b?.({output:j}),w.abort(new Error("Final reply delivered"))}return E}catch(E){throw await g("agent_run.tool.failed",{toolCallId:_,toolName:T.toolName,status:"failed",error:E instanceof Error?E.message:String(E)}),E}}:void 0;await l({type:"agent_run.accepted",agentRunId:e.message.agentRunId,payload:{agentId:e.message.payload.agentId,agentSessionId:e.message.payload.agentSessionId,providerSessionId:n,providerName:t,selectedModel:r}}),await l({type:"agent_run.event_batch",agentRunId:e.message.agentRunId,payload:{events:[{eventId:`${e.message.agentRunId}:workspace-prepared`,eventSeq:1,type:"agent_run.workspace_prepared",payload:{workspacePrepared:!0,fileToolRoot:"worktree",providerHomeExposedToFileTools:!1,...d}}]}});try{if(e.abortSignal?.aborted)throw new Error("Interrupted by user");let T=e.runProviderAgent??qo(s),_,E=!1,U=T({agentRunId:e.message.agentRunId,agentId:e.message.payload.agentId,agentSessionId:e.message.payload.agentSessionId,providerSessionId:n,prompt:p,provider:s,availableProviders:e.providers,providerName:t,selectedModel:Ho({providerFile:e.providerFile,providerName:t,provider:s,selectedModel:r}),reasoningEffort:e.message.payload.runtimeSelection.reasoningEffort,thinkingMode:e.message.payload.runtimeSelection.thinkingMode,serviceTier:e.message.payload.runtimeSelection.serviceTier,cwd:i,env:ho({...a.providerEnv,...vo(e.providerFile,t)}),sessionStateDir:a.contextDir,systemPrompt:e.message.payload.systemPrompt??void 0,invokeTool:A,emitEvent:async B=>{await l({type:"agent_run.event_batch",agentRunId:e.message.agentRunId,payload:{events:[B]}})},emitRawEvent:f,abortSignal:w.signal}).then(B=>(E=!0,B));try{_=await Promise.race([U,R]),!E&&k&&U.catch(()=>{})}catch(B){let Be=B instanceof Error?B:void 0,nr=Be?.emittedEventIds??new Set,Je=(Be?.events??[]).filter(or=>!nr.has(or.eventId));throw Je.length&&await l({type:"agent_run.event_batch",agentRunId:e.message.agentRunId,payload:{events:Je}}),B}let j=so(_);j.length&&await l({type:"agent_run.event_batch",agentRunId:e.message.agentRunId,payload:{events:j}});let de=await Go(d);de&&await l({type:"agent_run.event_batch",agentRunId:e.message.agentRunId,payload:{events:[{eventId:`${e.message.agentRunId}:git-terminal-evidence`,eventSeq:1e6,type:"agent_run.git_terminal_evidence",payload:de}]}}),await g("agent_run.completed",{output:_.output,..._.inputTokens===void 0?{}:{inputTokens:_.inputTokens},..._.outputTokens===void 0?{}:{outputTokens:_.outputTokens}}),await l({type:"agent_run.completed",agentRunId:e.message.agentRunId,payload:{output:_.output,...de?{git:de}:{},..._.inputTokens===void 0?{}:{inputTokens:_.inputTokens},..._.outputTokens===void 0?{}:{outputTokens:_.outputTokens}}})}catch(T){let _=Lo(T);await g("agent_run.failed",{error:_}),await l({type:"agent_run.failed",agentRunId:e.message.agentRunId,payload:{error:_}})}return e.abortSignal?.removeEventListener("abort",m),{layout:a,messages:v}}function Jo(e){let t=new URL(e);return t.protocol=t.protocol==="https:"?"wss:":"ws:",t.pathname="/api/nodes/ws",t.search="",t.toString()}function Ko(){return qt.default}function $t(e){e.readyState===1&&e.send(JSON.stringify({type:"node.heartbeat"}))}function We(e,t){if(e.readyState!==1)return!1;try{return e.send(JSON.stringify(t)),!0}catch{return!1}}function zo(e){$t(e);let t=setInterval(()=>{$t(e)},oo);return typeof t.unref=="function"&&t.unref(),()=>clearInterval(t)}async function Jt(e){let t=e.WebSocketImpl??Ko(),r=uo(e.providerFile??ge(e.truesayerNodeHome)),n=await lo({providerFile:r,probeProviderModels:e.probeProviderModels}),o=mo({...e,providerFile:r},n),s=new t(Jo(e.serverUrl),{headers:{Authorization:`Bearer ${e.apiKey}`}}),a=new Q(e.truesayerNodeHome),i=Ro(s),d=new Set,p=new Map,v=()=>{for(let l of a.unackedBatches())We(s,{type:"agent_run.event_batch",agentRunId:l.agentRunId,payload:{providerSessionId:l.providerSessionId,providerName:l.providerName,rawEvents:l.events}})};await new Promise((l,f)=>{let y=!1,c=null,k=null;s.addEventListener("open",()=>{s.send(JSON.stringify(o))}),s.addEventListener("message",b=>{let R=typeof b.data=="string"?b.data:"";try{let w=JSON.parse(R);if(i.handleJsonRpcMessage(w))return;if(ko(w)){(async()=>{try{let g=await Co({truesayerNodeHome:e.truesayerNodeHome,providerFile:r,providers:n,request:w,runProviderAgent:e.runProviderAgent,emitMessage:A=>{s.send(JSON.stringify(A))}});s.send(wo(w.id,g))}catch(g){s.send(bo(w.id,g instanceof Error?g.message:String(g)))}})();return}if(w.type==="node.ready"){y=!0,c??=zo(s),k??=(()=>{let g=setInterval(v,2e3);return typeof g.unref=="function"&&g.unref(),()=>clearInterval(g)})(),v();return}if(w.type==="agent_run.event_ack"){let g=$(w.payload),A=h(g.providerSessionId),T=typeof g.ackLine=="number"?g.ackLine:0;a.markAck(A,T);return}let m=$o(w);if(m){if(d.has(m.agentRunId))return;d.add(m.agentRunId);let g=new AbortController;p.set(m.agentRunId,g),Bo({truesayerNodeHome:e.truesayerNodeHome,providerFile:r,providers:n,message:m,invokeTool:i.invokeTool,runProviderAgent:e.runProviderAgent,abortSignal:g.signal,emitMessage:A=>{We(s,A)}}).catch(A=>{We(s,{type:"agent_run.failed",agentRunId:m.agentRunId,payload:{error:A instanceof Error?A.message:String(A)}})}).finally(()=>{p.delete(m.agentRunId)});return}if(w.type==="agent_run.cancel"){let g=h(w.agentRunId);p.get(g)?.abort(new Error("Interrupted by user"))}}catch{}}),s.addEventListener("error",b=>{c?.(),c=null,k?.(),k=null,f(new Error(`node ws error: ${String(b)}`))}),s.addEventListener("close",()=>{c?.(),c=null,k?.(),k=null,i.rejectPending(new Error("node websocket closed")),y?l():f(new Error("node ws closed before node.ready"))})})}var W=require("fs"),Kt=require("os"),zt=require("path");var Vt=["DATABASE_URL","APP_SECRET","ASSET_STORAGE_DRIVER","S3_ENDPOINT","S3_BUCKET","S3_ACCESS_KEY_ID","S3_SECRET_ACCESS_KEY","S3_REGION","S3_FORCE_PATH_STYLE"];function Vo(e=process.env){return e.TRUESAYER_NODE_HOME?.trim()||(0,zt.join)((0,Kt.homedir)(),".truesayer-node")}function Yt(e=process.env){let t=Vt.filter(r=>e[r]?.trim());if(t.length>0)throw new Error(`Node \u8FDB\u7A0B\u5E26\u6709 Server-only \u73AF\u5883\u53D8\u91CF\uFF1A${t.join(", ")}\u3002\u8BF7\u4ECE Node runtime \u73AF\u5883\u4E2D\u79FB\u9664\u8FD9\u4E9B\u53D8\u91CF\u540E\u518D\u542F\u52A8\u3002`)}function z(e,t){return{name:e,status:"pass",message:t}}function Yo(e,t){return{name:e,status:"warn",message:t}}function H(e,t){return{name:e,status:"fail",message:t}}function Xo(e){let t=e.trim().match(/^v?(\d+)/);if(t)return Number.parseInt(t[1],10)}function Zo(e){let t=e.hostname.toLowerCase();return t==="localhost"||t==="127.0.0.1"||t==="::1"||t==="0.0.0.0"}function Qo(e){let t=Xo(e);return t?t<22?H("Node \u7248\u672C","\u5F53\u524D Node \u7248\u672C\u4E0D\u6EE1\u8DB3 runtime WebSocket \u8981\u6C42\u3002\u8BF7\u5347\u7EA7\u5230 Node 22 \u6216\u66F4\u65B0\u7248\u672C\u3002"):z("Node \u7248\u672C","Node \u7248\u672C\u6EE1\u8DB3 runtime WebSocket \u8981\u6C42\u3002"):H("Node \u7248\u672C","\u65E0\u6CD5\u8BC6\u522B\u5F53\u524D Node \u7248\u672C\u3002\u8BF7\u4F7F\u7528 Node 22 \u6216\u66F4\u65B0\u7248\u672C\u3002")}function es(e){if(!e?.trim())return H("Server URL","\u7F3A\u5C11 SERVER_URL \u6216 --server\u3002\u751F\u4EA7\u793A\u4F8B\u4F7F\u7528 https://truesayer.ai\u3002");let t;try{t=new URL(e)}catch{return H("Server URL","SERVER_URL \u4E0D\u662F\u5408\u6CD5 URL\u3002\u8BF7\u8BBE\u7F6E\u4E3A https://truesayer.ai \u6216\u672C\u5730\u5F00\u53D1\u5730\u5740\u3002")}return t.protocol==="https:"?z("Server URL","Server URL \u4F7F\u7528 HTTPS\u3002"):t.protocol==="http:"&&Zo(t)?z("Server URL","\u672C\u5730\u5F00\u53D1\u5730\u5740\u5141\u8BB8\u4F7F\u7528 HTTP\u3002"):H("Server URL","\u751F\u4EA7 Server URL \u5FC5\u987B\u4F7F\u7528 HTTPS\uFF1BHTTP \u53EA\u5141\u8BB8 localhost\u3001127.0.0.1\u3001::1 \u6216 0.0.0.0\u3002")}function ts(e){return e?.trim()?z("Node API key","\u5DF2\u914D\u7F6E Node API key\u3002"):H("Node API key","\u7F3A\u5C11 NODE_API_KEY \u6216 --api-key\u3002\u8BF7\u4F7F\u7528 Server \u7B7E\u53D1\u7684 Node registration key\u3002")}function rs(e,t,r){let n=e?.trim()||Vo(r);try{(0,W.mkdirSync)(n,{recursive:!0,mode:448}),t!=="win32"&&(0,W.chmodSync)(n,448);let o=(0,W.statSync)(n);return o.isDirectory()?t!=="win32"&&(o.mode&63)!==0?H("Node home","TRUESAYER_NODE_HOME \u6743\u9650\u8FC7\u5BBD\u3002\u8BF7\u6267\u884C chmod 700\u3002"):z("Node home","TRUESAYER_NODE_HOME \u53EF\u521B\u5EFA\u4E14\u6743\u9650\u5DF2\u6536\u655B\u3002"):H("Node home","TRUESAYER_NODE_HOME \u6307\u5411\u7684\u8DEF\u5F84\u4E0D\u662F\u76EE\u5F55\u3002\u8BF7\u6539\u6210 Node \u53EF\u5199\u76EE\u5F55\u3002")}catch{return H("Node home","TRUESAYER_NODE_HOME \u4E0D\u53EF\u521B\u5EFA\u6216\u4E0D\u53EF\u5199\u3002\u8BF7\u6539\u6210 Node \u8FDB\u7A0B\u53EF\u5199\u76EE\u5F55\u3002")}}function ns(e,t){try{let r=(0,W.statSync)(e);if(!r.isFile())return H("Provider file","<node-home>/provider.json \u6307\u5411\u7684\u8DEF\u5F84\u4E0D\u662F\u6587\u4EF6\u3002");if(t!=="win32"&&(r.mode&63)!==0)return H("Provider file","provider.json \u6743\u9650\u8FC7\u5BBD\u3002\u8BF7\u6267\u884C chmod 600\u3002");let n=JSON.parse((0,W.readFileSync)(e,"utf8"));return!n||typeof n!="object"||Array.isArray(n)?H("Provider file","provider.json \u5FC5\u987B\u662F\u5408\u6CD5 JSON object\u3002"):z("Provider file","provider.json \u662F\u5408\u6CD5 JSON\uFF0C\u4E14\u6743\u9650\u6EE1\u8DB3\u8981\u6C42\u3002")}catch(r){return r instanceof SyntaxError?H("Provider file","provider.json \u4E0D\u662F\u5408\u6CD5 JSON\u3002\u8BF7\u4FEE\u6B63 JSON \u8BED\u6CD5\u3002"):Yo("Provider file","\u672A\u627E\u5230 <node-home>/provider.json\uFF1B\u542F\u52A8\u65F6\u4F1A\u521B\u5EFA\u7A7A provider registry\uFF0C\u5F53\u524D\u53EA\u4F7F\u7528 native provider \u767B\u5F55\u6001\u3002")}}function os(e){let t=Vt.filter(r=>e[r]?.trim());return t.length===0?z("Server-only env","\u672A\u53D1\u73B0 Server-only \u73AF\u5883\u53D8\u91CF\u3002"):H("Server-only env",`Node runtime \u4E0D\u5E94\u643A\u5E26\u8FD9\u4E9B Server-only \u73AF\u5883\u53D8\u91CF\uFF1A${t.join(", ")}\u3002\u8BF7\u4ECE\u542F\u52A8\u73AF\u5883\u4E2D\u79FB\u9664\u3002`)}function Xt(e={}){let t=e.env??process.env,r=e.platform??process.platform,n=e.truesayerNodeHome??t.TRUESAYER_NODE_HOME,o=e.providerFile??ge(n),s=[Qo(e.nodeVersion??process.versions.node),es(e.serverUrl??t.SERVER_URL),ts(e.apiKey??t.NODE_API_KEY),rs(n,r,t),ns(o,r),os(t)];return{ok:s.every(a=>a.status!=="fail"),checks:s}}function Zt(e){let t={pass:"\u901A\u8FC7",warn:"\u8B66\u544A",fail:"\u5931\u8D25"};return["truesayer-node doctor",...e.checks.map(n=>`[${t[n.status]}] ${n.name}\uFF1A${n.message}`),e.ok?"\u7ED3\u679C\uFF1A\u57FA\u7840\u68C0\u67E5\u901A\u8FC7\uFF0C\u53EF\u4EE5\u542F\u52A8 truesayer-node\u3002":"\u7ED3\u679C\uFF1A\u57FA\u7840\u68C0\u67E5\u5931\u8D25\u3002\u8BF7\u4FEE\u590D\u5931\u8D25\u9879\u540E\u518D\u542F\u52A8 truesayer-node\u3002"].join(`
39
- `)}function Ne(e){let t=`${e}=`,r=process.argv.find(o=>o.startsWith(t));if(r)return r.slice(t.length);let n=process.argv.indexOf(e);if(n>=0)return process.argv[n+1]}function ss(...e){return process.argv.some(t=>e.includes(t))}function is(){let e=Number(process.versions.node.split(".")[0]);if(!Number.isFinite(e)||e<22)throw new Error(`truesayer-node requires Node.js >=22. Current: ${process.version}`)}function Qt(){return"Usage: truesayer-node --server <url> --api-key <key> [--node-name <name>] [--node-home <path>]"}function er(){if(process.env.npm_package_version)return process.env.npm_package_version;try{let e=JSON.parse((0,tr.readFileSync)((0,rr.join)(__dirname,"..","package.json"),"utf8"));return typeof e.version=="string"&&e.version.trim()?e.version:"0.1.0"}catch{return"0.1.0"}}async function as(){let e=process.argv[2];if(ss("--version","-v")){console.log(er());return}let t=Ne("--server")??process.env.SERVER_URL,r=Ne("--api-key")??process.env.NODE_API_KEY,n=Ne("--node-name")??process.env.NODE_NAME??"truesayer-node",o=Ne("--node-home")??process.env.TRUESAYER_NODE_HOME;if(e==="doctor"){let s=Xt({serverUrl:t,apiKey:r,truesayerNodeHome:o,nodeVersion:process.version});console.log(Zt(s)),process.exit(s.ok?0:1)}if(is(),Yt(),!t)throw new Error(`--server or SERVER_URL is required
40
- ${Qt()}`);if(!r)throw new Error(`--api-key or NODE_API_KEY is required
41
- ${Qt()}`);for(;;){try{await Jt({serverUrl:t,apiKey:r,nodeName:n,nodeVersion:er(),truesayerNodeHome:o})}catch(s){console.error("[node] connection failed:",s instanceof Error?s.message:String(s))}await new Promise(s=>setTimeout(s,2e3))}}as().catch(e=>{console.error("[node] Fatal:",e instanceof Error?e.message:String(e)),process.exit(1)});
34
+ `)}function Hn(e){return e.prompt}function ke(e){return JSON.stringify(e)}function $n(e){return/^[A-Za-z0-9_-]+$/.test(e)?e:ke(e)}function qn(e){if(e.provider.source!=="provider-file"||e.provider.kind!=="codex"&&e.provider.kind!=="openai-compatible")return[];let t=e.provider.baseUrl?.trim()||e.env.OPENAI_BASE_URL?.trim();if(!t)return[];let r=e.providerName.trim();if(!r)return[];let n=[`name=${ke(e.provider.displayName||r)}`,`base_url=${ke(t)}`,'wire_api="responses"','env_key="OPENAI_API_KEY"',"requires_openai_auth=false","supports_websockets=false"].join(",");return["-c",`model_provider=${ke(r)}`,"-c",`model_providers.${$n(r)}={${n}}`]}function jn(e){return e===void 0?null:e}function Wn(e){return e&&typeof e=="object"&&!Array.isArray(e)?Fe.z.toJSONSchema(Fe.z.object(e)):{type:"object",properties:{},additionalProperties:!0}}function Gn(e){if(!e.invokeTool)return null;let t=De(e.agentRunId,e.invokeTool),r=new Map;return{dynamicTools:t.map(o=>{let s=o.handler;return r.set(o.name,async a=>s(a)),{namespace:"truesayer",name:o.name,description:o.description,inputSchema:jn(Wn(o.inputSchema)),deferLoading:!1}}),handlers:r}}function Bn(e){let t=N(e).content;if(Array.isArray(t)){let r=t.map(N).map(n=>$e(n.text)).filter(Boolean).join(`
35
+ `);if(r)return r}return JSON.stringify(e??{})}async function Jn(e,t){if(e.method!=="item/tool/call")throw new Error(`Unsupported Codex app-server request: ${e.method}`);if(!t)return{contentItems:[{type:"inputText",text:"Truesayer platform tools are not available for this run."}],success:!1};let r=S(e.params?.tool),n=t.handlers.get(r);if(!n)return{contentItems:[{type:"inputText",text:`Unknown Truesayer platform tool: ${r||"(missing)"}`}],success:!1};try{let o=N(e.params?.arguments),s=await n(o);return{contentItems:[{type:"inputText",text:Bn(s)}],success:!0}}catch(o){return{contentItems:[{type:"inputText",text:o instanceof Error?o.message:String(o)}],success:!1}}}function Kn(e){let t=N(e),r=N(t.last),n=N(t.total);return{inputTokens:we(r.input_tokens,r.inputTokens,r.prompt_tokens,r.promptTokens,n.input_tokens,n.inputTokens,n.prompt_tokens,n.promptTokens,t.input_tokens,t.inputTokens,t.prompt_tokens,t.promptTokens),outputTokens:we(r.output_tokens,r.outputTokens,r.completion_tokens,r.completionTokens,n.output_tokens,n.outputTokens,n.completion_tokens,n.completionTokens,t.output_tokens,t.outputTokens,t.completion_tokens,t.completionTokens)}}function ne(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function we(...e){for(let t of e){let r=ne(t);if(r!==void 0)return Math.max(0,Math.trunc(r))}}function zn(e){let t=N(e),r=N(t.usage),n=N(t.tokenUsage),o=N(t.token_usage),s=N(t.tokens),a=N(t.usageSummary);return{inputTokens:we(r.input_tokens,r.inputTokens,r.prompt_tokens,r.promptTokens,n.input_tokens,n.inputTokens,n.prompt_tokens,n.promptTokens,o.input_tokens,o.inputTokens,o.prompt_tokens,o.promptTokens,s.input_tokens,s.inputTokens,s.prompt_tokens,s.promptTokens,a.input_tokens,a.inputTokens,t.input_tokens,t.inputTokens,t.total_input_tokens,t.prompt_tokens,t.promptTokens),outputTokens:we(r.output_tokens,r.outputTokens,r.completion_tokens,r.completionTokens,n.output_tokens,n.outputTokens,n.completion_tokens,n.completionTokens,o.output_tokens,o.outputTokens,o.completion_tokens,o.completionTokens,s.output_tokens,s.outputTokens,s.completion_tokens,s.completionTokens,a.output_tokens,a.outputTokens,t.output_tokens,t.outputTokens,t.total_output_tokens,t.completion_tokens,t.completionTokens),costUsd:ne(t.total_cost_usd)??ne(t.cost_usd)??ne(r.total_cost_usd)??ne(r.cost_usd)}}function kt(...e){let t={};for(let r of e)r&&(r.inputTokens!==void 0&&(t.inputTokens=r.inputTokens),r.outputTokens!==void 0&&(t.outputTokens=r.outputTokens),"costUsd"in r&&r.costUsd!==void 0&&(t.costUsd=r.costUsd));return t}function Vn(e,t){let r=[],n=new Set,o=new Map,s=new Map,a=new Map,i=new Map,c=2,m="",v=null,l=null;function f(p){r.push(p),!n.has(p.eventId)&&(n.add(p.eventId),e.emitEvent?.(p))}function y(p,g){f({eventId:`${e.agentRunId}:codex:${c}`,eventSeq:c,type:`agent_run.provider_request.${p}`,payload:{provider:"codex",...g}}),c+=1}function d(p){let g=An(p);g&&(f({eventId:`${e.agentRunId}:codex:${c}`,eventSeq:c,type:g.type,payload:g.payload}),c+=1)}function k(p,g={}){let T={output:m.trim()||"Codex run completed",...g.inputTokens===void 0?{}:{inputTokens:g.inputTokens},...g.outputTokens===void 0?{}:{outputTokens:g.outputTokens}};a.set(p,T);let _=i.get(p)??[];i.delete(p);for(let E of _)E.resolve(T)}function b(p){for(let g of i.values())for(let A of g)A.reject(p);i.clear()}function R(p){e.emitRawEvent?.(p);let g=p.params??{},A=Et(p),T=xn(p);if(p.method==="item/agentMessage/delta"){let E=S(g.itemId),O=S(g.delta);if(E&&O){let j=`${o.get(E)??""}${O}`;o.set(E,j),m=j}}if(p.method==="item/completed"){let E=N(g.item);if(E.type==="agentMessage"){let O=S(E.text);O&&(m=O)}}if(p.method==="turn/completed"){let E=N(g.turn),O=S(E.id),j=S(E.status);O&&j==="completed"&&k(O,kt(s.get(O),zn(E)))}if(p.method==="thread/tokenUsage/updated"){let E=S(g.turnId);E&&s.set(E,kt(s.get(E),Kn(g.tokenUsage)))}d(p);let _=A??T;_&&(v=_,b(_))}let w=Tt({cwd:e.cwd,env:e.env,args:qn(e),requestTimeoutMs:Cn(e.env),onNotification:R,onServerRequest:p=>Jn(p,t),onRequestEvent:y,onExit(p){l=p,b(p)}});return{events:r,emittedEventIds:n,stderrTail:w.stderrTail,request:w.request,notify:w.notify,close:w.close,waitForTurnCompleted(p){let g=a.get(p);return g!==void 0?Promise.resolve(g):v?Promise.reject(v):l?Promise.reject(l):(y("started",{method:"turn/completed",turnId:p}),new Promise((A,T)=>{let _={resolve:A,reject:T},E=i.get(p)??[];E.push(_),i.set(p,E)}))}}}function Yn(e){let t=S(N(N(e).thread).id);if(!t)throw new Error("Codex app-server did not return a thread id");return t}function Xn(e){let t=S(N(N(e).turn).id);if(!t)throw new Error("Codex app-server did not return a turn id");return t}async function It(e){if(e.provider.kind!=="codex"&&e.provider.kind!=="openai-compatible")throw new Error(`unsupported node provider kind: ${e.provider.kind}`);let t=Gn(e),r=Vn(e,t),n=e.provider.source==="provider-file"?e.providerName:void 0,o={...e.reasoningEffort&&e.reasoningEffort!=="default"?{reasoningEffort:e.reasoningEffort}:{},...e.serviceTier&&e.serviceTier!=="default"?{serviceTier:e.serviceTier}:{}},s=Fn(e),a=()=>{};try{if(e.abortSignal?.aborted)throw new Error("Interrupted by user");await r.request("initialize",{clientInfo:{name:"truesayer-node",title:"Truesayer Node",version:"0.1.0"},capabilities:{experimentalApi:!0,optOutNotificationMethods:[]}}),r.notify("initialized");let i=On(e.sessionStateDir),c=i.threadId;if(t&&i.platformToolsVersion!==_t&&(c=void 0),c)await r.request("thread/resume",{threadId:c,model:e.selectedModel,...n?{modelProvider:n}:{},cwd:e.cwd,approvalPolicy:"never",sandbox:"danger-full-access",experimentalRawEvents:!1,excludeTurns:!0,persistExtendedHistory:!0,developerInstructions:s,...t?{dynamicTools:t.dynamicTools}:{},...o});else{let y=await r.request("thread/start",{model:e.selectedModel,...n?{modelProvider:n}:{},cwd:e.cwd,approvalPolicy:"never",sandbox:"danger-full-access",experimentalRawEvents:!1,persistExtendedHistory:!0,developerInstructions:s,...t?{dynamicTools:t.dynamicTools}:{},...o});c=Yn(y),Un(e.sessionStateDir,c,t)}let m=await r.request("turn/start",{threadId:c,input:[{type:"text",text:Hn(e),text_elements:[]}],cwd:e.cwd,approvalPolicy:"never",model:e.selectedModel,...o}),v=Xn(m),l=e.abortSignal?new Promise((y,d)=>{let k=()=>{r.request("turn/interrupt",{threadId:c,turnId:v}).catch(()=>{}),d(new Error("Interrupted by user"))};e.abortSignal?.addEventListener("abort",k,{once:!0}),a=()=>e.abortSignal?.removeEventListener("abort",k)}):null,f=await(l?Promise.race([r.waitForTurnCompleted(v),l]):r.waitForTurnCompleted(v));return{output:f.output.trim()||"Codex run completed",...f.inputTokens===void 0?{}:{inputTokens:f.inputTokens},...f.outputTokens===void 0?{}:{outputTokens:f.outputTokens},events:r.events,emittedEventIds:r.emittedEventIds}}catch(i){throw i instanceof Error&&(i.events=r.events,i.emittedEventIds=r.emittedEventIds),i}finally{a(),r.close()}}function be(e){return Array.from(new Set(e.map(t=>t.trim()).filter(Boolean)))}function qe(e){return typeof e=="object"&&e!==null?e:void 0}function Pt(e){return typeof e=="string"&&e.trim()?e.trim():void 0}function Zn(e){return e.replace(/\/+$/,"")}function At(e,t){let r=Zn(e);return t==="v1/models"&&/\/v1$/i.test(r)?`${r}/models`:`${r}/${t}`}function Qn(e){if(!e.baseUrl?.trim()||!e.apiKey?.trim())return[];let t=e.kind.toLowerCase(),r=e.baseUrl.trim(),n=[];return(t.includes("claude")||t.includes("anthropic"))&&n.push({url:At(r,"v1/models"),auth:"anthropic"}),(t.includes("openai")||t==="codex")&&n.push({url:At(r,"models"),auth:"bearer"}),n.filter((o,s,a)=>a.findIndex(i=>i.url===o.url)===s)}function eo(e){let t=qe(e);return Pt(t?.id)??Pt(t?.model)}function to(e){let t=qe(e)?.data;if(!Array.isArray(t))return[];let r=t.flatMap(s=>{let a=eo(s);if(!a)return[];let i=qe(s),c=typeof i?.created=="number"?i.created:typeof i?.created_at=="number"?i.created_at:void 0;return[{id:a,created:c}]}),o=r.some(s=>s.created!==void 0)?[...r].sort((s,a)=>(a.created??Number.NEGATIVE_INFINITY)-(s.created??Number.NEGATIVE_INFINITY)):r;return be(o.map(s=>s.id))}async function ro(e,t){let r={accept:"application/json"};e.auth==="anthropic"?(r["x-api-key"]=t,r["anthropic-version"]="2023-06-01"):r.authorization=`Bearer ${t}`;let n=await fetch(e.url,{method:"GET",headers:r});if(!n.ok)throw new Error(`HTTP ${n.status}`);let o=to(await n.json().catch(()=>null));if(o.length===0)throw new Error("response did not contain model ids");return o}async function je(e,t){let r=t.apiKey?.trim();if(!r)throw new Error(`provider ${e} cannot discover models without an API key`);let n=Qn(t);if(n.length===0)throw new Error(`provider ${e} cannot discover models without a supported baseUrl`);let o=[];for(let s of n)try{return await ro(s,r)}catch(a){o.push(`${s.url}: ${a instanceof Error?a.message:String(a)}`)}throw new Error(`provider ${e} model discovery failed: ${o.join("; ")}`)}async function xt(e,t){if(t.source==="provider-file"&&t.models?.length)return be(t.models);if(t.source==="provider-file")try{return await je(e,t)}catch(r){return console.warn(`[node] provider ${e} model discovery unavailable:`,r instanceof Error?r.message:String(r)),[]}if(t.source!=="native")return[];try{if(e==="local-claude-code"&&t.kind==="claude-code")return await lt();if(e==="local-codex"&&t.kind==="codex")return await Nt()}catch(r){console.warn(`[node] provider ${e} unavailable:`,r instanceof Error?r.message:String(r))}return[]}var $t=V(require("ws")),no=15e3;function oo(e){let t=e.emittedEventIds??new Set;return(e.events??[]).filter(r=>!t.has(r.eventId))}var Ct={"local-claude-code":{kind:"claude-code",displayName:"Local Claude Code",source:"native"},"local-codex":{kind:"codex",displayName:"Local Codex",source:"native"}};function so(e){return e.split(/[-_\s]+/).filter(Boolean).map(t=>`${t[0]?.toUpperCase()??""}${t.slice(1)}`).join(" ")}function io(e){if(!e?.trim()||!(0,x.existsSync)(e))return{};ao(e);let t;try{t=JSON.parse((0,x.readFileSync)(e,"utf8"))}catch{throw new Error(`provider file is not valid JSON: ${e}`)}let r=t&&typeof t=="object"&&!Array.isArray(t)&&t.providers&&typeof t.providers=="object"&&!Array.isArray(t.providers)?t.providers:{},n={};for(let[o,s]of Object.entries(r)){let a=o.trim();if(!a||!s||typeof s!="object"||Array.isArray(s))continue;let i=s,c=typeof i.kind=="string"&&i.kind.trim()?i.kind.trim():"openai-compatible",m=typeof i.displayName=="string"&&i.displayName.trim()?i.displayName.trim():so(a),v=Array.isArray(i.models)?Array.from(new Set(i.models.filter(b=>typeof b=="string"&&b.trim().length>0).map(b=>b.trim()))):void 0,l=typeof i.apiKey=="string"&&i.apiKey.trim()?i.apiKey.trim():void 0,f=typeof i.baseUrl=="string"&&i.baseUrl.trim()?i.baseUrl.trim():void 0,y=typeof i.ANTHROPIC_DEFAULT_HAIKU_MODEL=="string"&&i.ANTHROPIC_DEFAULT_HAIKU_MODEL.trim()?i.ANTHROPIC_DEFAULT_HAIKU_MODEL.trim():void 0,d=typeof i.ANTHROPIC_DEFAULT_SONNET_MODEL=="string"&&i.ANTHROPIC_DEFAULT_SONNET_MODEL.trim()?i.ANTHROPIC_DEFAULT_SONNET_MODEL.trim():void 0,k=typeof i.ANTHROPIC_DEFAULT_OPUS_MODEL=="string"&&i.ANTHROPIC_DEFAULT_OPUS_MODEL.trim()?i.ANTHROPIC_DEFAULT_OPUS_MODEL.trim():void 0;n[a]={kind:c,displayName:m,source:"provider-file",...Mt(c,v)?.length?{models:Mt(c,v)}:{},...l?{apiKey:l}:{},...f?{baseUrl:f}:{},...y?{anthropicDefaultHaikuModel:y}:{},...d?{anthropicDefaultSonnetModel:d}:{},...k?{anthropicDefaultOpusModel:k}:{}}}return n}function ao(e){if(process.platform!=="win32")try{((0,x.statSync)(e).mode&63)!==0&&console.warn(`[node] provider file permissions are too broad; run chmod 600 ${e}`)}catch{return}}function qt(e){process.platform!=="win32"&&(0,x.chmodSync)(e,384)}function co(e){return(0,x.mkdirSync)((0,M.dirname)(e),{recursive:!0,mode:448}),(0,x.existsSync)(e)||(0,x.writeFileSync)(e,`${JSON.stringify({providers:{}},null,2)}
36
+ `,{mode:384}),qt(e),Ge(e),e}function Mt(e,t){if(!t?.length)return;if(!e.toLowerCase().includes("claude"))return t;let r=t.filter(n=>!["haiku","sonnet","opus"].includes(n.trim().toLowerCase()));return r.length>0?r:void 0}function se(e){if(!e)return;let t=e.trim();if(t)return t.length>8?`${t.slice(0,4)}***${t.slice(-4)}`:`${t.slice(0,4)}***`}function _e(e){let t=io(e);for(let r of Object.keys(t))if(Ct[r])throw new Error(`duplicate provider name: ${r}`);return{...Ct,...t}}async function uo(e={}){let t=_e(e.providerFile),r={},n=e.probeProviderModels??xt,o=await Promise.all(Object.entries(t).map(async([s,a])=>[s,await n(s,a,{})]));for(let[s,a]of o){let i=t[s];i&&a.length!==0&&(r[s]={kind:i.kind,displayName:i.displayName,source:i.source,models:a,modelsDiscoveredBy:i.source==="provider-file"?i.models?.length?"provider-file":"api-probe":"sdk-probe",...i.source==="provider-file"&&i.baseUrl?{baseUrl:i.baseUrl}:{},...i.source==="provider-file"&&se(i.apiKey)?{apiKeyPreview:se(i.apiKey)}:{},...i.source==="provider-file"?{configEditable:!0}:{},...i.source==="provider-file"&&i.anthropicDefaultHaikuModel?{anthropicDefaultHaikuModel:i.anthropicDefaultHaikuModel}:{},...i.source==="provider-file"&&i.anthropicDefaultSonnetModel?{anthropicDefaultSonnetModel:i.anthropicDefaultSonnetModel}:{},...i.source==="provider-file"&&i.anthropicDefaultOpusModel?{anthropicDefaultOpusModel:i.anthropicDefaultOpusModel}:{}})}return r}function lo(e){return Object.fromEntries(Object.entries(e).map(([t,r])=>[t,{kind:r.kind,displayName:r.displayName,source:r.source,models:r.models,modelsDiscoveredBy:r.modelsDiscoveredBy}]))}function po(e,t){return{type:"node.hello",payload:{nodeName:e.nodeName,nodeVersion:e.nodeVersion,platform:{os:process.platform,arch:process.arch,hostname:ae.default.hostname()},capabilities:{providers:lo(t),supportsWorktrees:!0,browserE2E:(e.probeBrowserE2E??fo)()}}}}var mo={"libnss3.so":["/usr/lib/x86_64-linux-gnu/libnss3.so","/usr/lib/aarch64-linux-gnu/libnss3.so","/usr/lib64/libnss3.so"],"libatk-bridge-2.0.so.0":["/usr/lib/x86_64-linux-gnu/libatk-bridge-2.0.so.0","/usr/lib/aarch64-linux-gnu/libatk-bridge-2.0.so.0","/usr/lib64/libatk-bridge-2.0.so.0"],"libcups.so.2":["/usr/lib/x86_64-linux-gnu/libcups.so.2","/usr/lib/aarch64-linux-gnu/libcups.so.2","/usr/lib64/libcups.so.2"],"libxkbcommon.so.0":["/usr/lib/x86_64-linux-gnu/libxkbcommon.so.0","/usr/lib/aarch64-linux-gnu/libxkbcommon.so.0","/usr/lib64/libxkbcommon.so.0"],"libgbm.so.1":["/usr/lib/x86_64-linux-gnu/libgbm.so.1","/usr/lib/aarch64-linux-gnu/libgbm.so.1","/usr/lib64/libgbm.so.1"],"libasound.so.2":["/usr/lib/x86_64-linux-gnu/libasound.so.2","/usr/lib/aarch64-linux-gnu/libasound.so.2","/usr/lib64/libasound.so.2"]};function fo(){let e=process.env.TRUESAYER_NODE_BROWSER_E2E?.trim().toLowerCase();if(e==="available"||e==="unavailable"||e==="unknown")return{status:e,diagnostics:["set by TRUESAYER_NODE_BROWSER_E2E"]};if(process.platform!=="linux")return{status:"unknown",diagnostics:["automatic browser dependency detection only supports linux"]};let t=Object.entries(mo).filter(([,r])=>!r.some(n=>(0,x.existsSync)(n))).map(([r])=>r);return t.length>0?{status:"unavailable",diagnostics:t.map(r=>`missing ${r}`)}:{status:"unknown",diagnostics:["linux chromium libraries found; browser binary availability not verified"]}}function $(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}function h(e){return typeof e=="string"&&e.trim()?e.trim():""}function go(e){return te(e)}function ho(e,t){let r=e;if(!r?.trim())return{};let n=_e(r)[t];if(!n||n.source!=="provider-file")return{};let o={};return n.kind==="codex"||n.kind==="openai-compatible"?(n.apiKey&&(o.OPENAI_API_KEY=n.apiKey),n.baseUrl&&(o.OPENAI_BASE_URL=n.baseUrl),o):(n.apiKey&&(o.ANTHROPIC_API_KEY=n.apiKey),n.baseUrl&&(o.ANTHROPIC_BASE_URL=n.baseUrl),n.anthropicDefaultOpusModel&&(o.ANTHROPIC_DEFAULT_OPUS_MODEL=n.anthropicDefaultOpusModel,o.ANTHROPIC_DEFAULT_SONNET_MODEL=n.anthropicDefaultSonnetModel||n.anthropicDefaultOpusModel,o.ANTHROPIC_DEFAULT_HAIKU_MODEL=n.anthropicDefaultHaikuModel||n.anthropicDefaultOpusModel),o)}function vo(e){let t=$(e),r=t.id;return t.jsonrpc==="2.0"&&(typeof r=="string"||typeof r=="number"||r===null)&&("result"in t||"error"in t)}function yo(e){let t=$(e),r=t.id;return t.jsonrpc==="2.0"&&(typeof r=="string"||typeof r=="number"||r===null)&&typeof t.method=="string"&&t.method.trim().length>0}function ko(e,t){return JSON.stringify({jsonrpc:"2.0",id:e,result:t})}function wo(e,t){return JSON.stringify({jsonrpc:"2.0",id:e,error:{code:-32e3,message:t}})}function bo(e){let t=0,r=new Map;return{invokeTool(n){if(e.readyState!==1)throw new Error("node websocket is not open");let o=`tool:${++t}`,s={jsonrpc:"2.0",id:o,method:"tool.invoke",params:{...n,toolCallId:n.toolCallId??o}},a=new Promise((i,c)=>{r.set(o,{resolve:i,reject:c})});try{e.send(JSON.stringify(s))}catch(i){throw r.delete(o),i}return a},handleJsonRpcMessage(n){if(!vo(n)||n.id===null)return!1;let o=r.get(n.id);if(!o)return!1;if(r.delete(n.id),"error"in n&&n.error){let s=typeof n.error.message=="string"?n.error.message:"JSON-RPC tool call failed";return o.reject(new Error(s)),!0}return o.resolve(n.result),!0},rejectPending(n){for(let o of r.values())o.reject(n);r.clear()}}}function Ro(e){let t=$(e.runtimeSelection),r=h(t.providerName)||h(t.providerId),n=h(t.selectedModel)||h(t.modelId);if(!r||!n)throw new Error("agent.provision requires providerName and selectedModel");return{providerName:r,selectedModel:n}}var ie=new Map;function jt(e){let t=$(e),r=h(t.path);return r?{path:r,baseRef:h(t.baseRef)||null}:null}function Ee(e){let t=jt(e.workspaceCodeRepository);if(!t)throw new Error("workspaceCodeRepository.path is required");return t}function Dt(e){return(0,M.resolve)(e?.trim()||process.env.TRUESAYER_NODE_HOME||ae.default.homedir())}function _o(e,t){let r=e.trim();return r?r==="~"?ae.default.homedir():r.startsWith("~/")?(0,M.resolve)(ae.default.homedir(),r.slice(2)):(0,M.isAbsolute)(r)?(0,M.resolve)(r):(0,M.resolve)(Dt(t),r):Dt(t)}function Ot(e){try{return(0,x.statSync)(e).isDirectory()}catch{return!1}}function Eo(e){try{return(0,x.statSync)((0,M.join)(e,".git")).isDirectory()||(0,x.statSync)((0,M.join)(e,".git")).isFile()}catch{return!1}}function To(e,t){let r=h(e.path),n=typeof e.limit=="number"&&Number.isFinite(e.limit)?Math.trunc(e.limit):50,o=Math.min(Math.max(n,1),100),s=_o(r,t),a=/[\\/]$/.test(r),i=Ot(s)||a?s:(0,M.dirname)(s),c=Ot(s)||a?"":(0,M.basename)(s).toLowerCase(),m=[],v=null;try{m=(0,x.readdirSync)(i,{withFileTypes:!0}).filter(l=>l.isDirectory()&&l.name.toLowerCase().startsWith(c)).sort((l,f)=>l.name.localeCompare(f.name)).slice(0,o).map(l=>{let f=(0,M.join)(i,l.name);return{name:l.name,path:f,isDirectory:!0,isGitRepository:Eo(f)}})}catch(l){v=l instanceof Error?l.message:String(l)}return{path:r,basePath:i,parentPath:(0,M.dirname)(i)===i?null:(0,M.dirname)(i),entries:m,error:v}}function Wt(e){let t=e.files.reduce((n,o)=>n+o.additions,0),r=e.files.reduce((n,o)=>n+o.deletions,0);return{repoRoot:e.repoRoot,baseSha:e.baseSha,baseRef:e.baseRef,currentRef:e.currentRef,diff:e.diff,diffHash:e.diffHash,hasStagedChanges:e.hasStagedChanges,files:e.files,totalAdditions:t,totalDeletions:r,updatedAt:new Date().toISOString()}}async function No(e){let t=Ee(e);return Wt(await Y(t.path,t.baseRef??void 0))}async function So(e){let t=Ee(e),r=h(e.baseSha);if(!r)throw new Error("baseSha is required");let n=h(e.scope);if(n!=="file"&&n!=="all")throw new Error("scope must be file or all");let o=n==="file"?h(e.filePath):void 0;if(n==="file"&&!o)throw new Error("filePath is required");return Wt(await tt({worktreePath:t.path,baseSha:r,baseRef:t.baseRef,expectedDiffHash:h(e.diffHash)||void 0,filePath:o,expectedPatchHash:h(e.patchHash)||void 0}))}function Io(e){let t=!1,r=null,n=new Set,o=()=>{if(r=null,t){n.clear();return}let i=Array.from(n).sort();n.clear(),e.emitMessage?.({type:"repo.changed",payload:{watchId:e.watchId,workspaceCodeRepository:{path:e.repositoryPath},channelId:e.channelId,changedPaths:i,changedAt:new Date().toISOString()}})},s=(i,c)=>{t||(c&&n.add(String(c)),!r&&(r=setTimeout(o,750),typeof r.unref=="function"&&r.unref()))},a;try{a=(0,x.watch)(e.repositoryPath,{recursive:!0},s)}catch{a=(0,x.watch)(e.repositoryPath,s)}return{close(){t=!0,r&&(clearTimeout(r),r=null),n.clear(),a.close()}}}function Po(e){let t=h(e.params.watchId)||"default",r=Ee(e.params),n=h(e.params.channelId);if(!n)throw new Error("channelId is required");return ie.get(t)?.close(),ie.delete(t),ie.set(t,Io({watchId:t,repositoryPath:r.path,channelId:n,emitMessage:e.emitMessage})),{ok:!0,watchId:t,workspaceCodeRepository:r,channelId:n}}function Ao(e){let t=h(e.watchId)||"default";return ie.get(t)?.close(),ie.delete(t),{ok:!0,watchId:t}}async function xo(e){let t=$(e.request.params);if(e.request.method==="provider.updateConfig")return Mo({providerFile:e.providerFile,providers:e.providers,params:$(e.request.params)});if(e.request.method==="provider.discoverModels")return Co({providerFile:e.providerFile,providers:e.providers,params:$(e.request.params)});if(e.request.method==="repo.snapshot")return No(t);if(e.request.method==="repo.restore")return So(t);if(e.request.method==="channel_code_repository.prepare"){let c=Ee(t);return Ie({path:c.path,baseRef:c.baseRef})}if(e.request.method==="channel_code_repository.path_suggestions")return To(t,e.truesayerNodeHome);if(e.request.method==="repo.watch")return Po({params:t,emitMessage:e.emitMessage});if(e.request.method==="repo.unwatch")return Ao(t);if(e.request.method!=="agent.provision")throw new Error(`unsupported node request method: ${e.request.method}`);let r=h(t.workspaceId),n=h(t.agentId);if(!r||!n)throw new Error("agent.provision requires workspaceId and agentId");let{providerName:o,selectedModel:s}=Ro(t),a=e.providers[o];if(!a||!a.models.includes(s))throw new Error(`provider/model is not available on this node: ${o}/${s}`);let i=xe({truesayerNodeHome:e.truesayerNodeHome,workspaceId:r,agentId:n});return{ok:!0,agentId:n,providerName:o,selectedModel:s,providerHome:i.providerHome,agentRoot:i.agentRoot,spaceRoot:i.spaceRoot,profileDir:i.profileDir,providerHomeExposedToFileTools:!1}}function Gt(e,t){(0,x.writeFileSync)(e,`${JSON.stringify(t,null,2)}
37
+ `,{mode:384}),qt(e)}async function Co(e){let t=h(e.params.providerName)||h(e.params.providerId);if(!t)throw new Error("provider.discoverModels requires providerName");let r=e.providers[t];if(!r)throw new Error(`provider is not available on this node: ${t}`);if(r.source!=="provider-file")throw new Error(`provider model discovery is not editable on this node: ${t}`);if(!e.providerFile?.trim())throw new Error("provider.discoverModels requires provider file");let o=_e(e.providerFile)[t];if(!o||o.source!=="provider-file")throw new Error(`provider not found in provider file: ${t}`);let s=await je(t,o),a=Ge(e.providerFile),i=a.providers,c=i[t];if(!c||typeof c!="object"||Array.isArray(c))throw new Error(`provider not found in provider file: ${t}`);return i[t]={...c,models:s},Gt(e.providerFile,a),e.providers[t]={...r,models:s,modelsDiscoveredBy:"api-probe"},{ok:!0,providerName:t,models:s,source:"api-probe"}}function Ge(e){let t;try{t=JSON.parse((0,x.readFileSync)(e,"utf8"))}catch{throw new Error(`provider file is not valid JSON: ${e}`)}if(!t||typeof t!="object"||Array.isArray(t))throw new Error("provider file must be a JSON object");let r=t;if(!r.providers||typeof r.providers!="object"||Array.isArray(r.providers))throw new Error("provider file must contain a providers object");return r}function Mo(e){let t=h(e.params.providerName)||h(e.params.providerId);if(!t)throw new Error("provider.updateConfig requires providerName");let r=e.providers[t];if(r&&(r.source!=="provider-file"||r.configEditable!==!0))throw new Error(`provider is not editable on this node: ${t}`);if(!e.providerFile?.trim())throw new Error("provider.updateConfig requires provider file");let n=Object.prototype.hasOwnProperty.call(e.params,"baseUrl"),o=Object.prototype.hasOwnProperty.call(e.params,"apiKey"),s=Object.prototype.hasOwnProperty.call(e.params,"kind"),a=Object.prototype.hasOwnProperty.call(e.params,"models"),i=Object.prototype.hasOwnProperty.call(e.params,"defaultModel"),c=Object.prototype.hasOwnProperty.call(e.params,"anthropicDefaultOpusModel"),m=Object.prototype.hasOwnProperty.call(e.params,"anthropicDefaultSonnetModel"),v=Object.prototype.hasOwnProperty.call(e.params,"anthropicDefaultHaikuModel");if(!s&&!n&&!o&&!a&&!i&&!c&&!m&&!v)throw new Error("provider.updateConfig requires at least one provider config field");let l=Ge(e.providerFile),f=l.providers,y=f[t];if(y&&(typeof y!="object"||Array.isArray(y)))throw new Error(`provider not found in provider file: ${t}`);if(!r&&!s)throw new Error("provider.updateConfig requires kind when creating a provider");let d=y?{...y}:{kind:h(e.params.kind),displayName:h(e.params.displayName)||t};if(s){let R=h(e.params.kind);if(!["claude-compatible","openai-compatible"].includes(R))throw new Error("unsupported provider kind");d.kind=R}if(n){let R=h(e.params.baseUrl);if(!R)throw new Error("baseUrl cannot be empty");d.baseUrl=R}if(o){let R=h(e.params.apiKey);if(!R)throw new Error("apiKey cannot be empty");d.apiKey=R}if(a){let R=be(Array.isArray(e.params.models)?e.params.models.filter(w=>typeof w=="string"):[]);if(R.length===0)throw new Error("models cannot be empty");d.models=R}if(i){let R=h(e.params.defaultModel);R?d.defaultModel=R:delete d.defaultModel}if(c){let R=h(e.params.anthropicDefaultOpusModel);if(!R)throw new Error("anthropicDefaultOpusModel cannot be empty");d.ANTHROPIC_DEFAULT_OPUS_MODEL=R}if(m){let R=h(e.params.anthropicDefaultSonnetModel);R?d.ANTHROPIC_DEFAULT_SONNET_MODEL=R:delete d.ANTHROPIC_DEFAULT_SONNET_MODEL}if(v){let R=h(e.params.anthropicDefaultHaikuModel);R?d.ANTHROPIC_DEFAULT_HAIKU_MODEL=R:delete d.ANTHROPIC_DEFAULT_HAIKU_MODEL}f[t]=d,Gt(e.providerFile,l);let k=typeof d.kind=="string"?d.kind:r?.kind??"openai-compatible",b=Array.isArray(d.models)?d.models.filter(R=>typeof R=="string"):r?.models??[];return e.providers[t]={kind:k,displayName:typeof d.displayName=="string"?d.displayName:r?.displayName??t,source:"provider-file",models:b,modelsDiscoveredBy:r?.modelsDiscoveredBy??(b.length>0?"provider-file":"api-probe"),...typeof d.baseUrl=="string"?{baseUrl:d.baseUrl}:{},configEditable:!0,...se(typeof d.apiKey=="string"?d.apiKey:void 0)?{apiKeyPreview:se(typeof d.apiKey=="string"?d.apiKey:void 0)}:{},...typeof d.defaultModel=="string"?{defaultModel:d.defaultModel}:{},...typeof d.ANTHROPIC_DEFAULT_OPUS_MODEL=="string"?{anthropicDefaultOpusModel:d.ANTHROPIC_DEFAULT_OPUS_MODEL}:{},...typeof d.ANTHROPIC_DEFAULT_SONNET_MODEL=="string"?{anthropicDefaultSonnetModel:d.ANTHROPIC_DEFAULT_SONNET_MODEL}:{},...typeof d.ANTHROPIC_DEFAULT_HAIKU_MODEL=="string"?{anthropicDefaultHaikuModel:d.ANTHROPIC_DEFAULT_HAIKU_MODEL}:{}},{ok:!0,providerName:t,...s?{kind:k}:{},apiKeyPreview:se(typeof d.apiKey=="string"?d.apiKey:void 0)??null,...a?{models:Array.isArray(d.models)?d.models:[]}:{},...i?{defaultModel:typeof d.defaultModel=="string"?d.defaultModel:null}:{},...v?{anthropicDefaultHaikuModel:typeof d.ANTHROPIC_DEFAULT_HAIKU_MODEL=="string"?d.ANTHROPIC_DEFAULT_HAIKU_MODEL:null}:{},...m?{anthropicDefaultSonnetModel:typeof d.ANTHROPIC_DEFAULT_SONNET_MODEL=="string"?d.ANTHROPIC_DEFAULT_SONNET_MODEL:null}:{},...c?{anthropicDefaultOpusModel:typeof d.ANTHROPIC_DEFAULT_OPUS_MODEL=="string"?d.ANTHROPIC_DEFAULT_OPUS_MODEL:null}:{},needsRestart:!0}}var Do=/api[-_]?key|secret|token|password|authorization|base[-_]?url|api[-_]?url/i,Oo=/(api[-_]?key|secret|token|password|authorization)\s*[:=]\s*([^\s,;]+)/gi;function Re(e,t=0){if(t>6)return"[redacted:depth]";if(Array.isArray(e))return e.map(n=>Re(n,t+1));if(!e||typeof e!="object")return typeof e=="string"&&e.length>1e3?`${e.slice(0,1e3)}...`:e;let r={};for(let[n,o]of Object.entries(e))r[n]=Do.test(n)?"[redacted]":Re(o,t+1);return r}function Uo(e){return(e instanceof Error?e.message:String(e)).replace(Oo,"$1=[redacted]").replace(/Bearer\s+[A-Za-z0-9._~+/=-]+/gi,"Bearer [redacted]").slice(0,1e3)}function Lo(e){if(["opus","sonnet","haiku"].includes(e.selectedModel))return e.selectedModel;let t=e.providerFile?.trim()?_e(e.providerFile)[e.providerName]:void 0,r=e.provider.anthropicDefaultOpusModel??t?.anthropicDefaultOpusModel,n=e.provider.anthropicDefaultSonnetModel??t?.anthropicDefaultSonnetModel,o=e.provider.anthropicDefaultHaikuModel??t?.anthropicDefaultHaikuModel;return e.selectedModel===n?"sonnet":e.selectedModel===o?"haiku":e.selectedModel===r||r?"opus":e.selectedModel}function Fo(e){return e.provider.kind==="claude-code"||e.provider.kind==="claude-compatible"?Lo(e):e.selectedModel}function Ut(e){return e==="default"||e==="none"||e==="minimal"||e==="low"||e==="medium"||e==="high"||e==="xhigh"||e==="max"?e:void 0}function Lt(e){return e==="default"||e==="disabled"||e==="adaptive"?e:void 0}function Ft(e){return e==="default"||e==="fast"||e==="flex"?e:void 0}function Ho(e){let t=$(e);if(t.type!=="agent_run.assigned")return null;let r=h(t.agentRunId),n=$(t.payload),o=$(n.runtimeSelection),s=h(n.workspaceId),a=h(n.agentId),i=h(n.agentSessionId),c=h(n.providerSessionId)||i,m=h(n.prompt),v=h(o.providerName),l=h(o.selectedModel);return!r||!s||!a||!i||!m||!v||!l?null:{type:"agent_run.assigned",agentRunId:r,payload:{workspaceId:s,agentId:a,agentSessionId:i,providerSessionId:c,channelId:h(n.channelId)||null,systemPrompt:h(n.systemPrompt)||null,prompt:m,repoAlias:h(n.repoAlias)||"default",workspaceCodeRepository:jt(n.workspaceCodeRepository),runtimeSelection:{providerName:v,selectedModel:l,...Ut(o.reasoningEffort)?{reasoningEffort:Ut(o.reasoningEffort)}:{},...Lt(o.thinkingMode)?{thinkingMode:Lt(o.thinkingMode)}:{},...Ft(o.serviceTier)?{serviceTier:Ft(o.serviceTier)}:{}}}}}function $o(e){switch(e.kind){case"claude-code":case"claude-compatible":return gt;case"codex":case"openai-compatible":return It;default:return async()=>{throw new Error(`unsupported node provider kind: ${e.kind}`)}}}function qo(e){return{type:"agent_run.rejected",agentRunId:e.agentRunId,payload:{reason:"capability_mismatch",providerName:e.payload.runtimeSelection.providerName,selectedModel:e.payload.runtimeSelection.selectedModel}}}function jo(e){return["<truesayer_workspace_context>",`Current channel worktree root: ${e.cwd}`,e.worktreePath?`Node-managed worktree path: ${e.worktreePath}`:null,e.workspaceCodeRepository?.path?`Workspace code repository: ${e.workspaceCodeRepository.path}`:null,"Treat the current channel as the active repository workspace. Unless the user explicitly says otherwise, repository modifications may span the whole worktree.","</truesayer_workspace_context>","",e.prompt].filter(r=>!!r).join(`
38
+ `)}async function Wo(e){let t=h(e.worktreePath);if(!t)return null;let r=h(e.baseSha);if(!r&&!h(e.branch))return null;try{let[n,o]=await Promise.all([Pe(t),Y(t,h(e.baseRef)||void 0).catch(()=>null)]);return{...e,headSha:n,dirty:o?o.files.length>0||o.hasStagedChanges:void 0,hasCommitsSinceBase:!!(r&&n&&r!==n)}}catch{return{...e,refreshFailed:!0}}}async function Go(e){let{providerName:t,selectedModel:r}=e.message.payload.runtimeSelection,n=e.message.payload.providerSessionId||e.message.payload.agentSessionId,o=new Q(e.truesayerNodeHome),s=e.providers[t];if(!s||!s.models.includes(r)){let T=qo(e.message);return await e.emitMessage?.(T),{messages:[T]}}let a=ot({truesayerNodeHome:e.truesayerNodeHome,workspaceId:e.message.payload.workspaceId,agentId:e.message.payload.agentId,agentSessionId:e.message.payload.agentSessionId,agentRunId:e.message.agentRunId,repoAlias:e.message.payload.repoAlias||"default"}),i=a.worktreeDir,c={cwd:i};if(e.message.payload.workspaceCodeRepository){let T=e.message.payload.workspaceCodeRepository,_=await Ie({path:T.path,baseRef:T.baseRef||"main"}),E=await Qe({actionId:e.message.agentRunId,baseBranch:_.baseRef,repoPath:_.repoRoot,worktreePath:a.worktreeDir});i=E.path,c.cwd=i,c.workspaceCodeRepository={path:_.path,baseRef:_.baseRef},c.worktreePath=E.path,c.branch=E.branch,c.baseSha=E.baseSha,c.baseRef=E.baseRef,c.headSha=await Pe(E.path)}else c.worktreePath=a.worktreeDir;let m=jo({prompt:e.message.payload.prompt,cwd:i,workspaceCodeRepository:e.message.payload.workspaceCodeRepository,worktreePath:h(c.worktreePath)}),v=[],l=async T=>{v.push(T),await e.emitMessage?.(T)},f=async T=>{let _=o.append({providerSessionId:n,agentRunId:e.message.agentRunId,providerName:t,raw:T});await l({type:"agent_run.event_batch",agentRunId:e.message.agentRunId,payload:{providerSessionId:n,providerName:t,rawEvents:[_]}})},y=1,d=0,k=!1,b=null,R=new Promise(T=>{b=T}),w=new AbortController,p=()=>{w.abort(e.abortSignal?.reason??new Error("Interrupted by user"))};e.abortSignal&&(e.abortSignal.aborted?p():e.abortSignal.addEventListener("abort",p,{once:!0}));let g=async(T,_)=>{y+=1,await l({type:"agent_run.event_batch",agentRunId:e.message.agentRunId,payload:{events:[{eventId:`${e.message.agentRunId}:event:${y}`,eventSeq:y,type:T,payload:_}]}})},A=e.invokeTool?async T=>{d+=1;let _=T.toolCallId||`${e.message.agentRunId}:tool:${d}`;await g("agent_run.tool.started",{toolCallId:_,toolName:T.toolName,status:"started",args:Re(T.args)});try{let E=await e.invokeTool({...T,toolCallId:_});await g("agent_run.tool.completed",{toolCallId:_,toolName:T.toolName,status:"completed",result:Re(E)});let O=$(T.args);if(T.toolName==="reply_to_channel"&&O.intent==="final"&&!k){k=!0;let j=h(O.body)||"Final reply delivered";b?.({output:j}),w.abort(new Error("Final reply delivered"))}return E}catch(E){throw await g("agent_run.tool.failed",{toolCallId:_,toolName:T.toolName,status:"failed",error:E instanceof Error?E.message:String(E)}),E}}:void 0;await l({type:"agent_run.accepted",agentRunId:e.message.agentRunId,payload:{agentId:e.message.payload.agentId,agentSessionId:e.message.payload.agentSessionId,providerSessionId:n,providerName:t,selectedModel:r}}),await l({type:"agent_run.event_batch",agentRunId:e.message.agentRunId,payload:{events:[{eventId:`${e.message.agentRunId}:workspace-prepared`,eventSeq:1,type:"agent_run.workspace_prepared",payload:{workspacePrepared:!0,fileToolRoot:"worktree",providerHomeExposedToFileTools:!1,...c}}]}});try{if(e.abortSignal?.aborted)throw new Error("Interrupted by user");let T=e.runProviderAgent??$o(s),_,E=!1,O=T({agentRunId:e.message.agentRunId,agentId:e.message.payload.agentId,agentSessionId:e.message.payload.agentSessionId,providerSessionId:n,prompt:m,provider:s,availableProviders:e.providers,providerName:t,selectedModel:Fo({providerFile:e.providerFile,providerName:t,provider:s,selectedModel:r}),reasoningEffort:e.message.payload.runtimeSelection.reasoningEffort,thinkingMode:e.message.payload.runtimeSelection.thinkingMode,serviceTier:e.message.payload.runtimeSelection.serviceTier,cwd:i,env:go({...a.providerEnv,...ho(e.providerFile,t)}),sessionStateDir:a.contextDir,systemPrompt:e.message.payload.systemPrompt??void 0,invokeTool:A,emitEvent:async B=>{await l({type:"agent_run.event_batch",agentRunId:e.message.agentRunId,payload:{events:[B]}})},emitRawEvent:f,abortSignal:w.signal}).then(B=>(E=!0,B));try{_=await Promise.race([O,R]),!E&&k&&O.catch(()=>{})}catch(B){let Be=B instanceof Error?B:void 0,rr=Be?.emittedEventIds??new Set,Je=(Be?.events??[]).filter(nr=>!rr.has(nr.eventId));throw Je.length&&await l({type:"agent_run.event_batch",agentRunId:e.message.agentRunId,payload:{events:Je}}),B}let j=oo(_);j.length&&await l({type:"agent_run.event_batch",agentRunId:e.message.agentRunId,payload:{events:j}});let de=await Wo(c);de&&await l({type:"agent_run.event_batch",agentRunId:e.message.agentRunId,payload:{events:[{eventId:`${e.message.agentRunId}:git-terminal-evidence`,eventSeq:1e6,type:"agent_run.git_terminal_evidence",payload:de}]}}),await g("agent_run.completed",{output:_.output,..._.inputTokens===void 0?{}:{inputTokens:_.inputTokens},..._.outputTokens===void 0?{}:{outputTokens:_.outputTokens}}),await l({type:"agent_run.completed",agentRunId:e.message.agentRunId,payload:{output:_.output,...de?{git:de}:{},..._.inputTokens===void 0?{}:{inputTokens:_.inputTokens},..._.outputTokens===void 0?{}:{outputTokens:_.outputTokens}}})}catch(T){let _=Uo(T);await g("agent_run.failed",{error:_}),await l({type:"agent_run.failed",agentRunId:e.message.agentRunId,payload:{error:_}})}return e.abortSignal?.removeEventListener("abort",p),{layout:a,messages:v}}function Bo(e){let t=new URL(e);return t.protocol=t.protocol==="https:"?"wss:":"ws:",t.pathname="/api/nodes/ws",t.search="",t.toString()}function Jo(){return $t.default}function Ht(e){e.readyState===1&&e.send(JSON.stringify({type:"node.heartbeat"}))}function We(e,t){if(e.readyState!==1)return!1;try{return e.send(JSON.stringify(t)),!0}catch{return!1}}function Ko(e){Ht(e);let t=setInterval(()=>{Ht(e)},no);return typeof t.unref=="function"&&t.unref(),()=>clearInterval(t)}async function Bt(e){let t=e.WebSocketImpl??Jo(),r=co(e.providerFile??fe(e.truesayerNodeHome)),n=await uo({providerFile:r,probeProviderModels:e.probeProviderModels}),o=po({...e,providerFile:r},n),s=new t(Bo(e.serverUrl),{headers:{Authorization:`Bearer ${e.apiKey}`}}),a=new Q(e.truesayerNodeHome),i=bo(s),c=new Set,m=new Map,v=()=>{for(let l of a.unackedBatches())We(s,{type:"agent_run.event_batch",agentRunId:l.agentRunId,payload:{providerSessionId:l.providerSessionId,providerName:l.providerName,rawEvents:l.events}})};await new Promise((l,f)=>{let y=!1,d=null,k=null;s.addEventListener("open",()=>{s.send(JSON.stringify(o))}),s.addEventListener("message",b=>{let R=typeof b.data=="string"?b.data:"";try{let w=JSON.parse(R);if(i.handleJsonRpcMessage(w))return;if(yo(w)){(async()=>{try{let g=await xo({truesayerNodeHome:e.truesayerNodeHome,providerFile:r,providers:n,request:w,runProviderAgent:e.runProviderAgent,emitMessage:A=>{s.send(JSON.stringify(A))}});s.send(ko(w.id,g))}catch(g){s.send(wo(w.id,g instanceof Error?g.message:String(g)))}})();return}if(w.type==="node.ready"){y=!0,d??=Ko(s),k??=(()=>{let g=setInterval(v,2e3);return typeof g.unref=="function"&&g.unref(),()=>clearInterval(g)})(),v();return}if(w.type==="agent_run.event_ack"){let g=$(w.payload),A=h(g.providerSessionId),T=typeof g.ackLine=="number"?g.ackLine:0;a.markAck(A,T);return}let p=Ho(w);if(p){if(c.has(p.agentRunId))return;c.add(p.agentRunId);let g=new AbortController;m.set(p.agentRunId,g),Go({truesayerNodeHome:e.truesayerNodeHome,providerFile:r,providers:n,message:p,invokeTool:i.invokeTool,runProviderAgent:e.runProviderAgent,abortSignal:g.signal,emitMessage:A=>{We(s,A)}}).catch(A=>{We(s,{type:"agent_run.failed",agentRunId:p.agentRunId,payload:{error:A instanceof Error?A.message:String(A)}})}).finally(()=>{m.delete(p.agentRunId)});return}if(w.type==="agent_run.cancel"){let g=h(w.agentRunId);m.get(g)?.abort(new Error("Interrupted by user"))}}catch{}}),s.addEventListener("error",b=>{d?.(),d=null,k?.(),k=null,f(new Error(`node ws error: ${String(b)}`))}),s.addEventListener("close",()=>{d?.(),d=null,k?.(),k=null,i.rejectPending(new Error("node websocket closed")),y?l():f(new Error("node ws closed before node.ready"))})})}var W=require("fs"),Jt=require("os"),Kt=require("path");var zt=["DATABASE_URL","APP_SECRET","ASSET_STORAGE_DRIVER","S3_ENDPOINT","S3_BUCKET","S3_ACCESS_KEY_ID","S3_SECRET_ACCESS_KEY","S3_REGION","S3_FORCE_PATH_STYLE"];function zo(e=process.env){return e.TRUESAYER_NODE_HOME?.trim()||(0,Kt.join)((0,Jt.homedir)(),".truesayer-node")}function Vt(e=process.env){let t=zt.filter(r=>e[r]?.trim());if(t.length>0)throw new Error(`Node \u8FDB\u7A0B\u5E26\u6709 Server-only \u73AF\u5883\u53D8\u91CF\uFF1A${t.join(", ")}\u3002\u8BF7\u4ECE Node runtime \u73AF\u5883\u4E2D\u79FB\u9664\u8FD9\u4E9B\u53D8\u91CF\u540E\u518D\u542F\u52A8\u3002`)}function K(e,t){return{name:e,status:"pass",message:t}}function Vo(e,t){return{name:e,status:"warn",message:t}}function H(e,t){return{name:e,status:"fail",message:t}}function Yo(e){let t=e.trim().match(/^v?(\d+)/);if(t)return Number.parseInt(t[1],10)}function Xo(e){let t=e.hostname.toLowerCase();return t==="localhost"||t==="127.0.0.1"||t==="::1"||t==="0.0.0.0"}function Zo(e){let t=Yo(e);return t?t<22?H("Node \u7248\u672C","\u5F53\u524D Node \u7248\u672C\u4E0D\u6EE1\u8DB3 runtime WebSocket \u8981\u6C42\u3002\u8BF7\u5347\u7EA7\u5230 Node 22 \u6216\u66F4\u65B0\u7248\u672C\u3002"):K("Node \u7248\u672C","Node \u7248\u672C\u6EE1\u8DB3 runtime WebSocket \u8981\u6C42\u3002"):H("Node \u7248\u672C","\u65E0\u6CD5\u8BC6\u522B\u5F53\u524D Node \u7248\u672C\u3002\u8BF7\u4F7F\u7528 Node 22 \u6216\u66F4\u65B0\u7248\u672C\u3002")}function Qo(e){if(!e?.trim())return H("Server URL","\u7F3A\u5C11 SERVER_URL \u6216 --server\u3002\u751F\u4EA7\u793A\u4F8B\u4F7F\u7528 https://truesayer.ai\u3002");let t;try{t=new URL(e)}catch{return H("Server URL","SERVER_URL \u4E0D\u662F\u5408\u6CD5 URL\u3002\u8BF7\u8BBE\u7F6E\u4E3A https://truesayer.ai \u6216\u672C\u5730\u5F00\u53D1\u5730\u5740\u3002")}return t.protocol==="https:"?K("Server URL","Server URL \u4F7F\u7528 HTTPS\u3002"):t.protocol==="http:"&&Xo(t)?K("Server URL","\u672C\u5730\u5F00\u53D1\u5730\u5740\u5141\u8BB8\u4F7F\u7528 HTTP\u3002"):H("Server URL","\u751F\u4EA7 Server URL \u5FC5\u987B\u4F7F\u7528 HTTPS\uFF1BHTTP \u53EA\u5141\u8BB8 localhost\u3001127.0.0.1\u3001::1 \u6216 0.0.0.0\u3002")}function es(e){return e?.trim()?K("Node API key","\u5DF2\u914D\u7F6E Node API key\u3002"):H("Node API key","\u7F3A\u5C11 NODE_API_KEY \u6216 --api-key\u3002\u8BF7\u4F7F\u7528 Server \u7B7E\u53D1\u7684 Node registration key\u3002")}function ts(e,t,r){let n=e?.trim()||zo(r);try{(0,W.mkdirSync)(n,{recursive:!0,mode:448}),t!=="win32"&&(0,W.chmodSync)(n,448);let o=(0,W.statSync)(n);return o.isDirectory()?t!=="win32"&&(o.mode&63)!==0?H("Node home","TRUESAYER_NODE_HOME \u6743\u9650\u8FC7\u5BBD\u3002\u8BF7\u6267\u884C chmod 700\u3002"):K("Node home","TRUESAYER_NODE_HOME \u53EF\u521B\u5EFA\u4E14\u6743\u9650\u5DF2\u6536\u655B\u3002"):H("Node home","TRUESAYER_NODE_HOME \u6307\u5411\u7684\u8DEF\u5F84\u4E0D\u662F\u76EE\u5F55\u3002\u8BF7\u6539\u6210 Node \u53EF\u5199\u76EE\u5F55\u3002")}catch{return H("Node home","TRUESAYER_NODE_HOME \u4E0D\u53EF\u521B\u5EFA\u6216\u4E0D\u53EF\u5199\u3002\u8BF7\u6539\u6210 Node \u8FDB\u7A0B\u53EF\u5199\u76EE\u5F55\u3002")}}function rs(e,t){try{let r=(0,W.statSync)(e);if(!r.isFile())return H("Provider file","<node-home>/provider.json \u6307\u5411\u7684\u8DEF\u5F84\u4E0D\u662F\u6587\u4EF6\u3002");if(t!=="win32"&&(r.mode&63)!==0)return H("Provider file","provider.json \u6743\u9650\u8FC7\u5BBD\u3002\u8BF7\u6267\u884C chmod 600\u3002");let n=JSON.parse((0,W.readFileSync)(e,"utf8"));return!n||typeof n!="object"||Array.isArray(n)?H("Provider file","provider.json \u5FC5\u987B\u662F\u5408\u6CD5 JSON object\u3002"):K("Provider file","provider.json \u662F\u5408\u6CD5 JSON\uFF0C\u4E14\u6743\u9650\u6EE1\u8DB3\u8981\u6C42\u3002")}catch(r){return r instanceof SyntaxError?H("Provider file","provider.json \u4E0D\u662F\u5408\u6CD5 JSON\u3002\u8BF7\u4FEE\u6B63 JSON \u8BED\u6CD5\u3002"):Vo("Provider file","\u672A\u627E\u5230 <node-home>/provider.json\uFF1B\u542F\u52A8\u65F6\u4F1A\u521B\u5EFA\u7A7A provider registry\uFF0C\u5F53\u524D\u53EA\u4F7F\u7528 native provider \u767B\u5F55\u6001\u3002")}}function ns(e){let t=zt.filter(r=>e[r]?.trim());return t.length===0?K("Server-only env","\u672A\u53D1\u73B0 Server-only \u73AF\u5883\u53D8\u91CF\u3002"):H("Server-only env",`Node runtime \u4E0D\u5E94\u643A\u5E26\u8FD9\u4E9B Server-only \u73AF\u5883\u53D8\u91CF\uFF1A${t.join(", ")}\u3002\u8BF7\u4ECE\u542F\u52A8\u73AF\u5883\u4E2D\u79FB\u9664\u3002`)}function Yt(e={}){let t=e.env??process.env,r=e.platform??process.platform,n=e.truesayerNodeHome??t.TRUESAYER_NODE_HOME,o=e.providerFile??fe(n),s=[Zo(e.nodeVersion??process.versions.node),Qo(e.serverUrl??t.SERVER_URL),es(e.apiKey??t.NODE_API_KEY),ts(n,r,t),rs(o,r),ns(t)];return{ok:s.every(a=>a.status!=="fail"),checks:s}}function Xt(e){let t={pass:"\u901A\u8FC7",warn:"\u8B66\u544A",fail:"\u5931\u8D25"};return["truesayer-node doctor",...e.checks.map(n=>`[${t[n.status]}] ${n.name}\uFF1A${n.message}`),e.ok?"\u7ED3\u679C\uFF1A\u57FA\u7840\u68C0\u67E5\u901A\u8FC7\uFF0C\u53EF\u4EE5\u542F\u52A8 truesayer-node\u3002":"\u7ED3\u679C\uFF1A\u57FA\u7840\u68C0\u67E5\u5931\u8D25\u3002\u8BF7\u4FEE\u590D\u5931\u8D25\u9879\u540E\u518D\u542F\u52A8 truesayer-node\u3002"].join(`
39
+ `)}function Te(e){let t=`${e}=`,r=process.argv.find(o=>o.startsWith(t));if(r)return r.slice(t.length);let n=process.argv.indexOf(e);if(n>=0)return process.argv[n+1]}function os(...e){return process.argv.some(t=>e.includes(t))}function ss(){let e=Number(process.versions.node.split(".")[0]);if(!Number.isFinite(e)||e<22)throw new Error(`truesayer-node requires Node.js >=22. Current: ${process.version}`)}function Zt(){return"Usage: truesayer-node --server <url> --api-key <key> [--node-name <name>] [--node-home <path>]"}function Qt(){if(process.env.npm_package_version)return process.env.npm_package_version;try{let e=JSON.parse((0,er.readFileSync)((0,tr.join)(__dirname,"..","package.json"),"utf8"));return typeof e.version=="string"&&e.version.trim()?e.version:"0.1.0"}catch{return"0.1.0"}}async function is(){let e=process.argv[2];if(os("--version","-v")){console.log(Qt());return}let t=Te("--server")??process.env.SERVER_URL,r=Te("--api-key")??process.env.NODE_API_KEY,n=Te("--node-name")??process.env.NODE_NAME??"truesayer-node",o=Te("--node-home")??process.env.TRUESAYER_NODE_HOME;if(e==="doctor"){let s=Yt({serverUrl:t,apiKey:r,truesayerNodeHome:o,nodeVersion:process.version});console.log(Xt(s)),process.exit(s.ok?0:1)}if(ss(),Vt(),!t)throw new Error(`--server or SERVER_URL is required
40
+ ${Zt()}`);if(!r)throw new Error(`--api-key or NODE_API_KEY is required
41
+ ${Zt()}`);for(;;){try{await Bt({serverUrl:t,apiKey:r,nodeName:n,nodeVersion:Qt(),truesayerNodeHome:o})}catch(s){console.error("[node] connection failed:",s instanceof Error?s.message:String(s))}await new Promise(s=>setTimeout(s,2e3))}}is().catch(e=>{console.error("[node] Fatal:",e instanceof Error?e.message:String(e)),process.exit(1)});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@truesayer/node",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "private": false,
5
5
  "description": "Truesayer local Node runtime CLI",
6
6
  "license": "UNLICENSED",