@hunsu/bridge 0.2.0-next.5 → 0.2.0-next.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -32,7 +32,7 @@ For advanced local package verification only, run setup from an absolute
32
32
  tarball path:
33
33
 
34
34
  ```sh
35
- hunsu-bridge setup --runtime-package /absolute/path/hunsu-bridge-0.2.0-next.5.tgz
35
+ hunsu-bridge setup --runtime-package /absolute/path/hunsu-bridge-0.2.0-next.6.tgz
36
36
  ```
37
37
 
38
38
  This option rejects URLs, dist-tags, ranges, Git specs, relative paths, and
package/dist/cli.js CHANGED
@@ -201,7 +201,7 @@ ${n}
201
201
  `),s=n.slice(i+2).trim();if(o[0]!==r)return Bn(`Invalid Hunsu runtime header in ${e}`);let a=new Map(o.slice(1).map(l=>{let f=l.indexOf(":");return f===-1?[l.trim(),""]:[l.slice(0,f).trim(),l.slice(f+1).trim()]}));if(a.get("encoding")!==C8)return Bn(`Unsupported Hunsu runtime encoding in ${e}: ${a.get("encoding")??"missing"}`);let c=a.get("checksum")?.replace(/^sha256:/,"");if(!c)return Bn(`Missing Hunsu runtime checksum in ${e}`);let u;try{u=uie(Buffer.from(s,"base64url")).toString("utf8")}catch(l){return Bn(`Invalid Hunsu runtime payload in ${e}: ${l instanceof Error?l.message:String(l)}`)}let d=wg(u);if(d!==c)return Bn(`Hunsu runtime checksum mismatch in ${e}`);try{return S({value:JSON.parse(u),checksum:Kf(d)})}catch(l){return Bn(`Invalid Hunsu runtime JSON in ${e}: ${l instanceof Error?l.message:String(l)}`)}}function jie(t){let e=jt(t),r=cu(e,W1);if(!yg(r))return;let n=bg(H8(G1(r,"utf8"),r));return{state:n,checksum:U8(n)}}function qie(t,e){let r=jt(t);try{let n=ke(["show",`${e}:${W1}`],{cwd:r}),i=bg(H8(n,`${e}:${W1}`));return{state:i,checksum:U8(i)}}catch(n){if(n instanceof Tr)return;throw n}}function H8(t,e){let r=ib(t,e,pie);if(!r.ok)return r;let n=r.value.value;if(!n||typeof n!="object")return Bn(`Invalid legacy Hunsu runtime state JSON in ${e}: expected object`);let i=n;if(i.version!==1||!Array.isArray(i.events))return Bn(`Invalid legacy Hunsu runtime state in ${e}`);let o=[];for(let[s,a]of i.events.entries()){let c=VS(a);if(!c.ok)return Bn(`Invalid legacy Hunsu runtime state event ${s} in ${e}: ${c.error.message}`);o.push(c.value)}return S({version:1,events:o,...typeof i.updatedAt=="string"?{updatedAt:i.updatedAt}:{}})}function U8(t){return Kf(wg(`${JSON.stringify(t)}
202
202
  `))}function Bn(t){return oe({type:"DomainStoreError",message:t})}function gg(t,e,r){let n=cu(t,e,r);try{return S(JSON.parse(G1(n,"utf8")))}catch(i){return Bn(`Cannot read ${e}/${r}: ${i instanceof Error?i.message:String(i)}`)}}function Gd(t){return JSON.parse(JSON.stringify(t))}function YS(t){return JSON.stringify(V1(t))}function V1(t){return Array.isArray(t)?t.map(V1):t&&typeof t=="object"?Object.fromEntries(Object.entries(t).sort(([e],[r])=>e.localeCompare(r)).map(([e,r])=>[e,V1(r)])):t}function bg(t){if(t.ok)return t.value;throw new Error(t.error.message)}function Wie(t){try{return Kr(ke(["rev-parse","--verify","HEAD^{commit}"],{cwd:t}).trim())}catch(e){if(e instanceof Tr)return;throw e}}function Vie(t){return t instanceof Error?"code"in t&&t.code==="ENOENT":!1}function wg(t){return aie("sha256").update(t).digest("hex")}function Gie(t){let[e,r,n]=t.split(gie);return{ref:e,object:r,objectType:n,ordinal:zie(e)}}function zie(t){let r=t.slice(t.lastIndexOf("/")+1).match(/^E(\d+)(?:-|$)/);return r?Number.parseInt(r[1],10):Number.MAX_SAFE_INTEGER}import{existsSync as Os,readFileSync as j8,readdirSync as Kie,statSync as Jie,writeFileSync as Xie}from"node:fs";import{basename as Yie,join as Ua,resolve as Qie}from"node:path";var Zie="Port Git Project",eoe="Make this project ready for Hunsu-managed MOVEs and Artifact Actions.";function oA(t=process.cwd()){let e=Qie(t),r=[],n=e,i=!1;try{n=jt(e),i=!0}catch{r.push("Not a Git repository. Hunsu Port expects an existing Git project.")}let o=noe(n),s=o?.scripts??{},a=roe(n,o),c=$8(n,/^Dockerfile(?:\.|$)/),u=$8(n,/^(?:docker-)?compose(?:\.[^.]+)?\.ya?ml$/),d=i&&q8(n),l=toe(n),f=ioe(n,s),p=[];return!o&&i&&r.push("No package.json found. Port can still create Roadmap state, but Artifact Actions may need a later Hunsu setup."),i&&!d&&r.push("Hunsu runtime state is missing. Port apply will create Initial Team state."),{root:n,isGitRepository:i,isHunsuRoadmap:d,packageManager:a,packageScripts:s,docker:{dockerfiles:c,composeFiles:u},artifactActions:l,env:f,recommendedFiles:p,issues:r}}function sA(t={}){let e=oA(t.cwd);if(!e.isGitRepository)throw new Error("Hunsu Port requires an existing Git repository");let r=t.title?.trim()||Yie(e.root)||Zie,n=t.goal?.trim()||eoe,i=t.destinations&&t.destinations.length>0?t.destinations:[{id:"destination_001",title:"Establish artifact-action-ready product execution",priority:100}],o=e.isHunsuRoadmap?[]:[{type:"CreateInitialTeam",requestId:F8("req",r),lineId:`run/${F8("req",r)}`,title:r,goal:n,destinations:i,harness:t.harness}];return{root:e.root,title:r,goal:n,destinations:i,inspection:e,files:[],commands:o}}function aA(t={}){let e=sA(t),r=[];for(let i of e.files){let o=Ua(e.root,i.path);Os(o)||(Xie(o,i.content,"utf8"),r.push(i.path))}let n=e.commands.length>0?xg(e.commands,{cwd:e.root,commitMessage:`hunsu: port ${e.title}`}):{acceptedEvents:[],board:Dn(e.root).board};return{root:e.root,plan:e,writtenFiles:r,acceptedEvents:n.acceptedEvents,board:n.board}}function toe(t){if(!q8(t))return{configured:!1,count:0,issues:[]};let e=Dn(t).board;return{configured:e.artifactActions.length>0,count:e.artifactActions.length,issues:[]}}function roe(t,e){if(Os(Ua(t,"pnpm-lock.yaml"))||e?.packageManager?.startsWith("pnpm@"))return"pnpm";if(Os(Ua(t,"yarn.lock"))||e?.packageManager?.startsWith("yarn@"))return"yarn";if(Os(Ua(t,"bun.lockb"))||Os(Ua(t,"bun.lock"))||e?.packageManager?.startsWith("bun@"))return"bun";if(Os(Ua(t,"package-lock.json"))||e)return"npm"}function noe(t){let e=Ua(t,"package.json");if(Os(e))return JSON.parse(j8(e,"utf8"))}function $8(t,e){return!Os(t)||!Jie(t).isDirectory()?[]:Kie(t).filter(r=>e.test(r)).sort()}function q8(t){try{return Sg(t)||tA(t).length>0||ke(["for-each-ref","--count=1","--format=%(refname)","refs/hunsu"],{cwd:t}).trim().length>0}catch(e){if(e instanceof Tr)return!1;throw e}}function ioe(t,e){let r=[".env",".env.local",".env.development",".env.example"].filter(i=>Os(Ua(t,i))),n=Object.entries(e).filter(([,i])=>/\b(?:3000|5173|8080|4187)\b|localhost|127\.0\.0\.1/.test(i)).map(([i])=>`package.json scripts.${i}`);for(let i of["vite.config.ts","vite.config.js","next.config.js","next.config.mjs"]){let o=Ua(t,i);if(!Os(o))continue;let s=j8(o,"utf8");/\b(?:3000|5173|8080|4187)\b|localhost|127\.0\.0\.1/.test(s)&&n.push(i)}return{files:r,hardcodedHints:n}}function F8(t,e){let r=e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"").slice(0,48);return`${t}_${r||"project"}`}import{createHash as ooe}from"node:crypto";import{spawnSync as soe}from"node:child_process";import{existsSync as cb,mkdirSync as W8,readFileSync as aoe,readdirSync as coe,rmSync as V8,writeFileSync as uoe}from"node:fs";import{tmpdir as doe}from"node:os";import{basename as loe,join as ob,resolve as dA}from"node:path";function G8(t=process.cwd(),e){let r=jt(t),n=Dn(r);if(e){let i=n.board.moves.find(s=>s.id===e);if(!i)throw new Error(`No MOVE found for Artifact Action source: ${e}`);let o=n.board.nodes.find(s=>s.id===i.toNodeId);return ab(i.snapshot?.artifactActions??o?.artifactActions??[])}return ab(n.board.artifactActions)}function lA(t){let e=jt(t.cwd??process.cwd()),r=foe(e,t),n=r.actions.find(d=>d.id===t.actionId);if(!n)throw new Error(`Unknown Artifact Action for selected source: ${t.actionId}`);poe(n,r.source);let i=t.now??new Date().toISOString(),o=xoe(n.id,r.source,i),s=t.baseActionPath??voe(t.roadmapId,o),a=n.kind==="host"?hoe(n,s):void 0,c=fA(n,t.env,t.ambientEnv),u={runId:o,actionId:n.id,roadmapId:t.roadmapId,action:uA(n),source:r.source,status:"queued",env:moe(n,c),aliases:a,createdAt:i,updatedAt:i};return{action:uA(n),run:u,commands:X8(e,n,u,c)}}function z8(t,e={}){let r=jt(t.cwd??process.cwd()),n=lA(t),i=t.now??new Date().toISOString(),o=yoe(r,n.run.runId,n.run.source.commit,i,t.worktreeRoot),s=t.processEnv??e.processEnv,a=e.runner??((l,f,p)=>r5(l,f,{...p,processEnv:s})),c={...n.run,status:(n.action.kind==="host","running"),sourceWorktree:o,updatedAt:i},u=fA(n.action,t.env,t.ambientEnv),d=X8(r,n.action,c,u);try{if(n.action.runner.type==="docker_compose")Ig(a,d[0]),Ig(a,d[1]),c.aliases=goe(r,c,a,u),c.status="running";else{let l=Ig(a,d[0]);if(c.exitCode=l.status,c.stdout=l.stdout,c.stderr=l.stderr,c.status=n.action.kind==="host"?"running":"succeeded",n.action.kind==="check"){let f=sb(r,o.path);c.sourceWorktree={...o,removedAt:f}}}c.updatedAt=new Date().toISOString()}catch(l){c.status="failed",c.updatedAt=new Date().toISOString(),c.error=l instanceof Error?l.message:String(l);let f=sb(r,o.path);c.sourceWorktree={...o,removedAt:f}}if(e.store!==!1&&Q8(r,c),c.status==="failed")throw new Error(c.error??`Artifact Action ${c.runId} failed`);return c}function K8(t=process.cwd()){let e=jt(t),r=pA(e);return cb(r)?coe(r).filter(n=>n.endsWith(".json")).map(n=>Eg(e,n.slice(0,-5))).sort((n,i)=>i.updatedAt.localeCompare(n.updatedAt)):[]}function Eg(t,e){let r=jt(t),n=Z8(r,e);if(!cb(n))throw new Error(`Unknown Artifact Action Run: ${e}`);return JSON.parse(aoe(n,"utf8"))}function J8(t,e,r={}){let n=jt(t),i=Eg(n,e),o=r.runner??((u,d,l)=>r5(u,d,{...l,processEnv:r.processEnv})),s=fA(i.action,i.env,r.processEnv);i.action.runner.type==="docker_compose"?Ig(o,cA(n,i,["down"],s)):i.action.runner.stopCommand&&Ig(o,Y8(n,i,i.action.runner.stopCommand,s));let a=i.sourceWorktree?.path?sb(n,i.sourceWorktree.path):void 0,c={...i,sourceWorktree:i.sourceWorktree?{...i.sourceWorktree,removedAt:a}:void 0,status:"stopped",stoppedAt:new Date().toISOString(),updatedAt:new Date().toISOString()};return r.store!==!1&&Q8(n,c),c}function foe(t,e){if(e.moveId&&e.commit)throw new Error("Artifact Action source accepts either moveId or commit, not both");let r=Dn(t);if(e.moveId){let i=r.board.moves.find(s=>s.id===e.moveId);if(!i)throw new Error(`No MOVE found for Artifact Action source: ${e.moveId}`);let o=r.board.nodes.find(s=>s.id===i.toNodeId);return{source:{moveId:i.id,commit:ke(["rev-parse","--verify",`${i.commit}^{commit}`],{cwd:t}).trim(),ref:i.commit},actions:ab(i.snapshot?.artifactActions??o?.artifactActions??[])}}let n=e.commit??"HEAD";return{source:{commit:ke(["rev-parse","--verify",`${n}^{commit}`],{cwd:t}).trim(),ref:n},actions:ab(r.board.artifactActions)}}function poe(t,e){if(t.sourceScope==="move"&&!e.moveId)throw new Error(`Artifact Action ${t.id} can only run against a MOVE source`);if(t.sourceScope==="commit"&&e.moveId)throw new Error(`Artifact Action ${t.id} can only run against a commit source`)}function fA(t,e={},r={}){let n={},i=new Set;for(let[o,s]of Object.entries(t.env??{}))if(i.add(o),"default"in s)n[o]=e[o]??String(s.default);else if("value"in s)n[o]=e[o]??String(s.value);else if("alias"in s){let a=t.aliases?.[s.alias];if(!a)throw new Error(`Artifact Action env ${o} references unknown alias: ${s.alias}`);n[o]=String(a.containerPort??a.target??"")}else if("fromAliasUrl"in s){let a=t.aliases?.[s.fromAliasUrl];if(!a)throw new Error(`Artifact Action env ${o} references unknown alias: ${s.fromAliasUrl}`);n[o]=a.service&&a.containerPort?`http://${a.service}:${a.containerPort}`:String(a.target??"")}else if(s.required){let a=e[o]??r[o];if(!a)throw new Error(`Artifact Action env ${o} is required but not set`);n[o]=a}for(let[o,s]of Object.entries(e))i.has(o)||(n[o]=s);return n}function moe(t,e){let r={};for(let[n,i]of Object.entries(e)){let o=t.env?.[n];r[n]=o&&"required"in o&&o.secret?"<secret>":i}return r}function X8(t,e,r,n){return e.runner.type==="docker_compose"?[cA(t,r,["build"],n),cA(t,r,["up","-d"],n)]:[Y8(t,r,e.runner.command,n)]}function cA(t,e,r,n){if(e.action.runner.type!=="docker_compose")throw new Error(`Artifact Action ${e.actionId} does not use docker compose`);let i=e.source.commit.slice(0,12),o=e5(t5(e.action.runner.projectName??`hunsu-${e.actionId}-${i}`,{actionId:e.actionId,runId:e.runId,commit:e.source.commit,shortCommit:i,moveId:e.source.moveId??""}));return{command:"docker",args:["compose","-f",dA(e.sourceWorktree?.path??t,e.action.runner.file),"-p",o,...r],cwd:e.sourceWorktree?.path??t,env:n}}function Y8(t,e,r,n){return{command:"sh",args:["-lc",r],cwd:e.sourceWorktree?.path??t,env:n}}function Ig(t,e){let r=t(e.command,e.args,{cwd:e.cwd,env:e.env});if(r.status!==0)throw new Error(`${e.command} ${e.args.join(" ")} failed
203
203
  ${r.stderr||r.stdout}`);return r}function hoe(t,e){if(t.aliases)return Object.fromEntries(Object.entries(t.aliases).map(([r,n])=>[r,{alias:r,service:n.service,containerPort:n.containerPort,healthPath:n.healthPath,target:n.target,internalUrl:n.service&&n.containerPort?`http://${n.service}:${n.containerPort}`:n.target,externalPath:`${e}/${encodeURIComponent(r)}/`}]))}function goe(t,e,r,n){if(!e.aliases||e.action.runner.type!=="docker_compose")return e.aliases;let i=e.action.runner;return Object.fromEntries(Object.entries(e.aliases).map(([o,s])=>{if(!s.service||!s.containerPort)return[o,s];let a=r("docker",["compose","-f",dA(e.sourceWorktree?.path??t,i.file),"-p",e5(t5(i.projectName??`hunsu-${e.actionId}-${e.source.commit.slice(0,12)}`,{actionId:e.actionId,runId:e.runId,commit:e.source.commit,shortCommit:e.source.commit.slice(0,12),moveId:e.source.moveId??""})),"port",s.service,String(s.containerPort)],{cwd:e.sourceWorktree?.path??t,env:n});return a.status!==0||!a.stdout.trim()?[o,s]:[o,{...s,directUrl:boe(a.stdout.trim())}]}))}function yoe(t,e,r,n,i){let o=dA(i??ob(doe(),"hunsu-action-runs",`${loe(t)}-${Soe(t)}`)),s=ob(o,mA(e));return W8(o,{recursive:!0}),cb(s)&&(sb(t,s),V8(s,{recursive:!0,force:!0})),ke(["worktree","add","--detach",s,r],{cwd:t}),{path:s,commit:r,createdAt:n}}function sb(t,e){let r=new Date().toISOString();if(!cb(e))return r;try{ke(["worktree","remove","--force",e],{cwd:t})}catch{V8(e,{recursive:!0,force:!0}),ke(["worktree","prune"],{cwd:t})}return r}function Q8(t,e){W8(pA(t),{recursive:!0}),uoe(Z8(t,e.runId),`${JSON.stringify(e,null,2)}
204
- `,"utf8")}function pA(t){return ob(t,".hunsu","action-runs")}function Z8(t,e){return ob(pA(t),`${mA(e)}.json`)}function voe(t,e){return t?`/api/roadmaps/${encodeURIComponent(t)}/action-runs/${encodeURIComponent(e)}/proxy`:`/api/action-runs/${encodeURIComponent(e)}/proxy`}function xoe(t,e,r){return mA(`${t}-${e.moveId??e.commit.slice(0,12)}-${r.replace(/[^0-9A-Za-z]/g,"").slice(0,14)}`)}function mA(t){return t.toLowerCase().replace(/[^a-z0-9_.-]+/g,"-").replace(/^-+|-+$/g,"")||"action-run"}function e5(t){return t.toLowerCase().replace(/[^a-z0-9_-]+/g,"-").replace(/^-+|-+$/g,"").slice(0,63)||"hunsu-action"}function t5(t,e){return t.replace(/\{([a-zA-Z][a-zA-Z0-9]*)\}/g,(r,n)=>e[n]??"")}function Soe(t){return ooe("sha256").update(t).digest("hex").slice(0,12)}function boe(t){let e=t.split(/\r?\n/).find(Boolean)??t,r=e.match(/(?:0\.0\.0\.0|127\.0\.0\.1|localhost|\[::\]|::):(\d+)$/);return r?`http://127.0.0.1:${r[1]}`:/^https?:\/\//.test(e)?e:`http://${e}`}function r5(t,e,r){let n=soe(t,e,{cwd:r.cwd,env:{...woe(r.processEnv),...r.env},encoding:"utf8",maxBuffer:16777216});return{status:n.status??1,stdout:n.stdout,stderr:n.stderr}}function woe(t){if(t===void 0)return;let e={};for(let[r,n]of Object.entries(t))n!==void 0&&(e[r]=n);return e}function ab(t){return t.map(uA).sort((e,r)=>e.displayOrder-r.displayOrder||String(e.id).localeCompare(String(r.id)))}function uA(t){return{...t,env:t.env?Object.fromEntries(Object.entries(t.env).map(([e,r])=>[e,{...r}])):void 0,runner:{...t.runner},aliases:t.aliases?Object.fromEntries(Object.entries(t.aliases).map(([e,r])=>[e,{...r}])):void 0,evidence:t.evidence?{...t.evidence,paths:t.evidence.paths?.slice()}:void 0}}import{createHash as Ioe}from"node:crypto";var Eoe="hunsu.hub-package-manifest.v1",n5="hunsu-json-c14n-v1+sha256:";function koe(t){vA(t);let{integrity:e,...r}=t;return JSON.stringify(yA(r,"manifest"))}function Roe(t){let e=koe(t);return`${n5}${Ioe("sha256").update(e,"utf8").digest("hex")}`}async function kg(t,e){if(!t.integrity.startsWith(n5))throw new Error(`Unsupported Hub package integrity prefix: ${t.integrity}`);let r=e.origins.find(a=>a.name===t.origin);if(!r)throw new Error(`Unknown Origin: ${t.origin}`);if(r.transport!=="http")throw new Error(`Origin ${r.name} uses unsupported transport ${r.transport}`);let i=await(e.fetch??fetch)(Aoe(r.url,t.kind,t.key,t.version));if(!i.ok)throw i.status===404?new Error(`Missing Hub package manifest: ${t.origin}/${t.kind}/${t.key}@${t.version}`):new Error(`Origin ${r.name} returned ${i.status} for ${t.kind}/${t.key}@${t.version}`);let o=await i.json();if(vA(o),o.kind!==t.kind||o.key!==t.key||o.version!==t.version)throw new Error(`Hub package manifest from ${r.name} does not match requested ${t.kind}/${t.key}@${t.version}`);let s=Roe(o);if(s!==t.integrity)throw new Error(`Hub package integrity mismatch for ${t.origin}/${t.kind}/${t.key}@${t.version}: expected ${t.integrity}, got ${s}`);return{lock:{...t},manifest:o,integrity:s,origin:{...r}}}function Aoe(t,e,r,n){let i=new URL(t),o=`/v1/packages/${e}/${encodeURIComponent(r)}/versions/${encodeURIComponent(n)}`;return new URL(o,i).toString()}function i5(t){if(vA(t),t.kind!=="team")throw new Error(`Hub package ${t.kind}/${t.key}@${t.version} is not a team package`);return Doe(t.team)}function vA(t){let e=hA(t,"manifest");if(e.schema!==Eoe)throw new Error(`Unsupported Hub package manifest schema: ${String(e.schema)}`);gA(e,["integrity","key","kind","team","member","manager","schema","skill","version"],"manifest");let r=Boe(e.kind,"manifest.kind");switch(Yf(e.key,"manifest.key"),Yf(e.version,"manifest.version"),e.integrity!==void 0&&Yf(e.integrity,"manifest.integrity"),r){case"team":if(Coe(e.team),e.member!==void 0||e.manager!==void 0||e.skill!==void 0)throw new Error("Team package manifest must not include member, manager, or skill payloads");return;case"member":if(Poe(e.member),e.team!==void 0||e.manager!==void 0||e.skill!==void 0)throw new Error("Member package manifest must not include team, manager, or skill payloads");return;case"manager":if(_oe(e.manager),e.team!==void 0||e.member!==void 0||e.skill!==void 0)throw new Error("Manager package manifest must not include team, member, or skill payloads");return;case"skill":if(Toe(e.skill),e.team!==void 0||e.member!==void 0||e.manager!==void 0)throw new Error("Skill package manifest must not include team, member, or manager payloads");return}}function Coe(t){let e=Fd(t,"manifest.team");if(!e.ok)throw new Error(`Invalid manifest.team: ${e.error.message}`)}function Poe(t){let e=JR(t,"manifest.member");if(!e.ok)throw new Error(`Invalid manifest.member: ${e.error.message}`)}function _oe(t){let e=zh(t,"manifest.manager");if(!e.ok)throw new Error(`Invalid manifest.manager: ${e.error.message}`)}function Toe(t){let e=hA(t,"manifest.skill");if(gA(e,["contentHash","files","name"],"manifest.skill"),Yf(e.name,"manifest.skill.name"),Yf(e.contentHash,"manifest.skill.contentHash"),e.files!==void 0){if(!Array.isArray(e.files))throw new Error("manifest.skill.files must be an array");for(let[r,n]of e.files.entries()){let i=hA(n,`manifest.skill.files[${r}]`);gA(i,["path","text"],`manifest.skill.files[${r}]`),Yf(i.path,`manifest.skill.files[${r}].path`),o5(i.text,`manifest.skill.files[${r}].text`)}}}function Boe(t,e){if(t==="team"||t==="member"||t==="manager"||t==="skill")return t;throw new Error(`${e} must be team, member, manager, or skill`)}function hA(t,e){if(typeof t!="object"||t===null||Array.isArray(t))throw new Error(`${e} must be an object`);return t}function gA(t,e,r){let n=e.filter(o=>o!=="integrity"&&o!=="team"&&o!=="member"&&o!=="manager"&&o!=="skill"&&o!=="files"&&!(o in t));if(n.length>0)throw new Error(`${r} is missing required keys: ${n.join(", ")}`);let i=Object.keys(t).filter(o=>!e.includes(o));if(i.length>0)throw new Error(`${r} has unsupported keys: ${i.join(", ")}`)}function o5(t,e){if(typeof t!="string")throw new Error(`${e} must be a string`);return t}function Yf(t,e){let r=o5(t,e);if(r.trim().length===0)throw new Error(`${e} must be non-empty`);return r}function yA(t,e){if(t===null||typeof t=="string"||typeof t=="boolean")return t;if(typeof t=="number"){if(!Number.isFinite(t))throw new Error(`${e} must be a finite number`);return t}if(Array.isArray(t))return t.map((r,n)=>{if(r===void 0)throw new Error(`${e}[${n}] must not be undefined`);return yA(r,`${e}[${n}]`)});if(typeof t=="object"&&t!==null){let r=t,n={};for(let i of Object.keys(r).sort()){let o=r[i];o!==void 0&&(n[i]=yA(o,`${e}.${i}`))}return n}throw new Error(`${e} must be JSON-serializable`)}function Doe(t){return JSON.parse(JSON.stringify(t))}function wt(t,e,r){return r===void 0?{code:t,message:e}:{code:t,message:e,details:r}}function Rg(t){let e=new Error(t.message);return e.name=`ExecuteOrchestrationError:${t.code}`,t.details!==void 0&&(e.details=t.details),e}function zd(t){if(t.ok)return t.value;throw Rg(t.error)}function SA(t){let e=h5(t,"Team planning final response must be a JSON ExecutionPlan object");return e.ok?wA(e.value,"execution"):e}function a5(t){let e=h5(t,"Goal evaluator final response must be a JSON object");if(!e.ok)return e;let r=e.value;if(r.type==="pass"){if(typeof r.summary!="string"||r.summary.trim()==="")return oe(wt("goal_evaluation_invalid","pass evaluation must include a non-empty summary"));let n=xA(r.evidence,"evidence");return n.ok?S({type:"pass",summary:r.summary,evidence:n.value}):n}if(r.type==="fail"){if(typeof r.reason!="string"||r.reason.trim()==="")return oe(wt("goal_evaluation_invalid","fail evaluation must include a non-empty reason"));if(typeof r.feedback!="string"||r.feedback.trim()==="")return oe(wt("goal_evaluation_invalid","fail evaluation must include non-empty feedback"));if(r.nextGoal!==void 0&&typeof r.nextGoal!="string")return oe(wt("goal_evaluation_invalid","fail evaluation nextGoal must be a string when present"));let n=xA(r.evidence,"evidence");return n.ok?S({type:"fail",reason:r.reason,feedback:r.feedback,nextGoal:typeof r.nextGoal=="string"&&r.nextGoal.trim()!==""?r.nextGoal:void 0,evidence:n.value}):n}return oe(wt("goal_evaluation_invalid","Goal evaluator response type must be pass or fail"))}function bA(t,e,r,n){if(e==="assignee")return{id:r,executorId:t.assignee.executorId,goal:t.assignee.goal,requires:n};let i=t.evaluator;if(!i)throw new Error(`Goal ${t.id} does not define an evaluator`);return{id:r,executorId:i.executorId,goal:i.prompt,requires:n}}function c5(t,e){let[,...r]=t.items;if(e)return{...t,items:[e,...r]};if(r.length!==0)return{...t,items:r}}function wA(t,e){return Ag(t)?t.kind==="queue"?Noe(t,e):t.kind==="goal"?u5(t,e):t.kind==="continuation"?Ooe(t,e):oe(wt("execution_plan_invalid",`${e}.kind must be queue, goal, or continuation`)):oe(wt("execution_plan_invalid",`${e} must be an object`))}function Noe(t,e){let r=l5(t.id,`${e}.id`);if(!r.ok)return r;if(!Array.isArray(t.items))return oe(wt("execution_plan_invalid",`${e}.items must be an array`));let n=[];for(let[i,o]of t.items.entries()){let s=wA(o,`${e}.items[${i}]`);if(!s.ok)return s;n.push(s.value)}return S({kind:"queue",id:r.value,items:n})}function u5(t,e){return t.stage==="needs_evaluation"?d5(t,e):t.stage==="needs_execution"?Moe(t,e):oe(wt("execution_plan_invalid",`${e}.stage must be needs_evaluation or needs_execution`))}function Ooe(t,e){let r=IA(t.id,`${e}.id`);if(!r.ok)return r;let n=f5(t.teamScopeId,`${e}.teamScopeId`);if(!n.ok)return n;let i=wA(t.execution,`${e}.execution`);if(!i.ok)return i;let o=t.continuation===void 0?S(void 0):Ag(t.continuation)?u5(t.continuation,`${e}.continuation`):oe(wt("execution_plan_invalid",`${e}.continuation must be an object`));return o.ok?S({kind:"continuation",id:r.value,teamScopeId:n.value,execution:i.value,continuation:o.value}):o}function d5(t,e){let r=IA(t.id,`${e}.id`);if(!r.ok)return r;let n=s5(t.assignee,`${e}.assignee`,"goal");if(!n.ok)return n;let i=t.evaluator===void 0||t.evaluator===null?S(void 0):s5(t.evaluator,`${e}.evaluator`,"prompt");if(!i.ok)return i;let o=b3(t.remainingAttempts,`${e}.remainingAttempts`);if(!o.ok)return oe(wt("execution_plan_invalid",o.error.message));let s=Hoe(t.requires,`${e}.requires`);return s.ok?S({kind:"goal",stage:"needs_evaluation",id:r.value,assignee:{executorId:n.value.executorId,goal:n.value.text},evaluator:i.value?{executorId:i.value.executorId,prompt:i.value.text}:void 0,remainingAttempts:o.value,requires:s.value}):s}function Moe(t,e){let r=d5({...t,stage:"needs_evaluation"},e);if(!r.ok)return r;let n=IA(t.evaluationPathId,`${e}.evaluationPathId`);if(!n.ok)return n;let i=Loe(t.evaluation,`${e}.evaluation`);if(!i.ok)return i;if(!Array.isArray(t.requires))return oe(wt("execution_plan_invalid",`${e}.requires must be an array for needs_execution`));let o=p5(t.requires,`${e}.requires`);return o.ok?o.value.length!==1||o.value[0]!==n.value?oe(wt("execution_plan_invalid",`${e}.requires must contain only ${e}.evaluationPathId`)):S({...r.value,stage:"needs_execution",evaluationPathId:n.value,evaluation:i.value,requires:o.value}):o}function s5(t,e,r){if(!Ag(t))return oe(wt("execution_plan_invalid",`${e} must be an object`));let n=f5(t.executorId,`${e}.executorId`);if(!n.ok)return n;let i=l5(t[r],`${e}.${r}`);return i.ok?S({executorId:n.value,text:i.value}):i}function Loe(t,e){if(!Ag(t))return oe(wt("execution_plan_invalid",`${e} must be an object`));if(t.type!=="fail")return oe(wt("execution_plan_invalid",`${e}.type must be fail`));if(typeof t.reason!="string"||t.reason.trim()==="")return oe(wt("execution_plan_invalid",`${e}.reason must be a non-empty string`));if(typeof t.feedback!="string"||t.feedback.trim()==="")return oe(wt("execution_plan_invalid",`${e}.feedback must be a non-empty string`));if(t.nextGoal!==void 0&&typeof t.nextGoal!="string")return oe(wt("execution_plan_invalid",`${e}.nextGoal must be a string when present`));let r=xA(t.evidence,`${e}.evidence`);return r.ok?S({type:"fail",reason:t.reason,feedback:t.feedback,nextGoal:typeof t.nextGoal=="string"&&t.nextGoal.trim()!==""?t.nextGoal:void 0,evidence:r.value}):r}function l5(t,e){return typeof t!="string"||t.trim()===""?oe(wt("execution_plan_invalid",`${e} must be a non-empty string`)):S(t)}function IA(t,e){let r=Ie(t,e);return r.ok?S(r.value):oe(wt("execution_plan_invalid",r.error.message))}function f5(t,e){let r=Ie(t,e);return r.ok?S(r.value):oe(wt("execution_plan_invalid",r.error.message))}function Hoe(t,e){return t==="PrevMove"?S("PrevMove"):p5(t,e)}function p5(t,e){let r=m5(t,e,"execution_plan_invalid");if(!r.ok)return r;let n=[];for(let[i,o]of r.value.entries()){let s=Ie(o,`${e}[${i}]`);if(!s.ok)return oe(wt("execution_plan_invalid",s.error.message));n.push(s.value)}return S(n)}function xA(t,e){return t===void 0?S(void 0):m5(t,e,"goal_evaluation_invalid")}function m5(t,e,r){return Array.isArray(t)?t.every(n=>typeof n=="string")?S([...t]):oe(wt(r,`${e} must be an array of strings`)):oe(wt(r,`${e} must be an array of strings`))}function h5(t,e){try{let r=JSON.parse(t);return Ag(r)?S(r):oe(wt("execution_plan_invalid",e))}catch(r){return oe(wt("execution_plan_invalid",e,{cause:r instanceof Error?r.message:String(r)}))}}function Ag(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}function EA(t){let{line:e,lineNode:r}=t;if(!r)return oe(wt("invalid_start_state",`No execute-ready MOVE found for Team route ${e.id}`));if(e.status==="failed"||e.status==="complete"||e.status==="abandoned")return oe(wt("invalid_start_state",`Cannot start Execute from ${e.id} because the route is ${e.status}`));if(new Set(t.board.edges.filter(a=>a.type==="move").map(a=>a.fromNodeId)).has(r.id))return oe(wt("invalid_start_state",`Cannot start Execute from ${g5(r,t.formatMovePosition)} because Arrived or Accident already exists`));if(t.existingRuns.find(a=>a.sourceNodeId===r.id&&(a.status==="running"||a.status==="paused")))return oe(wt("active_execute_exists",`A Execute is already active for ${g5(r,t.formatMovePosition)}`));let o=Ba(r.ordinal+1,"targetMoveOrdinal");if(!o.ok)return oe(wt("invalid_start_state",o.error.message));let s=Uoe(t.selectedDestinationIds,t.activeDestinations);return s.ok?S({lineNode:r,selectedDestinationIds:s.value,targetMoveOrdinal:o.value}):s}function y5(t){return t?S(t):oe(wt("terminal_output_missing","ExecutionPlan completed without a terminal output"))}function Uoe(t,e){let r=$oe(e);return t&&t.length>0?t.length!==1?oe(wt("invalid_start_state","Execute must select exactly one Destination")):r&&t[0]===r.id?S([...t]):oe(wt("invalid_start_state","Execute must select the next Destination in the queue")):S(r?[r.id]:[])}function $oe(t){return[...t].sort(Foe)[0]}function Foe(t,e){return(e.priority??0)-(t.priority??0)}function g5(t,e){return e?e(t):`${t.teamName??"Team"} MOVE ${t.ordinal}`}import{execFile as zoe,spawn as Koe}from"node:child_process";import{accessSync as Joe,constants as Xoe,existsSync as Cg,readdirSync as Yoe,statSync as Qoe}from"node:fs";import{delimiter as S5,isAbsolute as fb,join as Ls}from"node:path";import{promisify as Zoe}from"node:util";function ub(t,e,r,n=process.platform){return n!=="win32"||!/\.(?:cmd|bat)$/iu.test(t)?{command:t,args:e}:{command:r.ComSpec??r.COMSPEC??"cmd.exe",args:["/d","/s","/v:off","/c",joe(t,e)],windowsVerbatimArguments:!0}}function joe(t,e){return`"${[t,...e].map(qoe).join(" ")}"`}function qoe(t){if(/[%"\u0000-\u001f\u007f]/u.test(t))throw new Error("Windows command-shim paths and arguments cannot contain percent, quote, or control characters.");return`"${t}"`}var bn="0.2.0-next.5",Kd="local-bridge-v1";import{win32 as Woe}from"node:path";var Voe=new Set(["psmodulepath","winpsmodulepath"]);function db(t,e){if(/[\u0000-\u001f\u007f]/u.test(t))throw new Error("Windows ACL paths cannot contain control characters.");if(!/^[A-Za-z][A-Za-z0-9]*$/u.test(e))throw new Error("Windows ACL PowerShell variable names must be identifiers.");let r=`$${e}`,n=["$ErrorActionPreference = 'Stop'",`${r} = ${Goe(t)}`,"$sid = [System.Security.Principal.WindowsIdentity]::GetCurrent().User","$acl = [System.Security.AccessControl.FileSecurity]::new()","$acl.SetOwner($sid)","$acl.SetAccessRuleProtection($true, $false)","$rule = [System.Security.AccessControl.FileSystemAccessRule]::new($sid, [System.Security.AccessControl.FileSystemRights]::FullControl, [System.Security.AccessControl.AccessControlType]::Allow)","$acl.SetAccessRule($rule)",`[System.IO.File]::SetAccessControl(${r}, $acl)`].join("; ");return{command:"powershell.exe",args:["-NoProfile","-NonInteractive","-ExecutionPolicy","Bypass","-EncodedCommand",Buffer.from(n,"utf16le").toString("base64")]}}function lb(t){let e=Woe.basename(t).toLowerCase();return e==="powershell"||e==="powershell.exe"}function Ms(t){let e={};for(let[r,n]of Object.entries(t))Voe.has(r.toLowerCase())||n===void 0||(e[r]=n);return e}function Goe(t){return`'${t.replace(/'/g,"''")}'`}var mb=Zoe(zoe),_g=3500;async function lu(t={}){let e=t.env??Rr(),r=t.platform??process.platform,n=await ese({env:e,platform:r,customBinaryPath:t.customBinaryPath}),i=[];for(let c of n){let u=await tse(c,e,r,t.timeoutMs);if(i.push(u),c.rejectWhitespace&&u.error?.includes("HUNSU_CODEX_APP_SERVER_COMMAND"))return{installed:!1,source:u.source,appServerAvailable:!1,discovery:i,error:u.error};if(u.usable&&u.path)return{installed:!0,binaryPath:u.path,source:u.source,version:u.version,appServerAvailable:!0,discovery:i}}let o=i.find(c=>c.path&&c.versionOk===!0&&c.appServerOk===!1);if(o?.path)return{installed:!0,binaryPath:o.path,source:o.source,version:o.version,appServerAvailable:!1,discovery:i,error:o.error??"Codex was found, but Codex app-server is not available."};let s=i.find(c=>c.source==="windows_apps_alias"||c.path&&CA(c.path,r));if(s)return{installed:!1,binaryPath:s.path,source:"windows_apps_alias",appServerAvailable:!1,discovery:i,aliasDetected:!0,error:s.error??"Codex resolved to a WindowsApps execution alias. Select the real Codex binary path in Hunsu Bridge."};let a=i.find(c=>c.path)??i[0];return{installed:!1,binaryPath:a?.path,source:a?.source??"unknown",appServerAvailable:!1,discovery:i,error:a?.error??"Codex CLI was not found by Hunsu Bridge."}}async function hb(t){try{let e=t.env??Rr(),r=t.platform??process.platform,n=I5(t.binaryPath,["--version"],e,r),{stdout:i,stderr:o}=await mb(n.command,n.args,{env:E5(e,r),timeout:t.timeoutMs??_g,windowsHide:!0,windowsVerbatimArguments:n.windowsVerbatimArguments,maxBuffer:64*1024});return`${i}
204
+ `,"utf8")}function pA(t){return ob(t,".hunsu","action-runs")}function Z8(t,e){return ob(pA(t),`${mA(e)}.json`)}function voe(t,e){return t?`/api/roadmaps/${encodeURIComponent(t)}/action-runs/${encodeURIComponent(e)}/proxy`:`/api/action-runs/${encodeURIComponent(e)}/proxy`}function xoe(t,e,r){return mA(`${t}-${e.moveId??e.commit.slice(0,12)}-${r.replace(/[^0-9A-Za-z]/g,"").slice(0,14)}`)}function mA(t){return t.toLowerCase().replace(/[^a-z0-9_.-]+/g,"-").replace(/^-+|-+$/g,"")||"action-run"}function e5(t){return t.toLowerCase().replace(/[^a-z0-9_-]+/g,"-").replace(/^-+|-+$/g,"").slice(0,63)||"hunsu-action"}function t5(t,e){return t.replace(/\{([a-zA-Z][a-zA-Z0-9]*)\}/g,(r,n)=>e[n]??"")}function Soe(t){return ooe("sha256").update(t).digest("hex").slice(0,12)}function boe(t){let e=t.split(/\r?\n/).find(Boolean)??t,r=e.match(/(?:0\.0\.0\.0|127\.0\.0\.1|localhost|\[::\]|::):(\d+)$/);return r?`http://127.0.0.1:${r[1]}`:/^https?:\/\//.test(e)?e:`http://${e}`}function r5(t,e,r){let n=soe(t,e,{cwd:r.cwd,env:{...woe(r.processEnv),...r.env},encoding:"utf8",maxBuffer:16777216});return{status:n.status??1,stdout:n.stdout,stderr:n.stderr}}function woe(t){if(t===void 0)return;let e={};for(let[r,n]of Object.entries(t))n!==void 0&&(e[r]=n);return e}function ab(t){return t.map(uA).sort((e,r)=>e.displayOrder-r.displayOrder||String(e.id).localeCompare(String(r.id)))}function uA(t){return{...t,env:t.env?Object.fromEntries(Object.entries(t.env).map(([e,r])=>[e,{...r}])):void 0,runner:{...t.runner},aliases:t.aliases?Object.fromEntries(Object.entries(t.aliases).map(([e,r])=>[e,{...r}])):void 0,evidence:t.evidence?{...t.evidence,paths:t.evidence.paths?.slice()}:void 0}}import{createHash as Ioe}from"node:crypto";var Eoe="hunsu.hub-package-manifest.v1",n5="hunsu-json-c14n-v1+sha256:";function koe(t){vA(t);let{integrity:e,...r}=t;return JSON.stringify(yA(r,"manifest"))}function Roe(t){let e=koe(t);return`${n5}${Ioe("sha256").update(e,"utf8").digest("hex")}`}async function kg(t,e){if(!t.integrity.startsWith(n5))throw new Error(`Unsupported Hub package integrity prefix: ${t.integrity}`);let r=e.origins.find(a=>a.name===t.origin);if(!r)throw new Error(`Unknown Origin: ${t.origin}`);if(r.transport!=="http")throw new Error(`Origin ${r.name} uses unsupported transport ${r.transport}`);let i=await(e.fetch??fetch)(Aoe(r.url,t.kind,t.key,t.version));if(!i.ok)throw i.status===404?new Error(`Missing Hub package manifest: ${t.origin}/${t.kind}/${t.key}@${t.version}`):new Error(`Origin ${r.name} returned ${i.status} for ${t.kind}/${t.key}@${t.version}`);let o=await i.json();if(vA(o),o.kind!==t.kind||o.key!==t.key||o.version!==t.version)throw new Error(`Hub package manifest from ${r.name} does not match requested ${t.kind}/${t.key}@${t.version}`);let s=Roe(o);if(s!==t.integrity)throw new Error(`Hub package integrity mismatch for ${t.origin}/${t.kind}/${t.key}@${t.version}: expected ${t.integrity}, got ${s}`);return{lock:{...t},manifest:o,integrity:s,origin:{...r}}}function Aoe(t,e,r,n){let i=new URL(t),o=`/v1/packages/${e}/${encodeURIComponent(r)}/versions/${encodeURIComponent(n)}`;return new URL(o,i).toString()}function i5(t){if(vA(t),t.kind!=="team")throw new Error(`Hub package ${t.kind}/${t.key}@${t.version} is not a team package`);return Doe(t.team)}function vA(t){let e=hA(t,"manifest");if(e.schema!==Eoe)throw new Error(`Unsupported Hub package manifest schema: ${String(e.schema)}`);gA(e,["integrity","key","kind","team","member","manager","schema","skill","version"],"manifest");let r=Boe(e.kind,"manifest.kind");switch(Yf(e.key,"manifest.key"),Yf(e.version,"manifest.version"),e.integrity!==void 0&&Yf(e.integrity,"manifest.integrity"),r){case"team":if(Coe(e.team),e.member!==void 0||e.manager!==void 0||e.skill!==void 0)throw new Error("Team package manifest must not include member, manager, or skill payloads");return;case"member":if(Poe(e.member),e.team!==void 0||e.manager!==void 0||e.skill!==void 0)throw new Error("Member package manifest must not include team, manager, or skill payloads");return;case"manager":if(_oe(e.manager),e.team!==void 0||e.member!==void 0||e.skill!==void 0)throw new Error("Manager package manifest must not include team, member, or skill payloads");return;case"skill":if(Toe(e.skill),e.team!==void 0||e.member!==void 0||e.manager!==void 0)throw new Error("Skill package manifest must not include team, member, or manager payloads");return}}function Coe(t){let e=Fd(t,"manifest.team");if(!e.ok)throw new Error(`Invalid manifest.team: ${e.error.message}`)}function Poe(t){let e=JR(t,"manifest.member");if(!e.ok)throw new Error(`Invalid manifest.member: ${e.error.message}`)}function _oe(t){let e=zh(t,"manifest.manager");if(!e.ok)throw new Error(`Invalid manifest.manager: ${e.error.message}`)}function Toe(t){let e=hA(t,"manifest.skill");if(gA(e,["contentHash","files","name"],"manifest.skill"),Yf(e.name,"manifest.skill.name"),Yf(e.contentHash,"manifest.skill.contentHash"),e.files!==void 0){if(!Array.isArray(e.files))throw new Error("manifest.skill.files must be an array");for(let[r,n]of e.files.entries()){let i=hA(n,`manifest.skill.files[${r}]`);gA(i,["path","text"],`manifest.skill.files[${r}]`),Yf(i.path,`manifest.skill.files[${r}].path`),o5(i.text,`manifest.skill.files[${r}].text`)}}}function Boe(t,e){if(t==="team"||t==="member"||t==="manager"||t==="skill")return t;throw new Error(`${e} must be team, member, manager, or skill`)}function hA(t,e){if(typeof t!="object"||t===null||Array.isArray(t))throw new Error(`${e} must be an object`);return t}function gA(t,e,r){let n=e.filter(o=>o!=="integrity"&&o!=="team"&&o!=="member"&&o!=="manager"&&o!=="skill"&&o!=="files"&&!(o in t));if(n.length>0)throw new Error(`${r} is missing required keys: ${n.join(", ")}`);let i=Object.keys(t).filter(o=>!e.includes(o));if(i.length>0)throw new Error(`${r} has unsupported keys: ${i.join(", ")}`)}function o5(t,e){if(typeof t!="string")throw new Error(`${e} must be a string`);return t}function Yf(t,e){let r=o5(t,e);if(r.trim().length===0)throw new Error(`${e} must be non-empty`);return r}function yA(t,e){if(t===null||typeof t=="string"||typeof t=="boolean")return t;if(typeof t=="number"){if(!Number.isFinite(t))throw new Error(`${e} must be a finite number`);return t}if(Array.isArray(t))return t.map((r,n)=>{if(r===void 0)throw new Error(`${e}[${n}] must not be undefined`);return yA(r,`${e}[${n}]`)});if(typeof t=="object"&&t!==null){let r=t,n={};for(let i of Object.keys(r).sort()){let o=r[i];o!==void 0&&(n[i]=yA(o,`${e}.${i}`))}return n}throw new Error(`${e} must be JSON-serializable`)}function Doe(t){return JSON.parse(JSON.stringify(t))}function wt(t,e,r){return r===void 0?{code:t,message:e}:{code:t,message:e,details:r}}function Rg(t){let e=new Error(t.message);return e.name=`ExecuteOrchestrationError:${t.code}`,t.details!==void 0&&(e.details=t.details),e}function zd(t){if(t.ok)return t.value;throw Rg(t.error)}function SA(t){let e=h5(t,"Team planning final response must be a JSON ExecutionPlan object");return e.ok?wA(e.value,"execution"):e}function a5(t){let e=h5(t,"Goal evaluator final response must be a JSON object");if(!e.ok)return e;let r=e.value;if(r.type==="pass"){if(typeof r.summary!="string"||r.summary.trim()==="")return oe(wt("goal_evaluation_invalid","pass evaluation must include a non-empty summary"));let n=xA(r.evidence,"evidence");return n.ok?S({type:"pass",summary:r.summary,evidence:n.value}):n}if(r.type==="fail"){if(typeof r.reason!="string"||r.reason.trim()==="")return oe(wt("goal_evaluation_invalid","fail evaluation must include a non-empty reason"));if(typeof r.feedback!="string"||r.feedback.trim()==="")return oe(wt("goal_evaluation_invalid","fail evaluation must include non-empty feedback"));if(r.nextGoal!==void 0&&typeof r.nextGoal!="string")return oe(wt("goal_evaluation_invalid","fail evaluation nextGoal must be a string when present"));let n=xA(r.evidence,"evidence");return n.ok?S({type:"fail",reason:r.reason,feedback:r.feedback,nextGoal:typeof r.nextGoal=="string"&&r.nextGoal.trim()!==""?r.nextGoal:void 0,evidence:n.value}):n}return oe(wt("goal_evaluation_invalid","Goal evaluator response type must be pass or fail"))}function bA(t,e,r,n){if(e==="assignee")return{id:r,executorId:t.assignee.executorId,goal:t.assignee.goal,requires:n};let i=t.evaluator;if(!i)throw new Error(`Goal ${t.id} does not define an evaluator`);return{id:r,executorId:i.executorId,goal:i.prompt,requires:n}}function c5(t,e){let[,...r]=t.items;if(e)return{...t,items:[e,...r]};if(r.length!==0)return{...t,items:r}}function wA(t,e){return Ag(t)?t.kind==="queue"?Noe(t,e):t.kind==="goal"?u5(t,e):t.kind==="continuation"?Ooe(t,e):oe(wt("execution_plan_invalid",`${e}.kind must be queue, goal, or continuation`)):oe(wt("execution_plan_invalid",`${e} must be an object`))}function Noe(t,e){let r=l5(t.id,`${e}.id`);if(!r.ok)return r;if(!Array.isArray(t.items))return oe(wt("execution_plan_invalid",`${e}.items must be an array`));let n=[];for(let[i,o]of t.items.entries()){let s=wA(o,`${e}.items[${i}]`);if(!s.ok)return s;n.push(s.value)}return S({kind:"queue",id:r.value,items:n})}function u5(t,e){return t.stage==="needs_evaluation"?d5(t,e):t.stage==="needs_execution"?Moe(t,e):oe(wt("execution_plan_invalid",`${e}.stage must be needs_evaluation or needs_execution`))}function Ooe(t,e){let r=IA(t.id,`${e}.id`);if(!r.ok)return r;let n=f5(t.teamScopeId,`${e}.teamScopeId`);if(!n.ok)return n;let i=wA(t.execution,`${e}.execution`);if(!i.ok)return i;let o=t.continuation===void 0?S(void 0):Ag(t.continuation)?u5(t.continuation,`${e}.continuation`):oe(wt("execution_plan_invalid",`${e}.continuation must be an object`));return o.ok?S({kind:"continuation",id:r.value,teamScopeId:n.value,execution:i.value,continuation:o.value}):o}function d5(t,e){let r=IA(t.id,`${e}.id`);if(!r.ok)return r;let n=s5(t.assignee,`${e}.assignee`,"goal");if(!n.ok)return n;let i=t.evaluator===void 0||t.evaluator===null?S(void 0):s5(t.evaluator,`${e}.evaluator`,"prompt");if(!i.ok)return i;let o=b3(t.remainingAttempts,`${e}.remainingAttempts`);if(!o.ok)return oe(wt("execution_plan_invalid",o.error.message));let s=Hoe(t.requires,`${e}.requires`);return s.ok?S({kind:"goal",stage:"needs_evaluation",id:r.value,assignee:{executorId:n.value.executorId,goal:n.value.text},evaluator:i.value?{executorId:i.value.executorId,prompt:i.value.text}:void 0,remainingAttempts:o.value,requires:s.value}):s}function Moe(t,e){let r=d5({...t,stage:"needs_evaluation"},e);if(!r.ok)return r;let n=IA(t.evaluationPathId,`${e}.evaluationPathId`);if(!n.ok)return n;let i=Loe(t.evaluation,`${e}.evaluation`);if(!i.ok)return i;if(!Array.isArray(t.requires))return oe(wt("execution_plan_invalid",`${e}.requires must be an array for needs_execution`));let o=p5(t.requires,`${e}.requires`);return o.ok?o.value.length!==1||o.value[0]!==n.value?oe(wt("execution_plan_invalid",`${e}.requires must contain only ${e}.evaluationPathId`)):S({...r.value,stage:"needs_execution",evaluationPathId:n.value,evaluation:i.value,requires:o.value}):o}function s5(t,e,r){if(!Ag(t))return oe(wt("execution_plan_invalid",`${e} must be an object`));let n=f5(t.executorId,`${e}.executorId`);if(!n.ok)return n;let i=l5(t[r],`${e}.${r}`);return i.ok?S({executorId:n.value,text:i.value}):i}function Loe(t,e){if(!Ag(t))return oe(wt("execution_plan_invalid",`${e} must be an object`));if(t.type!=="fail")return oe(wt("execution_plan_invalid",`${e}.type must be fail`));if(typeof t.reason!="string"||t.reason.trim()==="")return oe(wt("execution_plan_invalid",`${e}.reason must be a non-empty string`));if(typeof t.feedback!="string"||t.feedback.trim()==="")return oe(wt("execution_plan_invalid",`${e}.feedback must be a non-empty string`));if(t.nextGoal!==void 0&&typeof t.nextGoal!="string")return oe(wt("execution_plan_invalid",`${e}.nextGoal must be a string when present`));let r=xA(t.evidence,`${e}.evidence`);return r.ok?S({type:"fail",reason:t.reason,feedback:t.feedback,nextGoal:typeof t.nextGoal=="string"&&t.nextGoal.trim()!==""?t.nextGoal:void 0,evidence:r.value}):r}function l5(t,e){return typeof t!="string"||t.trim()===""?oe(wt("execution_plan_invalid",`${e} must be a non-empty string`)):S(t)}function IA(t,e){let r=Ie(t,e);return r.ok?S(r.value):oe(wt("execution_plan_invalid",r.error.message))}function f5(t,e){let r=Ie(t,e);return r.ok?S(r.value):oe(wt("execution_plan_invalid",r.error.message))}function Hoe(t,e){return t==="PrevMove"?S("PrevMove"):p5(t,e)}function p5(t,e){let r=m5(t,e,"execution_plan_invalid");if(!r.ok)return r;let n=[];for(let[i,o]of r.value.entries()){let s=Ie(o,`${e}[${i}]`);if(!s.ok)return oe(wt("execution_plan_invalid",s.error.message));n.push(s.value)}return S(n)}function xA(t,e){return t===void 0?S(void 0):m5(t,e,"goal_evaluation_invalid")}function m5(t,e,r){return Array.isArray(t)?t.every(n=>typeof n=="string")?S([...t]):oe(wt(r,`${e} must be an array of strings`)):oe(wt(r,`${e} must be an array of strings`))}function h5(t,e){try{let r=JSON.parse(t);return Ag(r)?S(r):oe(wt("execution_plan_invalid",e))}catch(r){return oe(wt("execution_plan_invalid",e,{cause:r instanceof Error?r.message:String(r)}))}}function Ag(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}function EA(t){let{line:e,lineNode:r}=t;if(!r)return oe(wt("invalid_start_state",`No execute-ready MOVE found for Team route ${e.id}`));if(e.status==="failed"||e.status==="complete"||e.status==="abandoned")return oe(wt("invalid_start_state",`Cannot start Execute from ${e.id} because the route is ${e.status}`));if(new Set(t.board.edges.filter(a=>a.type==="move").map(a=>a.fromNodeId)).has(r.id))return oe(wt("invalid_start_state",`Cannot start Execute from ${g5(r,t.formatMovePosition)} because Arrived or Accident already exists`));if(t.existingRuns.find(a=>a.sourceNodeId===r.id&&(a.status==="running"||a.status==="paused")))return oe(wt("active_execute_exists",`A Execute is already active for ${g5(r,t.formatMovePosition)}`));let o=Ba(r.ordinal+1,"targetMoveOrdinal");if(!o.ok)return oe(wt("invalid_start_state",o.error.message));let s=Uoe(t.selectedDestinationIds,t.activeDestinations);return s.ok?S({lineNode:r,selectedDestinationIds:s.value,targetMoveOrdinal:o.value}):s}function y5(t){return t?S(t):oe(wt("terminal_output_missing","ExecutionPlan completed without a terminal output"))}function Uoe(t,e){let r=$oe(e);return t&&t.length>0?t.length!==1?oe(wt("invalid_start_state","Execute must select exactly one Destination")):r&&t[0]===r.id?S([...t]):oe(wt("invalid_start_state","Execute must select the next Destination in the queue")):S(r?[r.id]:[])}function $oe(t){return[...t].sort(Foe)[0]}function Foe(t,e){return(e.priority??0)-(t.priority??0)}function g5(t,e){return e?e(t):`${t.teamName??"Team"} MOVE ${t.ordinal}`}import{execFile as zoe,spawn as Koe}from"node:child_process";import{accessSync as Joe,constants as Xoe,existsSync as Cg,readdirSync as Yoe,statSync as Qoe}from"node:fs";import{delimiter as S5,isAbsolute as fb,join as Ls}from"node:path";import{promisify as Zoe}from"node:util";function ub(t,e,r,n=process.platform){return n!=="win32"||!/\.(?:cmd|bat)$/iu.test(t)?{command:t,args:e}:{command:r.ComSpec??r.COMSPEC??"cmd.exe",args:["/d","/s","/v:off","/c",joe(t,e)],windowsVerbatimArguments:!0}}function joe(t,e){return`"${[t,...e].map(qoe).join(" ")}"`}function qoe(t){if(/[%"\u0000-\u001f\u007f]/u.test(t))throw new Error("Windows command-shim paths and arguments cannot contain percent, quote, or control characters.");return`"${t}"`}var bn="0.2.0-next.6",Kd="local-bridge-v1";import{win32 as Woe}from"node:path";var Voe=new Set(["psmodulepath","winpsmodulepath"]);function db(t,e){if(/[\u0000-\u001f\u007f]/u.test(t))throw new Error("Windows ACL paths cannot contain control characters.");if(!/^[A-Za-z][A-Za-z0-9]*$/u.test(e))throw new Error("Windows ACL PowerShell variable names must be identifiers.");let r=`$${e}`,n=["$ErrorActionPreference = 'Stop'",`${r} = ${Goe(t)}`,"$sid = [System.Security.Principal.WindowsIdentity]::GetCurrent().User","$acl = [System.Security.AccessControl.FileSecurity]::new()","$acl.SetOwner($sid)","$acl.SetAccessRuleProtection($true, $false)","$rule = [System.Security.AccessControl.FileSystemAccessRule]::new($sid, [System.Security.AccessControl.FileSystemRights]::FullControl, [System.Security.AccessControl.AccessControlType]::Allow)","$acl.SetAccessRule($rule)",`[System.IO.File]::SetAccessControl(${r}, $acl)`].join("; ");return{command:"powershell.exe",args:["-NoProfile","-NonInteractive","-ExecutionPolicy","Bypass","-EncodedCommand",Buffer.from(n,"utf16le").toString("base64")]}}function lb(t){let e=Woe.basename(t).toLowerCase();return e==="powershell"||e==="powershell.exe"}function Ms(t){let e={};for(let[r,n]of Object.entries(t))Voe.has(r.toLowerCase())||n===void 0||(e[r]=n);return e}function Goe(t){return`'${t.replace(/'/g,"''")}'`}var mb=Zoe(zoe),_g=3500;async function lu(t={}){let e=t.env??Rr(),r=t.platform??process.platform,n=await ese({env:e,platform:r,customBinaryPath:t.customBinaryPath}),i=[];for(let c of n){let u=await tse(c,e,r,t.timeoutMs);if(i.push(u),c.rejectWhitespace&&u.error?.includes("HUNSU_CODEX_APP_SERVER_COMMAND"))return{installed:!1,source:u.source,appServerAvailable:!1,discovery:i,error:u.error};if(u.usable&&u.path)return{installed:!0,binaryPath:u.path,source:u.source,version:u.version,appServerAvailable:!0,discovery:i}}let o=i.find(c=>c.path&&c.versionOk===!0&&c.appServerOk===!1);if(o?.path)return{installed:!0,binaryPath:o.path,source:o.source,version:o.version,appServerAvailable:!1,discovery:i,error:o.error??"Codex was found, but Codex app-server is not available."};let s=i.find(c=>c.source==="windows_apps_alias"||c.path&&CA(c.path,r));if(s)return{installed:!1,binaryPath:s.path,source:"windows_apps_alias",appServerAvailable:!1,discovery:i,aliasDetected:!0,error:s.error??"Codex resolved to a WindowsApps execution alias. Select the real Codex binary path in Hunsu Bridge."};let a=i.find(c=>c.path)??i[0];return{installed:!1,binaryPath:a?.path,source:a?.source??"unknown",appServerAvailable:!1,discovery:i,error:a?.error??"Codex CLI was not found by Hunsu Bridge."}}async function hb(t){try{let e=t.env??Rr(),r=t.platform??process.platform,n=I5(t.binaryPath,["--version"],e,r),{stdout:i,stderr:o}=await mb(n.command,n.args,{env:E5(e,r),timeout:t.timeoutMs??_g,windowsHide:!0,windowsVerbatimArguments:n.windowsVerbatimArguments,maxBuffer:64*1024});return`${i}
205
205
  ${o}`.trim().split(/\r?\n/).map(a=>a.trim()).find(Boolean)}catch{return}}async function b5(t){let e=t.env??Rr(),r=t.command?{ok:!0,value:{command:t.command,args:t.args??["app-server","--stdio"]}}:kA({env:e,cliBinaryPath:t.binaryPath});if(!r.ok)return{available:!1,error:r.error};let n=new Pg(r.value.command,t.timeoutMs??_g,{env:e,platform:t.platform,args:r.value.args});try{let i=await n.initialize();return{available:!0,initialized:Xr(i)}}catch(i){return{available:!1,error:Jd(i)}}finally{n.close()}}function kA(t){let e=t.env.HUNSU_CODEX_APP_SERVER_COMMAND?.trim();if(e&&/\s/.test(e))return{ok:!1,error:"HUNSU_CODEX_APP_SERVER_COMMAND must be a binary path or command name without arguments. Put arguments in HUNSU_CODEX_APP_SERVER_ARGS."};let r=Fh(t.env);if(!r.ok)return{ok:!1,error:r.error.message};let n=t.cliBinaryPath?.trim();return{ok:!0,value:{command:r.value.command==="codex"&&n?n:r.value.command,args:r.value.args}}}function RA(t,e){if(e!=="win32")return[];let r=Qf(t,"LOCALAPPDATA","LocalAppData","localappdata"),n=Qf(t,"APPDATA","AppData","appdata");return yb([r?Ls(r,"OpenAI","Codex","bin"):void 0,n?Ls(n,"npm"):void 0,r?Ls(r,"Programs","OpenAI Codex"):void 0])}function AA(t,e){return e!=="win32"?t.PATH??"":[t.PATH,t.Path,t.path,t.HUNSU_WINDOWS_USER_PATH,t.HUNSU_WINDOWS_MACHINE_PATH].filter(r=>typeof r=="string"&&r.trim().length>0).join(";")}async function ese(t){let{env:e,platform:r}=t,n=[],i=t.customBinaryPath?.trim();i&&n.push({candidate:i,source:"custom"});let o=e.HUNSU_CODEX_BINARY_PATH?.trim();o&&n.push({candidate:o,source:e.HUNSU_CODEX_BINARY_PATH_SOURCE==="user_config"?"custom":"env"});let s=e.HUNSU_CODEX_APP_SERVER_COMMAND?.trim();if(s&&n.push({candidate:s,source:"env",rejectWhitespace:!0}),n.push(...pb("codex",e,r,gb(e,r)).map(a=>({candidate:a,source:"process_path"}))),r==="win32"){n.push(...pb("codex",e,r,await v5("user",e,r)).map(c=>({candidate:c,source:"registry_user_path"}))),n.push(...pb("codex",e,r,await v5("machine",e,r)).map(c=>({candidate:c,source:"registry_machine_path"}))),n.push(...(await ose(e)).map(c=>({candidate:c,source:"where"}))),n.push(...(await sse(e)).map(c=>({candidate:c,source:"powershell_get_command"}))),n.push(...ise(e,r).map(c=>({candidate:c,source:"known_install_dir"})));let a=cse(e,r);a&&n.push({candidate:a,source:"windows_apps_alias"})}return dse(n)}async function tse(t,e,r,n){let i=rse(t.candidate,t.source,e,r,{rejectWhitespace:t.rejectWhitespace});if(i.kind!=="binary")return{source:i.source==="unknown"?t.source:i.source,path:i.kind==="missing"?i.binaryPath:void 0,usable:!1,error:i.error};let o=CA(i.binaryPath,r)?"windows_apps_alias":i.source;if(o==="windows_apps_alias")return{source:o,path:i.binaryPath,usable:!1,versionOk:!1,appServerOk:!1,error:"Codex resolved to a WindowsApps execution alias. Select the real Codex binary path in Hunsu Bridge."};let s=await hb({binaryPath:i.binaryPath,timeoutMs:n,env:e,platform:r});if(!s)return{source:o,path:i.binaryPath,usable:!1,versionOk:!1,appServerOk:!1,error:"Codex candidate did not return a CLI version."};let a=await b5({binaryPath:i.binaryPath,timeoutMs:n,env:e,platform:r});return a.available?{source:o,path:i.binaryPath,usable:!0,versionOk:!0,appServerOk:!0,version:s}:{source:o,path:i.binaryPath,usable:!1,versionOk:!0,appServerOk:!1,version:s,error:a.error}}function rse(t,e,r,n,i={}){let o=t.trim();if(!o)return{kind:"missing",installed:!1,source:e??"unknown",error:"Codex command is empty."};if(i.rejectWhitespace&&/\s/.test(o))return{kind:"unsupported_command_string",installed:!1,source:"env",error:"HUNSU_CODEX_APP_SERVER_COMMAND must be a binary path or command name without arguments. Put arguments in HUNSU_CODEX_APP_SERVER_ARGS."};let s=fb(o)?o:nse(o,r,n,gb(r,n));if(!s)return{kind:"missing",installed:!1,source:e??"unknown",binaryPath:fb(o)?o:void 0,error:fb(o)?"Configured Codex path does not exist.":`Codex command was not found on PATH: ${o}`};if(CA(s,n))return{kind:"missing",installed:!1,source:"windows_apps_alias",binaryPath:s,error:"Codex resolved to a WindowsApps execution alias. Select the real Codex binary path in Hunsu Bridge."};try{return Qoe(s).isFile()?(n!=="win32"&&Joe(s,Xoe.X_OK),{kind:"binary",installed:!0,binaryPath:s,source:e==="unknown"||e===void 0?"process_path":e}):{kind:"missing",installed:!1,binaryPath:s,source:e??"unknown",error:"Configured Codex path is not a file."}}catch(a){return{kind:"missing",installed:!1,binaryPath:s,source:e??"unknown",error:Jd(a)}}}function nse(t,e,r=process.platform,n=gb(e,r)){return pb(t,e,r,n)[0]}function pb(t,e,r=process.platform,n=gb(e,r)){if(fb(t))return Cg(t)?[t]:[];let i=r==="win32"?["",...(e.PATHEXT??e.PathExt??".EXE;.CMD;.BAT;.COM").split(";").filter(Boolean)]:[""],o=r==="win32"?";":S5,s=[];for(let a of n.split(o).filter(Boolean))for(let c of i){let u=Ls(a,r==="win32"&&!t.toUpperCase().endsWith(c.toUpperCase())?`${t}${c}`:t);Cg(u)&&s.push(u)}return yb(s)}function ise(t,e){if(e!=="win32")return[];let r=Qf(t,"LOCALAPPDATA","LocalAppData","localappdata"),n=Qf(t,"APPDATA","AppData","appdata"),i=[];if(r){let o=Ls(r,"OpenAI","Codex","bin");if(Cg(o))for(let s of use(o))i.push(Ls(o,s,"codex.exe"));i.push(Ls(r,"OpenAI","Codex","bin","codex.exe"),Ls(r,"Programs","OpenAI Codex","codex.exe"))}return n&&i.push(Ls(n,"npm","codex.cmd")),yb(i.filter(Cg))}async function v5(t,e,r){if(r!=="win32")return"";let n=t==="user"?e.HUNSU_WINDOWS_USER_PATH:e.HUNSU_WINDOWS_MACHINE_PATH;if(n?.trim())return x5(n,e);let i=t==="user"?"HKCU\\Environment":"HKLM\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment";try{let{stdout:o}=await mb("reg.exe",["query",i,"/v","Path"],{env:e,timeout:1500,windowsHide:!0,maxBuffer:65536});return x5(ase(o),e)}catch{return""}}async function ose(t){try{let{stdout:e}=await mb("where.exe",["codex"],{env:t,timeout:1500,windowsHide:!0,maxBuffer:65536});return w5(e)}catch{return[]}}async function sse(t){let e="Get-Command codex -All | ForEach-Object { $_.Source }";for(let r of["powershell.exe","pwsh"])try{let{stdout:n}=await mb(r,["-NoProfile","-Command",e],{env:r==="powershell.exe"?Ms(t):t,timeout:2e3,windowsHide:!0,maxBuffer:65536}),i=w5(n);if(i.length>0)return i}catch{}return[]}function ase(t){return t.split(/\r?\n/).map(r=>r.trim()).find(r=>/^Path\s+REG_/i.test(r))?.replace(/^Path\s+REG_\w+\s+/i,"").trim()??""}function w5(t){return yb(t.split(/\r?\n/).map(e=>e.trim()).filter(e=>e.length>0&&!/^[-\s]+$/.test(e)&&!/^CommandType\b|^Name\b|^Source\b/i.test(e)))}function cse(t,e){if(e!=="win32")return;let r=Qf(t,"LOCALAPPDATA","LocalAppData","localappdata"),n=r?Ls(r,"Microsoft","WindowsApps","codex.exe"):void 0;return n&&Cg(n)?n:void 0}function gb(t,e){return e!=="win32"?t.PATH??"":[t.PATH,t.Path,t.path].filter(r=>typeof r=="string"&&r.trim().length>0).join(";")}function use(t){try{return Yoe(t,{withFileTypes:!0}).filter(e=>e.isDirectory()).map(e=>e.name)}catch{return[]}}function dse(t){let e=new Set,r=[];for(let n of t){let i=`${n.source}:${n.candidate}`;e.has(i)||(e.add(i),r.push(n))}return r}function Qf(t,...e){return e.map(r=>t[r]).find(r=>typeof r=="string"&&r.trim().length>0)?.trim()}function yb(t){return[...new Set(t.filter(e=>typeof e=="string"&&e.length>0))]}function CA(t,e){return e==="win32"&&/(?:^|[\\/])WindowsApps[\\/]/i.test(t)}function x5(t,e){return t.replace(/%([^%]+)%/g,(r,n)=>{let i=n.trim(),o=Rr();return Qf(e,i,i.toUpperCase(),i.toLowerCase())??o[i]??r})}function I5(t,e,r,n){return ub(t,e,r,n)}function E5(t,e){let r=Rr(),n={...r,...t},i=e==="win32"?";":S5;for(let o of["PATH","Path","path"]){let s=t[o],a=r[o];if(s===""&&a){n[o]=a;continue}s&&a&&!s.split(i).includes(a)&&(n[o]=`${s}${i}${a}`)}return n}var Pg=class{command;args;timeoutMs;child;nextId=1;buffer="";pending=new Map;constructor(e,r,n={}){this.command=e,this.args=n.args??["app-server","--stdio"],this.timeoutMs=r;let i=n.env??Rr(),o=n.platform??process.platform,s=I5(this.command,this.args,i,o);this.child=Koe(s.command,s.args,{env:E5(i,o),stdio:["pipe","pipe","pipe"],windowsHide:!0,windowsVerbatimArguments:s.windowsVerbatimArguments}),this.child.stdout.setEncoding("utf8"),this.child.stdout.on("data",a=>this.read(a)),this.child.stderr.setEncoding("utf8"),this.child.on("error",a=>this.rejectAll(a)),this.child.on("exit",()=>this.rejectAll(new Error("Codex app-server process exited before probe completed.")))}request(e,r){let n=this.nextId;return this.nextId+=1,new Promise((i,o)=>{let s=setTimeout(()=>{this.pending.delete(n),o(new Error(`Codex app-server probe timed out: ${e}`))},this.timeoutMs);this.pending.set(n,{resolve:i,reject:o,timer:s});try{this.write({jsonrpc:"2.0",id:n,method:e,params:r})}catch(a){clearTimeout(s),this.pending.delete(n),o(a instanceof Error?a:new Error(String(a)))}})}async initialize(){let e=await this.request("initialize",{clientInfo:{name:"hunsu-bridge",title:"Hunsu Bridge",version:bn}});return this.notify("initialized",{}),e}notify(e,r){this.write({jsonrpc:"2.0",method:e,params:r})}close(){this.rejectAll(new Error("Codex app-server probe closed.")),this.child.kill()}write(e){this.child.stdin.write(`${JSON.stringify(e)}
206
206
  `)}read(e){this.buffer+=e;let r=this.buffer.indexOf(`
207
207
  `);for(;r>=0;){let n=this.buffer.slice(0,r).trim();if(this.buffer=this.buffer.slice(r+1),r=this.buffer.indexOf(`
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export const HUNSU_BRIDGE_VERSION: "0.2.0-next.5";
1
+ export const HUNSU_BRIDGE_VERSION: "0.2.0-next.6";
2
2
  export const HUNSU_BRIDGE_PROTOCOL_VERSION: "local-bridge-v1";
3
3
  export const BRIDGE_CLI_RESULT_SCHEMA: "hunsu.bridge.cli-result.v1";
4
4
  export const BRIDGE_DEPLOYMENT_PROFILES: readonly ["production", "preview"];
package/dist/index.js CHANGED
@@ -201,7 +201,7 @@ ${n}
201
201
  `),s=n.slice(i+2).trim();if(o[0]!==r)return Bn(`Invalid Hunsu runtime header in ${e}`);let a=new Map(o.slice(1).map(l=>{let f=l.indexOf(":");return f===-1?[l.trim(),""]:[l.slice(0,f).trim(),l.slice(f+1).trim()]}));if(a.get("encoding")!==F8)return Bn(`Unsupported Hunsu runtime encoding in ${e}: ${a.get("encoding")??"missing"}`);let c=a.get("checksum")?.replace(/^sha256:/,"");if(!c)return Bn(`Missing Hunsu runtime checksum in ${e}`);let u;try{u=jie(Buffer.from(s,"base64url")).toString("utf8")}catch(l){return Bn(`Invalid Hunsu runtime payload in ${e}: ${l instanceof Error?l.message:String(l)}`)}let d=Cg(u);if(d!==c)return Bn(`Hunsu runtime checksum mismatch in ${e}`);try{return S({value:JSON.parse(u),checksum:Jf(d)})}catch(l){return Bn(`Invalid Hunsu runtime JSON in ${e}: ${l instanceof Error?l.message:String(l)}`)}}function boe(t){let e=jt(t),r=fu(e,J1);if(!Ig(r))return;let n=Ag(Y8(Y1(r,"utf8"),r));return{state:n,checksum:Q8(n)}}function woe(t,e){let r=jt(t);try{let n=ke(["show",`${e}:${J1}`],{cwd:r}),i=Ag(Y8(n,`${e}:${J1}`));return{state:i,checksum:Q8(i)}}catch(n){if(n instanceof Tr)return;throw n}}function Y8(t,e){let r=fb(t,e,Gie);if(!r.ok)return r;let n=r.value.value;if(!n||typeof n!="object")return Bn(`Invalid legacy Hunsu runtime state JSON in ${e}: expected object`);let i=n;if(i.version!==1||!Array.isArray(i.events))return Bn(`Invalid legacy Hunsu runtime state in ${e}`);let o=[];for(let[s,a]of i.events.entries()){let c=ZS(a);if(!c.ok)return Bn(`Invalid legacy Hunsu runtime state event ${s} in ${e}: ${c.error.message}`);o.push(c.value)}return S({version:1,events:o,...typeof i.updatedAt=="string"?{updatedAt:i.updatedAt}:{}})}function Q8(t){return Jf(Cg(`${JSON.stringify(t)}
202
202
  `))}function Bn(t){return oe({type:"DomainStoreError",message:t})}function wg(t,e,r){let n=fu(t,e,r);try{return S(JSON.parse(Y1(n,"utf8")))}catch(i){return Bn(`Cannot read ${e}/${r}: ${i instanceof Error?i.message:String(i)}`)}}function Kd(t){return JSON.parse(JSON.stringify(t))}function ob(t){return JSON.stringify(X1(t))}function X1(t){return Array.isArray(t)?t.map(X1):t&&typeof t=="object"?Object.fromEntries(Object.entries(t).sort(([e],[r])=>e.localeCompare(r)).map(([e,r])=>[e,X1(r)])):t}function Ag(t){if(t.ok)return t.value;throw new Error(t.error.message)}function Ioe(t){try{return Kr(ke(["rev-parse","--verify","HEAD^{commit}"],{cwd:t}).trim())}catch(e){if(e instanceof Tr)return;throw e}}function Eoe(t){return t instanceof Error?"code"in t&&t.code==="ENOENT":!1}function Cg(t){return $ie("sha256").update(t).digest("hex")}function koe(t){let[e,r,n]=t.split(Jie);return{ref:e,object:r,objectType:n,ordinal:Roe(e)}}function Roe(t){let r=t.slice(t.lastIndexOf("/")+1).match(/^E(\d+)(?:-|$)/);return r?Number.parseInt(r[1],10):Number.MAX_SAFE_INTEGER}import{existsSync as Ls,readFileSync as t5,readdirSync as Aoe,statSync as Coe,writeFileSync as Poe}from"node:fs";import{basename as _oe,join as $a,resolve as Toe}from"node:path";var Boe="Port Git Project",Doe="Make this project ready for Hunsu-managed MOVEs and Artifact Actions.";function dA(t=process.cwd()){let e=Toe(t),r=[],n=e,i=!1;try{n=jt(e),i=!0}catch{r.push("Not a Git repository. Hunsu Port expects an existing Git project.")}let o=Moe(n),s=o?.scripts??{},a=Ooe(n,o),c=Z8(n,/^Dockerfile(?:\.|$)/),u=Z8(n,/^(?:docker-)?compose(?:\.[^.]+)?\.ya?ml$/),d=i&&r5(n),l=Noe(n),f=Loe(n,s),p=[];return!o&&i&&r.push("No package.json found. Port can still create Roadmap state, but Artifact Actions may need a later Hunsu setup."),i&&!d&&r.push("Hunsu runtime state is missing. Port apply will create Initial Team state."),{root:n,isGitRepository:i,isHunsuRoadmap:d,packageManager:a,packageScripts:s,docker:{dockerfiles:c,composeFiles:u},artifactActions:l,env:f,recommendedFiles:p,issues:r}}function lA(t={}){let e=dA(t.cwd);if(!e.isGitRepository)throw new Error("Hunsu Port requires an existing Git repository");let r=t.title?.trim()||_oe(e.root)||Boe,n=t.goal?.trim()||Doe,i=t.destinations&&t.destinations.length>0?t.destinations:[{id:"destination_001",title:"Establish artifact-action-ready product execution",priority:100}],o=e.isHunsuRoadmap?[]:[{type:"CreateInitialTeam",requestId:e5("req",r),lineId:`run/${e5("req",r)}`,title:r,goal:n,destinations:i,harness:t.harness}];return{root:e.root,title:r,goal:n,destinations:i,inspection:e,files:[],commands:o}}function fA(t={}){let e=lA(t),r=[];for(let i of e.files){let o=$a(e.root,i.path);Ls(o)||(Poe(o,i.content,"utf8"),r.push(i.path))}let n=e.commands.length>0?kg(e.commands,{cwd:e.root,commitMessage:`hunsu: port ${e.title}`}):{acceptedEvents:[],board:Dn(e.root).board};return{root:e.root,plan:e,writtenFiles:r,acceptedEvents:n.acceptedEvents,board:n.board}}function Noe(t){if(!r5(t))return{configured:!1,count:0,issues:[]};let e=Dn(t).board;return{configured:e.artifactActions.length>0,count:e.artifactActions.length,issues:[]}}function Ooe(t,e){if(Ls($a(t,"pnpm-lock.yaml"))||e?.packageManager?.startsWith("pnpm@"))return"pnpm";if(Ls($a(t,"yarn.lock"))||e?.packageManager?.startsWith("yarn@"))return"yarn";if(Ls($a(t,"bun.lockb"))||Ls($a(t,"bun.lock"))||e?.packageManager?.startsWith("bun@"))return"bun";if(Ls($a(t,"package-lock.json"))||e)return"npm"}function Moe(t){let e=$a(t,"package.json");if(Ls(e))return JSON.parse(t5(e,"utf8"))}function Z8(t,e){return!Ls(t)||!Coe(t).isDirectory()?[]:Aoe(t).filter(r=>e.test(r)).sort()}function r5(t){try{return Rg(t)||sA(t).length>0||ke(["for-each-ref","--count=1","--format=%(refname)","refs/hunsu"],{cwd:t}).trim().length>0}catch(e){if(e instanceof Tr)return!1;throw e}}function Loe(t,e){let r=[".env",".env.local",".env.development",".env.example"].filter(i=>Ls($a(t,i))),n=Object.entries(e).filter(([,i])=>/\b(?:3000|5173|8080|4187)\b|localhost|127\.0\.0\.1/.test(i)).map(([i])=>`package.json scripts.${i}`);for(let i of["vite.config.ts","vite.config.js","next.config.js","next.config.mjs"]){let o=$a(t,i);if(!Ls(o))continue;let s=t5(o,"utf8");/\b(?:3000|5173|8080|4187)\b|localhost|127\.0\.0\.1/.test(s)&&n.push(i)}return{files:r,hardcodedHints:n}}function e5(t,e){let r=e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"").slice(0,48);return`${t}_${r||"project"}`}import{createHash as Hoe}from"node:crypto";import{spawnSync as Uoe}from"node:child_process";import{existsSync as gb,mkdirSync as n5,readFileSync as $oe,readdirSync as Foe,rmSync as i5,writeFileSync as joe}from"node:fs";import{tmpdir as qoe}from"node:os";import{basename as Woe,join as pb,resolve as hA}from"node:path";function o5(t=process.cwd(),e){let r=jt(t),n=Dn(r);if(e){let i=n.board.moves.find(s=>s.id===e);if(!i)throw new Error(`No MOVE found for Artifact Action source: ${e}`);let o=n.board.nodes.find(s=>s.id===i.toNodeId);return hb(i.snapshot?.artifactActions??o?.artifactActions??[])}return hb(n.board.artifactActions)}function gA(t){let e=jt(t.cwd??process.cwd()),r=Voe(e,t),n=r.actions.find(d=>d.id===t.actionId);if(!n)throw new Error(`Unknown Artifact Action for selected source: ${t.actionId}`);Goe(n,r.source);let i=t.now??new Date().toISOString(),o=Qoe(n.id,r.source,i),s=t.baseActionPath??Yoe(t.roadmapId,o),a=n.kind==="host"?Koe(n,s):void 0,c=yA(n,t.env,t.ambientEnv),u={runId:o,actionId:n.id,roadmapId:t.roadmapId,action:mA(n),source:r.source,status:"queued",env:zoe(n,c),aliases:a,createdAt:i,updatedAt:i};return{action:mA(n),run:u,commands:u5(e,n,u,c)}}function s5(t,e={}){let r=jt(t.cwd??process.cwd()),n=gA(t),i=t.now??new Date().toISOString(),o=Xoe(r,n.run.runId,n.run.source.commit,i,t.worktreeRoot),s=t.processEnv??e.processEnv,a=e.runner??((l,f,p)=>h5(l,f,{...p,processEnv:s})),c={...n.run,status:(n.action.kind==="host","running"),sourceWorktree:o,updatedAt:i},u=yA(n.action,t.env,t.ambientEnv),d=u5(r,n.action,c,u);try{if(n.action.runner.type==="docker_compose")Pg(a,d[0]),Pg(a,d[1]),c.aliases=Joe(r,c,a,u),c.status="running";else{let l=Pg(a,d[0]);if(c.exitCode=l.status,c.stdout=l.stdout,c.stderr=l.stderr,c.status=n.action.kind==="host"?"running":"succeeded",n.action.kind==="check"){let f=mb(r,o.path);c.sourceWorktree={...o,removedAt:f}}}c.updatedAt=new Date().toISOString()}catch(l){c.status="failed",c.updatedAt=new Date().toISOString(),c.error=l instanceof Error?l.message:String(l);let f=mb(r,o.path);c.sourceWorktree={...o,removedAt:f}}if(e.store!==!1&&l5(r,c),c.status==="failed")throw new Error(c.error??`Artifact Action ${c.runId} failed`);return c}function a5(t=process.cwd()){let e=jt(t),r=vA(e);return gb(r)?Foe(r).filter(n=>n.endsWith(".json")).map(n=>_g(e,n.slice(0,-5))).sort((n,i)=>i.updatedAt.localeCompare(n.updatedAt)):[]}function _g(t,e){let r=jt(t),n=f5(r,e);if(!gb(n))throw new Error(`Unknown Artifact Action Run: ${e}`);return JSON.parse($oe(n,"utf8"))}function c5(t,e,r={}){let n=jt(t),i=_g(n,e),o=r.runner??((u,d,l)=>h5(u,d,{...l,processEnv:r.processEnv})),s=yA(i.action,i.env,r.processEnv);i.action.runner.type==="docker_compose"?Pg(o,pA(n,i,["down"],s)):i.action.runner.stopCommand&&Pg(o,d5(n,i,i.action.runner.stopCommand,s));let a=i.sourceWorktree?.path?mb(n,i.sourceWorktree.path):void 0,c={...i,sourceWorktree:i.sourceWorktree?{...i.sourceWorktree,removedAt:a}:void 0,status:"stopped",stoppedAt:new Date().toISOString(),updatedAt:new Date().toISOString()};return r.store!==!1&&l5(n,c),c}function Voe(t,e){if(e.moveId&&e.commit)throw new Error("Artifact Action source accepts either moveId or commit, not both");let r=Dn(t);if(e.moveId){let i=r.board.moves.find(s=>s.id===e.moveId);if(!i)throw new Error(`No MOVE found for Artifact Action source: ${e.moveId}`);let o=r.board.nodes.find(s=>s.id===i.toNodeId);return{source:{moveId:i.id,commit:ke(["rev-parse","--verify",`${i.commit}^{commit}`],{cwd:t}).trim(),ref:i.commit},actions:hb(i.snapshot?.artifactActions??o?.artifactActions??[])}}let n=e.commit??"HEAD";return{source:{commit:ke(["rev-parse","--verify",`${n}^{commit}`],{cwd:t}).trim(),ref:n},actions:hb(r.board.artifactActions)}}function Goe(t,e){if(t.sourceScope==="move"&&!e.moveId)throw new Error(`Artifact Action ${t.id} can only run against a MOVE source`);if(t.sourceScope==="commit"&&e.moveId)throw new Error(`Artifact Action ${t.id} can only run against a commit source`)}function yA(t,e={},r={}){let n={},i=new Set;for(let[o,s]of Object.entries(t.env??{}))if(i.add(o),"default"in s)n[o]=e[o]??String(s.default);else if("value"in s)n[o]=e[o]??String(s.value);else if("alias"in s){let a=t.aliases?.[s.alias];if(!a)throw new Error(`Artifact Action env ${o} references unknown alias: ${s.alias}`);n[o]=String(a.containerPort??a.target??"")}else if("fromAliasUrl"in s){let a=t.aliases?.[s.fromAliasUrl];if(!a)throw new Error(`Artifact Action env ${o} references unknown alias: ${s.fromAliasUrl}`);n[o]=a.service&&a.containerPort?`http://${a.service}:${a.containerPort}`:String(a.target??"")}else if(s.required){let a=e[o]??r[o];if(!a)throw new Error(`Artifact Action env ${o} is required but not set`);n[o]=a}for(let[o,s]of Object.entries(e))i.has(o)||(n[o]=s);return n}function zoe(t,e){let r={};for(let[n,i]of Object.entries(e)){let o=t.env?.[n];r[n]=o&&"required"in o&&o.secret?"<secret>":i}return r}function u5(t,e,r,n){return e.runner.type==="docker_compose"?[pA(t,r,["build"],n),pA(t,r,["up","-d"],n)]:[d5(t,r,e.runner.command,n)]}function pA(t,e,r,n){if(e.action.runner.type!=="docker_compose")throw new Error(`Artifact Action ${e.actionId} does not use docker compose`);let i=e.source.commit.slice(0,12),o=p5(m5(e.action.runner.projectName??`hunsu-${e.actionId}-${i}`,{actionId:e.actionId,runId:e.runId,commit:e.source.commit,shortCommit:i,moveId:e.source.moveId??""}));return{command:"docker",args:["compose","-f",hA(e.sourceWorktree?.path??t,e.action.runner.file),"-p",o,...r],cwd:e.sourceWorktree?.path??t,env:n}}function d5(t,e,r,n){return{command:"sh",args:["-lc",r],cwd:e.sourceWorktree?.path??t,env:n}}function Pg(t,e){let r=t(e.command,e.args,{cwd:e.cwd,env:e.env});if(r.status!==0)throw new Error(`${e.command} ${e.args.join(" ")} failed
203
203
  ${r.stderr||r.stdout}`);return r}function Koe(t,e){if(t.aliases)return Object.fromEntries(Object.entries(t.aliases).map(([r,n])=>[r,{alias:r,service:n.service,containerPort:n.containerPort,healthPath:n.healthPath,target:n.target,internalUrl:n.service&&n.containerPort?`http://${n.service}:${n.containerPort}`:n.target,externalPath:`${e}/${encodeURIComponent(r)}/`}]))}function Joe(t,e,r,n){if(!e.aliases||e.action.runner.type!=="docker_compose")return e.aliases;let i=e.action.runner;return Object.fromEntries(Object.entries(e.aliases).map(([o,s])=>{if(!s.service||!s.containerPort)return[o,s];let a=r("docker",["compose","-f",hA(e.sourceWorktree?.path??t,i.file),"-p",p5(m5(i.projectName??`hunsu-${e.actionId}-${e.source.commit.slice(0,12)}`,{actionId:e.actionId,runId:e.runId,commit:e.source.commit,shortCommit:e.source.commit.slice(0,12),moveId:e.source.moveId??""})),"port",s.service,String(s.containerPort)],{cwd:e.sourceWorktree?.path??t,env:n});return a.status!==0||!a.stdout.trim()?[o,s]:[o,{...s,directUrl:ese(a.stdout.trim())}]}))}function Xoe(t,e,r,n,i){let o=hA(i??pb(qoe(),"hunsu-action-runs",`${Woe(t)}-${Zoe(t)}`)),s=pb(o,xA(e));return n5(o,{recursive:!0}),gb(s)&&(mb(t,s),i5(s,{recursive:!0,force:!0})),ke(["worktree","add","--detach",s,r],{cwd:t}),{path:s,commit:r,createdAt:n}}function mb(t,e){let r=new Date().toISOString();if(!gb(e))return r;try{ke(["worktree","remove","--force",e],{cwd:t})}catch{i5(e,{recursive:!0,force:!0}),ke(["worktree","prune"],{cwd:t})}return r}function l5(t,e){n5(vA(t),{recursive:!0}),joe(f5(t,e.runId),`${JSON.stringify(e,null,2)}
204
- `,"utf8")}function vA(t){return pb(t,".hunsu","action-runs")}function f5(t,e){return pb(vA(t),`${xA(e)}.json`)}function Yoe(t,e){return t?`/api/roadmaps/${encodeURIComponent(t)}/action-runs/${encodeURIComponent(e)}/proxy`:`/api/action-runs/${encodeURIComponent(e)}/proxy`}function Qoe(t,e,r){return xA(`${t}-${e.moveId??e.commit.slice(0,12)}-${r.replace(/[^0-9A-Za-z]/g,"").slice(0,14)}`)}function xA(t){return t.toLowerCase().replace(/[^a-z0-9_.-]+/g,"-").replace(/^-+|-+$/g,"")||"action-run"}function p5(t){return t.toLowerCase().replace(/[^a-z0-9_-]+/g,"-").replace(/^-+|-+$/g,"").slice(0,63)||"hunsu-action"}function m5(t,e){return t.replace(/\{([a-zA-Z][a-zA-Z0-9]*)\}/g,(r,n)=>e[n]??"")}function Zoe(t){return Hoe("sha256").update(t).digest("hex").slice(0,12)}function ese(t){let e=t.split(/\r?\n/).find(Boolean)??t,r=e.match(/(?:0\.0\.0\.0|127\.0\.0\.1|localhost|\[::\]|::):(\d+)$/);return r?`http://127.0.0.1:${r[1]}`:/^https?:\/\//.test(e)?e:`http://${e}`}function h5(t,e,r){let n=Uoe(t,e,{cwd:r.cwd,env:{...tse(r.processEnv),...r.env},encoding:"utf8",maxBuffer:16777216});return{status:n.status??1,stdout:n.stdout,stderr:n.stderr}}function tse(t){if(t===void 0)return;let e={};for(let[r,n]of Object.entries(t))n!==void 0&&(e[r]=n);return e}function hb(t){return t.map(mA).sort((e,r)=>e.displayOrder-r.displayOrder||String(e.id).localeCompare(String(r.id)))}function mA(t){return{...t,env:t.env?Object.fromEntries(Object.entries(t.env).map(([e,r])=>[e,{...r}])):void 0,runner:{...t.runner},aliases:t.aliases?Object.fromEntries(Object.entries(t.aliases).map(([e,r])=>[e,{...r}])):void 0,evidence:t.evidence?{...t.evidence,paths:t.evidence.paths?.slice()}:void 0}}import{createHash as rse}from"node:crypto";var nse="hunsu.hub-package-manifest.v1",g5="hunsu-json-c14n-v1+sha256:";function ise(t){IA(t);let{integrity:e,...r}=t;return JSON.stringify(wA(r,"manifest"))}function ose(t){let e=ise(t);return`${g5}${rse("sha256").update(e,"utf8").digest("hex")}`}async function Tg(t,e){if(!t.integrity.startsWith(g5))throw new Error(`Unsupported Hub package integrity prefix: ${t.integrity}`);let r=e.origins.find(a=>a.name===t.origin);if(!r)throw new Error(`Unknown Origin: ${t.origin}`);if(r.transport!=="http")throw new Error(`Origin ${r.name} uses unsupported transport ${r.transport}`);let i=await(e.fetch??fetch)(sse(r.url,t.kind,t.key,t.version));if(!i.ok)throw i.status===404?new Error(`Missing Hub package manifest: ${t.origin}/${t.kind}/${t.key}@${t.version}`):new Error(`Origin ${r.name} returned ${i.status} for ${t.kind}/${t.key}@${t.version}`);let o=await i.json();if(IA(o),o.kind!==t.kind||o.key!==t.key||o.version!==t.version)throw new Error(`Hub package manifest from ${r.name} does not match requested ${t.kind}/${t.key}@${t.version}`);let s=ose(o);if(s!==t.integrity)throw new Error(`Hub package integrity mismatch for ${t.origin}/${t.kind}/${t.key}@${t.version}: expected ${t.integrity}, got ${s}`);return{lock:{...t},manifest:o,integrity:s,origin:{...r}}}function sse(t,e,r,n){let i=new URL(t),o=`/v1/packages/${e}/${encodeURIComponent(r)}/versions/${encodeURIComponent(n)}`;return new URL(o,i).toString()}function y5(t){if(IA(t),t.kind!=="team")throw new Error(`Hub package ${t.kind}/${t.key}@${t.version} is not a team package`);return fse(t.team)}function IA(t){let e=SA(t,"manifest");if(e.schema!==nse)throw new Error(`Unsupported Hub package manifest schema: ${String(e.schema)}`);bA(e,["integrity","key","kind","team","member","manager","schema","skill","version"],"manifest");let r=lse(e.kind,"manifest.kind");switch(Qf(e.key,"manifest.key"),Qf(e.version,"manifest.version"),e.integrity!==void 0&&Qf(e.integrity,"manifest.integrity"),r){case"team":if(ase(e.team),e.member!==void 0||e.manager!==void 0||e.skill!==void 0)throw new Error("Team package manifest must not include member, manager, or skill payloads");return;case"member":if(cse(e.member),e.team!==void 0||e.manager!==void 0||e.skill!==void 0)throw new Error("Member package manifest must not include team, manager, or skill payloads");return;case"manager":if(use(e.manager),e.team!==void 0||e.member!==void 0||e.skill!==void 0)throw new Error("Manager package manifest must not include team, member, or skill payloads");return;case"skill":if(dse(e.skill),e.team!==void 0||e.member!==void 0||e.manager!==void 0)throw new Error("Skill package manifest must not include team, member, or manager payloads");return}}function ase(t){let e=qd(t,"manifest.team");if(!e.ok)throw new Error(`Invalid manifest.team: ${e.error.message}`)}function cse(t){let e=e1(t,"manifest.member");if(!e.ok)throw new Error(`Invalid manifest.member: ${e.error.message}`)}function use(t){let e=Zh(t,"manifest.manager");if(!e.ok)throw new Error(`Invalid manifest.manager: ${e.error.message}`)}function dse(t){let e=SA(t,"manifest.skill");if(bA(e,["contentHash","files","name"],"manifest.skill"),Qf(e.name,"manifest.skill.name"),Qf(e.contentHash,"manifest.skill.contentHash"),e.files!==void 0){if(!Array.isArray(e.files))throw new Error("manifest.skill.files must be an array");for(let[r,n]of e.files.entries()){let i=SA(n,`manifest.skill.files[${r}]`);bA(i,["path","text"],`manifest.skill.files[${r}]`),Qf(i.path,`manifest.skill.files[${r}].path`),v5(i.text,`manifest.skill.files[${r}].text`)}}}function lse(t,e){if(t==="team"||t==="member"||t==="manager"||t==="skill")return t;throw new Error(`${e} must be team, member, manager, or skill`)}function SA(t,e){if(typeof t!="object"||t===null||Array.isArray(t))throw new Error(`${e} must be an object`);return t}function bA(t,e,r){let n=e.filter(o=>o!=="integrity"&&o!=="team"&&o!=="member"&&o!=="manager"&&o!=="skill"&&o!=="files"&&!(o in t));if(n.length>0)throw new Error(`${r} is missing required keys: ${n.join(", ")}`);let i=Object.keys(t).filter(o=>!e.includes(o));if(i.length>0)throw new Error(`${r} has unsupported keys: ${i.join(", ")}`)}function v5(t,e){if(typeof t!="string")throw new Error(`${e} must be a string`);return t}function Qf(t,e){let r=v5(t,e);if(r.trim().length===0)throw new Error(`${e} must be non-empty`);return r}function wA(t,e){if(t===null||typeof t=="string"||typeof t=="boolean")return t;if(typeof t=="number"){if(!Number.isFinite(t))throw new Error(`${e} must be a finite number`);return t}if(Array.isArray(t))return t.map((r,n)=>{if(r===void 0)throw new Error(`${e}[${n}] must not be undefined`);return wA(r,`${e}[${n}]`)});if(typeof t=="object"&&t!==null){let r=t,n={};for(let i of Object.keys(r).sort()){let o=r[i];o!==void 0&&(n[i]=wA(o,`${e}.${i}`))}return n}throw new Error(`${e} must be JSON-serializable`)}function fse(t){return JSON.parse(JSON.stringify(t))}function wt(t,e,r){return r===void 0?{code:t,message:e}:{code:t,message:e,details:r}}function Bg(t){let e=new Error(t.message);return e.name=`ExecuteOrchestrationError:${t.code}`,t.details!==void 0&&(e.details=t.details),e}function Jd(t){if(t.ok)return t.value;throw Bg(t.error)}function kA(t){let e=C5(t,"Team planning final response must be a JSON ExecutionPlan object");return e.ok?AA(e.value,"execution"):e}function S5(t){let e=C5(t,"Goal evaluator final response must be a JSON object");if(!e.ok)return e;let r=e.value;if(r.type==="pass"){if(typeof r.summary!="string"||r.summary.trim()==="")return oe(wt("goal_evaluation_invalid","pass evaluation must include a non-empty summary"));let n=EA(r.evidence,"evidence");return n.ok?S({type:"pass",summary:r.summary,evidence:n.value}):n}if(r.type==="fail"){if(typeof r.reason!="string"||r.reason.trim()==="")return oe(wt("goal_evaluation_invalid","fail evaluation must include a non-empty reason"));if(typeof r.feedback!="string"||r.feedback.trim()==="")return oe(wt("goal_evaluation_invalid","fail evaluation must include non-empty feedback"));if(r.nextGoal!==void 0&&typeof r.nextGoal!="string")return oe(wt("goal_evaluation_invalid","fail evaluation nextGoal must be a string when present"));let n=EA(r.evidence,"evidence");return n.ok?S({type:"fail",reason:r.reason,feedback:r.feedback,nextGoal:typeof r.nextGoal=="string"&&r.nextGoal.trim()!==""?r.nextGoal:void 0,evidence:n.value}):n}return oe(wt("goal_evaluation_invalid","Goal evaluator response type must be pass or fail"))}function RA(t,e,r,n){if(e==="assignee")return{id:r,executorId:t.assignee.executorId,goal:t.assignee.goal,requires:n};let i=t.evaluator;if(!i)throw new Error(`Goal ${t.id} does not define an evaluator`);return{id:r,executorId:i.executorId,goal:i.prompt,requires:n}}function b5(t,e){let[,...r]=t.items;if(e)return{...t,items:[e,...r]};if(r.length!==0)return{...t,items:r}}function AA(t,e){return Dg(t)?t.kind==="queue"?pse(t,e):t.kind==="goal"?w5(t,e):t.kind==="continuation"?mse(t,e):oe(wt("execution_plan_invalid",`${e}.kind must be queue, goal, or continuation`)):oe(wt("execution_plan_invalid",`${e} must be an object`))}function pse(t,e){let r=E5(t.id,`${e}.id`);if(!r.ok)return r;if(!Array.isArray(t.items))return oe(wt("execution_plan_invalid",`${e}.items must be an array`));let n=[];for(let[i,o]of t.items.entries()){let s=AA(o,`${e}.items[${i}]`);if(!s.ok)return s;n.push(s.value)}return S({kind:"queue",id:r.value,items:n})}function w5(t,e){return t.stage==="needs_evaluation"?I5(t,e):t.stage==="needs_execution"?hse(t,e):oe(wt("execution_plan_invalid",`${e}.stage must be needs_evaluation or needs_execution`))}function mse(t,e){let r=CA(t.id,`${e}.id`);if(!r.ok)return r;let n=k5(t.teamScopeId,`${e}.teamScopeId`);if(!n.ok)return n;let i=AA(t.execution,`${e}.execution`);if(!i.ok)return i;let o=t.continuation===void 0?S(void 0):Dg(t.continuation)?w5(t.continuation,`${e}.continuation`):oe(wt("execution_plan_invalid",`${e}.continuation must be an object`));return o.ok?S({kind:"continuation",id:r.value,teamScopeId:n.value,execution:i.value,continuation:o.value}):o}function I5(t,e){let r=CA(t.id,`${e}.id`);if(!r.ok)return r;let n=x5(t.assignee,`${e}.assignee`,"goal");if(!n.ok)return n;let i=t.evaluator===void 0||t.evaluator===null?S(void 0):x5(t.evaluator,`${e}.evaluator`,"prompt");if(!i.ok)return i;let o=N3(t.remainingAttempts,`${e}.remainingAttempts`);if(!o.ok)return oe(wt("execution_plan_invalid",o.error.message));let s=yse(t.requires,`${e}.requires`);return s.ok?S({kind:"goal",stage:"needs_evaluation",id:r.value,assignee:{executorId:n.value.executorId,goal:n.value.text},evaluator:i.value?{executorId:i.value.executorId,prompt:i.value.text}:void 0,remainingAttempts:o.value,requires:s.value}):s}function hse(t,e){let r=I5({...t,stage:"needs_evaluation"},e);if(!r.ok)return r;let n=CA(t.evaluationPathId,`${e}.evaluationPathId`);if(!n.ok)return n;let i=gse(t.evaluation,`${e}.evaluation`);if(!i.ok)return i;if(!Array.isArray(t.requires))return oe(wt("execution_plan_invalid",`${e}.requires must be an array for needs_execution`));let o=R5(t.requires,`${e}.requires`);return o.ok?o.value.length!==1||o.value[0]!==n.value?oe(wt("execution_plan_invalid",`${e}.requires must contain only ${e}.evaluationPathId`)):S({...r.value,stage:"needs_execution",evaluationPathId:n.value,evaluation:i.value,requires:o.value}):o}function x5(t,e,r){if(!Dg(t))return oe(wt("execution_plan_invalid",`${e} must be an object`));let n=k5(t.executorId,`${e}.executorId`);if(!n.ok)return n;let i=E5(t[r],`${e}.${r}`);return i.ok?S({executorId:n.value,text:i.value}):i}function gse(t,e){if(!Dg(t))return oe(wt("execution_plan_invalid",`${e} must be an object`));if(t.type!=="fail")return oe(wt("execution_plan_invalid",`${e}.type must be fail`));if(typeof t.reason!="string"||t.reason.trim()==="")return oe(wt("execution_plan_invalid",`${e}.reason must be a non-empty string`));if(typeof t.feedback!="string"||t.feedback.trim()==="")return oe(wt("execution_plan_invalid",`${e}.feedback must be a non-empty string`));if(t.nextGoal!==void 0&&typeof t.nextGoal!="string")return oe(wt("execution_plan_invalid",`${e}.nextGoal must be a string when present`));let r=EA(t.evidence,`${e}.evidence`);return r.ok?S({type:"fail",reason:t.reason,feedback:t.feedback,nextGoal:typeof t.nextGoal=="string"&&t.nextGoal.trim()!==""?t.nextGoal:void 0,evidence:r.value}):r}function E5(t,e){return typeof t!="string"||t.trim()===""?oe(wt("execution_plan_invalid",`${e} must be a non-empty string`)):S(t)}function CA(t,e){let r=Ie(t,e);return r.ok?S(r.value):oe(wt("execution_plan_invalid",r.error.message))}function k5(t,e){let r=Ie(t,e);return r.ok?S(r.value):oe(wt("execution_plan_invalid",r.error.message))}function yse(t,e){return t==="PrevMove"?S("PrevMove"):R5(t,e)}function R5(t,e){let r=A5(t,e,"execution_plan_invalid");if(!r.ok)return r;let n=[];for(let[i,o]of r.value.entries()){let s=Ie(o,`${e}[${i}]`);if(!s.ok)return oe(wt("execution_plan_invalid",s.error.message));n.push(s.value)}return S(n)}function EA(t,e){return t===void 0?S(void 0):A5(t,e,"goal_evaluation_invalid")}function A5(t,e,r){return Array.isArray(t)?t.every(n=>typeof n=="string")?S([...t]):oe(wt(r,`${e} must be an array of strings`)):oe(wt(r,`${e} must be an array of strings`))}function C5(t,e){try{let r=JSON.parse(t);return Dg(r)?S(r):oe(wt("execution_plan_invalid",e))}catch(r){return oe(wt("execution_plan_invalid",e,{cause:r instanceof Error?r.message:String(r)}))}}function Dg(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}function PA(t){let{line:e,lineNode:r}=t;if(!r)return oe(wt("invalid_start_state",`No execute-ready MOVE found for Team route ${e.id}`));if(e.status==="failed"||e.status==="complete"||e.status==="abandoned")return oe(wt("invalid_start_state",`Cannot start Execute from ${e.id} because the route is ${e.status}`));if(new Set(t.board.edges.filter(a=>a.type==="move").map(a=>a.fromNodeId)).has(r.id))return oe(wt("invalid_start_state",`Cannot start Execute from ${P5(r,t.formatMovePosition)} because Arrived or Accident already exists`));if(t.existingRuns.find(a=>a.sourceNodeId===r.id&&(a.status==="running"||a.status==="paused")))return oe(wt("active_execute_exists",`A Execute is already active for ${P5(r,t.formatMovePosition)}`));let o=Da(r.ordinal+1,"targetMoveOrdinal");if(!o.ok)return oe(wt("invalid_start_state",o.error.message));let s=vse(t.selectedDestinationIds,t.activeDestinations);return s.ok?S({lineNode:r,selectedDestinationIds:s.value,targetMoveOrdinal:o.value}):s}function _5(t){return t?S(t):oe(wt("terminal_output_missing","ExecutionPlan completed without a terminal output"))}function vse(t,e){let r=xse(e);return t&&t.length>0?t.length!==1?oe(wt("invalid_start_state","Execute must select exactly one Destination")):r&&t[0]===r.id?S([...t]):oe(wt("invalid_start_state","Execute must select the next Destination in the queue")):S(r?[r.id]:[])}function xse(t){return[...t].sort(Sse)[0]}function Sse(t,e){return(e.priority??0)-(t.priority??0)}function P5(t,e){return e?e(t):`${t.teamName??"Team"} MOVE ${t.ordinal}`}import{execFile as Ise,spawn as Ese}from"node:child_process";import{accessSync as kse,constants as Rse,existsSync as Ng,readdirSync as Ase,statSync as Cse}from"node:fs";import{delimiter as D5,isAbsolute as vb,join as Hs}from"node:path";import{promisify as Pse}from"node:util";function yb(t,e,r,n=process.platform){return n!=="win32"||!/\.(?:cmd|bat)$/iu.test(t)?{command:t,args:e}:{command:r.ComSpec??r.COMSPEC??"cmd.exe",args:["/d","/s","/v:off","/c",bse(t,e)],windowsVerbatimArguments:!0}}function bse(t,e){return`"${[t,...e].map(wse).join(" ")}"`}function wse(t){if(/[%"\u0000-\u001f\u007f]/u.test(t))throw new Error("Windows command-shim paths and arguments cannot contain percent, quote, or control characters.");return`"${t}"`}var dn="0.2.0-next.5",hu="local-bridge-v1";var Sb=Pse(Ise),Mg=3500;async function gu(t={}){let e=t.env??Rr(),r=t.platform??process.platform,n=await _se({env:e,platform:r,customBinaryPath:t.customBinaryPath}),i=[];for(let c of n){let u=await Tse(c,e,r,t.timeoutMs);if(i.push(u),c.rejectWhitespace&&u.error?.includes("HUNSU_CODEX_APP_SERVER_COMMAND"))return{installed:!1,source:u.source,appServerAvailable:!1,discovery:i,error:u.error};if(u.usable&&u.path)return{installed:!0,binaryPath:u.path,source:u.source,version:u.version,appServerAvailable:!0,discovery:i}}let o=i.find(c=>c.path&&c.versionOk===!0&&c.appServerOk===!1);if(o?.path)return{installed:!0,binaryPath:o.path,source:o.source,version:o.version,appServerAvailable:!1,discovery:i,error:o.error??"Codex was found, but Codex app-server is not available."};let s=i.find(c=>c.source==="windows_apps_alias"||c.path&&DA(c.path,r));if(s)return{installed:!1,binaryPath:s.path,source:"windows_apps_alias",appServerAvailable:!1,discovery:i,aliasDetected:!0,error:s.error??"Codex resolved to a WindowsApps execution alias. Select the real Codex binary path in Hunsu Bridge."};let a=i.find(c=>c.path)??i[0];return{installed:!1,binaryPath:a?.path,source:a?.source??"unknown",appServerAvailable:!1,discovery:i,error:a?.error??"Codex CLI was not found by Hunsu Bridge."}}async function bb(t){try{let e=t.env??Rr(),r=t.platform??process.platform,n=M5(t.binaryPath,["--version"],e,r),{stdout:i,stderr:o}=await Sb(n.command,n.args,{env:L5(e,r),timeout:t.timeoutMs??Mg,windowsHide:!0,windowsVerbatimArguments:n.windowsVerbatimArguments,maxBuffer:64*1024});return`${i}
204
+ `,"utf8")}function vA(t){return pb(t,".hunsu","action-runs")}function f5(t,e){return pb(vA(t),`${xA(e)}.json`)}function Yoe(t,e){return t?`/api/roadmaps/${encodeURIComponent(t)}/action-runs/${encodeURIComponent(e)}/proxy`:`/api/action-runs/${encodeURIComponent(e)}/proxy`}function Qoe(t,e,r){return xA(`${t}-${e.moveId??e.commit.slice(0,12)}-${r.replace(/[^0-9A-Za-z]/g,"").slice(0,14)}`)}function xA(t){return t.toLowerCase().replace(/[^a-z0-9_.-]+/g,"-").replace(/^-+|-+$/g,"")||"action-run"}function p5(t){return t.toLowerCase().replace(/[^a-z0-9_-]+/g,"-").replace(/^-+|-+$/g,"").slice(0,63)||"hunsu-action"}function m5(t,e){return t.replace(/\{([a-zA-Z][a-zA-Z0-9]*)\}/g,(r,n)=>e[n]??"")}function Zoe(t){return Hoe("sha256").update(t).digest("hex").slice(0,12)}function ese(t){let e=t.split(/\r?\n/).find(Boolean)??t,r=e.match(/(?:0\.0\.0\.0|127\.0\.0\.1|localhost|\[::\]|::):(\d+)$/);return r?`http://127.0.0.1:${r[1]}`:/^https?:\/\//.test(e)?e:`http://${e}`}function h5(t,e,r){let n=Uoe(t,e,{cwd:r.cwd,env:{...tse(r.processEnv),...r.env},encoding:"utf8",maxBuffer:16777216});return{status:n.status??1,stdout:n.stdout,stderr:n.stderr}}function tse(t){if(t===void 0)return;let e={};for(let[r,n]of Object.entries(t))n!==void 0&&(e[r]=n);return e}function hb(t){return t.map(mA).sort((e,r)=>e.displayOrder-r.displayOrder||String(e.id).localeCompare(String(r.id)))}function mA(t){return{...t,env:t.env?Object.fromEntries(Object.entries(t.env).map(([e,r])=>[e,{...r}])):void 0,runner:{...t.runner},aliases:t.aliases?Object.fromEntries(Object.entries(t.aliases).map(([e,r])=>[e,{...r}])):void 0,evidence:t.evidence?{...t.evidence,paths:t.evidence.paths?.slice()}:void 0}}import{createHash as rse}from"node:crypto";var nse="hunsu.hub-package-manifest.v1",g5="hunsu-json-c14n-v1+sha256:";function ise(t){IA(t);let{integrity:e,...r}=t;return JSON.stringify(wA(r,"manifest"))}function ose(t){let e=ise(t);return`${g5}${rse("sha256").update(e,"utf8").digest("hex")}`}async function Tg(t,e){if(!t.integrity.startsWith(g5))throw new Error(`Unsupported Hub package integrity prefix: ${t.integrity}`);let r=e.origins.find(a=>a.name===t.origin);if(!r)throw new Error(`Unknown Origin: ${t.origin}`);if(r.transport!=="http")throw new Error(`Origin ${r.name} uses unsupported transport ${r.transport}`);let i=await(e.fetch??fetch)(sse(r.url,t.kind,t.key,t.version));if(!i.ok)throw i.status===404?new Error(`Missing Hub package manifest: ${t.origin}/${t.kind}/${t.key}@${t.version}`):new Error(`Origin ${r.name} returned ${i.status} for ${t.kind}/${t.key}@${t.version}`);let o=await i.json();if(IA(o),o.kind!==t.kind||o.key!==t.key||o.version!==t.version)throw new Error(`Hub package manifest from ${r.name} does not match requested ${t.kind}/${t.key}@${t.version}`);let s=ose(o);if(s!==t.integrity)throw new Error(`Hub package integrity mismatch for ${t.origin}/${t.kind}/${t.key}@${t.version}: expected ${t.integrity}, got ${s}`);return{lock:{...t},manifest:o,integrity:s,origin:{...r}}}function sse(t,e,r,n){let i=new URL(t),o=`/v1/packages/${e}/${encodeURIComponent(r)}/versions/${encodeURIComponent(n)}`;return new URL(o,i).toString()}function y5(t){if(IA(t),t.kind!=="team")throw new Error(`Hub package ${t.kind}/${t.key}@${t.version} is not a team package`);return fse(t.team)}function IA(t){let e=SA(t,"manifest");if(e.schema!==nse)throw new Error(`Unsupported Hub package manifest schema: ${String(e.schema)}`);bA(e,["integrity","key","kind","team","member","manager","schema","skill","version"],"manifest");let r=lse(e.kind,"manifest.kind");switch(Qf(e.key,"manifest.key"),Qf(e.version,"manifest.version"),e.integrity!==void 0&&Qf(e.integrity,"manifest.integrity"),r){case"team":if(ase(e.team),e.member!==void 0||e.manager!==void 0||e.skill!==void 0)throw new Error("Team package manifest must not include member, manager, or skill payloads");return;case"member":if(cse(e.member),e.team!==void 0||e.manager!==void 0||e.skill!==void 0)throw new Error("Member package manifest must not include team, manager, or skill payloads");return;case"manager":if(use(e.manager),e.team!==void 0||e.member!==void 0||e.skill!==void 0)throw new Error("Manager package manifest must not include team, member, or skill payloads");return;case"skill":if(dse(e.skill),e.team!==void 0||e.member!==void 0||e.manager!==void 0)throw new Error("Skill package manifest must not include team, member, or manager payloads");return}}function ase(t){let e=qd(t,"manifest.team");if(!e.ok)throw new Error(`Invalid manifest.team: ${e.error.message}`)}function cse(t){let e=e1(t,"manifest.member");if(!e.ok)throw new Error(`Invalid manifest.member: ${e.error.message}`)}function use(t){let e=Zh(t,"manifest.manager");if(!e.ok)throw new Error(`Invalid manifest.manager: ${e.error.message}`)}function dse(t){let e=SA(t,"manifest.skill");if(bA(e,["contentHash","files","name"],"manifest.skill"),Qf(e.name,"manifest.skill.name"),Qf(e.contentHash,"manifest.skill.contentHash"),e.files!==void 0){if(!Array.isArray(e.files))throw new Error("manifest.skill.files must be an array");for(let[r,n]of e.files.entries()){let i=SA(n,`manifest.skill.files[${r}]`);bA(i,["path","text"],`manifest.skill.files[${r}]`),Qf(i.path,`manifest.skill.files[${r}].path`),v5(i.text,`manifest.skill.files[${r}].text`)}}}function lse(t,e){if(t==="team"||t==="member"||t==="manager"||t==="skill")return t;throw new Error(`${e} must be team, member, manager, or skill`)}function SA(t,e){if(typeof t!="object"||t===null||Array.isArray(t))throw new Error(`${e} must be an object`);return t}function bA(t,e,r){let n=e.filter(o=>o!=="integrity"&&o!=="team"&&o!=="member"&&o!=="manager"&&o!=="skill"&&o!=="files"&&!(o in t));if(n.length>0)throw new Error(`${r} is missing required keys: ${n.join(", ")}`);let i=Object.keys(t).filter(o=>!e.includes(o));if(i.length>0)throw new Error(`${r} has unsupported keys: ${i.join(", ")}`)}function v5(t,e){if(typeof t!="string")throw new Error(`${e} must be a string`);return t}function Qf(t,e){let r=v5(t,e);if(r.trim().length===0)throw new Error(`${e} must be non-empty`);return r}function wA(t,e){if(t===null||typeof t=="string"||typeof t=="boolean")return t;if(typeof t=="number"){if(!Number.isFinite(t))throw new Error(`${e} must be a finite number`);return t}if(Array.isArray(t))return t.map((r,n)=>{if(r===void 0)throw new Error(`${e}[${n}] must not be undefined`);return wA(r,`${e}[${n}]`)});if(typeof t=="object"&&t!==null){let r=t,n={};for(let i of Object.keys(r).sort()){let o=r[i];o!==void 0&&(n[i]=wA(o,`${e}.${i}`))}return n}throw new Error(`${e} must be JSON-serializable`)}function fse(t){return JSON.parse(JSON.stringify(t))}function wt(t,e,r){return r===void 0?{code:t,message:e}:{code:t,message:e,details:r}}function Bg(t){let e=new Error(t.message);return e.name=`ExecuteOrchestrationError:${t.code}`,t.details!==void 0&&(e.details=t.details),e}function Jd(t){if(t.ok)return t.value;throw Bg(t.error)}function kA(t){let e=C5(t,"Team planning final response must be a JSON ExecutionPlan object");return e.ok?AA(e.value,"execution"):e}function S5(t){let e=C5(t,"Goal evaluator final response must be a JSON object");if(!e.ok)return e;let r=e.value;if(r.type==="pass"){if(typeof r.summary!="string"||r.summary.trim()==="")return oe(wt("goal_evaluation_invalid","pass evaluation must include a non-empty summary"));let n=EA(r.evidence,"evidence");return n.ok?S({type:"pass",summary:r.summary,evidence:n.value}):n}if(r.type==="fail"){if(typeof r.reason!="string"||r.reason.trim()==="")return oe(wt("goal_evaluation_invalid","fail evaluation must include a non-empty reason"));if(typeof r.feedback!="string"||r.feedback.trim()==="")return oe(wt("goal_evaluation_invalid","fail evaluation must include non-empty feedback"));if(r.nextGoal!==void 0&&typeof r.nextGoal!="string")return oe(wt("goal_evaluation_invalid","fail evaluation nextGoal must be a string when present"));let n=EA(r.evidence,"evidence");return n.ok?S({type:"fail",reason:r.reason,feedback:r.feedback,nextGoal:typeof r.nextGoal=="string"&&r.nextGoal.trim()!==""?r.nextGoal:void 0,evidence:n.value}):n}return oe(wt("goal_evaluation_invalid","Goal evaluator response type must be pass or fail"))}function RA(t,e,r,n){if(e==="assignee")return{id:r,executorId:t.assignee.executorId,goal:t.assignee.goal,requires:n};let i=t.evaluator;if(!i)throw new Error(`Goal ${t.id} does not define an evaluator`);return{id:r,executorId:i.executorId,goal:i.prompt,requires:n}}function b5(t,e){let[,...r]=t.items;if(e)return{...t,items:[e,...r]};if(r.length!==0)return{...t,items:r}}function AA(t,e){return Dg(t)?t.kind==="queue"?pse(t,e):t.kind==="goal"?w5(t,e):t.kind==="continuation"?mse(t,e):oe(wt("execution_plan_invalid",`${e}.kind must be queue, goal, or continuation`)):oe(wt("execution_plan_invalid",`${e} must be an object`))}function pse(t,e){let r=E5(t.id,`${e}.id`);if(!r.ok)return r;if(!Array.isArray(t.items))return oe(wt("execution_plan_invalid",`${e}.items must be an array`));let n=[];for(let[i,o]of t.items.entries()){let s=AA(o,`${e}.items[${i}]`);if(!s.ok)return s;n.push(s.value)}return S({kind:"queue",id:r.value,items:n})}function w5(t,e){return t.stage==="needs_evaluation"?I5(t,e):t.stage==="needs_execution"?hse(t,e):oe(wt("execution_plan_invalid",`${e}.stage must be needs_evaluation or needs_execution`))}function mse(t,e){let r=CA(t.id,`${e}.id`);if(!r.ok)return r;let n=k5(t.teamScopeId,`${e}.teamScopeId`);if(!n.ok)return n;let i=AA(t.execution,`${e}.execution`);if(!i.ok)return i;let o=t.continuation===void 0?S(void 0):Dg(t.continuation)?w5(t.continuation,`${e}.continuation`):oe(wt("execution_plan_invalid",`${e}.continuation must be an object`));return o.ok?S({kind:"continuation",id:r.value,teamScopeId:n.value,execution:i.value,continuation:o.value}):o}function I5(t,e){let r=CA(t.id,`${e}.id`);if(!r.ok)return r;let n=x5(t.assignee,`${e}.assignee`,"goal");if(!n.ok)return n;let i=t.evaluator===void 0||t.evaluator===null?S(void 0):x5(t.evaluator,`${e}.evaluator`,"prompt");if(!i.ok)return i;let o=N3(t.remainingAttempts,`${e}.remainingAttempts`);if(!o.ok)return oe(wt("execution_plan_invalid",o.error.message));let s=yse(t.requires,`${e}.requires`);return s.ok?S({kind:"goal",stage:"needs_evaluation",id:r.value,assignee:{executorId:n.value.executorId,goal:n.value.text},evaluator:i.value?{executorId:i.value.executorId,prompt:i.value.text}:void 0,remainingAttempts:o.value,requires:s.value}):s}function hse(t,e){let r=I5({...t,stage:"needs_evaluation"},e);if(!r.ok)return r;let n=CA(t.evaluationPathId,`${e}.evaluationPathId`);if(!n.ok)return n;let i=gse(t.evaluation,`${e}.evaluation`);if(!i.ok)return i;if(!Array.isArray(t.requires))return oe(wt("execution_plan_invalid",`${e}.requires must be an array for needs_execution`));let o=R5(t.requires,`${e}.requires`);return o.ok?o.value.length!==1||o.value[0]!==n.value?oe(wt("execution_plan_invalid",`${e}.requires must contain only ${e}.evaluationPathId`)):S({...r.value,stage:"needs_execution",evaluationPathId:n.value,evaluation:i.value,requires:o.value}):o}function x5(t,e,r){if(!Dg(t))return oe(wt("execution_plan_invalid",`${e} must be an object`));let n=k5(t.executorId,`${e}.executorId`);if(!n.ok)return n;let i=E5(t[r],`${e}.${r}`);return i.ok?S({executorId:n.value,text:i.value}):i}function gse(t,e){if(!Dg(t))return oe(wt("execution_plan_invalid",`${e} must be an object`));if(t.type!=="fail")return oe(wt("execution_plan_invalid",`${e}.type must be fail`));if(typeof t.reason!="string"||t.reason.trim()==="")return oe(wt("execution_plan_invalid",`${e}.reason must be a non-empty string`));if(typeof t.feedback!="string"||t.feedback.trim()==="")return oe(wt("execution_plan_invalid",`${e}.feedback must be a non-empty string`));if(t.nextGoal!==void 0&&typeof t.nextGoal!="string")return oe(wt("execution_plan_invalid",`${e}.nextGoal must be a string when present`));let r=EA(t.evidence,`${e}.evidence`);return r.ok?S({type:"fail",reason:t.reason,feedback:t.feedback,nextGoal:typeof t.nextGoal=="string"&&t.nextGoal.trim()!==""?t.nextGoal:void 0,evidence:r.value}):r}function E5(t,e){return typeof t!="string"||t.trim()===""?oe(wt("execution_plan_invalid",`${e} must be a non-empty string`)):S(t)}function CA(t,e){let r=Ie(t,e);return r.ok?S(r.value):oe(wt("execution_plan_invalid",r.error.message))}function k5(t,e){let r=Ie(t,e);return r.ok?S(r.value):oe(wt("execution_plan_invalid",r.error.message))}function yse(t,e){return t==="PrevMove"?S("PrevMove"):R5(t,e)}function R5(t,e){let r=A5(t,e,"execution_plan_invalid");if(!r.ok)return r;let n=[];for(let[i,o]of r.value.entries()){let s=Ie(o,`${e}[${i}]`);if(!s.ok)return oe(wt("execution_plan_invalid",s.error.message));n.push(s.value)}return S(n)}function EA(t,e){return t===void 0?S(void 0):A5(t,e,"goal_evaluation_invalid")}function A5(t,e,r){return Array.isArray(t)?t.every(n=>typeof n=="string")?S([...t]):oe(wt(r,`${e} must be an array of strings`)):oe(wt(r,`${e} must be an array of strings`))}function C5(t,e){try{let r=JSON.parse(t);return Dg(r)?S(r):oe(wt("execution_plan_invalid",e))}catch(r){return oe(wt("execution_plan_invalid",e,{cause:r instanceof Error?r.message:String(r)}))}}function Dg(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}function PA(t){let{line:e,lineNode:r}=t;if(!r)return oe(wt("invalid_start_state",`No execute-ready MOVE found for Team route ${e.id}`));if(e.status==="failed"||e.status==="complete"||e.status==="abandoned")return oe(wt("invalid_start_state",`Cannot start Execute from ${e.id} because the route is ${e.status}`));if(new Set(t.board.edges.filter(a=>a.type==="move").map(a=>a.fromNodeId)).has(r.id))return oe(wt("invalid_start_state",`Cannot start Execute from ${P5(r,t.formatMovePosition)} because Arrived or Accident already exists`));if(t.existingRuns.find(a=>a.sourceNodeId===r.id&&(a.status==="running"||a.status==="paused")))return oe(wt("active_execute_exists",`A Execute is already active for ${P5(r,t.formatMovePosition)}`));let o=Da(r.ordinal+1,"targetMoveOrdinal");if(!o.ok)return oe(wt("invalid_start_state",o.error.message));let s=vse(t.selectedDestinationIds,t.activeDestinations);return s.ok?S({lineNode:r,selectedDestinationIds:s.value,targetMoveOrdinal:o.value}):s}function _5(t){return t?S(t):oe(wt("terminal_output_missing","ExecutionPlan completed without a terminal output"))}function vse(t,e){let r=xse(e);return t&&t.length>0?t.length!==1?oe(wt("invalid_start_state","Execute must select exactly one Destination")):r&&t[0]===r.id?S([...t]):oe(wt("invalid_start_state","Execute must select the next Destination in the queue")):S(r?[r.id]:[])}function xse(t){return[...t].sort(Sse)[0]}function Sse(t,e){return(e.priority??0)-(t.priority??0)}function P5(t,e){return e?e(t):`${t.teamName??"Team"} MOVE ${t.ordinal}`}import{execFile as Ise,spawn as Ese}from"node:child_process";import{accessSync as kse,constants as Rse,existsSync as Ng,readdirSync as Ase,statSync as Cse}from"node:fs";import{delimiter as D5,isAbsolute as vb,join as Hs}from"node:path";import{promisify as Pse}from"node:util";function yb(t,e,r,n=process.platform){return n!=="win32"||!/\.(?:cmd|bat)$/iu.test(t)?{command:t,args:e}:{command:r.ComSpec??r.COMSPEC??"cmd.exe",args:["/d","/s","/v:off","/c",bse(t,e)],windowsVerbatimArguments:!0}}function bse(t,e){return`"${[t,...e].map(wse).join(" ")}"`}function wse(t){if(/[%"\u0000-\u001f\u007f]/u.test(t))throw new Error("Windows command-shim paths and arguments cannot contain percent, quote, or control characters.");return`"${t}"`}var dn="0.2.0-next.6",hu="local-bridge-v1";var Sb=Pse(Ise),Mg=3500;async function gu(t={}){let e=t.env??Rr(),r=t.platform??process.platform,n=await _se({env:e,platform:r,customBinaryPath:t.customBinaryPath}),i=[];for(let c of n){let u=await Tse(c,e,r,t.timeoutMs);if(i.push(u),c.rejectWhitespace&&u.error?.includes("HUNSU_CODEX_APP_SERVER_COMMAND"))return{installed:!1,source:u.source,appServerAvailable:!1,discovery:i,error:u.error};if(u.usable&&u.path)return{installed:!0,binaryPath:u.path,source:u.source,version:u.version,appServerAvailable:!0,discovery:i}}let o=i.find(c=>c.path&&c.versionOk===!0&&c.appServerOk===!1);if(o?.path)return{installed:!0,binaryPath:o.path,source:o.source,version:o.version,appServerAvailable:!1,discovery:i,error:o.error??"Codex was found, but Codex app-server is not available."};let s=i.find(c=>c.source==="windows_apps_alias"||c.path&&DA(c.path,r));if(s)return{installed:!1,binaryPath:s.path,source:"windows_apps_alias",appServerAvailable:!1,discovery:i,aliasDetected:!0,error:s.error??"Codex resolved to a WindowsApps execution alias. Select the real Codex binary path in Hunsu Bridge."};let a=i.find(c=>c.path)??i[0];return{installed:!1,binaryPath:a?.path,source:a?.source??"unknown",appServerAvailable:!1,discovery:i,error:a?.error??"Codex CLI was not found by Hunsu Bridge."}}async function bb(t){try{let e=t.env??Rr(),r=t.platform??process.platform,n=M5(t.binaryPath,["--version"],e,r),{stdout:i,stderr:o}=await Sb(n.command,n.args,{env:L5(e,r),timeout:t.timeoutMs??Mg,windowsHide:!0,windowsVerbatimArguments:n.windowsVerbatimArguments,maxBuffer:64*1024});return`${i}
205
205
  ${o}`.trim().split(/\r?\n/).map(a=>a.trim()).find(Boolean)}catch{return}}async function N5(t){let e=t.env??Rr(),r=t.command?{ok:!0,value:{command:t.command,args:t.args??["app-server","--stdio"]}}:_A({env:e,cliBinaryPath:t.binaryPath});if(!r.ok)return{available:!1,error:r.error};let n=new Og(r.value.command,t.timeoutMs??Mg,{env:e,platform:t.platform,args:r.value.args});try{let i=await n.initialize();return{available:!0,initialized:Xr(i)}}catch(i){return{available:!1,error:Xd(i)}}finally{n.close()}}function _A(t){let e=t.env.HUNSU_CODEX_APP_SERVER_COMMAND?.trim();if(e&&/\s/.test(e))return{ok:!1,error:"HUNSU_CODEX_APP_SERVER_COMMAND must be a binary path or command name without arguments. Put arguments in HUNSU_CODEX_APP_SERVER_ARGS."};let r=zh(t.env);if(!r.ok)return{ok:!1,error:r.error.message};let n=t.cliBinaryPath?.trim();return{ok:!0,value:{command:r.value.command==="codex"&&n?n:r.value.command,args:r.value.args}}}function TA(t,e){if(e!=="win32")return[];let r=Zf(t,"LOCALAPPDATA","LocalAppData","localappdata"),n=Zf(t,"APPDATA","AppData","appdata");return Ib([r?Hs(r,"OpenAI","Codex","bin"):void 0,n?Hs(n,"npm"):void 0,r?Hs(r,"Programs","OpenAI Codex"):void 0])}function BA(t,e){return e!=="win32"?t.PATH??"":[t.PATH,t.Path,t.path,t.HUNSU_WINDOWS_USER_PATH,t.HUNSU_WINDOWS_MACHINE_PATH].filter(r=>typeof r=="string"&&r.trim().length>0).join(";")}async function _se(t){let{env:e,platform:r}=t,n=[],i=t.customBinaryPath?.trim();i&&n.push({candidate:i,source:"custom"});let o=e.HUNSU_CODEX_BINARY_PATH?.trim();o&&n.push({candidate:o,source:e.HUNSU_CODEX_BINARY_PATH_SOURCE==="user_config"?"custom":"env"});let s=e.HUNSU_CODEX_APP_SERVER_COMMAND?.trim();if(s&&n.push({candidate:s,source:"env",rejectWhitespace:!0}),n.push(...xb("codex",e,r,wb(e,r)).map(a=>({candidate:a,source:"process_path"}))),r==="win32"){n.push(...xb("codex",e,r,await T5("user",e,r)).map(c=>({candidate:c,source:"registry_user_path"}))),n.push(...xb("codex",e,r,await T5("machine",e,r)).map(c=>({candidate:c,source:"registry_machine_path"}))),n.push(...(await Ose(e)).map(c=>({candidate:c,source:"where"}))),n.push(...(await Mse(e)).map(c=>({candidate:c,source:"powershell_get_command"}))),n.push(...Nse(e,r).map(c=>({candidate:c,source:"known_install_dir"})));let a=Hse(e,r);a&&n.push({candidate:a,source:"windows_apps_alias"})}return $se(n)}async function Tse(t,e,r,n){let i=Bse(t.candidate,t.source,e,r,{rejectWhitespace:t.rejectWhitespace});if(i.kind!=="binary")return{source:i.source==="unknown"?t.source:i.source,path:i.kind==="missing"?i.binaryPath:void 0,usable:!1,error:i.error};let o=DA(i.binaryPath,r)?"windows_apps_alias":i.source;if(o==="windows_apps_alias")return{source:o,path:i.binaryPath,usable:!1,versionOk:!1,appServerOk:!1,error:"Codex resolved to a WindowsApps execution alias. Select the real Codex binary path in Hunsu Bridge."};let s=await bb({binaryPath:i.binaryPath,timeoutMs:n,env:e,platform:r});if(!s)return{source:o,path:i.binaryPath,usable:!1,versionOk:!1,appServerOk:!1,error:"Codex candidate did not return a CLI version."};let a=await N5({binaryPath:i.binaryPath,timeoutMs:n,env:e,platform:r});return a.available?{source:o,path:i.binaryPath,usable:!0,versionOk:!0,appServerOk:!0,version:s}:{source:o,path:i.binaryPath,usable:!1,versionOk:!0,appServerOk:!1,version:s,error:a.error}}function Bse(t,e,r,n,i={}){let o=t.trim();if(!o)return{kind:"missing",installed:!1,source:e??"unknown",error:"Codex command is empty."};if(i.rejectWhitespace&&/\s/.test(o))return{kind:"unsupported_command_string",installed:!1,source:"env",error:"HUNSU_CODEX_APP_SERVER_COMMAND must be a binary path or command name without arguments. Put arguments in HUNSU_CODEX_APP_SERVER_ARGS."};let s=vb(o)?o:Dse(o,r,n,wb(r,n));if(!s)return{kind:"missing",installed:!1,source:e??"unknown",binaryPath:vb(o)?o:void 0,error:vb(o)?"Configured Codex path does not exist.":`Codex command was not found on PATH: ${o}`};if(DA(s,n))return{kind:"missing",installed:!1,source:"windows_apps_alias",binaryPath:s,error:"Codex resolved to a WindowsApps execution alias. Select the real Codex binary path in Hunsu Bridge."};try{return Cse(s).isFile()?(n!=="win32"&&kse(s,Rse.X_OK),{kind:"binary",installed:!0,binaryPath:s,source:e==="unknown"||e===void 0?"process_path":e}):{kind:"missing",installed:!1,binaryPath:s,source:e??"unknown",error:"Configured Codex path is not a file."}}catch(a){return{kind:"missing",installed:!1,binaryPath:s,source:e??"unknown",error:Xd(a)}}}function Dse(t,e,r=process.platform,n=wb(e,r)){return xb(t,e,r,n)[0]}function xb(t,e,r=process.platform,n=wb(e,r)){if(vb(t))return Ng(t)?[t]:[];let i=r==="win32"?["",...(e.PATHEXT??e.PathExt??".EXE;.CMD;.BAT;.COM").split(";").filter(Boolean)]:[""],o=r==="win32"?";":D5,s=[];for(let a of n.split(o).filter(Boolean))for(let c of i){let u=Hs(a,r==="win32"&&!t.toUpperCase().endsWith(c.toUpperCase())?`${t}${c}`:t);Ng(u)&&s.push(u)}return Ib(s)}function Nse(t,e){if(e!=="win32")return[];let r=Zf(t,"LOCALAPPDATA","LocalAppData","localappdata"),n=Zf(t,"APPDATA","AppData","appdata"),i=[];if(r){let o=Hs(r,"OpenAI","Codex","bin");if(Ng(o))for(let s of Use(o))i.push(Hs(o,s,"codex.exe"));i.push(Hs(r,"OpenAI","Codex","bin","codex.exe"),Hs(r,"Programs","OpenAI Codex","codex.exe"))}return n&&i.push(Hs(n,"npm","codex.cmd")),Ib(i.filter(Ng))}async function T5(t,e,r){if(r!=="win32")return"";let n=t==="user"?e.HUNSU_WINDOWS_USER_PATH:e.HUNSU_WINDOWS_MACHINE_PATH;if(n?.trim())return B5(n,e);let i=t==="user"?"HKCU\\Environment":"HKLM\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment";try{let{stdout:o}=await Sb("reg.exe",["query",i,"/v","Path"],{env:e,timeout:1500,windowsHide:!0,maxBuffer:65536});return B5(Lse(o),e)}catch{return""}}async function Ose(t){try{let{stdout:e}=await Sb("where.exe",["codex"],{env:t,timeout:1500,windowsHide:!0,maxBuffer:65536});return O5(e)}catch{return[]}}async function Mse(t){let e="Get-Command codex -All | ForEach-Object { $_.Source }";for(let r of["powershell.exe","pwsh"])try{let{stdout:n}=await Sb(r,["-NoProfile","-Command",e],{env:r==="powershell.exe"?Ts(t):t,timeout:2e3,windowsHide:!0,maxBuffer:65536}),i=O5(n);if(i.length>0)return i}catch{}return[]}function Lse(t){return t.split(/\r?\n/).map(r=>r.trim()).find(r=>/^Path\s+REG_/i.test(r))?.replace(/^Path\s+REG_\w+\s+/i,"").trim()??""}function O5(t){return Ib(t.split(/\r?\n/).map(e=>e.trim()).filter(e=>e.length>0&&!/^[-\s]+$/.test(e)&&!/^CommandType\b|^Name\b|^Source\b/i.test(e)))}function Hse(t,e){if(e!=="win32")return;let r=Zf(t,"LOCALAPPDATA","LocalAppData","localappdata"),n=r?Hs(r,"Microsoft","WindowsApps","codex.exe"):void 0;return n&&Ng(n)?n:void 0}function wb(t,e){return e!=="win32"?t.PATH??"":[t.PATH,t.Path,t.path].filter(r=>typeof r=="string"&&r.trim().length>0).join(";")}function Use(t){try{return Ase(t,{withFileTypes:!0}).filter(e=>e.isDirectory()).map(e=>e.name)}catch{return[]}}function $se(t){let e=new Set,r=[];for(let n of t){let i=`${n.source}:${n.candidate}`;e.has(i)||(e.add(i),r.push(n))}return r}function Zf(t,...e){return e.map(r=>t[r]).find(r=>typeof r=="string"&&r.trim().length>0)?.trim()}function Ib(t){return[...new Set(t.filter(e=>typeof e=="string"&&e.length>0))]}function DA(t,e){return e==="win32"&&/(?:^|[\\/])WindowsApps[\\/]/i.test(t)}function B5(t,e){return t.replace(/%([^%]+)%/g,(r,n)=>{let i=n.trim(),o=Rr();return Zf(e,i,i.toUpperCase(),i.toLowerCase())??o[i]??r})}function M5(t,e,r,n){return yb(t,e,r,n)}function L5(t,e){let r=Rr(),n={...r,...t},i=e==="win32"?";":D5;for(let o of["PATH","Path","path"]){let s=t[o],a=r[o];if(s===""&&a){n[o]=a;continue}s&&a&&!s.split(i).includes(a)&&(n[o]=`${s}${i}${a}`)}return n}var Og=class{command;args;timeoutMs;child;nextId=1;buffer="";pending=new Map;constructor(e,r,n={}){this.command=e,this.args=n.args??["app-server","--stdio"],this.timeoutMs=r;let i=n.env??Rr(),o=n.platform??process.platform,s=M5(this.command,this.args,i,o);this.child=Ese(s.command,s.args,{env:L5(i,o),stdio:["pipe","pipe","pipe"],windowsHide:!0,windowsVerbatimArguments:s.windowsVerbatimArguments}),this.child.stdout.setEncoding("utf8"),this.child.stdout.on("data",a=>this.read(a)),this.child.stderr.setEncoding("utf8"),this.child.on("error",a=>this.rejectAll(a)),this.child.on("exit",()=>this.rejectAll(new Error("Codex app-server process exited before probe completed.")))}request(e,r){let n=this.nextId;return this.nextId+=1,new Promise((i,o)=>{let s=setTimeout(()=>{this.pending.delete(n),o(new Error(`Codex app-server probe timed out: ${e}`))},this.timeoutMs);this.pending.set(n,{resolve:i,reject:o,timer:s});try{this.write({jsonrpc:"2.0",id:n,method:e,params:r})}catch(a){clearTimeout(s),this.pending.delete(n),o(a instanceof Error?a:new Error(String(a)))}})}async initialize(){let e=await this.request("initialize",{clientInfo:{name:"hunsu-bridge",title:"Hunsu Bridge",version:dn}});return this.notify("initialized",{}),e}notify(e,r){this.write({jsonrpc:"2.0",method:e,params:r})}close(){this.rejectAll(new Error("Codex app-server probe closed.")),this.child.kill()}write(e){this.child.stdin.write(`${JSON.stringify(e)}
206
206
  `)}read(e){this.buffer+=e;let r=this.buffer.indexOf(`
207
207
  `);for(;r>=0;){let n=this.buffer.slice(0,r).trim();if(this.buffer=this.buffer.slice(r+1),r=this.buffer.indexOf(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hunsu/bridge",
3
- "version": "0.2.0-next.5",
3
+ "version": "0.2.0-next.6",
4
4
  "private": false,
5
5
  "description": "Headless Hunsu Bridge daemon, authenticated CLI, and local Web API.",
6
6
  "license": "Apache-2.0",
@@ -36,11 +36,11 @@
36
36
  "ipaddr.js": "2.4.0",
37
37
  "werift": "0.23.0",
38
38
  "ws": "8.21.0",
39
- "@hunsu/codex-runner": "0.1.1",
40
- "@hunsu/config": "0.1.1",
41
39
  "@hunsu/core": "0.1.1",
42
- "@hunsu/protocol": "0.1.1",
43
- "@hunsu/protocol-registry": "0.1.1"
40
+ "@hunsu/config": "0.1.1",
41
+ "@hunsu/codex-runner": "0.1.1",
42
+ "@hunsu/protocol-registry": "0.1.1",
43
+ "@hunsu/protocol": "0.1.1"
44
44
  },
45
45
  "scripts": {
46
46
  "dev": "node --conditions=development src/cli.ts dev",